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 
9 
10 #include <unistd.h>
11 #include "SDL.h"
12 #include "sdlport.h"
13 #include "video.h"
14 #include "openbor.h"
15 #include "soundmix.h"
16 #include "packfile.h"
17 #include "gfx.h"
18 #include "hankaku.h"
19 #include "stristr.h"
20 #include "stringptr.h"
21 
22 #include "pngdec.h"
23 #include "../resources/OpenBOR_Logo_480x272_Link_png.h"
24 #include "../resources/OpenBOR_Logo_320x240_Link_png.h"
25 #include "../resources/OpenBOR_Menu_480x272_png.h"
26 #include "../resources/OpenBOR_Menu_320x240_png.h"
27 
28 #include <dirent.h>
29 
30 extern int videoMode;
31 
32 #define RGB32(B,G,R) ((R) | ((G) << 8) | ((B) << 16))
33 #define RGB16(B,G,R) ((B&0xF8)<<8) | ((G&0xFC)<<3) | (R>>3)
34 #define RGB(B,G,R)   (bpp==16?RGB16(B,G,R):RGB32(B,G,R))
35 
36 #define BLACK		RGB(  0,   0,   0)
37 #define WHITE		RGB(255, 255, 255)
38 #define RED			RGB(255,   0,   0)
39 #define	GREEN		RGB(  0, 255,   0)
40 #define BLUE		RGB(  0,   0, 255)
41 #define YELLOW		RGB(255, 255,   0)
42 #define PURPLE		RGB(255,   0, 255)
43 #define ORANGE		RGB(255, 128,   0)
44 #define GRAY		RGB(112, 128, 144)
45 #define LIGHT_GRAY  RGB(223, 223, 223)
46 #define DARK_RED	RGB(128,   0,   0)
47 #define DARK_GREEN	RGB(  0, 128,   0)
48 #define DARK_BLUE	RGB(  0,   0, 128)
49 
50 #define LOG_SCREEN_TOP 2
51 #define LOG_SCREEN_END (isWide ? 26 : 23)
52 
53 SDL_Surface *Source = NULL;
54 SDL_Surface *Scaler = NULL;
55 SDL_Surface *Screen = NULL;
56 int bpp = 16;
57 int factor = 1;
58 int isFull = 0;
59 int isWide = 0;
60 int flags;
61 int dListTotal;
62 int dListCurrentPosition;
63 int dListScrollPosition;
64 int which_logfile = OPENBOR_LOG;
65 FILE *bgmFile = NULL;
66 unsigned int bgmPlay = 0, bgmLoop = 0, bgmCycle = 0, bgmCurrent = 0, bgmStatus = 0;
67 extern u32 bothkeys, bothnewkeys;
68 fileliststruct *filelist;
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("./Paks");
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 
copyScreens(SDL_Surface * Image)206 void copyScreens(SDL_Surface *Image)
207 {
208 	// Copy Logo or Menu from Source to Scaler to give us a background
209 	// prior to printing to this SDL_Surface.
210 	if(factor > 1)
211 	{
212 		// Center Text Surface within Scaler Image prior to final Blitting.
213 		Scaler->clip_rect.x = 1;
214 		Scaler->clip_rect.y = factor == 2 ? 4 : 5;
215 		Scaler->clip_rect.w = Image->w;
216 		Scaler->clip_rect.h = Image->h;
217 		SDL_BlitSurface(Image, NULL, Scaler, &Scaler->clip_rect);
218 	}
219 	else
220 		SDL_BlitSurface(Image, NULL, Scaler, &Scaler->clip_rect);
221 }
222 
writeToScreen(unsigned char * src,int pitch)223 void writeToScreen(unsigned char *src, int pitch)
224 {
225 	int i;
226 	// pitch = bpp;
227 	unsigned char *dst = Screen->pixels;
228 	for(i=0; i<Screen->h; i++)
229 	{
230 		memcpy(dst, src, pitch);
231 		src += pitch;
232 		dst += pitch;
233 	}
234 }
235 
drawScreens(SDL_Surface * Image)236 void drawScreens(SDL_Surface *Image)
237 {
238 	SDL_Surface *FirstPass = NULL;
239 	SDL_Surface *SecondPass = NULL;
240 
241 	if(SDL_MUSTLOCK(Screen)) SDL_LockSurface(Screen);
242 	switch(factor)
243 	{
244 		case 2:
245 			FirstPass = SDL_AllocSurface(SDL_SWSURFACE, Screen->w,Screen->h, bpp, 0, 0, 0, 0);
246 			(*GfxBlitters[(int)savedata.screen[videoMode][1]])((u8*)Scaler->pixels+Scaler->pitch*4+4, Scaler->pitch, pDeltaBuffer+Scaler->pitch, (u8*)FirstPass->pixels, FirstPass->pitch, FirstPass->w>>1, FirstPass->h>>1);
247 			if(Image) SDL_BlitSurface(Image, NULL, FirstPass, &Image->clip_rect);
248 			writeToScreen(FirstPass->pixels, FirstPass->pitch);
249 			SDL_FreeSurface(FirstPass);
250 			FirstPass = NULL;
251 			break;
252 
253 		case 4:
254 			FirstPass = SDL_AllocSurface(SDL_SWSURFACE, Screen->w, Screen->h, bpp, 0, 0, 0, 0);
255 			(*GfxBlitters[(int)savedata.screen[videoMode][1]])((u8*)Scaler->pixels+Scaler->pitch*4+4, Scaler->pitch, pDeltaBuffer+Scaler->pitch, (u8*)FirstPass->pixels, FirstPass->pitch, FirstPass->w>>1, FirstPass->h>>1);
256 			SecondPass = SDL_AllocSurface(SDL_SWSURFACE, FirstPass->w, FirstPass->h, bpp, 0, 0, 0, 0);
257 			(*GfxBlitters[(int)savedata.screen[videoMode][1]])((u8*)FirstPass->pixels+FirstPass->pitch, FirstPass->pitch, pDeltaBuffer+FirstPass->pitch, (u8*)SecondPass->pixels, SecondPass->pitch, SecondPass->w>>1, SecondPass->h>>1);
258 			if(Image) SDL_BlitSurface(Image, NULL, SecondPass, &Image->clip_rect);
259 			writeToScreen(SecondPass->pixels, SecondPass->pitch);
260 			SDL_FreeSurface(FirstPass);
261 			FirstPass = NULL;
262 			SDL_FreeSurface(SecondPass);
263 			SecondPass = NULL;
264 			break;
265 
266 		default:
267 			if(Image) SDL_BlitSurface(Image, NULL, Scaler, &Image->clip_rect);
268 			writeToScreen(Scaler->pixels, Scaler->pitch);
269 			break;
270 	}
271 	if(SDL_MUSTLOCK(Screen)) SDL_UnlockSurface(Screen);
272 
273 	SDL_Flip(Screen);
274 }
275 
printText(int x,int y,int col,int backcol,int fill,char * format,...)276 void printText(int x, int y, int col, int backcol, int fill, char *format, ...)
277 {
278 	int x1, y1, i;
279 	u32 data;
280 	u16 *line16 = NULL;
281 	u32 *line32 = NULL;
282 	u8 *font;
283 	u8 ch = 0;
284 	char buf[128] = {""};
285 	va_list arglist;
286 		va_start(arglist, format);
287 		vsprintf(buf, format, arglist);
288 		va_end(arglist);
289 
290 	if(factor > 1){ y += 5; }
291 
292 	for(i=0; i<sizeof(buf); i++)
293 	{
294 		ch = buf[i];
295 		// mapping
296 		if (ch<0x20) ch = 0;
297 		else if (ch<0x80) { ch -= 0x20; }
298 		else if (ch<0xa0) {	ch = 0;	}
299 		else ch -= 0x40;
300 		font = (u8 *)&hankaku_font10[ch*10];
301 		// draw
302 		if (bpp == 16) line16 = (u16*)Scaler->pixels + x + y * Scaler->w;
303 		else           line32 = (u32*)Scaler->pixels + x + y * Scaler->w;
304 
305 		for (y1=0; y1<10; y1++)
306 		{
307 			data = *font++;
308 			for (x1=0; x1<5; x1++)
309 			{
310 				if (data & 1)
311 				{
312 					if (bpp == 16) *line16 = col;
313 				    else           *line32 = col;
314 				}
315 				else if (fill)
316 				{
317 					if (bpp == 16) *line16 = backcol;
318 					else           *line32 = backcol;
319 				}
320 
321 				if (bpp == 16) line16++;
322 				else           line32++;
323 
324 				data = data >> 1;
325 			}
326 			if (bpp == 16) line16 += Scaler->w-5;
327 			else           line32 += Scaler->w-5;
328 		}
329 		x+=5;
330 	}
331 }
332 
getPreview(char * filename)333 SDL_Surface *getPreview(char *filename)
334 {
335 	int i;
336 	int width = factor == 4 ? 640 : (factor == 2 ? 320 : 160);
337 	int height = factor == 4 ? 480 : (factor == 2 ? 240 : 120);
338 	unsigned char *sp;
339 	unsigned char *dp;
340 	unsigned char *tempPal;
341 	unsigned char realPal[1024];
342 	SDL_Color newPal[256];
343 	SDL_Surface *image = NULL;
344 	s_screen *title = NULL;
345 	s_screen *scale = NULL;
346 
347 	// Grab current path and filename
348 	getBasePath(packfile, filename, 1);
349 
350 	// Create & Load & Scale Image
351 	if(!loadscreen("data/bgs/title", packfile, realPal, PIXEL_8, &title)) return NULL;
352 	if((scale = allocscreen(width, height, title->pixelformat)) == NULL) return NULL;
353 	if((image = SDL_AllocSurface(SDL_SWSURFACE, width, height, 8, 0, 0, 0, 0)) == NULL) return NULL;
354 
355 	scalescreen(scale, title);
356 
357 	sp = (unsigned char*)scale->data;
358 	dp = (unsigned char*)image->pixels;
359 
360 	do{
361 		memcpy(dp, sp, width);
362 		sp += scale->width;
363 		dp += image->pitch;
364 	}while(--height);
365 
366 	tempPal = realPal;
367 	for(i=0;i<256;i++)
368 	{
369 		newPal[i].r=tempPal[0];
370 		newPal[i].g=tempPal[1];
371 		newPal[i].b=tempPal[2];
372 		tempPal+=3;
373 	}
374 	SDL_SetColors(image, newPal, 0, 256);
375 
376 	// Free Images and Terminate FileCaching
377 	freescreen(&title);
378 	freescreen(&scale);
379 
380 	// ScreenShots within Menu will be saved as "Menu"
381 	strncpy(packfile,"Menu.xxx",128);
382 
383 	return image;
384 }
385 
StopBGM()386 void StopBGM()
387 {
388 	sound_close_music();
389 	if (bgmFile)
390 	{
391 		fclose(bgmFile);
392 		bgmFile = NULL;
393 	}
394 	bgmPlay = 0;
395 }
396 
PlayBGM()397 void PlayBGM()
398 {
399 	bgmPlay = packfile_music_play(filelist, bgmFile, bgmLoop, dListCurrentPosition, dListScrollPosition);
400 }
401 
ControlMenu()402 int ControlMenu()
403 {
404 	int status = -1;
405 	int dListMaxDisplay = 17;
406 	bothnewkeys = 0;
407 	inputrefresh();
408 	switch(bothnewkeys)
409 	{
410 		case FLAG_MOVEUP:
411 			dListScrollPosition--;
412 			if(dListScrollPosition < 0)
413 			{
414 				dListScrollPosition = 0;
415 				dListCurrentPosition--;
416 			}
417 			if(dListCurrentPosition < 0) dListCurrentPosition = 0;
418 			break;
419 
420 		case FLAG_MOVEDOWN:
421 			dListCurrentPosition++;
422 			if(dListCurrentPosition > dListTotal - 1) dListCurrentPosition = dListTotal - 1;
423 			if(dListCurrentPosition > dListMaxDisplay)
424 	        {
425 		        if((dListCurrentPosition+dListScrollPosition) < dListTotal) dListScrollPosition++;
426 			    dListCurrentPosition = dListMaxDisplay;
427 			}
428 			break;
429 
430 		case FLAG_MOVELEFT:
431 			break;
432 
433 		case FLAG_MOVERIGHT:
434 			break;
435 
436 		case FLAG_START:
437 		case FLAG_ATTACK:
438 			// Start Engine!
439 			status = 1;
440 			break;
441 
442 		case FLAG_ATTACK2:
443 			pControl = ControlBGM;
444 			status = -2;
445 			break;
446 
447 		case FLAG_SPECIAL:
448 		case FLAG_ESC:
449 			// Exit Engine!
450 			status = 2;
451 			break;
452 
453 		case FLAG_JUMP:
454 			//drawLogs();
455 			status = 3;
456 			break;
457 
458 		default:
459 			// No Update Needed!
460 			status = 0;
461 			break;
462 	}
463 	return status;
464 }
465 
ControlBGM()466 int ControlBGM()
467 {
468 	int status = -2;
469 	int dListMaxDisplay = 17;
470 	bothnewkeys = 0;
471 	inputrefresh();
472 	switch(bothnewkeys)
473 	{
474 		case FLAG_MOVEUP:
475 			dListScrollPosition--;
476 			if(dListScrollPosition < 0)
477 			{
478 				dListScrollPosition = 0;
479 				dListCurrentPosition--;
480 			}
481 			if(dListCurrentPosition < 0) dListCurrentPosition = 0;
482 			break;
483 
484 		case FLAG_MOVEDOWN:
485 			dListCurrentPosition++;
486 			if(dListCurrentPosition > dListTotal - 1) dListCurrentPosition = dListTotal - 1;
487 			if(dListCurrentPosition > dListMaxDisplay)
488 	        {
489 		        if((dListCurrentPosition+dListScrollPosition) < dListTotal) dListScrollPosition++;
490 			    dListCurrentPosition = dListMaxDisplay;
491 			}
492 			break;
493 
494 		case FLAG_MOVELEFT:
495 			if(!bgmStatus || (bgmPlay && bgmCurrent == dListCurrentPosition+dListScrollPosition))
496 			{
497 				filelist[bgmCurrent].bgmTrack--;
498 				if(filelist[bgmCurrent].bgmTrack < 0) filelist[bgmCurrent].bgmTrack = filelist[bgmCurrent].nTracks-1;
499 				if(bgmStatus) PlayBGM();
500 			}
501 			break;
502 
503 		case FLAG_MOVERIGHT:
504 			if(!bgmStatus || (bgmPlay && bgmCurrent == dListCurrentPosition+dListScrollPosition))
505 			{
506 				filelist[bgmCurrent].bgmTrack++;
507 				if(filelist[bgmCurrent].bgmTrack > filelist[bgmCurrent].nTracks - 1) filelist[bgmCurrent].bgmTrack = 0;
508 				if(bgmStatus) PlayBGM();
509 			}
510 			break;
511 
512 		case FLAG_START:
513 		case FLAG_ATTACK:
514 			if(bgmPlay) StopBGM();
515 			else PlayBGM();
516 			break;
517 
518 		case FLAG_ATTACK2:
519 			if(!bgmPlay)
520 			{
521 				if(bgmLoop) bgmLoop = 0;
522 				else bgmLoop = 1;
523 			}
524 			break;
525 
526 		case FLAG_JUMP:
527 			if(!bgmPlay)
528 			{
529 				if(bgmCycle) bgmCycle = 0;
530 				else bgmCycle = 1;
531 			}
532 			break;
533 
534 		case FLAG_SPECIAL:
535 		case FLAG_ESC:
536 			pControl = ControlMenu;
537 			status = -1;
538 			break;
539 
540 		default:
541 			// No Update Needed!
542 			status = 0;
543 			break;
544 	}
545 	return status;
546 }
547 
initMenu(int type)548 void initMenu(int type)
549 {
550 #if WIN || LINUX
551 	factor = savedata.screen[videoMode][0] ? savedata.screen[videoMode][0] : 1;
552 	isFull = savedata.fullscreen;
553 	//isWide = savedata.fullscreen && (((float)nativeWidth / (float)nativeHeight) > 1.54);
554 #ifndef DARWIN
555 	bpp = 32;
556 #endif
557 #endif
558 
559 	Init_Gfx(bpp==32 ? 888 : 565, bpp);
560 	memset(pDeltaBuffer, 0x00, 1244160);
561 #if !defined(DINGOO) && !defined(WIZ)
562 	flags = isFull?(SDL_SWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN):(SDL_SWSURFACE|SDL_DOUBLEBUF);
563 #else
564 	flags = SDL_SWSURFACE;
565 #endif
566 
567 	// Read Logo or Menu from Array.
568 	if(!type) {
569 		Source = pngToSurface(isWide ? (void*) openbor_logo_480x272_link_png.data : (void*) openbor_logo_320x240_link_png.data);
570 
571 		// Depending on which mode we are in (WideScreen/FullScreen)
572 		// allocate proper size for SDL_Surface to perform final Blitting.
573 		Screen = SDL_SetVideoMode(Source->w * factor, Source->h * factor, bpp, flags);
574 
575 		// Allocate Scaler with extra space for upscaling.
576 		Scaler = SDL_AllocSurface(SDL_SWSURFACE,
577 								  factor > 1 ? Screen->w + 4 : Screen->w,
578 								  factor > 1 ? Screen->h + 8 : Screen->h,
579 								  bpp, 0, 0, 0, 0);
580 	}
581 	else {
582 		Source = pngToSurface(isWide ? (void*) openbor_menu_480x272_png.data : (void*) openbor_menu_320x240_png.data);
583 
584 		// Depending on which mode we are in (WideScreen/FullScreen)
585 		// allocate proper size for SDL_Surface to perform final Blitting.
586 		Screen = SDL_SetVideoMode(Source->w * factor, Source->h * factor, bpp, flags);
587 
588 		// Allocate Scaler with extra space for upscaling.
589 		Scaler = SDL_AllocSurface(SDL_SWSURFACE,
590 		                      factor > 1 ? Screen->w + 4 : Screen->w,
591 							  factor > 1 ? Screen->h + 8 : Screen->h,
592 							  bpp, 0, 0, 0, 0);
593 	}
594 
595 	control_init(2);
596 	apply_controls();
597 	sound_init(12);
598 	sound_start_playback(savedata.soundbits,savedata.soundrate);
599 }
600 
termMenu()601 void termMenu()
602 {
603 	SDL_FreeSurface(Source);
604 	Source = NULL;
605 	SDL_FreeSurface(Scaler);
606 	Scaler = NULL;
607 #ifndef SDL13
608 	SDL_FreeSurface(Screen);
609 	Screen = NULL;
610 #endif
611 	sound_exit();
612 	control_exit();
613 	Term_Gfx();
614 }
615 
drawMenu()616 void drawMenu()
617 {
618 	SDL_Surface *Image = NULL;
619 	char listing[45] = {""};
620 	int list = 0;
621 	int shift = 0;
622 	int colors = 0;
623 
624 	copyScreens(Source);
625 	if(dListTotal < 1) printText((isWide ? 30 : 8), (isWide ? 33 : 24), RED, 0, 0, "No Mods In Paks Folder!");
626 	for(list=0; list<dListTotal; list++)
627 	{
628 		if(list<18)
629 		{
630 			shift = 0;
631 			colors = GRAY;
632 			strncpy(listing, "", (isWide ? 44 : 28));
633 			if(strlen(filelist[list+dListScrollPosition].filename)-4 < (isWide ? 44 : 28))
634 				strncpy(listing, filelist[list+dListScrollPosition].filename, strlen(filelist[list+dListScrollPosition].filename)-4);
635 			if(strlen(filelist[list+dListScrollPosition].filename)-4 > (isWide ? 44 : 28))
636 				strncpy(listing, filelist[list+dListScrollPosition].filename, (isWide ? 44 : 28));
637 			if(list == dListCurrentPosition)
638 			{
639 				shift = 2;
640 				colors = RED;
641 #ifdef WII
642 				Image = NULL;
643 #else
644 				Image = getPreview(filelist[list+dListScrollPosition].filename);
645 #endif
646 				if(Image)
647 				{
648 					Image->clip_rect.x = factor * (isWide ? 286 : 155);
649 					Image->clip_rect.y = factor * (isWide ? (factor == 4 ? (Sint16)32.5 : 32) : (factor == 4 ? (Sint16)21.5 : 21));
650 				}
651 				else
652 					printText((isWide ? 288 : 157), (isWide ? 141 : 130), RED, 0, 0, "No Preview Available!");
653 			}
654 			printText((isWide ? 30 : 7) + shift, (isWide ? 33 : 22)+(11*list) , colors, 0, 0, "%s", listing);
655 		}
656 	}
657 
658 	printText((isWide ? 26 : 5), (isWide ? 11 : 4), WHITE, 0, 0, "OpenBoR %s", VERSION);
659 	printText((isWide ? 392 : 261),(isWide ? 11 : 4), WHITE, 0, 0, __DATE__);
660 	printText((isWide ? 23 : 4),(isWide ? 251 : 226), WHITE, 0, 0, "%s: Start Game", control_getkeyname(savedata.keys[0][SDID_ATTACK]));
661 	printText((isWide ? 150 : 84),(isWide ? 251 : 226), WHITE, 0, 0, "%s: BGM Player", control_getkeyname(savedata.keys[0][SDID_ATTACK2]));
662 	printText((isWide ? 270 : 164),(isWide ? 251 : 226), WHITE, 0, 0, "%s: View Logs", control_getkeyname(savedata.keys[0][SDID_JUMP]));
663 	printText((isWide ? 390 : 244),(isWide ? 251 : 226), WHITE, 0, 0, "%s: Quit Game", control_getkeyname(savedata.keys[0][SDID_SPECIAL]));
664    	printText((isWide ? 330 : 197),(isWide ? 170 : 155), BLACK, 0, 0, "www.LavaLit.com");
665 	printText((isWide ? 322 : 190),(isWide ? 180 : 165), BLACK, 0, 0, "www.SenileTeam.com");
666 
667 #ifdef SPK_SUPPORTED
668 	printText((isWide ? 324 : 192),(isWide ? 191 : 176), DARK_RED, 0, 0, "SecurePAK Edition");
669 #endif
670 
671 	drawScreens(Image);
672 	if(Image)
673 	{
674 		SDL_FreeSurface(Image);
675 		Image = NULL;
676 	}
677 }
678 
drawBGMPlayer()679 void drawBGMPlayer()
680 {
681 	SDL_Surface *Image = NULL;
682 	SDL_Rect rect;
683 	char listing[45] = {""}, bgmListing[25] = {""};
684 	char t1[64] = "", t2[25] = "Unknown";
685 	char a1[64] = "", a2[25] = "Unknown";
686 	int list = 0, colors = 0, shift = 0;
687 
688 	// Allocate Preview Box for Music Text Info.
689 	Image = SDL_AllocSurface(SDL_SWSURFACE, Source->w, Source->h, bpp, 0, 0, 0, 0);
690 	if (Image != NULL)
691 	{
692 		SDL_BlitSurface(Source, NULL, Image, NULL);
693 		rect.x = (isWide ? 286 : 155);
694 		rect.y = (isWide ? (factor == 4 ? (Sint16)32.5 : 32) : (factor == 4 ? (Sint16)21.5 : 21));
695 		rect.w = 160;
696 		rect.h = 120;
697 		SDL_FillRect(Image, &rect, LIGHT_GRAY);
698 		copyScreens(Image);
699 		SDL_FreeSurface(Image);
700 		Image = NULL;
701 	}
702 
703 	for(list=0; list<dListTotal; list++)
704 	{
705 		if(list<18)
706 		{
707 			shift = 0;
708 			colors = GRAY;
709 			strncpy(listing, "", (isWide ? 44 : 28));
710 			if(strlen(filelist[list+dListScrollPosition].filename)-4 < (isWide ? 44 : 28))
711 				strncpy(listing, filelist[list+dListScrollPosition].filename, strlen(filelist[list+dListScrollPosition].filename)-4);
712 			if(strlen(filelist[list+dListScrollPosition].filename)-4 > (isWide ? 44 : 28))
713 				strncpy(listing, filelist[list+dListScrollPosition].filename, (isWide ? 44 : 28));
714 			if(list==dListCurrentPosition) { shift = 2; colors = RED; }
715 			printText((isWide ? 30 : 7) + shift, (isWide ? 33 : 22)+(11*list) , colors, 0, 0, "%s", listing);
716 		}
717 	}
718 
719 	printText((isWide ? 26 : 5), (isWide ? 11 : 4), WHITE, 0, 0, "OpenBoR %s", VERSION);
720 	printText((isWide ? 392 : 261),(isWide ? 11 : 4), WHITE, 0, 0, __DATE__);
721 	printText((isWide ? 23 : 4),(isWide ? 251 : 226), WHITE, 0, 0, "%s: %s", control_getkeyname(savedata.keys[0][SDID_ATTACK]), bgmPlay ? "Stop" : "Play");
722 	printText((isWide ? 150 : 84),(isWide ? 251 : 226), WHITE, 0, 0, "%s: %s", control_getkeyname(savedata.keys[0][SDID_ATTACK2]), bgmLoop ? "Repeat On" : "Repeat Off");
723 	printText((isWide ? 270 : 164),(isWide ? 251 : 226), WHITE, 0, 0, "%s: %s", control_getkeyname(savedata.keys[0][SDID_JUMP]), bgmCycle ? "Cycle On" : "Cycle Off");
724 	printText((isWide ? 390 : 244),(isWide ? 251 : 226), WHITE, 0, 0, "%s: Exit Player", control_getkeyname(savedata.keys[0][SDID_SPECIAL]));
725 	printText((isWide ? 330 : 197),(isWide ? 170 : 155), BLACK, 0, 0, "www.LavaLit.com");
726 	printText((isWide ? 322 : 190),(isWide ? 180 : 165), BLACK, 0, 0, "www.SenileTeam.com");
727 
728 #ifdef SPK_SUPPORTED
729 	printText((isWide ? 324 : 192),(isWide ? 191 : 176), DARK_RED, 0, 0, "SecurePAK Edition");
730 #endif
731 
732 	if(!bgmPlay) bgmCurrent = dListCurrentPosition+dListScrollPosition;
733 	if(strlen(filelist[bgmCurrent].filename)-4 < 24)
734 		strncpy(bgmListing, filelist[bgmCurrent].filename, strlen(filelist[bgmCurrent].filename)-4);
735 	if(strlen(filelist[bgmCurrent].filename)-4 > 24)
736 		strncpy(bgmListing, filelist[bgmCurrent].filename, 24);
737 	if(!sound_query_music(a1, t1))
738 	{
739 		PlayBGM();
740 		sound_query_music(a1, t1);
741 		StopBGM();
742 	}
743 	if(t1[0]) strncpy(t2, t1, 25);
744 	if(a1[0]) strncpy(a2, a1, 25);
745 	printText((isWide ? 288 : 157),(isWide ? 35 : 23) + (11 * 0), DARK_RED, 0, 0, "Game: %s", bgmListing);
746 	printText((isWide ? 288 : 157),(isWide ? 35 : 23) + (11 * 1), bgmPlay ? DARK_GREEN : DARK_BLUE, 0, 0, "Total Tracks: %d", filelist[bgmCurrent].nTracks-1);
747 	printText((isWide ? 288 : 157),(isWide ? 35 : 23) + (11 * 2), bgmPlay ? DARK_GREEN : DARK_BLUE, 0, 0, "Current Track: %d", filelist[bgmCurrent].bgmTrack);
748 	printText((isWide ? 288 : 157),(isWide ? 35 : 23) + (11 * 3), bgmPlay ? DARK_GREEN : DARK_BLUE, 0, 0, "File: %s", filelist[bgmCurrent].bgmFileName[filelist[bgmCurrent].bgmTrack]);
749 	printText((isWide ? 288 : 157),(isWide ? 35 : 23) + (11 * 4), bgmPlay ? DARK_GREEN : DARK_BLUE, 0, 0, "Track: %s", t2);
750 	printText((isWide ? 288 : 157),(isWide ? 35 : 23) + (11 * 5), bgmPlay ? DARK_GREEN : DARK_BLUE, 0, 0, "Artist: %s", a2);
751 
752 	drawScreens(NULL);
753 }
754 
drawLogs()755 void drawLogs()
756 {
757 	int i=which_logfile, j, k, l, done=0;
758 	SDL_Surface *Viewer = NULL;
759 
760 	bothkeys = bothnewkeys = 0;
761 	Viewer = SDL_AllocSurface(SDL_SWSURFACE, Source->w, Source->h, bpp, 0, 0, 0, 0);
762 	bothkeys = bothnewkeys = 0;
763 
764 	while(!done)
765 	{
766 	    copyScreens(Viewer);
767 	    inputrefresh();
768 	    sound_update_music();
769 #if DINGOO
770 	    printText(250, 3, RED, 0, 0, "Quit : Select");
771 #else
772 	    printText((isWide ? 410 : 250), 3, RED, 0, 0, "Quit : Escape");
773 #endif
774 		if(bothnewkeys & FLAG_ESC) done = 1;
775 
776 		if(logfile[i].ready)
777 		{
778 			printText(5, 3, RED, 0, 0, "OpenBorLog.txt");
779 			if(bothkeys & FLAG_MOVEUP) --logfile[i].line;
780 	        if(bothkeys & FLAG_MOVEDOWN) ++logfile[i].line;
781 			if(bothkeys & FLAG_MOVELEFT) logfile[i].line = 0;
782 			if(bothkeys & FLAG_MOVERIGHT) logfile[i].line = logfile[i].rows - (LOG_SCREEN_END - LOG_SCREEN_TOP);
783 			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;
784 			if(logfile[i].line < 0) logfile[i].line = 0;
785 			for(l=LOG_SCREEN_TOP, j=logfile[i].line; j<logfile[i].rows-1; l++, j++)
786 			{
787 				if(l<LOG_SCREEN_END)
788 				{
789 					char textpad[480] = {""};
790 					for(k=0; k<480; k++)
791 					{
792 						if(!logfile[i].buf->ptr[logfile[i].pos[j]+k]) break;
793 						textpad[k] = logfile[i].buf->ptr[logfile[i].pos[j]+k];
794 					}
795 					if(logfile[i].rows>0xFFFF)
796 						printText(5, l*10, WHITE, 0, 0, "0x%08x:  %s", j, textpad);
797 					else
798 						printText(5, l*10, WHITE, 0, 0, "0x%04x:  %s", j, textpad);
799 				}
800 				else break;
801 			}
802 		}
803 		else if(i == SCRIPT_LOG) printText(5, 3, RED, 0, 0, "Log NOT Found: ScriptLog.txt");
804 		else                     printText(5, 3, RED, 0, 0, "Log NOT Found: OpenBorLog.txt");
805 
806 	    drawScreens(NULL);
807 	}
808 	SDL_FreeSurface(Viewer);
809 	Viewer = NULL;
810 	drawMenu();
811 }
812 
drawLogo()813 void drawLogo()
814 {
815     if(savedata.logo) return;
816 	initMenu(0);
817 	copyScreens(Source);
818 	drawScreens(NULL);
819 	SDL_Delay(3000);
820 	termMenu();
821 }
822 
Menu()823 void Menu()
824 {
825 	int done = 0;
826 	int ctrl = 0;
827 	loadsettings();
828 	drawLogo();
829 	dListCurrentPosition = 0;
830 	if((dListTotal = findPaks()) != 1)
831 	{
832 		sortList();
833 		getAllLogs();
834 #ifndef WII
835 		packfile_music_read(filelist, dListTotal);
836 #endif
837 		initMenu(1);
838 		drawMenu();
839 		pControl = ControlMenu;
840 
841 		while(!done)
842 		{
843 			sound_update_music();
844 			bgmStatus = sound_query_music(NULL, NULL);
845 			if(bgmPlay && !bgmStatus)
846 			{
847 				if(bgmCycle)
848 				{
849 					filelist[bgmCurrent].bgmTrack++;
850 					if(filelist[bgmCurrent].bgmTrack > filelist[bgmCurrent].nTracks - 1) filelist[bgmCurrent].bgmTrack = 0;
851 					PlayBGM();
852 				}
853 				else StopBGM();
854 				drawBGMPlayer();
855 			}
856 
857 			ctrl = Control();
858 			switch(ctrl)
859 			{
860 				case 1:
861 				case 2:
862 					done = 1;
863 					break;
864 
865 				case 3:
866 					drawLogs();
867 					break;
868 
869 				case -1:
870 					drawMenu();
871 					break;
872 
873 				case -2:
874 					drawBGMPlayer();
875 					break;
876 			}
877 		}
878 		freeAllLogs();
879 		termMenu();
880 		if(dListTotal == 0 || ctrl == 2)
881 		{
882 			if (filelist)
883 			{
884 				free(filelist);
885 				filelist = NULL;
886 			}
887 			borExit(0);
888 		}
889 	}
890 	getBasePath(packfile, filelist[dListCurrentPosition+dListScrollPosition].filename, 1);
891 	free(filelist);
892 }
893