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}