1 /*
2 * OpenBOR - http://www.LavaLit.com
3 * -----------------------------------------------------------------------
4 * Licensed under the BSD license, see LICENSE in OpenBOR root for details.
5 *
6 * Copyright (c) 2004 - 2011 OpenBOR Team
7 */
8 // Adapted from sdl/menu.c. Uses s_screen images instead of SDL surfaces.
9
10 #include <dirent.h>
11 #include <unistd.h>
12 #include <ogcsys.h>
13 #include <wiiuse/wpad.h>
14 #include "wiiport.h"
15 #include "video.h"
16 #include "control.h"
17 #include "soundmix.h"
18 #include "packfile.h"
19 #include "hankaku.h"
20 #include "stristr.h"
21
22 #include "pngdec.h"
23 #include "../resources/OpenBOR_Menu_480x272_png.h"
24 #include "../resources/OpenBOR_Menu_320x240_png.h"
25
26 #undef MIN
27 #undef MAX
28 #include "openbor.h"
29 #undef time
30 #include <time.h>
31
32 extern int videoMode;
33
34 #define RGB32(R,G,B) ((R << 16) | ((G) << 8) | (B))
35 #define RGB16(R,G,B) ((B&0xF8)<<8) | ((G&0xFC)<<3) | (R>>3)
36 #define RGB(R,G,B) (bpp==16?RGB16(R,G,B):RGB32(R,G,B))
37
38 #define BLACK RGB( 0, 0, 0)
39 #define WHITE RGB(255, 255, 255)
40 #define RED RGB(255, 0, 0)
41 #define GREEN RGB( 0, 255, 0)
42 #define BLUE RGB( 0, 0, 255)
43 #define YELLOW RGB(255, 255, 0)
44 #define PURPLE RGB(255, 0, 255)
45 #define ORANGE RGB(255, 128, 0)
46 #define GRAY RGB(112, 128, 144)
47 #define LIGHT_GRAY RGB(223, 223, 223)
48 #define DARK_RED RGB(128, 0, 0)
49 #define DARK_GREEN RGB( 0, 128, 0)
50 #define DARK_BLUE RGB( 0, 0, 128)
51
52 #define LOG_SCREEN_TOP 2
53 #define LOG_SCREEN_END (isWide ? 26 : 23)
54
55 #define DIR_UP 0x00000001
56 #define DIR_RIGHT 0x00000002
57 #define DIR_DOWN 0x00000004
58 #define DIR_LEFT 0x00000008
59 #define WIIMOTE_A 0x00000010
60 #define WIIMOTE_B 0x00000020
61 #define WIIMOTE_1 0x00000040
62 #define WIIMOTE_2 0x00000080
63 #define WIIMOTE_PLUS 0x00000100
64 #define WIIMOTE_MINUS 0x00000200
65 #define WIIMOTE_HOME 0x00000400
66 #define NUNCHUK_C 0x00000800
67 #define NUNCHUK_Z 0x00001000
68 #define CC_A 0x00002000
69 #define CC_B 0x00004000
70 #define CC_X 0x00008000
71 #define CC_Y 0x00010000
72 #define CC_L 0x00020000
73 #define CC_R 0x00040000
74 #define CC_ZL 0x00080000
75 #define CC_ZR 0x00100000
76 #define CC_PLUS 0x00200000
77 #define CC_MINUS 0x00400000
78 #define CC_HOME 0x00800000
79 #define GC_A 0x01000000
80 #define GC_B 0x02000000
81 #define GC_X 0x04000000
82 #define GC_Y 0x08000000
83 #define GC_L 0x10000000
84 #define GC_R 0x20000000
85 #define GC_Z 0x40000000
86 #define GC_START 0x80000000
87
88 s_screen *Source = NULL;
89 s_screen *Scaler = NULL;
90 s_screen *Screen = NULL;
91 int bpp = 32;
92 int factor = 1;
93 int isFull = 0;
94 int isWide = 0;
95 int flags;
96 int dListTotal;
97 int dListCurrentPosition;
98 int dListScrollPosition;
99 int which_logfile = OPENBOR_LOG;
100 int buttonsHeld = 0;
101 int buttonsPressed = 0;
102 FILE *bgmFile = NULL;
103 extern unsigned long bothkeys, bothnewkeys;
104 fileliststruct *filelist;
105 s_videomodes videomodes;
106
107 typedef struct{
108 stringptr *buf;
109 int *pos;
110 int line;
111 int rows;
112 char ready;
113 }s_logfile;
114 s_logfile logfile[2];
115
116 typedef struct{
117 int x;
118 int y;
119 int width;
120 int height;
121 }Rect;
122
123 typedef int (*ControlInput)();
124
125 int ControlMenu();
126 int ControlBGM();
127 void PlayBGM();
128 void StopBGM();
129 void fillRect(s_screen* dest, Rect* rect, u32 color);
130 static ControlInput pControl;
131
Control()132 int Control()
133 {
134 return pControl();
135 }
136
refreshInput()137 void refreshInput()
138 {
139 unsigned long btns = 0;
140 unsigned short gcbtns;
141 WPADData *wpad;
142
143 PAD_Init();
144 PAD_ScanPads();
145 gcbtns = PAD_ButtonsDown(0) | PAD_ButtonsHeld(0);
146 WPAD_ScanPads();
147 wpad = WPAD_Data(0);
148
149 if(wpad->exp.type == WPAD_EXP_CLASSIC)
150 {
151 // Left thumb stick
152 if(wpad->exp.classic.ljs.mag >= 0.3)
153 {
154 if (wpad->exp.classic.ljs.ang >= 310 || wpad->exp.classic.ljs.ang <= 50) btns |= DIR_UP;
155 if (wpad->exp.classic.ljs.ang >= 130 && wpad->exp.classic.ljs.ang <= 230) btns |= DIR_DOWN;
156 if (wpad->exp.classic.ljs.ang >= 220 && wpad->exp.classic.ljs.ang <= 320) btns |= DIR_LEFT;
157 if (wpad->exp.classic.ljs.ang >= 40 && wpad->exp.classic.ljs.ang <= 140) btns |= DIR_RIGHT;
158 }
159 // D-pad
160 if(wpad->btns_h & WPAD_CLASSIC_BUTTON_UP) btns |= DIR_UP;
161 if(wpad->btns_h & WPAD_CLASSIC_BUTTON_DOWN) btns |= DIR_DOWN;
162 if(wpad->btns_h & WPAD_CLASSIC_BUTTON_LEFT) btns |= DIR_LEFT;
163 if(wpad->btns_h & WPAD_CLASSIC_BUTTON_RIGHT) btns |= DIR_RIGHT;
164 }
165 else if(wpad->exp.type == WPAD_EXP_NUNCHUK) // Wiimote + Nunchuk
166 {
167 if(wpad->exp.nunchuk.js.pos.y >= 0xB0) btns |= DIR_UP;
168 if(wpad->exp.nunchuk.js.pos.y <= 0x40) btns |= DIR_DOWN;
169 if(wpad->exp.nunchuk.js.pos.x <= 0x40) btns |= DIR_LEFT;
170 if(wpad->exp.nunchuk.js.pos.x >= 0xB0) btns |= DIR_RIGHT;
171 if(wpad->btns_h & WPAD_BUTTON_UP) btns |= DIR_UP;
172 if(wpad->btns_h & WPAD_BUTTON_DOWN) btns |= DIR_DOWN;
173 if(wpad->btns_h & WPAD_BUTTON_LEFT) btns |= DIR_LEFT;
174 if(wpad->btns_h & WPAD_BUTTON_RIGHT) btns |= DIR_RIGHT;
175 }
176 else // Wiimote held sideways
177 {
178 if(wpad->btns_h & WPAD_BUTTON_UP) btns |= DIR_LEFT;
179 if(wpad->btns_h & WPAD_BUTTON_DOWN) btns |= DIR_RIGHT;
180 if(wpad->btns_h & WPAD_BUTTON_LEFT) btns |= DIR_DOWN;
181 if(wpad->btns_h & WPAD_BUTTON_RIGHT) btns |= DIR_UP;
182 }
183
184 // GameCube analog stick and D-pad
185 if(PAD_StickY(0) > 18) btns |= DIR_UP;
186 if(PAD_StickY(0) < -18) btns |= DIR_DOWN;
187 if(PAD_StickX(0) < -18) btns |= DIR_LEFT;
188 if(PAD_StickX(0) > 18) btns |= DIR_RIGHT;
189 if(gcbtns & PAD_BUTTON_UP) btns |= DIR_UP;
190 if(gcbtns & PAD_BUTTON_DOWN) btns |= DIR_DOWN;
191 if(gcbtns & PAD_BUTTON_LEFT) btns |= DIR_LEFT;
192 if(gcbtns & PAD_BUTTON_RIGHT) btns |= DIR_RIGHT;
193
194 // Controller buttons
195 if(wpad->btns_h & WPAD_BUTTON_1) btns |= WIIMOTE_1;
196 if(wpad->btns_h & WPAD_BUTTON_2) btns |= WIIMOTE_2;
197 if(wpad->btns_h & WPAD_BUTTON_A) btns |= WIIMOTE_A;
198 if(wpad->btns_h & WPAD_BUTTON_B) btns |= WIIMOTE_B;
199 if(wpad->btns_h & WPAD_BUTTON_MINUS) btns |= WIIMOTE_MINUS;
200 if(wpad->btns_h & WPAD_BUTTON_PLUS) btns |= WIIMOTE_PLUS;
201 if(wpad->btns_h & WPAD_BUTTON_HOME) btns |= WIIMOTE_HOME;
202 if(wpad->btns_h & WPAD_NUNCHUK_BUTTON_Z) btns |= NUNCHUK_Z;
203 if(wpad->btns_h & WPAD_NUNCHUK_BUTTON_C) btns |= NUNCHUK_C;
204 if(wpad->btns_h & WPAD_CLASSIC_BUTTON_A) btns |= CC_A;
205 if(wpad->btns_h & WPAD_CLASSIC_BUTTON_B) btns |= CC_B;
206 if(wpad->btns_h & WPAD_CLASSIC_BUTTON_Y) btns |= CC_Y;
207 if(wpad->btns_h & WPAD_CLASSIC_BUTTON_X) btns |= CC_X;
208 if(wpad->btns_h & WPAD_CLASSIC_BUTTON_MINUS) btns |= CC_MINUS;
209 if(wpad->btns_h & WPAD_CLASSIC_BUTTON_PLUS) btns |= CC_PLUS;
210 if(wpad->btns_h & WPAD_CLASSIC_BUTTON_HOME) btns |= CC_HOME;
211 if(wpad->btns_h & WPAD_CLASSIC_BUTTON_FULL_R) btns |= CC_R;
212 if(wpad->btns_h & WPAD_CLASSIC_BUTTON_FULL_L) btns |= CC_L;
213 if(wpad->btns_h & WPAD_CLASSIC_BUTTON_ZL) btns |= CC_ZL;
214 if(wpad->btns_h & WPAD_CLASSIC_BUTTON_ZR) btns |= CC_ZR;
215 if(gcbtns & PAD_BUTTON_X) btns |= GC_X;
216 if(gcbtns & PAD_BUTTON_Y) btns |= GC_Y;
217 if(gcbtns & PAD_BUTTON_A) btns |= GC_A;
218 if(gcbtns & PAD_BUTTON_B) btns |= GC_B;
219 if(gcbtns & PAD_TRIGGER_R) btns |= GC_R;
220 if(gcbtns & PAD_TRIGGER_L) btns |= GC_L;
221 if(gcbtns & PAD_TRIGGER_Z) btns |= GC_Z;
222 if(gcbtns & PAD_BUTTON_START) btns |= GC_START;
223
224 // update buttons pressed (not held)
225 buttonsPressed = btns & ~buttonsHeld;
226 buttonsHeld = btns;
227 }
228
getAllLogs()229 void getAllLogs()
230 {
231 int i, j, k;
232 for(i=0; i<2; i++)
233 {
234 logfile[i].buf = readFromLogFile(i);
235 if(logfile[i].buf != NULL)
236 {
237 logfile[i].pos = malloc(++logfile[i].rows * sizeof(int));
238 if(logfile[i].pos == NULL) return;
239 memset(logfile[i].pos, 0, logfile[i].rows * sizeof(int));
240
241 for(k=0, j=0; j<logfile[i].buf->size; j++)
242 {
243 if(!k)
244 {
245 logfile[i].pos[logfile[i].rows - 1] = j;
246 k = 1;
247 }
248 if(logfile[i].buf->ptr[j]=='\n')
249 {
250 int *_pos = malloc(++logfile[i].rows * sizeof(int));
251 if(_pos == NULL) return;
252 memcpy(_pos, logfile[i].pos, (logfile[i].rows - 1) * sizeof(int));
253 _pos[logfile[i].rows - 1] = 0;
254 free(logfile[i].pos);
255 logfile[i].pos = NULL;
256 logfile[i].pos = malloc(logfile[i].rows * sizeof(int));
257 if(logfile[i].pos == NULL) return;
258 memcpy(logfile[i].pos, _pos, logfile[i].rows * sizeof(int));
259 free(_pos);
260 _pos = NULL;
261 logfile[i].buf->ptr[j] = 0;
262 k = 0;
263 }
264 if(logfile[i].buf->ptr[j]=='\r') logfile[i].buf->ptr[j] = 0;
265 if(logfile[i].rows>0xFFFFFFFE) break;
266 }
267 logfile[i].ready = 1;
268 }
269 }
270 }
271
freeAllLogs()272 void freeAllLogs()
273 {
274 int i;
275 for(i=0; i<2; i++)
276 {
277 if(logfile[i].ready)
278 {
279 free(logfile[i].buf);
280 logfile[i].buf = NULL;
281 free(logfile[i].pos);
282 logfile[i].pos = NULL;
283 }
284 }
285 }
286
sortList()287 void sortList()
288 {
289 int i, j;
290 fileliststruct temp;
291 if(dListTotal<2) return;
292 for(j=dListTotal-1; j>0; j--)
293 {
294 for(i=0; i<j; i++)
295 {
296 if(stricmp(filelist[i].filename, filelist[i+1].filename)>0)
297 {
298 temp = filelist[i];
299 filelist[i] = filelist[i+1];
300 filelist[i+1] = temp;
301 }
302 }
303 }
304 }
305
findPaks(void)306 int findPaks(void)
307 {
308 int i = 0;
309 DIR* dp = NULL;
310 struct dirent* ds;
311
312 dp = opendir(paksDir);
313
314 while((ds = readdir(dp)) != NULL)
315 {
316 if(packfile_supported(ds))
317 {
318 fileliststruct *copy = NULL;
319 if(filelist == NULL) filelist = malloc(sizeof(fileliststruct));
320 else
321 {
322 copy = malloc(i * sizeof(fileliststruct));
323 memcpy(copy, filelist, i * sizeof(fileliststruct));
324 free(filelist);
325 filelist = malloc((i + 1) * sizeof(fileliststruct));
326 memcpy(filelist, copy, i * sizeof(fileliststruct));
327 free(copy); copy = NULL;
328 }
329 memset(&filelist[i], 0, sizeof(fileliststruct));
330 strncpy(filelist[i].filename, ds->d_name, strlen(ds->d_name));
331 i++;
332 }
333 }
334 closedir(dp);
335 return i;
336 }
337
copyScreens(s_screen * Image)338 void copyScreens(s_screen *Image)
339 {
340 // Copy Logo or Menu from Source to Scaler to give us a background
341 // prior to printing to this s_screen.
342 copyscreen_o(Scaler, Image, 0, 0);
343 }
344
writeToScreen(s_screen * src)345 void writeToScreen(s_screen* src)
346 {
347 copyscreen(Screen, src);
348 }
349
drawScreens(s_screen * Image,int x,int y)350 void drawScreens(s_screen *Image, int x, int y)
351 {
352 if(Image) copyscreen_o(Scaler, Image, x, y);
353 writeToScreen(Scaler);
354 video_copy_screen(Screen);
355 }
356
printText(int x,int y,int col,int backcol,int fill,char * format,...)357 void printText(int x, int y, int col, int backcol, int fill, char *format, ...)
358 {
359 int x1, y1, i;
360 unsigned long data;
361 unsigned short *line16 = NULL;
362 unsigned long *line32 = NULL;
363 unsigned char *font;
364 unsigned char ch = 0;
365 char buf[128] = {""};
366 va_list arglist;
367 va_start(arglist, format);
368 vsprintf(buf, format, arglist);
369 va_end(arglist);
370 if(factor > 1){ y += 5; }
371
372 for(i=0; i<sizeof(buf); i++)
373 {
374 ch = buf[i];
375 // mapping
376 if (ch<0x20) ch = 0;
377 else if (ch<0x80) { ch -= 0x20; }
378 else if (ch<0xa0) { ch = 0; }
379 else ch -= 0x40;
380 font = (u8 *)&hankaku_font10[ch*10];
381 // draw
382 if (bpp == 16) line16 = (unsigned short *)Scaler->data + x + y * Scaler->width;
383 else line32 = (unsigned long *)Scaler->data + x + y * Scaler->width;
384
385 for (y1=0; y1<10; y1++)
386 {
387 data = *font++;
388 for (x1=0; x1<5; x1++)
389 {
390 if (data & 1)
391 {
392 if (bpp == 16) *line16 = col;
393 else *line32 = col;
394 }
395 else if (fill)
396 {
397 if (bpp == 16) *line16 = backcol;
398 else *line32 = backcol;
399 }
400
401 if (bpp == 16) line16++;
402 else line32++;
403
404 data = data >> 1;
405 }
406 if (bpp == 16) line16 += Scaler->width-5;
407 else line32 += Scaler->width-5;
408 }
409 x+=5;
410 }
411 }
412
getPreview(char * filename)413 s_screen *getPreview(char *filename)
414 {
415 int width = factor == 4 ? 640 : (factor == 2 ? 320 : 160);
416 int height = factor == 4 ? 480 : (factor == 2 ? 240 : 120);
417 s_screen *title = NULL;
418 s_screen *scale = NULL;
419
420 // Grab current path and filename
421 getBasePath(packfile, filename, 1);
422
423 // Create & Load & Scale Image
424 return NULL; //if(!loadscreen("data/bgs/title.gif", packfile, realPal, PIXEL_8, &title)) return NULL;
425 if((scale = allocscreen(width, height, title->pixelformat)) == NULL) return NULL;
426
427 scalescreen(scale, title);
428
429 // Free Images and Terminate FileCaching
430 freescreen(&title);
431
432 // ScreenShots within Menu will be saved as "Menu"
433 strncpy(packfile,"Menu.ext",128);
434
435 return scale;
436 }
437
ControlMenu()438 int ControlMenu()
439 {
440 int status = -1;
441 int dListMaxDisplay = 17;
442 //bothnewkeys = 0;
443 //inputrefresh();
444 refreshInput();
445 switch(buttonsPressed)
446 {
447 case DIR_UP:
448 dListScrollPosition--;
449 if(dListScrollPosition < 0)
450 {
451 dListScrollPosition = 0;
452 dListCurrentPosition--;
453 }
454 if(dListCurrentPosition < 0) dListCurrentPosition = 0;
455 break;
456
457 case DIR_DOWN:
458 dListCurrentPosition++;
459 if(dListCurrentPosition > dListTotal - 1) dListCurrentPosition = dListTotal - 1;
460 if(dListCurrentPosition > dListMaxDisplay)
461 {
462 if((dListCurrentPosition+dListScrollPosition) < dListTotal) dListScrollPosition++;
463 dListCurrentPosition = dListMaxDisplay;
464 }
465 break;
466
467 case DIR_LEFT:
468 break;
469
470 case DIR_RIGHT:
471 break;
472
473 case WIIMOTE_PLUS:
474 case WIIMOTE_2:
475 case CC_PLUS:
476 case CC_A:
477 case GC_START:
478 case GC_A:
479 // Start Engine!
480 status = 1;
481 break;
482
483 case WIIMOTE_HOME: // TODO? make a nice-looking Home menu
484 case CC_HOME:
485 case GC_Z:
486 // Exit Engine!
487 status = 2;
488 break;
489
490 case WIIMOTE_1:
491 case CC_X:
492 case GC_X:
493 status = 3;
494 break;
495
496 default:
497 // No Update Needed!
498 status = 0;
499 break;
500 }
501 return status;
502 }
503
initMenu(int type)504 void initMenu(int type)
505 {
506 // Read Logo or Menu from Array.
507 if(type) {
508
509 Source = pngToScreen(isWide ? (void*) openbor_menu_480x272_png.data : (void*) openbor_menu_320x240_png.data);
510
511 // Depending on which mode we are in (WideScreen/FullScreen)
512 // allocate proper size for final screen.
513 Screen = allocscreen(Source->width, Source->height, PIXEL_32);
514
515 // Allocate Scaler.
516 Scaler = allocscreen(Screen->width, Screen->height, PIXEL_32);
517 }
518
519 control_init(2);
520 apply_controls();
521 }
522
termMenu()523 void termMenu()
524 {
525 freescreen(&Source);
526 Source = NULL;
527 freescreen(&Scaler);
528 Scaler = NULL;
529 freescreen(&Screen);
530 Screen = NULL;
531 control_exit();
532 }
533
drawMenu()534 void drawMenu()
535 {
536 s_screen *Image = NULL;
537 char listing[45] = {""};
538 int list = 0;
539 int shift = 0;
540 int colors = 0;
541 int clipX=0, clipY=0;
542
543 copyScreens(Source);
544 if(dListTotal < 1) printText((isWide ? 30 : 8), (isWide ? 33 : 24), RED, 0, 0, "No Mods In Paks Folder!");
545 for(list=0; list<dListTotal; list++)
546 {
547 if(list<18)
548 {
549 shift = 0;
550 colors = GRAY;
551 strncpy(listing, "", (isWide ? 44 : 28));
552 if(strlen(filelist[list+dListScrollPosition].filename)-4 < (isWide ? 44 : 28))
553 strncpy(listing, filelist[list+dListScrollPosition].filename, strlen(filelist[list+dListScrollPosition].filename)-4);
554 if(strlen(filelist[list+dListScrollPosition].filename)-4 > (isWide ? 44 : 28))
555 strncpy(listing, filelist[list+dListScrollPosition].filename, (isWide ? 44 : 28));
556 if(list == dListCurrentPosition)
557 {
558 shift = 2;
559 colors = RED;
560 Image = NULL;
561 if(Image)
562 {
563 clipX = factor * (isWide ? 286 : 155);
564 clipY = factor * (isWide ? (factor == 4 ? (s16)32.5 : 32) : (factor == 4 ? (s16)21.5 : 21));
565 }
566 //else printText((isWide ? 288 : 157), (isWide ? 141 : 130), RED, 0, 0, "No Preview Available!");
567 }
568 printText((isWide ? 30 : 7) + shift, (isWide ? 33 : 22)+(11*list) , colors, 0, 0, "%s", listing);
569 }
570 }
571
572 printText((isWide ? 26 : 5), (isWide ? 11 : 4), WHITE, 0, 0, "OpenBoR %s", VERSION);
573 printText((isWide ? 392 : 261),(isWide ? 11 : 4), WHITE, 0, 0, __DATE__);
574 printText((isWide ? 23 : 4),(isWide ? 251 : 226), WHITE, 0, 0, "%s: Start Game", control_getkeyname(savedata.keys[0][SDID_ATTACK]));
575 printText((isWide ? 150 : 84),(isWide ? 251 : 226), WHITE, 0, 0, "%s: BGM Player", control_getkeyname(savedata.keys[0][SDID_ATTACK2]));
576 printText((isWide ? 270 : 164),(isWide ? 251 : 226), WHITE, 0, 0, "%s: View Logs", control_getkeyname(savedata.keys[0][SDID_JUMP]));
577 printText((isWide ? 390 : 244),(isWide ? 251 : 226), WHITE, 0, 0, "%s: Quit Game", control_getkeyname(savedata.keys[0][SDID_SPECIAL]));
578 printText((isWide ? 330 : 197),(isWide ? 170 : 155), BLACK, 0, 0, "www.LavaLit.com");
579 printText((isWide ? 322 : 190),(isWide ? 180 : 165), BLACK, 0, 0, "www.SenileTeam.com");
580
581 #ifdef SPK_SUPPORTED
582 printText((isWide ? 324 : 192),(isWide ? 191 : 176), DARK_RED, 0, 0, "SecurePAK Edition");
583 #endif
584
585 drawScreens(Image, clipX, clipY);
586
587 if(Image)
588 {
589 freescreen(&Image);
590 Image = NULL;
591 }
592 }
593
drawLogs()594 void drawLogs()
595 {
596 int i=which_logfile, j, k, l, done=0;
597 s_screen *Viewer = NULL;
598
599 bothkeys = bothnewkeys = 0;
600 Viewer = allocscreen(Source->width, Source->height, Source->pixelformat);
601 clearscreen(Viewer);
602 bothkeys = bothnewkeys = 0;
603
604 while(!done)
605 {
606 copyScreens(Viewer);
607 //inputrefresh();
608 refreshInput();
609 printText((isWide ? 410 : 250), 3, RED, 0, 0, "Quit : 1/B");
610 if(buttonsPressed & (WIIMOTE_1|CC_B|GC_B)) done = 1;
611
612 if(logfile[i].ready)
613 {
614 printText(5, 3, RED, 0, 0, "OpenBorLog.txt");
615 if(buttonsHeld & DIR_UP) --logfile[i].line;
616 if(buttonsHeld & DIR_DOWN) ++logfile[i].line;
617 if(buttonsHeld & DIR_LEFT) logfile[i].line = 0;
618 if(buttonsHeld & DIR_RIGHT) logfile[i].line = logfile[i].rows - (LOG_SCREEN_END - LOG_SCREEN_TOP);
619 if(logfile[i].line > logfile[i].rows - (LOG_SCREEN_END - LOG_SCREEN_TOP) - 1) logfile[i].line = logfile[i].rows - (LOG_SCREEN_END - LOG_SCREEN_TOP) - 1;
620 if(logfile[i].line < 0) logfile[i].line = 0;
621 for(l=LOG_SCREEN_TOP, j=logfile[i].line; j<logfile[i].rows-1; l++, j++)
622 {
623 if(l<LOG_SCREEN_END)
624 {
625 char textpad[480] = {""};
626 for(k=0; k<480; k++)
627 {
628 if(!logfile[i].buf->ptr[logfile[i].pos[j]+k]) break;
629 textpad[k] = logfile[i].buf->ptr[logfile[i].pos[j]+k];
630 }
631 if(logfile[i].rows>0xFFFF)
632 printText(5, l*10, WHITE, 0, 0, "0x%08x: %s", j, textpad);
633 else
634 printText(5, l*10, WHITE, 0, 0, "0x%04x: %s", j, textpad);
635 }
636 else break;
637 }
638 }
639 else if(i == SCRIPT_LOG) printText(5, 3, RED, 0, 0, "Log NOT Found: ScriptLog.txt");
640 else printText(5, 3, RED, 0, 0, "Log NOT Found: OpenBorLog.txt");
641
642 drawScreens(NULL, 0, 0);
643 }
644 freescreen(&Viewer);
645 Viewer = NULL;
646 drawMenu();
647 }
648
fillRect(s_screen * dest,Rect * rect,u32 color)649 void fillRect(s_screen *dest, Rect *rect, u32 color)
650 {
651 u32 *data = (u32*)dest->data;
652 int x, y, width=dest->width;
653 for(y=rect->y; y<rect->y+rect->height; y++)
654 {
655 for(x=rect->x; x<rect->x+rect->width; x++)
656 {
657 data[x+y*width] = color;
658 }
659 }
660 }
661
setVideoMode()662 void setVideoMode()
663 {
664 if(isWide) // 480x272
665 {
666 videomodes.mode = savedata.screen[videoMode][0];
667 videomodes.filter = savedata.screen[videoMode][1];
668 videomodes.hRes = 480;
669 videomodes.vRes = 272;
670 videomodes.hScale = (float)1.5;
671 videomodes.vScale = (float)1.13;
672 videomodes.hShift = 80;
673 videomodes.vShift = 20;
674 videomodes.dOffset = 263;
675 videomodes.pixel = 4;
676 }
677 else // 320x240
678 {
679 videomodes.mode = savedata.screen[videoMode][0];
680 videomodes.filter = savedata.screen[videoMode][1];
681 videomodes.hRes = 320;
682 videomodes.vRes = 240;
683 videomodes.hScale = 1;
684 videomodes.vScale = 1;
685 videomodes.hShift = 0;
686 videomodes.vShift = 0;
687 videomodes.dOffset = 231;
688 videomodes.pixel = 4;
689 }
690
691 video_set_mode(videomodes);
692 }
693
Menu()694 void Menu()
695 {
696 int done = 0;
697 int ctrl = 0;
698
699 // Set video mode based on aspect ratio
700 if(CONF_GetAspectRatio() == CONF_ASPECT_16_9) isWide = 1;
701 setVideoMode();
702 dListTotal = findPaks();
703
704 dListCurrentPosition = 0;
705 if(dListTotal != 1)
706 {
707 sortList();
708 getAllLogs();
709 initMenu(1);
710 drawMenu();
711 pControl = ControlMenu;
712
713 while(!done)
714 {
715 ctrl = Control();
716 switch(ctrl)
717 {
718 case 1:
719 case 2:
720 done = 1;
721 break;
722
723 case 3:
724 drawLogs();
725 break;
726
727 case -1:
728 drawMenu();
729 break;
730
731 case -2:
732 // BGM player isn't supported
733 break;
734 }
735 }
736 freeAllLogs();
737 termMenu();
738 if(ctrl == 2)
739 {
740 if (filelist)
741 {
742 free(filelist);
743 filelist = NULL;
744 }
745 borExit(0);
746 }
747 }
748 getBasePath(packfile, filelist[dListCurrentPosition+dListScrollPosition].filename, 1);
749 free(filelist);
750 }
751
752