diff options
author | Franklin Wei <frankhwei536@gmail.com> | 2016-11-03 22:27:01 -0400 |
---|---|---|
committer | Gerrit Rockbox <gerrit@rockbox.org> | 2016-11-19 19:17:14 +0100 |
commit | 05733649bce2623acfad7b163501c6fdefea985a (patch) | |
tree | 8db235af25ae7e72f9793879bd1119db90990cf4 | |
parent | deaeb73912c1bb9fd4d3498e59d1789761f3e322 (diff) | |
download | rockbox-05733649bce2623acfad7b163501c6fdefea985a.tar.gz rockbox-05733649bce2623acfad7b163501c6fdefea985a.zip |
XWorld: some fixes
Fixes sound on most platforms, original root cause was bad menu code
as well as DMA callbacks taking too long. Worked around with smaller
chunk sizes. Permanent fix would include moving mixing out of the
callback. Rewrites input with code from rockboy/doom. Cherry-picks a
change from Gregory Montoir's `rawgl' to patch the code wheel
screen. Finally, adds a motion blur filter on select targets.
Change-Id: I8df549c923c5075800c6625c36c8202e53de1d27
-rw-r--r-- | apps/plugins/xworld/SOURCES | 1 | ||||
-rw-r--r-- | apps/plugins/xworld/engine.c | 7 | ||||
-rw-r--r-- | apps/plugins/xworld/intern.c | 34 | ||||
-rw-r--r-- | apps/plugins/xworld/intern.h | 13 | ||||
-rw-r--r-- | apps/plugins/xworld/mixer.c | 13 | ||||
-rw-r--r-- | apps/plugins/xworld/resource.c | 14 | ||||
-rw-r--r-- | apps/plugins/xworld/sys.c | 340 | ||||
-rw-r--r-- | apps/plugins/xworld/sys.h | 13 | ||||
-rw-r--r-- | apps/plugins/xworld/video_data.c | 3 | ||||
-rw-r--r-- | apps/plugins/xworld/vm.c | 38 |
10 files changed, 341 insertions, 135 deletions
diff --git a/apps/plugins/xworld/SOURCES b/apps/plugins/xworld/SOURCES index 98b5f14fb8..eb331b18f5 100644 --- a/apps/plugins/xworld/SOURCES +++ b/apps/plugins/xworld/SOURCES | |||
@@ -1,7 +1,6 @@ | |||
1 | bank.c | 1 | bank.c |
2 | engine.c | 2 | engine.c |
3 | file.c | 3 | file.c |
4 | intern.c | ||
5 | mixer.c | 4 | mixer.c |
6 | parts.c | 5 | parts.c |
7 | resource.c | 6 | resource.c |
diff --git a/apps/plugins/xworld/engine.c b/apps/plugins/xworld/engine.c index 0d1c1bfa61..3a4ddfbf4e 100644 --- a/apps/plugins/xworld/engine.c +++ b/apps/plugins/xworld/engine.c | |||
@@ -61,6 +61,9 @@ void engine_run(struct Engine* e) { | |||
61 | engine_processInput(e); | 61 | engine_processInput(e); |
62 | 62 | ||
63 | vm_hostFrame(&e->vm); | 63 | vm_hostFrame(&e->vm); |
64 | |||
65 | /* only yield() in the whole game :P */ | ||
66 | rb->yield(); | ||
64 | } | 67 | } |
65 | 68 | ||
66 | } | 69 | } |
@@ -259,11 +262,11 @@ void engine_init(struct Engine* e) { | |||
259 | player_init(&e->player); | 262 | player_init(&e->player); |
260 | 263 | ||
261 | /* Init virtual machine, legacy way */ | 264 | /* Init virtual machine, legacy way */ |
262 | /* vm_initForPart(&e->vm, GAME_PART_FIRST); // This game part is the protection screen */ | 265 | vm_initForPart(&e->vm, GAME_PART_FIRST); // This game part is the protection screen */ |
263 | 266 | ||
264 | /* Try to cheat here. You can jump anywhere but the VM crashes afterward. */ | 267 | /* Try to cheat here. You can jump anywhere but the VM crashes afterward. */ |
265 | /* Starting somewhere is probably not enough, the variables and calls return are probably missing. */ | 268 | /* Starting somewhere is probably not enough, the variables and calls return are probably missing. */ |
266 | /* vm_initForPart(&e->vm, GAME_PART2); Skip protection screen and go directly to intro */ | 269 | /* vm_initForPart(&e->vm, GAME_PART2); Skip protection screen and go directly to intro */ |
267 | /* vm_initForPart(&e->vm, GAME_PART3); CRASH */ | 270 | /* vm_initForPart(&e->vm, GAME_PART3); CRASH */ |
268 | /* vm_initForPart(&e->vm, GAME_PART4); Start directly in jail but then crash */ | 271 | /* vm_initForPart(&e->vm, GAME_PART4); Start directly in jail but then crash */ |
269 | /* vm->initForPart(&e->vm, GAME_PART5); CRASH */ | 272 | /* vm->initForPart(&e->vm, GAME_PART5); CRASH */ |
diff --git a/apps/plugins/xworld/intern.c b/apps/plugins/xworld/intern.c deleted file mode 100644 index 0d58100f37..0000000000 --- a/apps/plugins/xworld/intern.c +++ /dev/null | |||
@@ -1,34 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2014 Franklin Wei, Benjamin Brown | ||
11 | * Copyright (C) 2004 Gregory Montoir | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version 2 | ||
16 | * of the License, or (at your option) any later version. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ***************************************************************************/ | ||
22 | |||
23 | #include "intern.h" | ||
24 | #include "awendian.h" | ||
25 | |||
26 | uint8_t ICODE_ATTR scriptPtr_fetchByte(struct Ptr* p) { | ||
27 | return *p->pc++; | ||
28 | } | ||
29 | |||
30 | uint16_t ICODE_ATTR scriptPtr_fetchWord(struct Ptr* p) { | ||
31 | uint16_t i = READ_BE_UINT16(p->pc); | ||
32 | p->pc += 2; | ||
33 | return i; | ||
34 | } | ||
diff --git a/apps/plugins/xworld/intern.h b/apps/plugins/xworld/intern.h index 3355f28eb1..90b640858d 100644 --- a/apps/plugins/xworld/intern.h +++ b/apps/plugins/xworld/intern.h | |||
@@ -34,11 +34,18 @@ struct Ptr { | |||
34 | uint8_t* pc; | 34 | uint8_t* pc; |
35 | }; | 35 | }; |
36 | 36 | ||
37 | uint8_t scriptPtr_fetchByte(struct Ptr* p) ICODE_ATTR; | ||
38 | uint16_t scriptPtr_fetchWord(struct Ptr* p) ICODE_ATTR; | ||
39 | |||
40 | struct Point { | 37 | struct Point { |
41 | int16_t x, y; | 38 | int16_t x, y; |
42 | }; | 39 | }; |
43 | 40 | ||
41 | static inline uint8_t scriptPtr_fetchByte(struct Ptr* p) { | ||
42 | return *p->pc++; | ||
43 | } | ||
44 | |||
45 | static inline uint16_t scriptPtr_fetchWord(struct Ptr* p) { | ||
46 | uint16_t i = READ_BE_UINT16(p->pc); | ||
47 | p->pc += 2; | ||
48 | return i; | ||
49 | } | ||
50 | |||
44 | #endif | 51 | #endif |
diff --git a/apps/plugins/xworld/mixer.c b/apps/plugins/xworld/mixer.c index de7536cd36..6035045239 100644 --- a/apps/plugins/xworld/mixer.c +++ b/apps/plugins/xworld/mixer.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include "serializer.h" | 24 | #include "serializer.h" |
25 | #include "sys.h" | 25 | #include "sys.h" |
26 | 26 | ||
27 | static int8_t ICODE_ATTR addclamp(int a, int b) { | 27 | static int8_t addclamp(int a, int b) { |
28 | int add = a + b; | 28 | int add = a + b; |
29 | if (add < -128) { | 29 | if (add < -128) { |
30 | add = -128; | 30 | add = -128; |
@@ -121,11 +121,11 @@ void mixer_stopAll(struct Mixer* mx) { | |||
121 | /* Since there is no way to know when SDL will ask for a buffer fill, we need */ | 121 | /* Since there is no way to know when SDL will ask for a buffer fill, we need */ |
122 | /* to synchronize with a mutex so the channels remain stable during the execution */ | 122 | /* to synchronize with a mutex so the channels remain stable during the execution */ |
123 | /* of this method. */ | 123 | /* of this method. */ |
124 | static void ICODE_ATTR mixer_mix(struct Mixer* mx, int8_t *buf, int len) { | 124 | static void mixer_mix(struct Mixer* mx, int8_t *buf, int len) { |
125 | int8_t *pBuf; | 125 | int8_t *pBuf; |
126 | 126 | ||
127 | struct MutexStack_t ms; | 127 | /* disabled because this will be called in IRQ */ |
128 | MutexStack(&ms, mx->sys, mx->_mutex); | 128 | /*sys_lockMutex(mx->sys, mx->_mutex);*/ |
129 | 129 | ||
130 | /* Clear the buffer since nothing guarantees we are receiving clean memory. */ | 130 | /* Clear the buffer since nothing guarantees we are receiving clean memory. */ |
131 | rb->memset(buf, 0, len); | 131 | rb->memset(buf, 0, len); |
@@ -170,11 +170,10 @@ static void ICODE_ATTR mixer_mix(struct Mixer* mx, int8_t *buf, int len) { | |||
170 | 170 | ||
171 | } | 171 | } |
172 | 172 | ||
173 | MutexStack_destroy(&ms); | 173 | /*sys_unlockMutex(mx->sys, mx->_mutex);*/ |
174 | } | 174 | } |
175 | 175 | ||
176 | static void ICODE_ATTR mixer_mixCallback(void *param, uint8_t *buf, int len) { | 176 | static void mixer_mixCallback(void *param, uint8_t *buf, int len) { |
177 | debug(DBG_SND, "mixer_mixCallback"); | ||
178 | mixer_mix((struct Mixer*)param, (int8_t *)buf, len); | 177 | mixer_mix((struct Mixer*)param, (int8_t *)buf, len); |
179 | } | 178 | } |
180 | 179 | ||
diff --git a/apps/plugins/xworld/resource.c b/apps/plugins/xworld/resource.c index 2820dcb998..4bd93f0616 100644 --- a/apps/plugins/xworld/resource.c +++ b/apps/plugins/xworld/resource.c | |||
@@ -354,12 +354,14 @@ void res_allocMemBlock(struct Resource* res) { | |||
354 | rb->audio_stop(); | 354 | rb->audio_stop(); |
355 | /* steal the audio buffer */ | 355 | /* steal the audio buffer */ |
356 | size_t sz; | 356 | size_t sz; |
357 | /* memory usage is as follows: | 357 | /* memory usage is first statically allocated, then the remainder is used dynamically: |
358 | [VM memory - 600K] | 358 | * static: |
359 | [Framebuffers - 128K] | 359 | * [VM memory - 600K] |
360 | [Temporary framebuffer - 192K] | 360 | * [Framebuffers - 128K] |
361 | [String table buffer] | 361 | * [Temporary framebuffer - 192K] |
362 | */ | 362 | * dynamic: |
363 | * [String table buffer] | ||
364 | */ | ||
363 | res->_memPtrStart = rb->plugin_get_audio_buffer(&sz); | 365 | res->_memPtrStart = rb->plugin_get_audio_buffer(&sz); |
364 | if(sz < MEM_BLOCK_SIZE + (4 * VID_PAGE_SIZE) + 320 * 200 * sizeof(fb_data)) | 366 | if(sz < MEM_BLOCK_SIZE + (4 * VID_PAGE_SIZE) + 320 * 200 * sizeof(fb_data)) |
365 | { | 367 | { |
diff --git a/apps/plugins/xworld/sys.c b/apps/plugins/xworld/sys.c index 03b032c055..b13d4fb9ed 100644 --- a/apps/plugins/xworld/sys.c +++ b/apps/plugins/xworld/sys.c | |||
@@ -130,13 +130,32 @@ static bool sys_do_help(void) | |||
130 | rb->lcd_set_background(LCD_BLACK); | 130 | rb->lcd_set_background(LCD_BLACK); |
131 | #endif | 131 | #endif |
132 | rb->lcd_setfont(FONT_UI); | 132 | rb->lcd_setfont(FONT_UI); |
133 | char* help_text[] = {"XWorld", "", | 133 | char *help_text[] = { |
134 | "XWorld", "is", "an", "interpreter", "for", "Another", "World,", "a", "fantastic", "game", "by", "Eric", "Chahi." | 134 | "XWorld", "", |
135 | }; | 135 | "XWorld", "is", "a", "port", "of", "a", "bytecode", "interpreter", "for", "`Another", "World',", "a", "cinematic", "adventure", "game", "by", "Eric", "Chahi.", |
136 | "", | ||
137 | "", | ||
138 | "Level", "Codes:", "", | ||
139 | "Level", "1:", "LDKD", "", | ||
140 | "Level", "2:", "HTDC", "", | ||
141 | "Level", "3:", "CLLD", "", | ||
142 | "Level", "4:", "LBKG", "", | ||
143 | "Level", "5:", "XDDJ", "", | ||
144 | "Level", "6:", "FXLC", "", | ||
145 | "Level", "7:", "KRFK", "", | ||
146 | "Level", "8:", "KFLB", "", | ||
147 | "Level", "9:", "DDRX", "", | ||
148 | "Level", "10:", "BFLX", "", | ||
149 | "Level", "11:", "BRTD", "", | ||
150 | "Level", "12:", "TFBB", "", | ||
151 | "Level", "13:", "TXHF", "", | ||
152 | "Level", "14:", "CKJL", "", | ||
153 | "Level", "15:", "LFCK", "", | ||
154 | }; | ||
136 | struct style_text style[] = { | 155 | struct style_text style[] = { |
137 | {0, TEXT_CENTER | TEXT_UNDERLINE}, | 156 | { 0, TEXT_CENTER | TEXT_UNDERLINE }, |
138 | LAST_STYLE_ITEM | ||
139 | }; | 157 | }; |
158 | |||
140 | return display_text(ARRAYLEN(help_text), help_text, style, NULL, true); | 159 | return display_text(ARRAYLEN(help_text), help_text, style, NULL, true); |
141 | } | 160 | } |
142 | 161 | ||
@@ -149,19 +168,22 @@ static const struct opt_items scaling_settings[3] = { | |||
149 | }; | 168 | }; |
150 | 169 | ||
151 | static const struct opt_items rotation_settings[3] = { | 170 | static const struct opt_items rotation_settings[3] = { |
152 | { "Disabled" , -1 }, | 171 | { "Disabled" , -1 }, |
153 | { "Clockwise" , -1 }, | 172 | { "Clockwise" , -1 }, |
154 | { "Anticlockwise", -1 } | 173 | { "Counterclockwise", -1 } |
155 | }; | 174 | }; |
156 | 175 | ||
157 | static void do_video_settings(struct System* sys) | 176 | static void do_video_settings(struct System* sys) |
158 | { | 177 | { |
159 | MENUITEM_STRINGLIST(menu, "Video Settings", NULL, | 178 | MENUITEM_STRINGLIST(menu, "Video Settings", NULL, |
160 | "Negative", | 179 | "Negative", |
180 | #ifdef SYS_MOTION_BLUR | ||
181 | "Motion Blur", | ||
182 | #endif | ||
161 | "Scaling", | 183 | "Scaling", |
162 | "Rotation", | 184 | "Rotation", |
163 | "Show FPS", | 185 | "Show FPS", |
164 | "Zoom on code", | 186 | "Zoom on Code", |
165 | "Back"); | 187 | "Back"); |
166 | int sel = 0; | 188 | int sel = 0; |
167 | while(1) | 189 | while(1) |
@@ -171,7 +193,16 @@ static void do_video_settings(struct System* sys) | |||
171 | case 0: | 193 | case 0: |
172 | rb->set_bool("Negative", &sys->settings.negative_enabled); | 194 | rb->set_bool("Negative", &sys->settings.negative_enabled); |
173 | break; | 195 | break; |
196 | #ifdef SYS_MOTION_BLUR | ||
197 | case 1: | ||
198 | rb->set_bool("Motion Blur", &sys->settings.blur); | ||
199 | break; | ||
200 | #endif | ||
201 | #ifndef SYS_MOTION_BLUR | ||
174 | case 1: | 202 | case 1: |
203 | #else | ||
204 | case 2: | ||
205 | #endif | ||
175 | rb->set_option("Scaling", &sys->settings.scaling_quality, INT, scaling_settings, | 206 | rb->set_option("Scaling", &sys->settings.scaling_quality, INT, scaling_settings, |
176 | #ifdef HAVE_LCD_COLOR | 207 | #ifdef HAVE_LCD_COLOR |
177 | 3 | 208 | 3 |
@@ -186,7 +217,11 @@ static void do_video_settings(struct System* sys) | |||
186 | sys->settings.zoom = false; | 217 | sys->settings.zoom = false; |
187 | } | 218 | } |
188 | break; | 219 | break; |
220 | #ifndef SYS_MOTION_BLUR | ||
189 | case 2: | 221 | case 2: |
222 | #else | ||
223 | case 3: | ||
224 | #endif | ||
190 | rb->set_option("Rotation", &sys->settings.rotation_option, INT, rotation_settings, 3, NULL); | 225 | rb->set_option("Rotation", &sys->settings.rotation_option, INT, rotation_settings, 3, NULL); |
191 | if(sys->settings.rotation_option && | 226 | if(sys->settings.rotation_option && |
192 | sys->settings.zoom) | 227 | sys->settings.zoom) |
@@ -196,45 +231,42 @@ static void do_video_settings(struct System* sys) | |||
196 | } | 231 | } |
197 | sys_rotate_keymap(sys); | 232 | sys_rotate_keymap(sys); |
198 | break; | 233 | break; |
234 | #ifndef SYS_MOTION_BLUR | ||
199 | case 3: | 235 | case 3: |
236 | #else | ||
237 | case 4: | ||
238 | #endif | ||
200 | rb->set_bool("Show FPS", &sys->settings.showfps); | 239 | rb->set_bool("Show FPS", &sys->settings.showfps); |
201 | break; | 240 | break; |
241 | #ifndef SYS_MOTION_BLUR | ||
202 | case 4: | 242 | case 4: |
203 | rb->set_bool("Zoom on code", &sys->settings.zoom); | 243 | #else |
244 | case 5: | ||
245 | #endif | ||
246 | rb->set_bool("Zoom on Code", &sys->settings.zoom); | ||
204 | /* zoom only works with scaling and rotation disabled */ | 247 | /* zoom only works with scaling and rotation disabled */ |
205 | if(sys->settings.zoom && | 248 | if(sys->settings.zoom && (sys->settings.scaling_quality || sys->settings.rotation_option)) |
206 | ( sys->settings.scaling_quality | | ||
207 | sys->settings.rotation_option)) | ||
208 | { | 249 | { |
209 | rb->splash(HZ*2, "Scaling and rotation automatically disabled."); | 250 | rb->splash(HZ*2, "Scaling and rotation automatically disabled."); |
210 | sys->settings.scaling_quality = 0; | 251 | sys->settings.scaling_quality = 0; |
211 | sys->settings.rotation_option = 0; | 252 | sys->settings.rotation_option = 0; |
212 | } | 253 | } |
213 | break; | 254 | break; |
214 | case 5: | 255 | default: |
215 | rb->lcd_clear_display(); | ||
216 | sys_save_settings(sys); | 256 | sys_save_settings(sys); |
217 | return; | 257 | return; |
218 | } | 258 | } |
219 | } | 259 | } |
220 | } | 260 | } |
221 | 261 | ||
222 | #define MAX_SOUNDBUF_SIZE 512 | 262 | #define MAX_SOUNDBUF_SIZE 256 |
223 | const struct opt_items sound_bufsize_options[] = { | ||
224 | {"8 samples" , 8}, | ||
225 | {"16 samples" , 16}, | ||
226 | {"32 samples" , 32}, | ||
227 | {"64 samples" , 64}, | ||
228 | {"128 samples", 128}, | ||
229 | {"256 samples", 256}, | ||
230 | {"512 samples", 512}, | ||
231 | }; | ||
232 | 263 | ||
233 | static void do_sound_settings(struct System* sys) | 264 | static void do_sound_settings(struct System* sys) |
234 | { | 265 | { |
235 | MENUITEM_STRINGLIST(menu, "Sound Settings", NULL, | 266 | MENUITEM_STRINGLIST(menu, "Sound Settings", NULL, |
236 | "Enabled", | 267 | "Enabled", |
237 | "Buffer Level", | 268 | "Buffer Level", |
269 | "Volume", | ||
238 | "Back", | 270 | "Back", |
239 | ); | 271 | ); |
240 | int sel = 0; | 272 | int sel = 0; |
@@ -246,10 +278,17 @@ static void do_sound_settings(struct System* sys) | |||
246 | rb->set_bool("Enabled", &sys->settings.sound_enabled); | 278 | rb->set_bool("Enabled", &sys->settings.sound_enabled); |
247 | break; | 279 | break; |
248 | case 1: | 280 | case 1: |
249 | rb->set_option("Buffer Level", &sys->settings.sound_bufsize, INT, | 281 | rb->set_int("Buffer Level", "samples", UNIT_INT, &sys->settings.sound_bufsize, NULL, 16, 16, MAX_SOUNDBUF_SIZE, NULL); |
250 | sound_bufsize_options, ARRAYLEN(sound_bufsize_options), NULL); | ||
251 | break; | 282 | break; |
252 | case 2: | 283 | case 2: |
284 | { | ||
285 | const struct settings_list* vol = | ||
286 | rb->find_setting(&rb->global_settings->volume, NULL); | ||
287 | rb->option_screen((struct settings_list*)vol, NULL, false, "Volume"); | ||
288 | break; | ||
289 | } | ||
290 | case 3: | ||
291 | default: | ||
253 | sys_save_settings(sys); | 292 | sys_save_settings(sys); |
254 | return; | 293 | return; |
255 | } | 294 | } |
@@ -259,12 +298,13 @@ static void do_sound_settings(struct System* sys) | |||
259 | static void sys_reset_settings(struct System* sys) | 298 | static void sys_reset_settings(struct System* sys) |
260 | { | 299 | { |
261 | sys->settings.negative_enabled = false; | 300 | sys->settings.negative_enabled = false; |
262 | sys->settings.rotation_option = 0; | 301 | sys->settings.rotation_option = 0; // off |
263 | sys->settings.scaling_quality = 1; | 302 | sys->settings.scaling_quality = 1; // fast |
264 | sys->settings.sound_enabled = true; | 303 | sys->settings.sound_enabled = true; |
265 | sys->settings.sound_bufsize = 64; | 304 | sys->settings.sound_bufsize = 32; /* keep this low */ |
266 | sys->settings.showfps = true; | 305 | sys->settings.showfps = false; |
267 | sys->settings.zoom = false; | 306 | sys->settings.zoom = false; |
307 | sys->settings.blur = false; | ||
268 | sys_rotate_keymap(sys); | 308 | sys_rotate_keymap(sys); |
269 | } | 309 | } |
270 | 310 | ||
@@ -278,18 +318,32 @@ static int mainmenu_cb(int action, const struct menu_item_ex *this_item) | |||
278 | return action; | 318 | return action; |
279 | } | 319 | } |
280 | 320 | ||
281 | static AudioCallback audio_callback; | 321 | static AudioCallback audio_callback = NULL; |
322 | static void get_more(const void** start, size_t* size); | ||
282 | static void* audio_param; | 323 | static void* audio_param; |
283 | static struct System* audio_sys; | 324 | static struct System* audio_sys; |
284 | 325 | ||
285 | /************************************** MAIN MENU ***************************************/ | 326 | /************************************** MAIN MENU ***************************************/ |
327 | /* called after game init */ | ||
286 | 328 | ||
287 | void sys_menu(struct System* sys) | 329 | void sys_menu(struct System* sys) |
288 | { | 330 | { |
289 | sys_stopAudio(sys); | 331 | sys_stopAudio(sys); |
332 | |||
333 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
334 | /* boost for load */ | ||
335 | rb->cpu_boost(true); | ||
336 | #endif | ||
337 | |||
290 | rb->splash(0, "Loading..."); | 338 | rb->splash(0, "Loading..."); |
291 | sys->loaded = engine_loadGameState(sys->e, 0); | 339 | sys->loaded = engine_loadGameState(sys->e, 0); |
340 | |||
341 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
342 | rb->cpu_boost(false); | ||
343 | #endif | ||
344 | |||
292 | rb->lcd_update(); | 345 | rb->lcd_update(); |
346 | |||
293 | mainmenu_sysptr = sys; | 347 | mainmenu_sysptr = sys; |
294 | MENUITEM_STRINGLIST(menu, "XWorld Menu", mainmenu_cb, | 348 | MENUITEM_STRINGLIST(menu, "XWorld Menu", mainmenu_cb, |
295 | "Resume Game", /* 0 */ | 349 | "Resume Game", /* 0 */ |
@@ -352,19 +406,21 @@ void sys_menu(struct System* sys) | |||
352 | exit(PLUGIN_OK); | 406 | exit(PLUGIN_OK); |
353 | break; | 407 | break; |
354 | default: | 408 | default: |
355 | error("sys_menu: fall-through!"); | 409 | break; |
356 | } | 410 | } |
357 | } | 411 | } |
358 | rb->lcd_clear_display(); | 412 | |
413 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
414 | /* boost for game */ | ||
415 | rb->cpu_boost(true); | ||
416 | #endif | ||
417 | |||
359 | sys_startAudio(sys, audio_callback, audio_param); | 418 | sys_startAudio(sys, audio_callback, audio_param); |
360 | } | 419 | } |
361 | 420 | ||
362 | void sys_init(struct System* sys, const char* title) | 421 | void sys_init(struct System* sys, const char* title) |
363 | { | 422 | { |
364 | (void) title; | 423 | (void) title; |
365 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
366 | rb->cpu_boost(true); | ||
367 | #endif | ||
368 | backlight_ignore_timeout(); | 424 | backlight_ignore_timeout(); |
369 | rb_atexit(exit_handler); | 425 | rb_atexit(exit_handler); |
370 | save_sys = sys; | 426 | save_sys = sys; |
@@ -565,9 +621,9 @@ void sys_copyRect(struct System* sys, uint16_t x, uint16_t y, uint16_t w, uint16 | |||
565 | int r, g, b; | 621 | int r, g, b; |
566 | fb_data pix = rb->lcd_framebuffer[y * LCD_WIDTH + x]; | 622 | fb_data pix = rb->lcd_framebuffer[y * LCD_WIDTH + x]; |
567 | #if (LCD_DEPTH == 24) | 623 | #if (LCD_DEPTH == 24) |
568 | r = pix.r; | 624 | r = 0xff - pix.r; |
569 | g = pix.g; | 625 | g = 0xff - pix.g; |
570 | b = pix.b; | 626 | b = 0xff - pix.b; |
571 | rb->lcd_framebuffer[y * LCD_WIDTH + x] = (fb_data) { b, g, r }; | 627 | rb->lcd_framebuffer[y * LCD_WIDTH + x] = (fb_data) { b, g, r }; |
572 | #else | 628 | #else |
573 | r = RGB_UNPACK_RED (pix); | 629 | r = RGB_UNPACK_RED (pix); |
@@ -582,6 +638,57 @@ void sys_copyRect(struct System* sys, uint16_t x, uint16_t y, uint16_t w, uint16 | |||
582 | } | 638 | } |
583 | } | 639 | } |
584 | 640 | ||
641 | #ifdef SYS_MOTION_BLUR | ||
642 | if(sys->settings.blur) | ||
643 | { | ||
644 | static fb_data *prev_frames = NULL; | ||
645 | static fb_data *orig_fb = NULL; | ||
646 | static int prev_baseidx = 0; /* circular buffer */ | ||
647 | if(!prev_frames) | ||
648 | { | ||
649 | prev_frames = sys_get_buffer(sys, sizeof(fb_data) * LCD_WIDTH * LCD_HEIGHT * BLUR_FRAMES); | ||
650 | orig_fb = sys_get_buffer(sys, sizeof(fb_data) * LCD_WIDTH * LCD_HEIGHT); | ||
651 | |||
652 | rb->memset(prev_frames, 0, sizeof(fb_data) * LCD_WIDTH * LCD_HEIGHT * BLUR_FRAMES); | ||
653 | } | ||
654 | if(prev_frames && orig_fb) | ||
655 | { | ||
656 | |||
657 | rb->memcpy(orig_fb, rb->lcd_framebuffer, sizeof(fb_data) * LCD_WIDTH * LCD_HEIGHT); | ||
658 | /* fancy useless slow motion blur */ | ||
659 | for(int y = 0; y < LCD_HEIGHT; ++y) | ||
660 | { | ||
661 | for(int x = 0; x < LCD_WIDTH; ++x) | ||
662 | { | ||
663 | int r, g, b; | ||
664 | fb_data pix = rb->lcd_framebuffer[y * LCD_WIDTH + x]; | ||
665 | r = RGB_UNPACK_RED (pix); | ||
666 | g = RGB_UNPACK_GREEN(pix); | ||
667 | b = RGB_UNPACK_BLUE (pix); | ||
668 | r *= BLUR_FRAMES + 1; | ||
669 | g *= BLUR_FRAMES + 1; | ||
670 | b *= BLUR_FRAMES + 1; | ||
671 | for(int i = 0; i < BLUR_FRAMES; ++i) | ||
672 | { | ||
673 | fb_data prev_pix = prev_frames[ (prev_baseidx + i * (LCD_WIDTH * LCD_HEIGHT)) % (LCD_WIDTH * LCD_HEIGHT * BLUR_FRAMES) + y * LCD_WIDTH + x]; | ||
674 | r += (BLUR_FRAMES-i) * RGB_UNPACK_RED(prev_pix); | ||
675 | g += (BLUR_FRAMES-i) * RGB_UNPACK_GREEN(prev_pix); | ||
676 | b += (BLUR_FRAMES-i) * RGB_UNPACK_BLUE(prev_pix); | ||
677 | } | ||
678 | r /= (BLUR_FRAMES + 1) / 2 * (1 + BLUR_FRAMES + 1); | ||
679 | g /= (BLUR_FRAMES + 1) / 2 * (1 + BLUR_FRAMES + 1); | ||
680 | b /= (BLUR_FRAMES + 1) / 2 * (1 + BLUR_FRAMES + 1); | ||
681 | rb->lcd_framebuffer[y * LCD_WIDTH + x] = LCD_RGBPACK(r, g, b); | ||
682 | } | ||
683 | } | ||
684 | prev_baseidx -= LCD_WIDTH * LCD_HEIGHT; | ||
685 | if(prev_baseidx < 0) | ||
686 | prev_baseidx += BLUR_FRAMES * LCD_WIDTH * LCD_HEIGHT; | ||
687 | rb->memcpy(prev_frames + prev_baseidx, orig_fb, sizeof(fb_data) * LCD_WIDTH * LCD_HEIGHT); | ||
688 | } | ||
689 | } | ||
690 | #endif | ||
691 | |||
585 | /*********************** SHOW FPS *************************/ | 692 | /*********************** SHOW FPS *************************/ |
586 | 693 | ||
587 | int current_time = sys_getTimeStamp(sys); | 694 | int current_time = sys_getTimeStamp(sys); |
@@ -599,6 +706,11 @@ void sys_copyRect(struct System* sys, uint16_t x, uint16_t y, uint16_t w, uint16 | |||
599 | static void do_pause_menu(struct System* sys) | 706 | static void do_pause_menu(struct System* sys) |
600 | { | 707 | { |
601 | sys_stopAudio(sys); | 708 | sys_stopAudio(sys); |
709 | |||
710 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
711 | rb->cpu_boost(false); | ||
712 | #endif | ||
713 | |||
602 | int sel = 0; | 714 | int sel = 0; |
603 | MENUITEM_STRINGLIST(menu, "XWorld Menu", NULL, | 715 | MENUITEM_STRINGLIST(menu, "XWorld Menu", NULL, |
604 | "Resume Game", /* 0 */ | 716 | "Resume Game", /* 0 */ |
@@ -663,52 +775,130 @@ static void do_pause_menu(struct System* sys) | |||
663 | break; | 775 | break; |
664 | } | 776 | } |
665 | } | 777 | } |
666 | rb->lcd_clear_display(); | 778 | |
779 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
780 | rb->cpu_boost(true); | ||
781 | #endif | ||
782 | |||
667 | sys_startAudio(sys, audio_callback, audio_param); | 783 | sys_startAudio(sys, audio_callback, audio_param); |
668 | } | 784 | } |
669 | 785 | ||
670 | void sys_processEvents(struct System* sys) | 786 | void sys_processEvents(struct System* sys) |
671 | { | 787 | { |
672 | int btn = rb->button_get(false); | 788 | int btn = rb->button_status(); |
673 | btn &= ~BUTTON_REDRAW; | 789 | rb->button_clear_queue(); |
790 | |||
791 | static int oldbuttonstate = 0; | ||
792 | |||
674 | debug(DBG_SYS, "button is 0x%08x", btn); | 793 | debug(DBG_SYS, "button is 0x%08x", btn); |
675 | 794 | ||
676 | /* exit early if we can */ | 795 | /* exit early if we can */ |
677 | if(btn == BUTTON_NONE) | 796 | if(btn == oldbuttonstate) |
678 | { | 797 | { |
679 | return; | 798 | return; |
680 | } | 799 | } |
681 | 800 | ||
801 | /* handle special keys first */ | ||
802 | switch(btn) | ||
803 | { | ||
804 | case BTN_PAUSE: | ||
805 | do_pause_menu(sys); | ||
806 | sys->input.dirMask = 0; | ||
807 | sys->input.button = false; | ||
808 | /* exit early to avoid unwanted button presses being detected */ | ||
809 | return; | ||
810 | default: | ||
811 | exit_on_usb(btn); | ||
812 | break; | ||
813 | } | ||
814 | |||
682 | /* Ignore some buttons that cause errant input */ | 815 | /* Ignore some buttons that cause errant input */ |
816 | |||
817 | btn &= ~BUTTON_REDRAW; | ||
818 | |||
683 | #if (CONFIG_KEYPAD == IPOD_4G_PAD) || \ | 819 | #if (CONFIG_KEYPAD == IPOD_4G_PAD) || \ |
684 | (CONFIG_KEYPAD == IPOD_3G_PAD) || \ | 820 | (CONFIG_KEYPAD == IPOD_3G_PAD) || \ |
685 | (CONFIG_KEYPAD == IPOD_1G2G_PAD) | 821 | (CONFIG_KEYPAD == IPOD_1G2G_PAD) |
686 | if(btn & 0x80000000) | 822 | if(btn & 0x80000000) |
687 | return; | 823 | return; |
688 | #endif | 824 | #endif |
825 | |||
689 | #if (CONFIG_KEYPAD == SANSA_E200_PAD) | 826 | #if (CONFIG_KEYPAD == SANSA_E200_PAD) |
690 | if(btn == (BUTTON_SCROLL_FWD || BUTTON_SCROLL_BACK)) | 827 | if(btn == (BUTTON_SCROLL_FWD || BUTTON_SCROLL_BACK)) |
691 | return; | 828 | return; |
692 | #endif | 829 | #endif |
830 | |||
693 | #if (CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD) | 831 | #if (CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD) |
694 | if(btn == (BUTTON_SELECT)) | 832 | if(btn == (BUTTON_SELECT)) |
695 | return; | 833 | return; |
696 | #endif | 834 | #endif |
697 | 835 | ||
698 | /* handle special keys first */ | 836 | /* copied from doom which was copied from rockboy... */ |
699 | switch(btn) | 837 | unsigned released = ~btn & oldbuttonstate; |
838 | unsigned pressed = btn & ~oldbuttonstate; | ||
839 | oldbuttonstate = btn; | ||
840 | |||
841 | if(released) | ||
700 | { | 842 | { |
701 | case BTN_PAUSE: | 843 | if(released & BTN_FIRE) |
702 | do_pause_menu(sys); | 844 | sys->input.button = false; |
703 | sys->input.dirMask = 0; | 845 | if(released & sys->keymap.up) |
704 | sys->input.button = false; | 846 | sys->input.dirMask &= ~DIR_UP; |
705 | /* exit early to avoid unwanted button presses being detected */ | 847 | if(released & sys->keymap.down) |
706 | return; | 848 | sys->input.dirMask &= ~DIR_DOWN; |
707 | default: | 849 | if(released & sys->keymap.left) |
708 | exit_on_usb(btn); | 850 | sys->input.dirMask &= ~DIR_LEFT; |
709 | break; | 851 | if(released & sys->keymap.right) |
852 | sys->input.dirMask &= ~DIR_RIGHT; | ||
853 | #ifdef BTN_DOWN_LEFT | ||
854 | if(released & sys->keymap.downleft) | ||
855 | sys->input.dirMask &= ~(DIR_DOWN | DIR_LEFT); | ||
856 | #endif | ||
857 | #ifdef BTN_DOWN_RIGHT | ||
858 | if(released & sys->keymap.downright) | ||
859 | sys->input.dirMask &= ~(DIR_DOWN | DIR_RIGHT); | ||
860 | #endif | ||
861 | #ifdef BTN_UP_LEFT | ||
862 | if(released & sys->keymap.upleft) | ||
863 | sys->input.dirMask &= ~(DIR_UP | DIR_LEFT); | ||
864 | #endif | ||
865 | #ifdef BTN_UP_RIGHT | ||
866 | if(released & sys->keymap.upright) | ||
867 | sys->input.dirMask &= ~(DIR_UP | DIR_RIGHT); | ||
868 | #endif | ||
869 | } | ||
870 | |||
871 | if(pressed) | ||
872 | { | ||
873 | if(pressed & BTN_FIRE) | ||
874 | sys->input.button = true; | ||
875 | if(pressed & sys->keymap.up) | ||
876 | sys->input.dirMask |= DIR_UP; | ||
877 | if(pressed & sys->keymap.down) | ||
878 | sys->input.dirMask |= DIR_DOWN; | ||
879 | if(pressed & sys->keymap.left) | ||
880 | sys->input.dirMask |= DIR_LEFT; | ||
881 | if(pressed & sys->keymap.right) | ||
882 | sys->input.dirMask |= DIR_RIGHT; | ||
883 | #ifdef BTN_DOWN_LEFT | ||
884 | if(pressed & sys->keymap.downleft) | ||
885 | sys->input.dirMask |= (DIR_DOWN | DIR_LEFT); | ||
886 | #endif | ||
887 | #ifdef BTN_DOWN_RIGHT | ||
888 | if(pressed & sys->keymap.downright) | ||
889 | sys->input.dirMask |= (DIR_DOWN | DIR_RIGHT); | ||
890 | #endif | ||
891 | #ifdef BTN_UP_LEFT | ||
892 | if(pressed & sys->keymap.upleft) | ||
893 | sys->input.dirMask |= (DIR_UP | DIR_LEFT); | ||
894 | #endif | ||
895 | #ifdef BTN_UP_RIGHT | ||
896 | if(pressed & sys->keymap.upright) | ||
897 | sys->input.dirMask |= (DIR_UP | DIR_RIGHT); | ||
898 | #endif | ||
710 | } | 899 | } |
711 | 900 | ||
901 | #if 0 | ||
712 | /* handle releases */ | 902 | /* handle releases */ |
713 | if(btn & BUTTON_REL) | 903 | if(btn & BUTTON_REL) |
714 | { | 904 | { |
@@ -774,6 +964,7 @@ void sys_processEvents(struct System* sys) | |||
774 | } | 964 | } |
775 | debug(DBG_SYS, "dirMask is 0x%02x", sys->input.dirMask); | 965 | debug(DBG_SYS, "dirMask is 0x%02x", sys->input.dirMask); |
776 | debug(DBG_SYS, "button is %s", sys->input.button == true ? "true" : "false"); | 966 | debug(DBG_SYS, "button is %s", sys->input.button == true ? "true" : "false"); |
967 | #endif | ||
777 | } | 968 | } |
778 | 969 | ||
779 | void sys_sleep(struct System* sys, uint32_t duration) | 970 | void sys_sleep(struct System* sys, uint32_t duration) |
@@ -789,26 +980,28 @@ uint32_t sys_getTimeStamp(struct System* sys) | |||
789 | return (uint32_t) (*rb->current_tick * (1000/HZ)); | 980 | return (uint32_t) (*rb->current_tick * (1000/HZ)); |
790 | } | 981 | } |
791 | 982 | ||
792 | static int16_t rb_soundbuf [MAX_SOUNDBUF_SIZE] IBSS_ATTR; | 983 | /* game provides us mono samples, we need stereo */ |
793 | static int8_t temp_soundbuf[MAX_SOUNDBUF_SIZE] IBSS_ATTR; | 984 | static int16_t rb_soundbuf[MAX_SOUNDBUF_SIZE * 2]; |
794 | static void ICODE_ATTR get_more(const void** start, size_t* size) | 985 | static int8_t temp_soundbuf[MAX_SOUNDBUF_SIZE]; |
986 | |||
987 | static void get_more(const void** start, size_t* size) | ||
795 | { | 988 | { |
796 | if(audio_sys->settings.sound_enabled) | 989 | if(audio_sys->settings.sound_enabled && audio_callback) |
797 | { | 990 | { |
798 | audio_callback(audio_param, temp_soundbuf, audio_sys->settings.sound_bufsize); | 991 | audio_callback(audio_param, temp_soundbuf, audio_sys->settings.sound_bufsize); |
799 | /* convert xworld format (signed 8-bit) to rockbox format (signed 16-bit) */ | 992 | |
993 | /* convert xworld format (signed 8-bit) to rockbox format (stereo signed 16-bit) */ | ||
800 | for(int i = 0; i < audio_sys->settings.sound_bufsize; ++i) | 994 | for(int i = 0; i < audio_sys->settings.sound_bufsize; ++i) |
801 | { | 995 | { |
802 | rb_soundbuf[i] = temp_soundbuf[i] * 0x100; | 996 | rb_soundbuf[2*i] = rb_soundbuf[2*i+1] = temp_soundbuf[i] * 256; |
803 | } | 997 | } |
804 | *start = rb_soundbuf; | ||
805 | *size = audio_sys->settings.sound_bufsize; | ||
806 | } | 998 | } |
807 | else | 999 | else |
808 | { | 1000 | { |
809 | *start = NULL; | 1001 | rb->memset(rb_soundbuf, 0, audio_sys->settings.sound_bufsize * 2 * sizeof(int16_t)); |
810 | *size = 0; | ||
811 | } | 1002 | } |
1003 | *start = rb_soundbuf; | ||
1004 | *size = audio_sys->settings.sound_bufsize * 2 * sizeof(int16_t); | ||
812 | } | 1005 | } |
813 | 1006 | ||
814 | void sys_startAudio(struct System* sys, AudioCallback callback, void *param) | 1007 | void sys_startAudio(struct System* sys, AudioCallback callback, void *param) |
@@ -817,6 +1010,7 @@ void sys_startAudio(struct System* sys, AudioCallback callback, void *param) | |||
817 | audio_callback = callback; | 1010 | audio_callback = callback; |
818 | audio_param = param; | 1011 | audio_param = param; |
819 | audio_sys = sys; | 1012 | audio_sys = sys; |
1013 | |||
820 | rb->pcm_play_data(get_more, NULL, NULL, 0); | 1014 | rb->pcm_play_data(get_more, NULL, NULL, 0); |
821 | } | 1015 | } |
822 | 1016 | ||
@@ -872,13 +1066,18 @@ void *sys_createMutex(struct System* sys) | |||
872 | { | 1066 | { |
873 | if(!sys) | 1067 | if(!sys) |
874 | error("sys is NULL!"); | 1068 | error("sys is NULL!"); |
1069 | |||
1070 | debug(DBG_SYS, "allocating mutex"); | ||
1071 | |||
1072 | /* this bitfield works as follows: bit set = free, unset = in use */ | ||
875 | for(int i = 0; i < MAX_MUTEXES; ++i) | 1073 | for(int i = 0; i < MAX_MUTEXES; ++i) |
876 | { | 1074 | { |
1075 | /* check that the corresponding bit is 1 (free) */ | ||
877 | if(sys->mutex_bitfield & (1 << i)) | 1076 | if(sys->mutex_bitfield & (1 << i)) |
878 | { | 1077 | { |
879 | rb->mutex_init(&sys->mutex_memory[i]); | 1078 | rb->mutex_init(sys->mutex_memory + i); |
880 | sys->mutex_bitfield |= (1 << i); | 1079 | sys->mutex_bitfield &= ~(1 << i); |
881 | return &sys->mutex_memory[i]; | 1080 | return sys->mutex_memory + i; |
882 | } | 1081 | } |
883 | } | 1082 | } |
884 | warning("Out of mutexes!"); | 1083 | warning("Out of mutexes!"); |
@@ -888,20 +1087,18 @@ void *sys_createMutex(struct System* sys) | |||
888 | void sys_destroyMutex(struct System* sys, void *mutex) | 1087 | void sys_destroyMutex(struct System* sys, void *mutex) |
889 | { | 1088 | { |
890 | int mutex_number = ((char*)mutex - (char*)sys->mutex_memory) / sizeof(struct mutex); /* pointer arithmetic! check for bugs! */ | 1089 | int mutex_number = ((char*)mutex - (char*)sys->mutex_memory) / sizeof(struct mutex); /* pointer arithmetic! check for bugs! */ |
891 | sys->mutex_bitfield &= ~(1 << mutex_number); | 1090 | sys->mutex_bitfield |= 1 << mutex_number; |
892 | } | 1091 | } |
893 | 1092 | ||
894 | void sys_lockMutex(struct System* sys, void *mutex) | 1093 | void sys_lockMutex(struct System* sys, void *mutex) |
895 | { | 1094 | { |
896 | (void) sys; | 1095 | (void) sys; |
897 | debug(DBG_SYS, "calling mutex_lock"); | ||
898 | rb->mutex_lock((struct mutex*) mutex); | 1096 | rb->mutex_lock((struct mutex*) mutex); |
899 | } | 1097 | } |
900 | 1098 | ||
901 | void sys_unlockMutex(struct System* sys, void *mutex) | 1099 | void sys_unlockMutex(struct System* sys, void *mutex) |
902 | { | 1100 | { |
903 | (void) sys; | 1101 | (void) sys; |
904 | debug(DBG_SYS, "calling mutex_unlock"); | ||
905 | rb->mutex_unlock((struct mutex*) mutex); | 1102 | rb->mutex_unlock((struct mutex*) mutex); |
906 | } | 1103 | } |
907 | 1104 | ||
@@ -937,4 +1134,5 @@ void MutexStack(struct MutexStack_t* s, struct System *stub, void *mutex) | |||
937 | void MutexStack_destroy(struct MutexStack_t* s) | 1134 | void MutexStack_destroy(struct MutexStack_t* s) |
938 | { | 1135 | { |
939 | sys_unlockMutex(s->sys, s->_mutex); | 1136 | sys_unlockMutex(s->sys, s->_mutex); |
1137 | |||
940 | } | 1138 | } |
diff --git a/apps/plugins/xworld/sys.h b/apps/plugins/xworld/sys.h index f1920acf37..20c6e859c4 100644 --- a/apps/plugins/xworld/sys.h +++ b/apps/plugins/xworld/sys.h | |||
@@ -23,12 +23,20 @@ | |||
23 | #ifndef __XWORLD_SYS_H__ | 23 | #ifndef __XWORLD_SYS_H__ |
24 | #define __XWORLD_SYS_H__ | 24 | #define __XWORLD_SYS_H__ |
25 | 25 | ||
26 | #include "plugin.h" | ||
26 | #include "intern.h" | 27 | #include "intern.h" |
27 | 28 | ||
28 | #define SYS_NEGATIVE_COLOR | 29 | #if (PLUGIN_BUFFER_SIZE >= 0x80000 && defined(HAVE_LCD_COLOR) && LCD_DEPTH < 24) |
30 | #define SYS_MOTION_BLUR | ||
31 | /* must be odd */ | ||
32 | #define BLUR_FRAMES 3 | ||
33 | #else | ||
34 | #error lol | ||
35 | #endif | ||
36 | |||
29 | #define NUM_COLORS 16 | 37 | #define NUM_COLORS 16 |
30 | #define MAX_MUTEXES 16 | 38 | #define MAX_MUTEXES 16 |
31 | #define SETTINGS_FILE "settings.xfg" | 39 | #define SETTINGS_FILE "settings.zfg" /* change when backwards-compatibility is broken */ |
32 | #define CODE_X 80 | 40 | #define CODE_X 80 |
33 | #define CODE_Y 36 | 41 | #define CODE_Y 36 |
34 | 42 | ||
@@ -103,6 +111,7 @@ struct System { | |||
103 | bool sound_enabled; | 111 | bool sound_enabled; |
104 | int sound_bufsize; | 112 | int sound_bufsize; |
105 | bool zoom; | 113 | bool zoom; |
114 | bool blur; | ||
106 | } settings; | 115 | } settings; |
107 | }; | 116 | }; |
108 | 117 | ||
diff --git a/apps/plugins/xworld/video_data.c b/apps/plugins/xworld/video_data.c index e658c175d9..afed9e06ea 100644 --- a/apps/plugins/xworld/video_data.c +++ b/apps/plugins/xworld/video_data.c | |||
@@ -126,9 +126,10 @@ uint8_t video_font[FONT_SIZE] = { | |||
126 | 0x00, 0xA0, 0x10, 0x80, 0x10, 0x80, 0x50, 0x00, /* DEL */ | 126 | 0x00, 0xA0, 0x10, 0x80, 0x10, 0x80, 0x50, 0x00, /* DEL */ |
127 | }; | 127 | }; |
128 | 128 | ||
129 | /* default bogus strings */ | ||
129 | struct StrEntry video_stringsTableEng[MAX_STRING_TABLE_SIZE] = { | 130 | struct StrEntry video_stringsTableEng[MAX_STRING_TABLE_SIZE] = { |
130 | { 0x001, "B A N A N A 2000" }, | 131 | { 0x001, "B A N A N A 2000" }, |
131 | { 0x002, "Copyright } 2014 Banana Corporation \nGPLv2\n\nBUNIX Revision 3.14" }, | 132 | { 0x002, "Copyright } 2016 Franklin Wei\nGPLv2\n\nBUNIX Revision 3.14" }, |
132 | { 0x003, "1" }, | 133 | { 0x003, "1" }, |
133 | { 0x004, "3" }, | 134 | { 0x004, "3" }, |
134 | { 0x005, "." }, | 135 | { 0x005, "." }, |
diff --git a/apps/plugins/xworld/vm.c b/apps/plugins/xworld/vm.c index de632d710d..10c3957ad7 100644 --- a/apps/plugins/xworld/vm.c +++ b/apps/plugins/xworld/vm.c | |||
@@ -52,7 +52,13 @@ void vm_init(struct VirtualMachine* m) { | |||
52 | 52 | ||
53 | rb->memset(m->vmVariables, 0, sizeof(m->vmVariables)); | 53 | rb->memset(m->vmVariables, 0, sizeof(m->vmVariables)); |
54 | m->vmVariables[0x54] = 0x81; | 54 | m->vmVariables[0x54] = 0x81; |
55 | m->vmVariables[VM_VARIABLE_RANDOM_SEED] = *rb->current_tick; | 55 | m->vmVariables[VM_VARIABLE_RANDOM_SEED] = *rb->current_tick % 0x10000; |
56 | |||
57 | /* rawgl has these, but they don't seem to do anything */ | ||
58 | //m->vmVariables[0xBC] = 0x10; | ||
59 | //m->vmVariables[0xC6] = 0x80; | ||
60 | //m->vmVariables[0xF2] = 4000; | ||
61 | //m->vmVariables[0xDC] = 33; | ||
56 | 62 | ||
57 | m->_fastMode = false; | 63 | m->_fastMode = false; |
58 | m->player->_markVar = &m->vmVariables[VM_VARIABLE_MUS_MARK]; | 64 | m->player->_markVar = &m->vmVariables[VM_VARIABLE_MUS_MARK]; |
@@ -81,7 +87,7 @@ void vm_op_add(struct VirtualMachine* m) { | |||
81 | 87 | ||
82 | void vm_op_addConst(struct VirtualMachine* m) { | 88 | void vm_op_addConst(struct VirtualMachine* m) { |
83 | if (m->res->currentPartId == 0x3E86 && m->_scriptPtr.pc == m->res->segBytecode + 0x6D48) { | 89 | if (m->res->currentPartId == 0x3E86 && m->_scriptPtr.pc == m->res->segBytecode + 0x6D48) { |
84 | warning("vm_op_addConst() hack for non-stop looping gun sound bug"); | 90 | //warning("vm_op_addConst() hack for non-stop looping gun sound bug"); |
85 | // the script 0x27 slot 0x17 doesn't stop the gun sound from looping, I | 91 | // the script 0x27 slot 0x17 doesn't stop the gun sound from looping, I |
86 | // don't really know why ; for now, let's play the 'stopping sound' like | 92 | // don't really know why ; for now, let's play the 'stopping sound' like |
87 | // the other scripts do | 93 | // the other scripts do |
@@ -152,10 +158,9 @@ void vm_op_jnz(struct VirtualMachine* m) { | |||
152 | #define BYPASS_PROTECTION | 158 | #define BYPASS_PROTECTION |
153 | void vm_op_condJmp(struct VirtualMachine* m) { | 159 | void vm_op_condJmp(struct VirtualMachine* m) { |
154 | 160 | ||
155 | //printf("Jump : %X \n",m->_scriptPtr.pc-m->res->segBytecode); | 161 | //debug(DBG_VM, "Jump : %X \n",m->_scriptPtr.pc-m->res->segBytecode); |
156 | //FCS Whoever wrote this is patching the bytecode on the fly. This is ballzy !! | 162 | //FCS Whoever wrote this is patching the bytecode on the fly. This is ballzy !! |
157 | #ifdef BYPASS_PROTECTION | 163 | #if 0 |
158 | |||
159 | if (m->res->currentPartId == GAME_PART_FIRST && m->_scriptPtr.pc == m->res->segBytecode + 0xCB9) { | 164 | if (m->res->currentPartId == GAME_PART_FIRST && m->_scriptPtr.pc == m->res->segBytecode + 0xCB9) { |
160 | 165 | ||
161 | // (0x0CB8) condJmp(0x80, VAR(41), VAR(30), 0xCD3) | 166 | // (0x0CB8) condJmp(0x80, VAR(41), VAR(30), 0xCD3) |
@@ -168,6 +173,8 @@ void vm_op_condJmp(struct VirtualMachine* m) { | |||
168 | debug(DBG_VM, "vm_op_condJmp() bypassing protection"); | 173 | debug(DBG_VM, "vm_op_condJmp() bypassing protection"); |
169 | debug(DBG_VM, "bytecode has been patched"); | 174 | debug(DBG_VM, "bytecode has been patched"); |
170 | 175 | ||
176 | //warning("bypassing protection"); | ||
177 | |||
171 | //vm_bypassProtection(m); | 178 | //vm_bypassProtection(m); |
172 | } | 179 | } |
173 | 180 | ||
@@ -175,7 +182,8 @@ void vm_op_condJmp(struct VirtualMachine* m) { | |||
175 | #endif | 182 | #endif |
176 | 183 | ||
177 | uint8_t opcode = scriptPtr_fetchByte(&m->_scriptPtr); | 184 | uint8_t opcode = scriptPtr_fetchByte(&m->_scriptPtr); |
178 | int16_t b = m->vmVariables[scriptPtr_fetchByte(&m->_scriptPtr)]; | 185 | uint8_t var = scriptPtr_fetchByte(&m->_scriptPtr); |
186 | int16_t b = m->vmVariables[var]; | ||
179 | uint8_t c = scriptPtr_fetchByte(&m->_scriptPtr); | 187 | uint8_t c = scriptPtr_fetchByte(&m->_scriptPtr); |
180 | int16_t a; | 188 | int16_t a; |
181 | 189 | ||
@@ -193,6 +201,22 @@ void vm_op_condJmp(struct VirtualMachine* m) { | |||
193 | switch (opcode & 7) { | 201 | switch (opcode & 7) { |
194 | case 0: // jz | 202 | case 0: // jz |
195 | expr = (b == a); | 203 | expr = (b == a); |
204 | |||
205 | #ifdef BYPASS_PROTECTION | ||
206 | /* always succeed in code wheel verification */ | ||
207 | if (m->res->currentPartId == GAME_PART_FIRST && var == 0x29 && (opcode & 0x80) != 0) { | ||
208 | |||
209 | m->vmVariables[0x29] = m->vmVariables[0x1E]; | ||
210 | m->vmVariables[0x2A] = m->vmVariables[0x1F]; | ||
211 | m->vmVariables[0x2B] = m->vmVariables[0x20]; | ||
212 | m->vmVariables[0x2C] = m->vmVariables[0x21]; | ||
213 | // counters | ||
214 | m->vmVariables[0x32] = 6; | ||
215 | m->vmVariables[0x64] = 20; | ||
216 | expr = true; | ||
217 | //warning("Script::op_condJmp() bypassing protection"); | ||
218 | } | ||
219 | #endif | ||
196 | break; | 220 | break; |
197 | case 1: // jnz | 221 | case 1: // jnz |
198 | expr = (b != a); | 222 | expr = (b != a); |
@@ -605,8 +629,6 @@ void vm_executeThread(struct VirtualMachine* m) { | |||
605 | { | 629 | { |
606 | (vm_opcodeTable[opcode])(m); | 630 | (vm_opcodeTable[opcode])(m); |
607 | } | 631 | } |
608 | |||
609 | rb->yield(); | ||
610 | } | 632 | } |
611 | } | 633 | } |
612 | 634 | ||