all repos — mgba @ 9efb41ecd5ea3e692fdf15ddc65999077f101eb2

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 "gba/gba.h"
  9#include "feature/gui/gui-runner.h"
 10#include "util/gui.h"
 11#include "util/gui/font.h"
 12#include "util/gui/file-select.h"
 13#include "util/gui/menu.h"
 14
 15#include <psp2/ctrl.h>
 16#include <psp2/display.h>
 17#include <psp2/kernel/processmgr.h>
 18#include <psp2/kernel/threadmgr.h>
 19#include <psp2/moduleinfo.h>
 20#include <psp2/power.h>
 21#include <psp2/sysmodule.h>
 22#include <psp2/touch.h>
 23
 24#include <vita2d.h>
 25
 26static void _drawStart(void) {
 27	vita2d_set_vblank_wait(false);
 28	vita2d_start_drawing();
 29	vita2d_clear_screen();
 30}
 31
 32static void _drawEnd(void) {
 33	static int vcount = 0;
 34	extern bool frameLimiter;
 35	int oldVCount = vcount;
 36	vita2d_end_drawing();
 37	vcount = sceDisplayGetVcount();
 38	vita2d_set_vblank_wait(frameLimiter && vcount + 1 >= oldVCount);
 39	vita2d_swap_buffers();
 40}
 41
 42static uint32_t _pollInput(const struct mInputMap* map) {
 43	SceCtrlData pad;
 44	sceCtrlPeekBufferPositive(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, "ux0:", _drawStart, _drawEnd,
 92			_pollInput, _pollCursor,
 93			_batteryState,
 94			0, 0,
 95
 96			GUI_PARAMS_TRAIL
 97		},
 98		.configExtra = (struct GUIMenuItem[]) {
 99			{
100				.title = "Screen mode",
101				.data = "screenMode",
102				.submenu = 0,
103				.state = 0,
104				.validStates = (const char*[]) {
105					"With Background",
106					"Without Background",
107					"Stretched",
108					"Fit Aspect Ratio",
109				},
110				.nStates = 4
111			}
112		},
113		.keySources = (struct GUIInputKeys[]) {
114			{
115				.name = "Vita Input",
116				.id = PSP2_INPUT,
117				.keyNames = (const char*[]) {
118					"Select",
119					0,
120					0,
121					"Start",
122					"Up",
123					"Right",
124					"Down",
125					"Left",
126					"L",
127					"R",
128					0, // L2?
129					0, // R2?
130					"\1\xC",
131					"\1\xA",
132					"\1\xB",
133					"\1\xD"
134				},
135				.nKeys = 16
136			},
137			{ .id = 0 }
138		},
139		.nConfigExtra = 1,
140		.setup = mPSP2Setup,
141		.teardown = mPSP2Teardown,
142		.gameLoaded = mPSP2LoadROM,
143		.gameUnloaded = mPSP2UnloadROM,
144		.prepareForFrame = mPSP2PrepareForFrame,
145		.drawFrame = mPSP2Draw,
146		.drawScreenshot = mPSP2DrawScreenshot,
147		.paused = mPSP2Paused,
148		.unpaused = mPSP2Unpaused,
149		.incrementScreenMode = mPSP2IncrementScreenMode,
150		.setFrameLimiter = mPSP2SetFrameLimiter,
151		.pollGameInput = mPSP2PollInput
152	};
153
154	sceTouchSetSamplingState(SCE_TOUCH_PORT_FRONT, SCE_TOUCH_SAMPLING_STATE_START);
155	sceCtrlSetSamplingMode(SCE_CTRL_MODE_ANALOG_WIDE);
156
157	mGUIInit(&runner, "psvita");
158
159	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_CROSS, GUI_INPUT_SELECT);
160	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_CIRCLE, GUI_INPUT_BACK);
161	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_TRIANGLE, GUI_INPUT_CANCEL);
162	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_UP, GUI_INPUT_UP);
163	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_DOWN, GUI_INPUT_DOWN);
164	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_LEFT, GUI_INPUT_LEFT);
165	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_RIGHT, GUI_INPUT_RIGHT);
166	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_SQUARE, mGUI_INPUT_SCREEN_MODE);
167
168	mGUIRunloop(&runner);
169
170	vita2d_fini();
171	mGUIDeinit(&runner);
172
173	int pgfLoaded = sceSysmoduleIsLoaded(SCE_SYSMODULE_PGF);
174	if (pgfLoaded != SCE_SYSMODULE_LOADED) {
175		sceSysmoduleLoadModule(SCE_SYSMODULE_PGF);
176	}
177	GUIFontDestroy(font);
178	sceSysmoduleUnloadModule(SCE_SYSMODULE_PGF);
179
180	sceKernelExitProcess(0);
181	return 0;
182}