all repos — mgba @ f116713f2eb6303f8efef8370b033efd3c97e23a

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/ctrl.h>
 16#include <psp2/display.h>
 17#include <psp2/kernel/processmgr.h>
 18#include <psp2/kernel/threadmgr.h>
 19#include <psp2/power.h>
 20#include <psp2/sysmodule.h>
 21#include <psp2/touch.h>
 22
 23#include <vita2d.h>
 24
 25static void _drawStart(void) {
 26	vita2d_set_vblank_wait(false);
 27	vita2d_start_drawing();
 28	vita2d_clear_screen();
 29}
 30
 31static void _drawEnd(void) {
 32	static int vcount = 0;
 33	extern bool frameLimiter;
 34	int oldVCount = vcount;
 35	vita2d_end_drawing();
 36	vcount = sceDisplayGetVcount();
 37	vita2d_set_vblank_wait(frameLimiter && vcount + 1 >= oldVCount);
 38	vita2d_swap_buffers();
 39}
 40
 41static uint32_t _pollInput(const struct mInputMap* map) {
 42	SceCtrlData pad;
 43	sceCtrlPeekBufferPositive(0, &pad, 1);
 44	int input = mInputMapKeyBits(map, PSP2_INPUT, pad.buttons, 0);
 45
 46	if (pad.buttons & SCE_CTRL_UP || pad.ly < 64) {
 47		input |= 1 << GUI_INPUT_UP;
 48	}
 49	if (pad.buttons & SCE_CTRL_DOWN || pad.ly >= 192) {
 50		input |= 1 << GUI_INPUT_DOWN;
 51	}
 52	if (pad.buttons & SCE_CTRL_LEFT || pad.lx < 64) {
 53		input |= 1 << GUI_INPUT_LEFT;
 54	}
 55	if (pad.buttons & SCE_CTRL_RIGHT || pad.lx >= 192) {
 56		input |= 1 << GUI_INPUT_RIGHT;
 57	}
 58
 59	return input;
 60}
 61
 62static enum GUICursorState _pollCursor(unsigned* x, unsigned* y) {
 63	SceTouchData touch;
 64	sceTouchPeek(SCE_TOUCH_PORT_FRONT, &touch, 1);
 65	if (touch.reportNum < 1) {
 66		return GUI_CURSOR_NOT_PRESENT;
 67	}
 68	*x = touch.report[0].x / 2;
 69	*y = touch.report[0].y / 2;
 70	return GUI_CURSOR_DOWN;
 71}
 72
 73static int _batteryState(void) {
 74	int charge = scePowerGetBatteryLifePercent();
 75	int adapter = scePowerIsPowerOnline();
 76	int state = 0;
 77	if (adapter) {
 78		state |= BATTERY_CHARGING;
 79	}
 80	charge /= 25;
 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, "ux0:data", _drawStart, _drawEnd,
 91			_pollInput, _pollCursor,
 92			_batteryState,
 93			0, 0,
 94		},
 95		.configExtra = (struct GUIMenuItem[]) {
 96			{
 97				.title = "Screen mode",
 98				.data = "screenMode",
 99				.submenu = 0,
100				.state = 0,
101				.validStates = (const char*[]) {
102					"With Background",
103					"Without Background",
104					"Stretched",
105					"Fit Aspect Ratio",
106				},
107				.nStates = 4
108			}
109		},
110		.keySources = (struct GUIInputKeys[]) {
111			{
112				.name = "Vita Input",
113				.id = PSP2_INPUT,
114				.keyNames = (const char*[]) {
115					"Select",
116					0,
117					0,
118					"Start",
119					"Up",
120					"Right",
121					"Down",
122					"Left",
123					"L",
124					"R",
125					0, // L2?
126					0, // R2?
127					"\1\xC",
128					"\1\xA",
129					"\1\xB",
130					"\1\xD"
131				},
132				.nKeys = 16
133			},
134			{ .id = 0 }
135		},
136		.nConfigExtra = 1,
137		.setup = mPSP2Setup,
138		.teardown = mPSP2Teardown,
139		.gameLoaded = mPSP2LoadROM,
140		.gameUnloaded = mPSP2UnloadROM,
141		.prepareForFrame = mPSP2PrepareForFrame,
142		.drawFrame = mPSP2Draw,
143		.drawScreenshot = mPSP2DrawScreenshot,
144		.paused = mPSP2Paused,
145		.unpaused = mPSP2Unpaused,
146		.incrementScreenMode = mPSP2IncrementScreenMode,
147		.setFrameLimiter = mPSP2SetFrameLimiter,
148		.pollGameInput = mPSP2PollInput
149	};
150
151	sceTouchSetSamplingState(SCE_TOUCH_PORT_FRONT, SCE_TOUCH_SAMPLING_STATE_START);
152	sceCtrlSetSamplingMode(SCE_CTRL_MODE_ANALOG_WIDE);
153	sceSysmoduleLoadModule(SCE_SYSMODULE_PHOTO_EXPORT);
154
155	mGUIInit(&runner, "psvita");
156
157	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_CROSS, GUI_INPUT_SELECT);
158	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_CIRCLE, GUI_INPUT_BACK);
159	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_TRIANGLE, GUI_INPUT_CANCEL);
160	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_UP, GUI_INPUT_UP);
161	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_DOWN, GUI_INPUT_DOWN);
162	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_LEFT, GUI_INPUT_LEFT);
163	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_RIGHT, GUI_INPUT_RIGHT);
164	mPSP2MapKey(&runner.params.keyMap, SCE_CTRL_SQUARE, mGUI_INPUT_SCREEN_MODE);
165
166	mGUIRunloop(&runner);
167
168	vita2d_fini();
169	mGUIDeinit(&runner);
170
171	int pgfLoaded = sceSysmoduleIsLoaded(SCE_SYSMODULE_PGF);
172	if (pgfLoaded != SCE_SYSMODULE_LOADED) {
173		sceSysmoduleLoadModule(SCE_SYSMODULE_PGF);
174	}
175	GUIFontDestroy(font);
176	sceSysmoduleUnloadModule(SCE_SYSMODULE_PGF);
177
178	sceKernelExitProcess(0);
179	return 0;
180}