1 /*
2  * OpenBOR - http://www.LavaLit.com
3  * -----------------------------------------------------------------------
4  * All rights reserved, see LICENSE in OpenBOR root for details.
5  *
6  * Copyright (c) 2004 - 2011 OpenBOR Team
7  */
8 #include <unistd.h>
9 #include "SDL.h"
10 #include "sdlport.h"
11 #include "video.h"
12 #include "openbor.h"
13 #include "soundmix.h"
14 #include "packfile.h"
15 #include "gfx.h"
16 #include "hankaku.h"
17 #include "stristr.h"
18 #include "stringptr.h"
19 
20 #include "pngdec.h"
21 #include "../resources/OpenBOR_Logo_480x272_png.h"
22 #include "../resources/OpenBOR_Logo_320x240_png.h"
23 #include "../resources/OpenBOR_Menu_480x272_png.h"
24 #include "../resources/OpenBOR_Menu_320x240_png.h"
25 
26 #include <dirent.h>
27 
28 extern int videoMode;
29 extern s_videomodes videomodes;
30 extern s_screen* vscreen;
31 extern int nativeHeight;
32 extern int nativeWidth;
33 s_screen* bgscreen;
34 
35 #define RGB32(R,G,B) ((R) | ((G) << 8) | ((B) << 16))
36 #define RGB16(R,G,B) ((B&0xF8)<<8) | ((G&0xFC)<<3) | (R>>3)
37 #define RGB(R,G,B)   (bpp==16?RGB16(R,G,B):RGB32(R,G,B))
38 
39 #define BLACK		RGB(  0,   0,   0)
40 #define WHITE		RGB(255, 255, 255)
41 #define RED			RGB(255,   0,   0)
42 #define	GREEN		RGB(  0, 255,   0)
43 #define BLUE		RGB(  0,   0, 255)
44 #define YELLOW		RGB(255, 255,   0)
45 #define PURPLE		RGB(255,   0, 255)
46 #define ORANGE		RGB(255, 128,   0)
47 #define GRAY		RGB(112, 128, 144)
48 #define LIGHT_GRAY  RGB(223, 223, 223)
49 #define DARK_RED	RGB(128,   0,   0)
50 #define DARK_GREEN	RGB(  0, 128,   0)
51 #define DARK_BLUE	RGB(  0,   0, 128)
52 
53 #define LOG_SCREEN_TOP 2
54 #define LOG_SCREEN_END (isWide ? 26 : 23)
55 
56 int bpp = 32;
57 int isWide = 0;
58 int isFull = 0;
59 int flags;
60 int dListTotal;
61 int dListCurrentPosition;
62 int dListScrollPosition;
63 int which_logfile = OPENBOR_LOG;
64 FILE *bgmFile = NULL;
65 unsigned int bgmPlay = 0, bgmLoop = 0, bgmCycle = 0, bgmCurrent = 0, bgmStatus = 0;
66 extern u32 bothkeys, bothnewkeys;
67 fileliststruct *filelist;
68 extern const s_drawmethod plainmethod;
69 
70 typedef struct{
71 	stringptr *buf;
72 	int *pos;
73 	int line;
74 	int rows;
75 	char ready;
76 }s_logfile;
77 s_logfile logfile[2];
78 
79 typedef int (*ControlInput)();
80 
81 int ControlMenu();
82 int ControlBGM();
83 void PlayBGM();
84 void StopBGM();
85 static ControlInput pControl;
86 
Control()87 int Control()
88 {
89 	return pControl();
90 }
91 
getAllLogs()92 void getAllLogs()
93 {
94 	ptrdiff_t i, j, k;
95 	for(i=0; i<2; i++)
96 	{
97 		logfile[i].buf = readFromLogFile(i);
98 		if(logfile[i].buf != NULL)
99 		{
100 			logfile[i].pos = malloc(++logfile[i].rows * sizeof(int));
101 			if(logfile[i].pos == NULL) return;
102 			memset(logfile[i].pos, 0, logfile[i].rows * sizeof(int));
103 
104 			for(k=0, j=0; j<logfile[i].buf->size; j++)
105 			{
106 				if(!k)
107 				{
108 					logfile[i].pos[logfile[i].rows - 1] = j;
109 					k = 1;
110 				}
111 				if(logfile[i].buf->ptr[j]=='\n')
112 				{
113 					int *_pos = malloc(++logfile[i].rows * sizeof(int));
114 					if(_pos == NULL) return;
115 					memcpy(_pos, logfile[i].pos, (logfile[i].rows - 1) * sizeof(int));
116 					_pos[logfile[i].rows - 1] = 0;
117 					free(logfile[i].pos);
118 					logfile[i].pos = NULL;
119 					logfile[i].pos = malloc(logfile[i].rows * sizeof(int));
120 					if(logfile[i].pos == NULL) return;
121 					memcpy(logfile[i].pos, _pos, logfile[i].rows * sizeof(int));
122 					free(_pos);
123 					_pos = NULL;
124 					logfile[i].buf->ptr[j] = 0;
125 					k = 0;
126 				}
127 				if(logfile[i].buf->ptr[j]=='\r') logfile[i].buf->ptr[j] = 0;
128 				if(logfile[i].rows>0xFFFFFFFE) break;
129 			}
130 			logfile[i].ready = 1;
131 		}
132 	}
133 }
134 
freeAllLogs()135 void freeAllLogs()
136 {
137 	int i;
138 	for(i=0; i<2; i++)
139 	{
140 		if(logfile[i].ready)
141 		{
142 			free_string(logfile[i].buf);
143 			logfile[i].buf = NULL;
144 			free(logfile[i].pos);
145 			logfile[i].pos = NULL;
146 		}
147 	}
148 }
149 
sortList()150 void sortList()
151 {
152 	int i, j;
153 	fileliststruct temp;
154 	if(dListTotal<2) return;
155 	for(j=dListTotal-1; j>0; j--)
156 	{
157 		for(i=0; i<j; i++)
158 		{
159 			if(stricmp(filelist[i].filename, filelist[i+1].filename)>0)
160 			{
161 				temp = filelist[i];
162 				filelist[i] = filelist[i+1];
163 				filelist[i+1] = temp;
164 			}
165 		}
166 	}
167 }
168 
findPaks(void)169 int findPaks(void)
170 {
171 	int i = 0;
172 	DIR* dp = NULL;
173 	struct dirent* ds;
174 #ifdef WII
175 	dp = opendir("sd:/apps/OpenBOR/Paks");
176 #else
177 	dp = opendir(paksDir);
178 #endif
179 	if(dp != NULL)
180    	{
181 		while((ds = readdir(dp)) != NULL)
182 		{
183 			if(packfile_supported(ds))
184 			{
185 				fileliststruct *copy = NULL;
186 				if(filelist == NULL) filelist = malloc(sizeof(fileliststruct));
187 				else
188 				{
189 					copy = malloc(i * sizeof(fileliststruct));
190 					memcpy(copy, filelist, i * sizeof(fileliststruct));
191 					free(filelist);
192 					filelist = malloc((i + 1) * sizeof(fileliststruct));
193 					memcpy(filelist, copy, i * sizeof(fileliststruct));
194 					free(copy); copy = NULL;
195 				}
196 				memset(&filelist[i], 0, sizeof(fileliststruct));
197 				strncpy(filelist[i].filename, ds->d_name, strlen(ds->d_name));
198 				i++;
199 			}
200 		}
201 		closedir(dp);
202    	}
203 	return i;
204 }
205 
drawScreens(s_screen * Image)206 void drawScreens(s_screen *Image)
207 {
208 	putscreen(vscreen, Image, 0, 0, NULL);
209 	video_copy_screen(vscreen);
210 }
211 
printText(int x,int y,int col,int backcol,int fill,char * format,...)212 void printText(int x, int y, int col, int backcol, int fill, char *format, ...)
213 {
214 	int x1, y1, i;
215 	u32 data;
216 	u16 *line16 = NULL;
217 	u32 *line32 = NULL;
218 	u8 *font;
219 	u8 ch = 0;
220 	char buf[128] = {""};
221 	int pitch = vscreen->width*bpp/8;
222 	va_list arglist;
223 		va_start(arglist, format);
224 		vsprintf(buf, format, arglist);
225 		va_end(arglist);
226 
227 	for(i=0; i<sizeof(buf); i++)
228 	{
229 		ch = buf[i];
230 		// mapping
231 		if (ch<0x20) ch = 0;
232 		else if (ch<0x80) { ch -= 0x20; }
233 		else if (ch<0xa0) {	ch = 0;	}
234 		else ch -= 0x40;
235 		font = (u8 *)&hankaku_font10[ch*10];
236 		// draw
237 		if (bpp == 16) line16 = (u16*)(vscreen->data + x*2 + y * pitch);
238 		else           line32 = (u32*)(vscreen->data + x*4 + y * pitch);
239 
240 		for (y1=0; y1<10; y1++)
241 		{
242 			data = *font++;
243 			for (x1=0; x1<5; x1++)
244 			{
245 				if (data & 1)
246 				{
247 					if (bpp == 16) *line16 = col;
248 				    else           *line32 = col;
249 				}
250 				else if (fill)
251 				{
252 					if (bpp == 16) *line16 = backcol;
253 					else           *line32 = backcol;
254 				}
255 
256 				if (bpp == 16) line16++;
257 				else           line32++;
258 
259 				data = data >> 1;
260 			}
261 			if (bpp == 16) line16 += pitch/2-5;
262 			else           line32 += pitch/4-5;
263 		}
264 		x+=5;
265 	}
266 }
267 
getPreview(char * filename)268 s_screen *getPreview(char *filename)
269 {
270 	s_screen *title = NULL;
271 	s_screen *scale = NULL;
272 	// Grab current path and filename
273 	getBasePath(packfile, filename, 1);
274 	// Create & Load & Scale Image
275 	if(!loadscreen("data/bgs/title", packfile, NULL, PIXEL_x8, &title)) return NULL;
276 	scale = allocscreen(160, 120, PIXEL_x8);
277 	scalescreen(scale, title);
278 	memcpy(scale->palette, title->palette, PAL_BYTES);
279 	// ScreenShots within Menu will be saved as "Menu"
280 	strncpy(packfile,"Menu.xxx",128);
281 	freescreen(&title);
282 	return scale;
283 }
284 
StopBGM()285 void StopBGM()
286 {
287 	sound_close_music();
288 	if (bgmFile)
289 	{
290 		fclose(bgmFile);
291 		bgmFile = NULL;
292 	}
293 	bgmPlay = 0;
294 }
295 
PlayBGM()296 void PlayBGM()
297 {
298 	bgmPlay = packfile_music_play(filelist, bgmFile, bgmLoop, dListCurrentPosition, dListScrollPosition);
299 }
300 
ControlMenu()301 int ControlMenu()
302 {
303 	int status = -1;
304 	int dListMaxDisplay = 17;
305 	bothnewkeys = 0;
306 	inputrefresh();
307 	switch(bothnewkeys)
308 	{
309 		case FLAG_MOVEUP:
310 			dListScrollPosition--;
311 			if(dListScrollPosition < 0)
312 			{
313 				dListScrollPosition = 0;
314 				dListCurrentPosition--;
315 			}
316 			if(dListCurrentPosition < 0) dListCurrentPosition = 0;
317 			break;
318 
319 		case FLAG_MOVEDOWN:
320 			dListCurrentPosition++;
321 			if(dListCurrentPosition > dListTotal - 1) dListCurrentPosition = dListTotal - 1;
322 			if(dListCurrentPosition > dListMaxDisplay)
323 	        {
324 		        if((dListCurrentPosition+dListScrollPosition) < dListTotal) dListScrollPosition++;
325 			    dListCurrentPosition = dListMaxDisplay;
326 			}
327 			break;
328 
329 		case FLAG_MOVELEFT:
330 			break;
331 
332 		case FLAG_MOVERIGHT:
333 			break;
334 
335 		case FLAG_START:
336 		case FLAG_ATTACK:
337 			// Start Engine!
338 			status = 1;
339 			break;
340 
341 		case FLAG_ATTACK2:
342 			pControl = ControlBGM;
343 			status = -2;
344 			break;
345 
346 		case FLAG_SPECIAL:
347 		case FLAG_ESC:
348 			// Exit Engine!
349 			status = 2;
350 			break;
351 
352 		case FLAG_JUMP:
353 			//drawLogs();
354 			status = 3;
355 			break;
356 
357 		default:
358 			// No Update Needed!
359 			status = 0;
360 			break;
361 	}
362 	return status;
363 }
364 
ControlBGM()365 int ControlBGM()
366 {
367 	int status = -2;
368 	int dListMaxDisplay = 17;
369 	bothnewkeys = 0;
370 	inputrefresh();
371 	switch(bothnewkeys)
372 	{
373 		case FLAG_MOVEUP:
374 			dListScrollPosition--;
375 			if(dListScrollPosition < 0)
376 			{
377 				dListScrollPosition = 0;
378 				dListCurrentPosition--;
379 			}
380 			if(dListCurrentPosition < 0) dListCurrentPosition = 0;
381 			break;
382 
383 		case FLAG_MOVEDOWN:
384 			dListCurrentPosition++;
385 			if(dListCurrentPosition > dListTotal - 1) dListCurrentPosition = dListTotal - 1;
386 			if(dListCurrentPosition > dListMaxDisplay)
387 	        {
388 		        if((dListCurrentPosition+dListScrollPosition) < dListTotal) dListScrollPosition++;
389 			    dListCurrentPosition = dListMaxDisplay;
390 			}
391 			break;
392 
393 		case FLAG_MOVELEFT:
394 			if(!bgmStatus || (bgmPlay && bgmCurrent == dListCurrentPosition+dListScrollPosition))
395 			{
396 				filelist[bgmCurrent].bgmTrack--;
397 				if(filelist[bgmCurrent].bgmTrack < 0) filelist[bgmCurrent].bgmTrack = filelist[bgmCurrent].nTracks-1;
398 				if(bgmStatus) PlayBGM();
399 			}
400 			break;
401 
402 		case FLAG_MOVERIGHT:
403 			if(!bgmStatus || (bgmPlay && bgmCurrent == dListCurrentPosition+dListScrollPosition))
404 			{
405 				filelist[bgmCurrent].bgmTrack++;
406 				if(filelist[bgmCurrent].bgmTrack > filelist[bgmCurrent].nTracks - 1) filelist[bgmCurrent].bgmTrack = 0;
407 				if(bgmStatus) PlayBGM();
408 			}
409 			break;
410 
411 		case FLAG_START:
412 		case FLAG_ATTACK:
413 			if(bgmPlay) StopBGM();
414 			else PlayBGM();
415 			break;
416 
417 		case FLAG_ATTACK2:
418 			if(!bgmPlay)
419 			{
420 				if(bgmLoop) bgmLoop = 0;
421 				else bgmLoop = 1;
422 			}
423 			break;
424 
425 		case FLAG_JUMP:
426 			if(!bgmPlay)
427 			{
428 				if(bgmCycle) bgmCycle = 0;
429 				else bgmCycle = 1;
430 			}
431 			break;
432 
433 		case FLAG_SPECIAL:
434 		case FLAG_ESC:
435 			pControl = ControlMenu;
436 			status = -1;
437 			break;
438 
439 		default:
440 			// No Update Needed!
441 			status = 0;
442 			break;
443 	}
444 	return status;
445 }
446 
initMenu(int type)447 void initMenu(int type)
448 {
449 
450 #ifdef ANDROID
451 	isWide = (float)nativeHeight/(float)nativeWidth < 3.0f/4.0f;
452 	isFull = 1;
453 	bpp = 32;
454 	savedata.glscale = 0.0f;
455 	screenformat = PIXEL_32;
456 #endif
457 
458 	screenformat = bpp==32?PIXEL_32:PIXEL_16;
459 	pixelformat = PIXEL_x8;
460 
461 	savedata.fullscreen = isFull;
462 	video_stretch(savedata.stretch);
463 	videoMode = isWide ? 1 : 0;
464 	videomodes.hRes = isWide ? 480 :320;
465 	videomodes.vRes = isWide ? 272 :240;
466 	videomodes.pixel = pixelbytes[PIXEL_32];
467 	vscreen = allocscreen(videomodes.hRes, videomodes.vRes, screenformat);
468 
469 	video_set_mode(videomodes);
470 
471 	// Read Logo or Menu from Array.
472 	if(!type)
473 		bgscreen = pngToScreen(isWide ? (void*) openbor_logo_480x272_png.data : (void*) openbor_logo_320x240_png.data);
474 	else
475 		bgscreen = pngToScreen(isWide ? (void*) openbor_menu_480x272_png.data : (void*) openbor_menu_320x240_png.data);
476 
477 	control_init(2);
478 	apply_controls();
479 	sound_init(12);
480 	sound_start_playback(savedata.soundbits,savedata.soundrate);
481 }
482 
termMenu()483 void termMenu()
484 {
485 	videomodes.hRes = videomodes.vRes = 0;
486 	video_set_mode(videomodes);
487 	if(bgscreen) freescreen(&bgscreen);
488 	if(vscreen) freescreen(&vscreen);
489 	sound_exit();
490 	control_exit();
491 }
492 
drawMenu()493 void drawMenu()
494 {
495 	char listing[45] = {""};
496 	int list = 0;
497 	int shift = 0;
498 	int colors = 0;
499 	s_screen* Image = NULL;
500 
501 	putscreen(vscreen,bgscreen,0,0,NULL);
502 	if(dListTotal < 1) printText((isWide ? 30 : 8), (isWide ? 33 : 24), RED, 0, 0, "No Mods In Paks Folder!");
503 	for(list=0; list<dListTotal; list++)
504 	{
505 		if(list<18)
506 		{
507 			shift = 0;
508 			colors = GRAY;
509 			strncpy(listing, "", (isWide ? 44 : 28));
510 			if(strlen(filelist[list+dListScrollPosition].filename)-4 < (isWide ? 44 : 28))
511 				strncpy(listing, filelist[list+dListScrollPosition].filename, strlen(filelist[list+dListScrollPosition].filename)-4);
512 			if(strlen(filelist[list+dListScrollPosition].filename)-4 > (isWide ? 44 : 28))
513 				strncpy(listing, filelist[list+dListScrollPosition].filename, (isWide ? 44 : 28));
514 			if(list == dListCurrentPosition)
515 			{
516 				shift = 2;
517 				colors = RED;
518 #ifdef WII
519 				Image = NULL;
520 #else
521 				Image = getPreview(filelist[list+dListScrollPosition].filename);
522 #endif
523 
524 			}
525 			printText((isWide ? 30 : 7) + shift, (isWide ? 33 : 22)+(11*list) , colors, 0, 0, "%s", listing);
526 		}
527 	}
528 
529 	printText((isWide ? 26 : 5), (isWide ? 11 : 4), WHITE, 0, 0, "OpenBoR %s", VERSION);
530 	printText((isWide ? 392 : 261),(isWide ? 11 : 4), WHITE, 0, 0, __DATE__);
531 	printText((isWide ? 23 : 4),(isWide ? 251 : 226), WHITE, 0, 0, "%s: Start Game", control_getkeyname(savedata.keys[0][SDID_ATTACK]));
532 	printText((isWide ? 150 : 84),(isWide ? 251 : 226), WHITE, 0, 0, "%s: BGM Player", control_getkeyname(savedata.keys[0][SDID_ATTACK2]));
533 	printText((isWide ? 270 : 164),(isWide ? 251 : 226), WHITE, 0, 0, "%s: View Logs", control_getkeyname(savedata.keys[0][SDID_JUMP]));
534 	printText((isWide ? 390 : 244),(isWide ? 251 : 226), WHITE, 0, 0, "%s: Quit Game", control_getkeyname(savedata.keys[0][SDID_SPECIAL]));
535    	printText((isWide ? 330 : 197),(isWide ? 170 : 155), BLACK, 0, 0, "www.LavaLit.com");
536 	printText((isWide ? 322 : 190),(isWide ? 180 : 165), BLACK, 0, 0, "www.SenileTeam.com");
537 
538 #ifdef SPK_SUPPORTED
539 	printText((isWide ? 324 : 192),(isWide ? 191 : 176), DARK_RED, 0, 0, "SecurePAK Edition");
540 #endif
541 
542 	if(Image)
543 	{
544 		putscreen(vscreen, Image, isWide ? 286 : 155, isWide ? 32:21, NULL);
545 		freescreen(&Image);
546 	}
547 	else
548 		printText((isWide ? 288 : 157), (isWide ? 141 : 130), RED, 0, 0, "No Preview Available!");
549 
550 	video_copy_screen(vscreen);
551 }
552 
drawBGMPlayer()553 void drawBGMPlayer()
554 {
555 	char listing[45] = {""}, bgmListing[25] = {""};
556 	char t1[64] = "", t2[25] = "Unknown";
557 	char a1[64] = "", a2[25] = "Unknown";
558 	int list = 0, colors = 0, shift = 0;
559 
560 	// Allocate Preview Box for Music Text Info.
561 	putscreen(vscreen,bgscreen,0,0,NULL);
562 	putbox((isWide ? 286 : 155),(isWide ? 32 : 21),160,120,LIGHT_GRAY,vscreen,NULL);
563 
564 	for(list=0; list<dListTotal; list++)
565 	{
566 		if(list<18)
567 		{
568 			shift = 0;
569 			colors = GRAY;
570 			strncpy(listing, "", (isWide ? 44 : 28));
571 			if(strlen(filelist[list+dListScrollPosition].filename)-4 < (isWide ? 44 : 28))
572 				strncpy(listing, filelist[list+dListScrollPosition].filename, strlen(filelist[list+dListScrollPosition].filename)-4);
573 			if(strlen(filelist[list+dListScrollPosition].filename)-4 > (isWide ? 44 : 28))
574 				strncpy(listing, filelist[list+dListScrollPosition].filename, (isWide ? 44 : 28));
575 			if(list==dListCurrentPosition) { shift = 2; colors = RED; }
576 			printText((isWide ? 30 : 7) + shift, (isWide ? 33 : 22)+(11*list) , colors, 0, 0, "%s", listing);
577 		}
578 	}
579 
580 	printText((isWide ? 26 : 5), (isWide ? 11 : 4), WHITE, 0, 0, "OpenBoR %s", VERSION);
581 	printText((isWide ? 392 : 261),(isWide ? 11 : 4), WHITE, 0, 0, __DATE__);
582 	printText((isWide ? 23 : 4),(isWide ? 251 : 226), WHITE, 0, 0, "%s: %s", control_getkeyname(savedata.keys[0][SDID_ATTACK]), bgmPlay ? "Stop" : "Play");
583 	printText((isWide ? 150 : 84),(isWide ? 251 : 226), WHITE, 0, 0, "%s: %s", control_getkeyname(savedata.keys[0][SDID_ATTACK2]), bgmLoop ? "Repeat On" : "Repeat Off");
584 	printText((isWide ? 270 : 164),(isWide ? 251 : 226), WHITE, 0, 0, "%s: %s", control_getkeyname(savedata.keys[0][SDID_JUMP]), bgmCycle ? "Cycle On" : "Cycle Off");
585 	printText((isWide ? 390 : 244),(isWide ? 251 : 226), WHITE, 0, 0, "%s: Exit Player", control_getkeyname(savedata.keys[0][SDID_SPECIAL]));
586 	printText((isWide ? 330 : 197),(isWide ? 170 : 155), BLACK, 0, 0, "www.LavaLit.com");
587 	printText((isWide ? 322 : 190),(isWide ? 180 : 165), BLACK, 0, 0, "www.SenileTeam.com");
588 
589 #ifdef SPK_SUPPORTED
590 	printText((isWide ? 324 : 192),(isWide ? 191 : 176), DARK_RED, 0, 0, "SecurePAK Edition");
591 #endif
592 
593 	if(!bgmPlay) bgmCurrent = dListCurrentPosition+dListScrollPosition;
594 	if(strlen(filelist[bgmCurrent].filename)-4 < 24)
595 		strncpy(bgmListing, filelist[bgmCurrent].filename, strlen(filelist[bgmCurrent].filename)-4);
596 	if(strlen(filelist[bgmCurrent].filename)-4 > 24)
597 		strncpy(bgmListing, filelist[bgmCurrent].filename, 24);
598 	if(!sound_query_music(a1, t1))
599 	{
600 		PlayBGM();
601 		sound_query_music(a1, t1);
602 		StopBGM();
603 	}
604 	if(t1[0]) strncpy(t2, t1, 25);
605 	if(a1[0]) strncpy(a2, a1, 25);
606 	printText((isWide ? 288 : 157),(isWide ? 35 : 23) + (11 * 0), DARK_RED, 0, 0, "Game: %s", bgmListing);
607 	printText((isWide ? 288 : 157),(isWide ? 35 : 23) + (11 * 1), bgmPlay ? DARK_GREEN : DARK_BLUE, 0, 0, "Total Tracks: %d", filelist[bgmCurrent].nTracks-1);
608 	printText((isWide ? 288 : 157),(isWide ? 35 : 23) + (11 * 2), bgmPlay ? DARK_GREEN : DARK_BLUE, 0, 0, "Current Track: %d", filelist[bgmCurrent].bgmTrack);
609 	printText((isWide ? 288 : 157),(isWide ? 35 : 23) + (11 * 3), bgmPlay ? DARK_GREEN : DARK_BLUE, 0, 0, "File: %s", filelist[bgmCurrent].bgmFileName[filelist[bgmCurrent].bgmTrack]);
610 	printText((isWide ? 288 : 157),(isWide ? 35 : 23) + (11 * 4), bgmPlay ? DARK_GREEN : DARK_BLUE, 0, 0, "Track: %s", t2);
611 	printText((isWide ? 288 : 157),(isWide ? 35 : 23) + (11 * 5), bgmPlay ? DARK_GREEN : DARK_BLUE, 0, 0, "Artist: %s", a2);
612 
613 	video_copy_screen(vscreen);
614 }
615 
drawLogs()616 void drawLogs()
617 {
618 	int i=which_logfile, j, k, l, done=0;
619 	bothkeys = bothnewkeys = 0;
620 
621 	while(!done)
622 	{
623 		putscreen(vscreen,bgscreen,0,0,NULL);
624 	    inputrefresh();
625 	    sound_update_music();
626 #if OPENDINGUX
627 	    printText(250, 3, RED, 0, 0, "Quit : Select");
628 #else
629 	    printText((isWide ? 410 : 250), 3, RED, 0, 0, "Quit : Escape");
630 #endif
631 		if(bothnewkeys & FLAG_ESC) done = 1;
632 
633 		if(logfile[i].ready)
634 		{
635 			printText(5, 3, RED, 0, 0, "OpenBorLog.txt");
636 			if(bothkeys & FLAG_MOVEUP) --logfile[i].line;
637 	        if(bothkeys & FLAG_MOVEDOWN) ++logfile[i].line;
638 			if(bothkeys & FLAG_MOVELEFT) logfile[i].line = 0;
639 			if(bothkeys & FLAG_MOVERIGHT) logfile[i].line = logfile[i].rows - (LOG_SCREEN_END - LOG_SCREEN_TOP);
640 			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;
641 			if(logfile[i].line < 0) logfile[i].line = 0;
642 			for(l=LOG_SCREEN_TOP, j=logfile[i].line; j<logfile[i].rows-1; l++, j++)
643 			{
644 				if(l<LOG_SCREEN_END)
645 				{
646 					char textpad[480] = {""};
647 					for(k=0; k<480; k++)
648 					{
649 						if(!logfile[i].buf->ptr[logfile[i].pos[j]+k]) break;
650 						textpad[k] = logfile[i].buf->ptr[logfile[i].pos[j]+k];
651 					}
652 					if(logfile[i].rows>0xFFFF)
653 						printText(5, l*10, WHITE, 0, 0, "0x%08x:  %s", j, textpad);
654 					else
655 						printText(5, l*10, WHITE, 0, 0, "0x%04x:  %s", j, textpad);
656 				}
657 				else break;
658 			}
659 		}
660 		else if(i == SCRIPT_LOG) printText(5, 3, RED, 0, 0, "Log NOT Found: ScriptLog.txt");
661 		else                     printText(5, 3, RED, 0, 0, "Log NOT Found: OpenBorLog.txt");
662 
663 	    video_copy_screen(vscreen);
664 	}
665 	drawMenu();
666 }
667 
drawLogo()668 void drawLogo()
669 {
670     if(savedata.logo) return;
671 	initMenu(0);
672 	video_copy_screen(bgscreen);
673 	SDL_Delay(3000);
674 	termMenu();
675 }
676 
Menu()677 void Menu()
678 {
679 	int done = 0;
680 	int ctrl = 0;
681 	loadsettings();
682 	drawLogo();
683 	dListCurrentPosition = 0;
684 	if((dListTotal = findPaks()) != 1)
685 	{
686 		sortList();
687 		getAllLogs();
688 #ifndef WII
689 		packfile_music_read(filelist, dListTotal);
690 #endif
691 		initMenu(1);
692 		drawMenu();
693 		pControl = ControlMenu;
694 
695 		while(!done)
696 		{
697 			sound_update_music();
698 			bgmStatus = sound_query_music(NULL, NULL);
699 			if(bgmPlay && !bgmStatus)
700 			{
701 				if(bgmCycle)
702 				{
703 					filelist[bgmCurrent].bgmTrack++;
704 					if(filelist[bgmCurrent].bgmTrack > filelist[bgmCurrent].nTracks - 1) filelist[bgmCurrent].bgmTrack = 0;
705 					PlayBGM();
706 				}
707 				else StopBGM();
708 				drawBGMPlayer();
709 			}
710 
711 			ctrl = Control();
712 			switch(ctrl)
713 			{
714 				case 1:
715 				case 2:
716 					done = 1;
717 					break;
718 
719 				case 3:
720 					drawLogs();
721 					break;
722 
723 				case -1:
724 					drawMenu();
725 					break;
726 
727 				case -2:
728 					drawBGMPlayer();
729 					break;
730 			}
731 		}
732 		freeAllLogs();
733 		termMenu();
734 		if(dListTotal == 0 || ctrl == 2)
735 		{
736 			if (filelist)
737 			{
738 				free(filelist);
739 				filelist = NULL;
740 			}
741 			borExit(0);
742 		}
743 	}
744 	getBasePath(packfile, filelist[dListCurrentPosition+dListScrollPosition].filename, 1);
745 	free(filelist);
746 }
747