all repos — mgba @ 33098926577f52a74730de1708a427e275a9bc88

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() | BATTERY_PERCENTAGE_VALID;
 76	int adapter = scePowerIsPowerOnline();
 77	int state = 0;
 78	if (adapter) {
 79		state |= BATTERY_CHARGING;
 80	}
 81	return state | charge;
 82}
 83
 84int main() {
 85	vita2d_init();
 86	struct GUIFont* font = GUIFontCreate();
 87	struct mGUIRunner runner = {
 88		.params = {
 89			PSP2_HORIZONTAL_PIXELS, PSP2_VERTICAL_PIXELS,
 90			font, "",
 91			_drawStart, _drawEnd,
 92			_pollInput, _pollCursor,
 93			_batteryState,
 94			0, 0,
 95		},
 96		.configExtra = (struct GUIMenuItem[]) {
 97			{
 98				.title = "Screen mode",
 99				.data = "screenMode",
100				.submenu = 0,
101				.state = 0,
102				.validStates = (const char*[]) {
103					"With Background",
104					"Without Background",
105					"Stretched",
106					"Fit Aspect Ratio",
107				},
108				.nStates = 4
109			},
110			{
111				.title = "Camera",
112				.data = "camera",
113				.submenu = 0,
114				.state = 1,
115				.validStates = (const char*[]) {
116					"None",
117					"Front",
118					"Back",
119				},
120				.nStates = 3
121			}
122		},
123		.keySources = (struct GUIInputKeys[]) {
124			{
125				.name = "Vita Input",
126				.id = PSP2_INPUT,
127				.keyNames = (const char*[]) {
128					"Select",
129					"L3",
130					"R3",
131					"Start",
132					"Up",
133					"Right",
134					"Down",
135					"Left",
136					"L2",
137					"R2",
138					"L1",
139					"R1",
140					"\1\xC",
141					"\1\xA",
142					"\1\xB",
143					"\1\xD"
144				},
145				.nKeys = 16
146			},
147			{ .id = 0 }
148		},
149		.nConfigExtra = 2,
150		.setup = mPSP2Setup,
151		.teardown = mPSP2Teardown,
152		.gameLoaded = mPSP2LoadROM,
153		.gameUnloaded = mPSP2UnloadROM,
154		.prepareForFrame = mPSP2Swap,
155		.drawFrame = mPSP2Draw,
156		.drawScreenshot = mPSP2DrawScreenshot,
157		.paused = mPSP2Paused,
158		.unpaused = mPSP2Unpaused,
159		.incrementScreenMode = mPSP2IncrementScreenMode,
160		.setFrameLimiter = mPSP2SetFrameLimiter,
161		.pollGameInput = mPSP2PollInput,
162		.running = mPSP2SystemPoll
163	};
164
165	sceTouchSetSamplingState(SCE_TOUCH_PORT_FRONT, SCE_TOUCH_SAMPLING_STATE_START);
166	sceCtrlSetSamplingMode(SCE_CTRL_MODE_ANALOG_WIDE);
167	sceCtrlSetSamplingModeExt(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}