diff options
Diffstat (limited to 'apps')
-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 | ||