diff options
author | Franklin Wei <git@fwei.tk> | 2017-01-21 15:18:31 -0500 |
---|---|---|
committer | Franklin Wei <git@fwei.tk> | 2017-12-23 21:01:26 -0500 |
commit | a855d6202536ff28e5aae4f22a0f31d8f5b325d0 (patch) | |
tree | 8c75f224dd64ed360505afa8843d016b0d75000b /apps/plugins/sdl/main.c | |
parent | 01c6dcf6c7b9bb1ad2fa0450f99bacc5f3d3e04b (diff) | |
download | rockbox-a855d6202536ff28e5aae4f22a0f31d8f5b325d0.tar.gz rockbox-a855d6202536ff28e5aae4f22a0f31d8f5b325d0.zip |
Port of Duke Nukem 3D
This ports Fabien Sanglard's Chocolate Duke to run on a version of SDL
for Rockbox.
Change-Id: I8f2c4c78af19de10c1633ed7bb7a997b43256dd9
Diffstat (limited to 'apps/plugins/sdl/main.c')
-rw-r--r-- | apps/plugins/sdl/main.c | 301 |
1 files changed, 301 insertions, 0 deletions
diff --git a/apps/plugins/sdl/main.c b/apps/plugins/sdl/main.c new file mode 100644 index 0000000000..5a3e016553 --- /dev/null +++ b/apps/plugins/sdl/main.c | |||
@@ -0,0 +1,301 @@ | |||
1 | #include "plugin.h" | ||
2 | |||
3 | #include "fixedpoint.h" | ||
4 | #include "lib/helper.h" | ||
5 | #include "lib/pluginlib_exit.h" | ||
6 | |||
7 | |||
8 | #include "SDL.h" | ||
9 | #include "SDL_video.h" | ||
10 | |||
11 | #ifndef COMBINED_SDL | ||
12 | extern int my_main(int argc, char *argv[]); | ||
13 | #else | ||
14 | //#if 0 | ||
15 | extern int SDLBlock_main(int argc, char *argv[]); | ||
16 | extern int ballfield_main(int argc, char *argv[]); | ||
17 | extern int parallax3_main(int argc, char *argv[]); | ||
18 | extern int parallax4_main(int argc, char *argv[]); | ||
19 | extern int testbitmap_main(int argc, char *argv[]); | ||
20 | extern int testcursor_main(int argc, char *argv[]); | ||
21 | extern int testhread_main(int argc, char *argv[]); | ||
22 | extern int testplatform_main(int argc, char *argv[]); | ||
23 | extern int testsprite_main(int argc, char *argv[]); | ||
24 | extern int testwin_main(int argc, char *argv[]); | ||
25 | //#endif | ||
26 | extern int abe_main(int argc, char *argv[]); | ||
27 | extern int ballerburg_main(int argc, char **argv); | ||
28 | extern int raytrace_main(int argc, char *argv[]); | ||
29 | extern int wolf3d_main(int argc, char *argv[]); | ||
30 | extern int testsound_main(int argc, char *argv[]); | ||
31 | extern int duke3d_main(int argc,char **argv); | ||
32 | extern int quake_main (int c, char **v); | ||
33 | |||
34 | char *wolf3d_argv[] = { "wolf3d", "--audiobuffer", "2048" }; | ||
35 | char *duke3d_argv[] = { "duke3d" }; | ||
36 | char *quake_argv[] = { "quake", "-basedir", "/.rockbox/quake" }; | ||
37 | |||
38 | struct prog_t { | ||
39 | const char *name; | ||
40 | int (*main)(int argc, char *argv[]); | ||
41 | bool printf_enabled; | ||
42 | int argc; | ||
43 | char **argv; | ||
44 | } programs[] = { | ||
45 | #if 0 | ||
46 | { "Abe's Amazing Adventure", abe_main, true }, | ||
47 | { "Ballerburg", ballerburg_main, false }, | ||
48 | { "Screensaver", SDLBlock_main, false }, | ||
49 | { "Ball Field", ballfield_main, false }, | ||
50 | { "Parallax v.3", parallax3_main, false }, | ||
51 | { "Parallax v.4", parallax4_main, false }, | ||
52 | { "Raytrace", raytrace_main, false }, | ||
53 | { "Test Bitmap", testbitmap_main, false }, | ||
54 | { "Test Cursor", testcursor_main, false }, | ||
55 | { "Test Thread", testhread_main, true }, | ||
56 | { "Test Platform", testplatform_main, true }, | ||
57 | { "Test Sprite", testsprite_main, false }, | ||
58 | { "Test Window", testwin_main, false }, | ||
59 | #endif | ||
60 | { "Duke3D", duke3d_main, true, ARRAYLEN(duke3d_argv), duke3d_argv }, | ||
61 | { "Wolf3D", wolf3d_main, false, ARRAYLEN(wolf3d_argv), wolf3d_argv }, | ||
62 | { "Quake", quake_main, true, ARRAYLEN(quake_argv), quake_argv }, | ||
63 | { "Test sound", testsound_main, true, 0, NULL }, | ||
64 | }; | ||
65 | #endif | ||
66 | |||
67 | void *audiobuf = NULL; | ||
68 | |||
69 | unsigned int sdl_thread_id, main_thread_id; | ||
70 | |||
71 | bool printf_enabled = true; | ||
72 | |||
73 | static void (*exit_cb)(void) = NULL; | ||
74 | |||
75 | /* sets "our" exit handler */ | ||
76 | void rbsdl_atexit(void (*cb)(void)) | ||
77 | { | ||
78 | if(exit_cb) | ||
79 | { | ||
80 | rb->splash(HZ, "WARNING: multiple exit handlers!"); | ||
81 | } | ||
82 | exit_cb = cb; | ||
83 | } | ||
84 | |||
85 | /* called by program */ | ||
86 | void rb_exit(int rc) | ||
87 | { | ||
88 | if(rb->thread_self() == main_thread_id) /* rockbox main thread */ | ||
89 | exit(rc); | ||
90 | else | ||
91 | rb->thread_exit(); | ||
92 | } | ||
93 | |||
94 | /* exit handler, called by rockbox */ | ||
95 | void cleanup(void) | ||
96 | { | ||
97 | if(exit_cb) | ||
98 | exit_cb(); | ||
99 | |||
100 | if(exit_cb != SDL_Quit) | ||
101 | SDL_Quit(); | ||
102 | |||
103 | if(audiobuf) | ||
104 | memset(audiobuf, 0, 4); /* clear */ | ||
105 | |||
106 | backlight_use_settings(); | ||
107 | |||
108 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
109 | rb->cpu_boost(false); | ||
110 | #endif | ||
111 | } | ||
112 | |||
113 | #ifdef COMBINED_SDL | ||
114 | const char *formatter(char *buf, size_t n, int i, const char *unit) | ||
115 | { | ||
116 | snprintf(buf, n, "%s", programs[i].name); | ||
117 | return buf; | ||
118 | } | ||
119 | #endif | ||
120 | |||
121 | #ifdef SIMULATOR | ||
122 | #include <signal.h> | ||
123 | |||
124 | void segv(int s, siginfo_t *si, void *ptr) | ||
125 | { | ||
126 | LOGF("SEGV: at address %llx (%d)", si->si_addr, si->si_code); | ||
127 | exit(1); | ||
128 | } | ||
129 | |||
130 | void install_segv(void) | ||
131 | { | ||
132 | struct sigaction act; | ||
133 | act.sa_handler = NULL; | ||
134 | sigemptyset(&act.sa_mask); | ||
135 | act.sa_flags = SA_SIGINFO; | ||
136 | act.sa_sigaction = segv; | ||
137 | sigaction(SIGSEGV, &act, NULL); | ||
138 | } | ||
139 | #endif | ||
140 | |||
141 | static long main_stack[1024 * 1024 / 4]; | ||
142 | int (*main_fn)(int argc, char *argv[]); | ||
143 | int prog_idx; | ||
144 | static void main_thread(void) | ||
145 | { | ||
146 | char *fallback[] = { "/blah", NULL }; | ||
147 | |||
148 | #ifdef COMBINED_SDL | ||
149 | char **argv = programs[prog_idx].argv ? programs[prog_idx].argv : fallback; | ||
150 | int argc = programs[prog_idx].argv ? programs[prog_idx].argc : 1; | ||
151 | #else | ||
152 | char **argv = fallback; | ||
153 | int argc = 1; | ||
154 | #endif | ||
155 | |||
156 | int rc = main_fn(argc, argv); | ||
157 | if(rc != 0) | ||
158 | rb->splash(HZ * 2, SDL_GetError()); | ||
159 | |||
160 | rb->thread_exit(); | ||
161 | } | ||
162 | |||
163 | #if defined(CPU_ARM) && !defined(SIMULATOR) | ||
164 | #define CR_M (1 << 0) /* MMU enable */ | ||
165 | #define CR_A (1 << 1) /* Alignment abort enable */ | ||
166 | #define CR_C (1 << 2) /* Dcache enable */ | ||
167 | #define CR_W (1 << 3) /* Write buffer enable */ | ||
168 | #define CR_P (1 << 4) /* 32-bit exception handler */ | ||
169 | #define CR_D (1 << 5) /* 32-bit data address range */ | ||
170 | #define CR_L (1 << 6) /* Implementation defined */ | ||
171 | #define CR_B (1 << 7) /* Big endian */ | ||
172 | #define CR_S (1 << 8) /* System MMU protection */ | ||
173 | #define CR_R (1 << 9) /* ROM MMU protection */ | ||
174 | #define CR_F (1 << 10) /* Implementation defined */ | ||
175 | #define CR_Z (1 << 11) /* Implementation defined */ | ||
176 | #define CR_I (1 << 12) /* Icache enable */ | ||
177 | #define CR_V (1 << 13) /* Vectors relocated to 0xffff0000 */ | ||
178 | #define CR_RR (1 << 14) /* Round Robin cache replacement */ | ||
179 | #define CR_L4 (1 << 15) /* LDR pc can set T bit */ | ||
180 | #define CR_DT (1 << 16) | ||
181 | #ifdef CONFIG_MMU | ||
182 | #define CR_HA (1 << 17) /* Hardware management of Access Flag */ | ||
183 | #else | ||
184 | #define CR_BR (1 << 17) /* MPU Background region enable (PMSA) */ | ||
185 | #endif | ||
186 | #define CR_IT (1 << 18) | ||
187 | #define CR_ST (1 << 19) | ||
188 | #define CR_FI (1 << 21) /* Fast interrupt (lower latency mode) */ | ||
189 | #define CR_U (1 << 22) /* Unaligned access operation */ | ||
190 | #define CR_XP (1 << 23) /* Extended page tables */ | ||
191 | #define CR_VE (1 << 24) /* Vectored interrupts */ | ||
192 | #define CR_EE (1 << 25) /* Exception (Big) Endian */ | ||
193 | #define CR_TRE (1 << 28) /* TEX remap enable */ | ||
194 | #define CR_AFE (1 << 29) /* Access flag enable */ | ||
195 | #define CR_TE (1 << 30) /* Thumb exception enable */ | ||
196 | |||
197 | #define __LINUX_ARM_ARCH__ ARM_ARCH | ||
198 | |||
199 | #if __LINUX_ARM_ARCH__ >= 7 | ||
200 | #define isb(option) __asm__ __volatile__ ("isb " #option : : : "memory") | ||
201 | #define dsb(option) __asm__ __volatile__ ("dsb " #option : : : "memory") | ||
202 | #define dmb(option) __asm__ __volatile__ ("dmb " #option : : : "memory") | ||
203 | #elif defined(CONFIG_CPU_XSC3) || __LINUX_ARM_ARCH__ == 6 | ||
204 | #define isb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \ | ||
205 | : : "r" (0) : "memory") | ||
206 | #define dsb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ | ||
207 | : : "r" (0) : "memory") | ||
208 | #define dmb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \ | ||
209 | : : "r" (0) : "memory") | ||
210 | #elif defined(CONFIG_CPU_FA526) | ||
211 | #define isb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \ | ||
212 | : : "r" (0) : "memory") | ||
213 | #define dsb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ | ||
214 | : : "r" (0) : "memory") | ||
215 | #define dmb(x) __asm__ __volatile__ ("" : : : "memory") | ||
216 | #else | ||
217 | #define isb(x) __asm__ __volatile__ ("" : : : "memory") | ||
218 | #define dsb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ | ||
219 | : : "r" (0) : "memory") | ||
220 | #define dmb(x) __asm__ __volatile__ ("" : : : "memory") | ||
221 | #endif | ||
222 | |||
223 | static inline unsigned long get_cr(void) | ||
224 | { | ||
225 | unsigned long val; | ||
226 | asm("mrc p15, 0, %0, c1, c0, 0 @ get CR" : "=r" (val) : : "cc"); | ||
227 | return val; | ||
228 | } | ||
229 | |||
230 | static inline void set_cr(unsigned long val) | ||
231 | { | ||
232 | asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR" | ||
233 | : : "r" (val) : "cc"); | ||
234 | isb(); | ||
235 | } | ||
236 | #endif | ||
237 | |||
238 | enum plugin_status plugin_start(const void *param) | ||
239 | { | ||
240 | (void) param; | ||
241 | |||
242 | #if defined(CPU_ARM) && !defined(SIMULATOR) | ||
243 | /* (don't) set alignment trap */ | ||
244 | //set_cr(get_cr() | CR_A); | ||
245 | #endif | ||
246 | |||
247 | /* don't confuse this with the main SDL thread! */ | ||
248 | main_thread_id = rb->thread_self(); | ||
249 | |||
250 | /* we always use the audio buffer */ | ||
251 | size_t sz; | ||
252 | audiobuf = rb->plugin_get_audio_buffer(&sz); | ||
253 | #ifndef SIMULATOR | ||
254 | if ((uintptr_t)audiobuf < (uintptr_t)plugin_start_addr) | ||
255 | { | ||
256 | uint32_t tmp_size = (uintptr_t)plugin_start_addr - (uintptr_t)audiobuf; | ||
257 | sz = MIN(sz, tmp_size); | ||
258 | } | ||
259 | #endif | ||
260 | |||
261 | /* wipe sig */ | ||
262 | rb->memset(audiobuf, 0, sz); | ||
263 | if(init_memory_pool(sz, audiobuf) == (size_t) -1) | ||
264 | { | ||
265 | rb->splashf(HZ*2, "TLSF init failed!"); | ||
266 | return PLUGIN_ERROR; | ||
267 | } | ||
268 | |||
269 | #ifdef SIMULATOR | ||
270 | install_segv(); | ||
271 | #endif | ||
272 | |||
273 | #ifdef COMBINED_SDL | ||
274 | int prog = 0; | ||
275 | |||
276 | rb->set_int("Choose SDL Program", "", UNIT_INT, &prog, NULL, 1, 0, ARRAYLEN(programs) - 1, formatter); | ||
277 | prog_idx = prog; | ||
278 | |||
279 | main_fn = programs[prog].main; | ||
280 | printf_enabled = programs[prog].printf_enabled; | ||
281 | #else | ||
282 | main_fn = my_main; | ||
283 | #endif | ||
284 | |||
285 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
286 | rb->cpu_boost(true); | ||
287 | #endif | ||
288 | |||
289 | backlight_ignore_timeout(); | ||
290 | /* real exit handler */ | ||
291 | #undef rb_atexit | ||
292 | rb_atexit(cleanup); | ||
293 | |||
294 | /* make a new thread to use a bigger stack */ | ||
295 | sdl_thread_id = rb->create_thread(main_thread, main_stack, sizeof(main_stack), 0, "sdl_main" IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU)); | ||
296 | rb->thread_wait(sdl_thread_id); | ||
297 | |||
298 | rb->sleep(HZ); /* wait a second... */ | ||
299 | |||
300 | return PLUGIN_OK; | ||
301 | } | ||