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 = NULL,
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 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}