all repos — mgba @ 1402593855729beaca177d43700eb462bd8c123d

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 = mPSP2Swap,
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	sceCtrlSetSamplingModeExt(SCE_CTRL_MODE_ANALOG_WIDE);
169	sceSysmoduleLoadModule(SCE_SYSMODULE_PHOTO_EXPORT);
170	sceSysmoduleLoadModule(SCE_SYSMODULE_APPUTIL);
171
172	mGUIInit(&runner, "psvita");
173
174	int enterButton;
175	SceAppUtilInitParam initParam;
176	SceAppUtilBootParam bootParam;
177	memset(&initParam, 0, sizeof(SceAppUtilInitParam));
178	memset(&bootParam, 0, sizeof(SceAppUtilBootParam));
179	sceAppUtilInit(&initParam, &bootParam);
180	sceAppUtilSystemParamGetInt(SCE_SYSTEM_PARAM_ID_ENTER_BUTTON, &enterButton);
181	sceAppUtilShutdown();
182
183	if (enterButton == SCE_SYSTEM_PARAM_ENTER_BUTTON_CIRCLE) {
184		mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_CROSS, GUI_INPUT_BACK);
185		mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_CIRCLE, GUI_INPUT_SELECT);
186	} else {
187		mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_CROSS, GUI_INPUT_SELECT);
188		mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_CIRCLE, GUI_INPUT_BACK);
189	}
190	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_TRIANGLE, GUI_INPUT_CANCEL);
191	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_UP, GUI_INPUT_UP);
192	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_DOWN, GUI_INPUT_DOWN);
193	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_LEFT, GUI_INPUT_LEFT);
194	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_RIGHT, GUI_INPUT_RIGHT);
195	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_SQUARE, mGUI_INPUT_SCREEN_MODE);
196
197	scePowerSetArmClockFrequency(444);
198	mGUIRunloop(&runner);
199
200	vita2d_fini();
201	mGUIDeinit(&runner);
202
203	int pgfLoaded = sceSysmoduleIsLoaded(SCE_SYSMODULE_PGF);
204	if (pgfLoaded != SCE_SYSMODULE_LOADED) {
205		sceSysmoduleLoadModule(SCE_SYSMODULE_PGF);
206	}
207	GUIFontDestroy(font);
208	sceSysmoduleUnloadModule(SCE_SYSMODULE_PGF);
209
210	sceKernelExitProcess(0);
211	return 0;
212}