all repos — mgba @ 789a84d2e25b2a6e7df0bb86351ec81726313eed

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	vita2d_set_vblank_wait(false);
 29	vita2d_start_drawing();
 30	vita2d_clear_screen();
 31}
 32
 33static void _drawEnd(void) {
 34	static int vcount = 0;
 35	extern bool frameLimiter;
 36	int oldVCount = vcount;
 37	vita2d_end_drawing();
 38	vcount = sceDisplayGetVcount();
 39	vita2d_set_vblank_wait(frameLimiter && vcount + 1 >= oldVCount);
 40	vita2d_swap_buffers();
 41}
 42
 43static uint32_t _pollInput(const struct mInputMap* map) {
 44	SceCtrlData pad;
 45	sceCtrlPeekBufferPositive(0, &pad, 1);
 46	int input = mInputMapKeyBits(map, PSP2_INPUT, pad.buttons, 0);
 47
 48	if (pad.buttons & SCE_CTRL_UP || pad.ly < 64) {
 49		input |= 1 << GUI_INPUT_UP;
 50	}
 51	if (pad.buttons & SCE_CTRL_DOWN || pad.ly >= 192) {
 52		input |= 1 << GUI_INPUT_DOWN;
 53	}
 54	if (pad.buttons & SCE_CTRL_LEFT || pad.lx < 64) {
 55		input |= 1 << GUI_INPUT_LEFT;
 56	}
 57	if (pad.buttons & SCE_CTRL_RIGHT || pad.lx >= 192) {
 58		input |= 1 << GUI_INPUT_RIGHT;
 59	}
 60
 61	return input;
 62}
 63
 64static enum GUICursorState _pollCursor(unsigned* x, unsigned* y) {
 65	SceTouchData touch;
 66	sceTouchPeek(SCE_TOUCH_PORT_FRONT, &touch, 1);
 67	if (touch.reportNum < 1) {
 68		return GUI_CURSOR_NOT_PRESENT;
 69	}
 70	*x = touch.report[0].x / 2;
 71	*y = touch.report[0].y / 2;
 72	return GUI_CURSOR_DOWN;
 73}
 74
 75static int _batteryState(void) {
 76	int charge = scePowerGetBatteryLifePercent();
 77	int adapter = scePowerIsPowerOnline();
 78	int state = 0;
 79	if (adapter) {
 80		state |= BATTERY_CHARGING;
 81	}
 82	charge /= 25;
 83	return state | charge;
 84}
 85
 86int main() {
 87	vita2d_init();
 88	struct GUIFont* font = GUIFontCreate();
 89	struct mGUIRunner runner = {
 90		.params = {
 91			PSP2_HORIZONTAL_PIXELS, PSP2_VERTICAL_PIXELS,
 92			font, "ux0:data", _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					0,
131					0,
132					"Start",
133					"Up",
134					"Right",
135					"Down",
136					"Left",
137					"L",
138					"R",
139					0, // L2?
140					0, // R2?
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 = mPSP2PrepareForFrame,
156		.drawFrame = mPSP2Draw,
157		.drawScreenshot = mPSP2DrawScreenshot,
158		.paused = mPSP2Paused,
159		.unpaused = mPSP2Unpaused,
160		.incrementScreenMode = mPSP2IncrementScreenMode,
161		.setFrameLimiter = mPSP2SetFrameLimiter,
162		.pollGameInput = mPSP2PollInput
163	};
164
165	sceTouchSetSamplingState(SCE_TOUCH_PORT_FRONT, SCE_TOUCH_SAMPLING_STATE_START);
166	sceCtrlSetSamplingMode(SCE_CTRL_MODE_ANALOG_WIDE);
167	sceSysmoduleLoadModule(SCE_SYSMODULE_PHOTO_EXPORT);
168	sceSysmoduleLoadModule(SCE_SYSMODULE_APPUTIL);
169
170	mGUIInit(&runner, "psvita");
171
172	int enterButton;
173	SceAppUtilInitParam initParam;
174	SceAppUtilBootParam bootParam;
175	memset(&initParam, 0, sizeof(SceAppUtilInitParam));
176	memset(&bootParam, 0, sizeof(SceAppUtilBootParam));
177	sceAppUtilInit(&initParam, &bootParam);
178	sceAppUtilSystemParamGetInt(SCE_SYSTEM_PARAM_ID_ENTER_BUTTON, &enterButton);
179	sceAppUtilShutdown();
180
181	if (enterButton == SCE_SYSTEM_PARAM_ENTER_BUTTON_CIRCLE) {
182		mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_CROSS, GUI_INPUT_BACK);
183		mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_CIRCLE, GUI_INPUT_SELECT);
184	} else {
185		mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_CROSS, GUI_INPUT_SELECT);
186		mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_CIRCLE, GUI_INPUT_BACK);
187	}
188	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_TRIANGLE, GUI_INPUT_CANCEL);
189	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_UP, GUI_INPUT_UP);
190	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_DOWN, GUI_INPUT_DOWN);
191	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_LEFT, GUI_INPUT_LEFT);
192	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_RIGHT, GUI_INPUT_RIGHT);
193	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_SQUARE, mGUI_INPUT_SCREEN_MODE);
194
195	scePowerSetArmClockFrequency(444);
196	mGUIRunloop(&runner);
197
198	vita2d_fini();
199	mGUIDeinit(&runner);
200
201	int pgfLoaded = sceSysmoduleIsLoaded(SCE_SYSMODULE_PGF);
202	if (pgfLoaded != SCE_SYSMODULE_LOADED) {
203		sceSysmoduleLoadModule(SCE_SYSMODULE_PGF);
204	}
205	GUIFontDestroy(font);
206	sceSysmoduleUnloadModule(SCE_SYSMODULE_PGF);
207
208	sceKernelExitProcess(0);
209	return 0;
210}