1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 // Disable printf override in common/forbidden.h to avoid
24 // clashes with pspdebug.h from the PSP SDK.
25 // That header file uses
26 // __attribute__((format(printf,1,2)));
27 // which gets messed up by our override mechanism; this could
28 // be avoided by either changing the PSP SDK to use the equally
29 // legal and valid
30 // __attribute__((format(__printf__,1,2)));
31 // or by refining our printf override to use a varadic macro
32 // (which then wouldn't be portable, though).
33 // Anyway, for now we just disable the printf override globally
34 // for the PSP port
35 #define FORBIDDEN_SYMBOL_EXCEPTION_printf
36
37 #define USERSPACE_ONLY //don't use kernel mode features
38
39 #ifndef USERSPACE_ONLY
40 #include <pspkernel.h>
41 #include <pspdebug.h>
42 #else
43 #include <pspuser.h>
44 #endif
45
46 #include <psppower.h>
47
48 #include <common/system.h>
49 #include <engines/engine.h>
50 #include <base/main.h>
51 #include <base/plugins.h>
52 #include "backends/platform/psp/powerman.h"
53 #include "backends/platform/psp/thread.h"
54
55 #include "backends/plugins/psp/psp-provider.h"
56 #include "backends/platform/psp/psppixelformat.h"
57 #include "backends/platform/psp/osys_psp.h"
58 #include "backends/platform/psp/tests.h" /* for unit/speed tests */
59 #include "backends/platform/psp/trace.h"
60
61 #ifdef ENABLE_PROFILING
62 #include <pspprof.h>
63 #endif
64
65 /**
66 * Define the module info section
67 *
68 * 2nd arg must 0x1000 so __init is executed in
69 * kernelmode for our loaderInit function
70 */
71 #ifndef USERSPACE_ONLY
72 PSP_MODULE_INFO("SCUMMVM-PSP", 0x1000, 1, 1);
73 #else
74 PSP_MODULE_INFO("SCUMMVM-PSP", 0, 1, 1);
75 #endif
76
77 /**
78 * THREAD_ATTR_USER causes the thread that the startup
79 * code (crt0.c) starts this program in to be in usermode
80 * even though the module was started in kernelmode
81 */
82 PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU);
83 PSP_HEAP_SIZE_KB(-128); //Leave 128kb for thread stacks, etc.
84
85
86 #ifndef USERSPACE_ONLY
MyExceptionHandler(PspDebugRegBlock * regs)87 void MyExceptionHandler(PspDebugRegBlock *regs) {
88 /* Do normal initial dump, setup screen etc */
89
90 pspDebugScreenInit();
91
92 pspDebugScreenSetBackColor(0x00FF0000);
93 pspDebugScreenSetTextColor(0xFFFFFFFF);
94 pspDebugScreenClear();
95
96 pspDebugScreenPrintf("Exception Details:\n");
97 pspDebugDumpException(regs);
98
99 while (1) ;
100 }
101
102 /**
103 * Function that is called from _init in kernelmode before the
104 * main thread is started in usermode.
105 */
106 __attribute__((constructor))
loaderInit()107 void loaderInit() {
108 pspKernelSetKernelPC();
109 pspDebugInstallErrorHandler(MyExceptionHandler);
110 }
111 #endif
112
113 /* Exit callback */
exit_callback(void)114 int exit_callback(void) {
115
116 #ifdef ENABLE_PROFILING
117 gprof_cleanup();
118 #endif
119
120 sceKernelExitGame();
121 return 0;
122 }
123
124 /* Function for handling suspend/resume */
power_callback(int,int powerinfo,void *)125 int power_callback(int , int powerinfo, void *) {
126 if (powerinfo & PSP_POWER_CB_POWER_SWITCH || powerinfo & PSP_POWER_CB_SUSPENDING) {
127 PowerMan.suspend();
128 } else if (powerinfo & PSP_POWER_CB_RESUME_COMPLETE) {
129 PowerMan.resume();
130 }
131 return 0;
132 }
133
134 /* Callback thread */
CallbackThread(SceSize,void * arg)135 int CallbackThread(SceSize /*size*/, void *arg) {
136 int cbid;
137
138 cbid = sceKernelCreateCallback("Exit Callback", (SceKernelCallbackFunction)exit_callback, NULL);
139 sceKernelRegisterExitCallback(cbid);
140 /* Set up callbacks for PSPIoStream */
141
142 cbid = sceKernelCreateCallback("Power Callback", (SceKernelCallbackFunction)power_callback, 0);
143 if (cbid >= 0) {
144 if (scePowerRegisterCallback(-1, cbid) < 0) {
145 PSP_ERROR("Couldn't register callback for power_callback\n");
146 }
147 } else {
148 PSP_ERROR("Couldn't create a callback for power_callback\n");
149 }
150
151 sceKernelSleepThreadCB();
152 return 0;
153 }
154
155 /* Sets up the callback thread and returns its thread id */
SetupCallbacks(void)156 int SetupCallbacks(void) {
157 int thid = sceKernelCreateThread("power_thread", CallbackThread, PRIORITY_POWER_THREAD, STACK_POWER_THREAD, THREAD_ATTR_USER, 0);
158 if (thid >= 0) {
159 sceKernelStartThread(thid, 0, 0);
160 }
161
162 return thid;
163 }
164
165 #undef main
main(void)166 int main(void) {
167 //change clock rate to 333mhz
168 scePowerSetClockFrequency(333, 333, 166);
169
170 PowerManager::instance(); // Setup power manager
171
172 SetupCallbacks();
173
174 static const char *argv[] = { "scummvm", NULL };
175 static int argc = sizeof(argv) / sizeof(char *) - 1;
176
177 g_system = new OSystem_PSP();
178 assert(g_system);
179
180 #ifdef DYNAMIC_MODULES
181 PluginManager::instance().addPluginProvider(new PSPPluginProvider());
182 #endif
183
184 /* unit/speed tests */
185 #if defined(PSP_ENABLE_UNIT_TESTS) || defined(PSP_ENABLE_SPEED_TESTS)
186 PSP_INFO_PRINT("running tests\n");
187 psp_tests();
188 sceKernelSleepThread(); // that's it. That's all we're doing
189 #endif
190
191 int res = scummvm_main(argc, argv);
192
193 g_system->quit(); // TODO: Consider removing / replacing this!
194
195 PowerManager::destroy(); // get rid of PowerManager
196
197 sceKernelSleepThread();
198
199 return res;
200 }
201