all repos — mgba @ f6755a6e1b7b0cf2b944cd8ca842746f11d6bf82

mGBA Game Boy Advance Emulator

src/platform/psp2/main.c (view raw)

  1/* Copyright (c) 2013-2015 Jeffrey Pfau
  2 *
  3 * This Source Code Form is subject to the terms of the Mozilla Public
  4 * License, v. 2.0. If a copy of the MPL was not distributed with this
  5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6#include "psp2-context.h"
  7
  8#include <mgba/internal/gba/gba.h>
  9#include "feature/gui/gui-runner.h"
 10#include <mgba-util/gui.h>
 11#include <mgba-util/gui/font.h>
 12#include <mgba-util/gui/file-select.h>
 13#include <mgba-util/gui/menu.h>
 14
 15#include <psp2/apputil.h>
 16#include <psp2/ctrl.h>
 17#include <psp2/display.h>
 18#include <psp2/kernel/processmgr.h>
 19#include <psp2/kernel/threadmgr.h>
 20#include <psp2/power.h>
 21#include <psp2/sysmodule.h>
 22#include <psp2/system_param.h>
 23#include <psp2/touch.h>
 24
 25#include <vita2d.h>
 26
 27static void _drawStart(void) {
 28	static int vcount = 0;
 29	extern bool frameLimiter;
 30	int oldVCount = vcount;
 31	vcount = sceDisplayGetVcount();
 32	vita2d_set_vblank_wait(frameLimiter && vcount + 1 >= oldVCount);
 33	vita2d_start_drawing();
 34	vita2d_clear_screen();
 35}
 36
 37static void _drawEnd(void) {
 38	vita2d_end_drawing();
 39	vita2d_swap_buffers();
 40}
 41
 42static uint32_t _pollInput(const struct mInputMap* map) {
 43	SceCtrlData pad;
 44	sceCtrlPeekBufferPositiveExt2(0, &pad, 1);
 45	int input = mInputMapKeyBits(map, PSP2_INPUT, pad.buttons, 0);
 46
 47	if (pad.buttons & SCE_CTRL_UP || pad.ly < 64) {
 48		input |= 1 << GUI_INPUT_UP;
 49	}
 50	if (pad.buttons & SCE_CTRL_DOWN || pad.ly >= 192) {
 51		input |= 1 << GUI_INPUT_DOWN;
 52	}
 53	if (pad.buttons & SCE_CTRL_LEFT || pad.lx < 64) {
 54		input |= 1 << GUI_INPUT_LEFT;
 55	}
 56	if (pad.buttons & SCE_CTRL_RIGHT || pad.lx >= 192) {
 57		input |= 1 << GUI_INPUT_RIGHT;
 58	}
 59
 60	return input;
 61}
 62
 63static enum GUICursorState _pollCursor(unsigned* x, unsigned* y) {
 64	SceTouchData touch;
 65	sceTouchPeek(SCE_TOUCH_PORT_FRONT, &touch, 1);
 66	if (touch.reportNum < 1) {
 67		return GUI_CURSOR_NOT_PRESENT;
 68	}
 69	*x = touch.report[0].x / 2;
 70	*y = touch.report[0].y / 2;
 71	return GUI_CURSOR_DOWN;
 72}
 73
 74static int _batteryState(void) {
 75	int charge = scePowerGetBatteryLifePercent();
 76	int adapter = scePowerIsPowerOnline();
 77	int state = 0;
 78	if (adapter) {
 79		state |= BATTERY_CHARGING;
 80	}
 81	charge /= 25;
 82	return state | charge;
 83}
 84
 85int main() {
 86	vita2d_init();
 87	struct GUIFont* font = GUIFontCreate();
 88	struct mGUIRunner runner = {
 89		.params = {
 90			PSP2_HORIZONTAL_PIXELS, PSP2_VERTICAL_PIXELS,
 91			font, "",
 92			_drawStart, _drawEnd,
 93			_pollInput, _pollCursor,
 94			_batteryState,
 95			0, 0,
 96		},
 97		.configExtra = (struct GUIMenuItem[]) {
 98			{
 99				.title = "Screen mode",
100				.data = "screenMode",
101				.submenu = 0,
102				.state = 0,
103				.validStates = (const char*[]) {
104					"With Background",
105					"Without Background",
106					"Stretched",
107					"Fit Aspect Ratio",
108				},
109				.nStates = 4
110			},
111			{
112				.title = "Camera",
113				.data = "camera",
114				.submenu = 0,
115				.state = 1,
116				.validStates = (const char*[]) {
117					"None",
118					"Front",
119					"Back",
120				},
121				.nStates = 3
122			}
123		},
124		.keySources = (struct GUIInputKeys[]) {
125			{
126				.name = "Vita Input",
127				.id = PSP2_INPUT,
128				.keyNames = (const char*[]) {
129					"Select",
130					"L3",
131					"R3",
132					"Start",
133					"Up",
134					"Right",
135					"Down",
136					"Left",
137					"L2",
138					"R2",
139					"L1",
140					"R1",
141					"\1\xC",
142					"\1\xA",
143					"\1\xB",
144					"\1\xD"
145				},
146				.nKeys = 16
147			},
148			{ .id = 0 }
149		},
150		.nConfigExtra = 2,
151		.setup = mPSP2Setup,
152		.teardown = mPSP2Teardown,
153		.gameLoaded = mPSP2LoadROM,
154		.gameUnloaded = mPSP2UnloadROM,
155		.prepareForFrame = NULL,
156		.drawFrame = mPSP2Draw,
157		.drawScreenshot = mPSP2DrawScreenshot,
158		.paused = mPSP2Paused,
159		.unpaused = mPSP2Unpaused,
160		.incrementScreenMode = mPSP2IncrementScreenMode,
161		.setFrameLimiter = mPSP2SetFrameLimiter,
162		.pollGameInput = mPSP2PollInput,
163		.running = mPSP2SystemPoll
164	};
165
166	sceTouchSetSamplingState(SCE_TOUCH_PORT_FRONT, SCE_TOUCH_SAMPLING_STATE_START);
167	sceCtrlSetSamplingMode(SCE_CTRL_MODE_ANALOG_WIDE);
168	sceSysmoduleLoadModule(SCE_SYSMODULE_PHOTO_EXPORT);
169	sceSysmoduleLoadModule(SCE_SYSMODULE_APPUTIL);
170
171	mGUIInit(&runner, "psvita");
172
173	int enterButton;
174	SceAppUtilInitParam initParam;
175	SceAppUtilBootParam bootParam;
176	memset(&initParam, 0, sizeof(SceAppUtilInitParam));
177	memset(&bootParam, 0, sizeof(SceAppUtilBootParam));
178	sceAppUtilInit(&initParam, &bootParam);
179	sceAppUtilSystemParamGetInt(SCE_SYSTEM_PARAM_ID_ENTER_BUTTON, &enterButton);
180	sceAppUtilShutdown();
181
182	if (enterButton == SCE_SYSTEM_PARAM_ENTER_BUTTON_CIRCLE) {
183		mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_CROSS, GUI_INPUT_BACK);
184		mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_CIRCLE, GUI_INPUT_SELECT);
185	} else {
186		mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_CROSS, GUI_INPUT_SELECT);
187		mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_CIRCLE, GUI_INPUT_BACK);
188	}
189	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_TRIANGLE, GUI_INPUT_CANCEL);
190	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_UP, GUI_INPUT_UP);
191	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_DOWN, GUI_INPUT_DOWN);
192	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_LEFT, GUI_INPUT_LEFT);
193	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_RIGHT, GUI_INPUT_RIGHT);
194	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_SQUARE, mGUI_INPUT_SCREEN_MODE);
195
196	scePowerSetArmClockFrequency(444);
197	mGUIRunloop(&runner);
198
199	vita2d_fini();
200	mGUIDeinit(&runner);
201
202	int pgfLoaded = sceSysmoduleIsLoaded(SCE_SYSMODULE_PGF);
203	if (pgfLoaded != SCE_SYSMODULE_LOADED) {
204		sceSysmoduleLoadModule(SCE_SYSMODULE_PGF);
205	}
206	GUIFontDestroy(font);
207	sceSysmoduleUnloadModule(SCE_SYSMODULE_PGF);
208
209	sceKernelExitProcess(0);
210	return 0;
211}