00001
00025 #include "main.h"
00026 #include "menu.h"
00027 #include "menuoptions.h"
00028 #include "resources.h"
00029 #include "music.h"
00030 #include "sound.h"
00031 #include "images.h"
00032 #include "sdlengine.h"
00033 #include "hqrdepack.h"
00034 #include "lbaengine.h"
00035 #include "dialogues.h"
00036 #include "interface.h"
00037
00039 #define PLASMA_EFFECT_FILESIZE 262176
00040
00042 #define MAINMENU_NEWGAME 20
00043
00044 #define MAINMENU_CONTINUEGAME 21
00045
00046 #define MAINMENU_OPTIONS 23
00047
00048 #define MAINMENU_QUIT 22
00049
00051 #define GIVEUPMENU_CONTINUE 28
00052
00053 #define GIVEUPMENU_QUIT 27
00054
00056 #define OPTIONSMENU_RETURNGAME 15
00057
00058 #define OPTIONSMENU_RETURNMENU 26
00059
00060 #define OPTIONSMENU_VOLUME 30
00061
00062 #define OPTIONSMENU_SAVEMANAGE 46
00063
00064 #define OPTIONSMENU_ADVOPTIONS 47
00065
00069 #define MAINMENU_BKGIMAGE 9999
00070
00071 #define MAINMENU_BUTTONWIDTH 320
00072
00073 #define MAINMENU_BUTTONSPAN 550
00074
00076 #define MUSICVOLUME 1
00077
00078 #define SOUNDVOLUME 2
00079
00080 #define CDVOLUME 3
00081
00082 #define LINEVOLUME 4
00083
00084 #define MASTERVOLUME 5
00085
00089 short int MainMenuSettings[]={
00090 0,
00091 4,
00092 200,
00093 0,
00094 0,
00095 20,
00096 0,
00097 21,
00098 0,
00099 23,
00100 0,
00101 22,
00102 };
00103
00107 short int GiveUpMenuSettings[]={
00108 0,
00109 2,
00110 240,
00111 0,
00112 0,
00113 28,
00114 0,
00115 27,
00116 };
00117
00121 short int GiveUpMenuSettingsWithSave[]={
00122 0,
00123 3,
00124 240,
00125 0,
00126 0,
00127 28,
00128 0,
00129 16,
00130 0,
00131 27,
00132 };
00133
00137 short int OptionsMenuSettings[]={
00138 0,
00139 4,
00140 0,
00141 0,
00142 0,
00143 24,
00144 0,
00145 30,
00146 0,
00147 46,
00148 0,
00149 47,
00150 };
00151
00155 short int AdvOptionsMenuSettings[]={
00156 0,
00157 5,
00158 0,
00159 0,
00160 0,
00161 26,
00162 0,
00163 4,
00164 6,
00165 31,
00166 7,
00167 32,
00168 8,
00169 33,
00170 };
00171
00175 short int SaveManageMenuSettings[]={
00176 0,
00177 3,
00178 0,
00179 0,
00180 0,
00181 26,
00182 0,
00183 41,
00184 0,
00185 45,
00186 };
00187
00191 short int VolumeMenuSettings[]={
00192 0,
00193 7,
00194 0,
00195 0,
00196 0,
00197 26,
00198 1,
00199 10,
00200 2,
00201 11,
00202 3,
00203 12,
00204 4,
00205 13,
00206 5,
00207 14,
00208 0,
00209 16,
00210 };
00211
00212
00214 unsigned char *plasmaEffectPtr;
00216 unsigned char *plasmaEffectVar1;
00218 unsigned char *plasmaEffectVar2;
00219
00220
00222 void plasma_effect_init()
00223 {
00224 unsigned char *temp1 = 0;
00225 unsigned char *temp2 = 0;
00226 char *temp2bis = 0;
00227 short int temp4 = 0;
00228 int i = 0;
00229 unsigned int *copy1 = 0;
00230 unsigned int *copy2 = 0;
00231
00232 plasmaEffectVar1 = plasmaEffectPtr;
00233 plasmaEffectVar2 = plasmaEffectPtr + 16000;
00234
00235 temp1 = plasmaEffectVar1 + 321;
00236 temp2 = plasmaEffectVar2 + 321;
00237
00238 for (i = 0; i < 15358; i++)
00239 {
00240 temp4 = 0;
00241
00242 temp4 += temp1[-1];
00243 temp4 += temp1[-320];
00244 temp4 += temp1[-319];
00245 temp4 += temp1[-321];
00246 temp4 += temp1[+1];
00247 temp4 += temp1[+320];
00248 temp4 += temp1[+319];
00249 temp4 += temp1[+321];
00250
00251 temp4 = (temp4 >> 3) | ((temp4 & 0x0003) << 13);
00252
00253 if (!(temp4 & 0x6500))
00254 {
00255 if (temp2 >= (plasmaEffectVar2 + 14720))
00256 {
00257 temp4--;
00258 }
00259 else if (temp4 > 0)
00260 {
00261 temp4--;
00262 }
00263 }
00264
00265 temp1++;
00266 *temp2 = (unsigned char) temp4;
00267 temp2++;
00268 }
00269
00270 copy1 = (unsigned int *) plasmaEffectVar1;
00271 copy2 = (unsigned int *) (plasmaEffectVar2 + 320);
00272
00273 for (i = 0; i < 3840; i++)
00274 *(copy1++) = *(copy2++);
00275
00276 temp2bis = (char *) plasmaEffectVar2 + 12480;
00277
00278 for (i = 1600; i >= 0; i--)
00279 {
00280 temp4 = *temp2bis;
00281 if (temp4 <= 15)
00282 {
00283 *temp2bis = -(temp4 - 11);
00284 }
00285 temp2++;
00286 }
00287 }
00288
00292 void process_plasma_effect(int top, int color)
00293 {
00294 unsigned char *temp;
00295 unsigned char *out;
00296 int i, j;
00297 unsigned char temp3;
00298 unsigned char bh, bl;
00299
00300 plasma_effect_init();
00301
00302 temp = plasmaEffectVar1 + 1600;
00303 out = frontVideoBuffer + screenLockupTable[top];
00304
00305 bl = color;
00306 bh = bl + 15;
00307
00308 for (i = 25; i >= 0; i--)
00309 {
00310 for (j = MAINMENU_BUTTONWIDTH; j >= 0; j--)
00311 {
00312 temp3 = *temp;
00313 temp3 = temp3 >> 1;
00314 temp3 += bl;
00315 if (temp3 > bh)
00316 temp3 = bh;
00317
00318 out[0] = temp3;
00319 out[1] = temp3;
00320 out[640] = temp3;
00321 out[641] = temp3;
00322
00323 temp++;
00324 out += 2;
00325 }
00326 out += 640;
00327 }
00328 }
00329
00335 void draw_button_box(int left, int top, int right, int bottom)
00336 {
00337 draw_line(left, top, right, top, 79);
00338 draw_line(left, top, left, bottom, 79);
00339 draw_line(right, ++top, right, bottom, 73);
00340 draw_line(++left, bottom, right, bottom, 73);
00341 }
00342
00349 void draw_button_gfx(int width, int topheight, int id, int value, int mode)
00350 {
00351 int right;
00352 int top;
00353 int left;
00354 int bottom2;
00355 int bottom;
00356
00357
00358
00359
00360
00361 char dialText[256];
00362 int textSize;
00363
00364 left = width - MAINMENU_BUTTONSPAN / 2;
00365 right = width + MAINMENU_BUTTONSPAN / 2;
00366
00367
00368 top = topheight - 25;
00369 bottom = bottom2 = topheight + 25;
00370
00371 if (mode != 0)
00372 {
00373 if (id <= 5 && id >= 1)
00374 {
00375 int newWidth=0;
00376
00377 switch (id)
00378 {
00379 case 1:
00380 {
00381 if(cfgfile.MusicVolume>255)
00382 cfgfile.MusicVolume=255;
00383 if(cfgfile.MusicVolume<0)
00384 cfgfile.MusicVolume=0;
00385 newWidth = cross_dot(left,right,255,cfgfile.MusicVolume);
00386 break;
00387 }
00388 case 2:
00389 {
00390 if(cfgfile.WaveVolume>255)
00391 cfgfile.WaveVolume=255;
00392 if(cfgfile.WaveVolume<0)
00393 cfgfile.WaveVolume=0;
00394 newWidth = cross_dot(left,right,255,cfgfile.WaveVolume);
00395 break;
00396 }
00397 case 3:
00398 {
00399 if(cfgfile.CDVolume>255)
00400 cfgfile.CDVolume=255;
00401 if(cfgfile.CDVolume<0)
00402 cfgfile.CDVolume=0;
00403 newWidth = cross_dot(left,right,255,cfgfile.CDVolume);
00404 break;
00405 }
00406 case 4:
00407 {
00408 if(cfgfile.LineVolume>255)
00409 cfgfile.LineVolume=255;
00410 if(cfgfile.LineVolume<0)
00411 cfgfile.LineVolume=0;
00412 newWidth = cross_dot(left,right,255,cfgfile.LineVolume);
00413 break;
00414 }
00415 case 5:
00416 {
00417 if(cfgfile.MasterVolume>255)
00418 cfgfile.MasterVolume=255;
00419 if(cfgfile.MasterVolume<0)
00420 cfgfile.MasterVolume=0;
00421 newWidth = cross_dot(left,right,255,cfgfile.MasterVolume);
00422 break;
00423 }
00424 };
00425
00426 process_plasma_effect(top, 80);
00427 if (!(rand() % 5))
00428 {
00429 plasmaEffectPtr[rand() % 140 * 10 + 1900] = 255;
00430 }
00431 draw_splitted_box(newWidth, top, right, bottom, 68);
00432 }
00433 else
00434 {
00435 process_plasma_effect(top, 64);
00436 if (!(rand() % 5))
00437 {
00438 plasmaEffectPtr[rand() % 320 * 10 + 6400] = 255;
00439 }
00440 }
00441
00442 if (id <= 5 && id >= 1)
00443 {
00444
00445 }
00446 }
00447 else
00448 {
00449 blit_box(left, top, right, bottom, (char *) workVideoBuffer, left, top,(char *) frontVideoBuffer);
00450 draw_transparent_box(left, top, right, bottom2, 4);
00451 }
00452
00453 draw_button_box(left, top, right, bottom);
00454
00455 set_font_color(15);
00456 get_menu_text(value, dialText);
00457 textSize = dialogue_text_size(dialText);
00458 display_dialogue_text(width - (textSize / 2), topheight - 18, dialText);
00459
00460
00461
00462 copy_block_phys(left, top, right, bottom);
00463 }
00464
00468 void draw_button(short int *menuSettings, int mode)
00469 {
00470 int buttonNumber;
00471 int maxButton;
00472 short int *localData = menuSettings;
00473 int topHeight;
00474 unsigned char menuItemId;
00475 unsigned short menuItemValue;
00476 char currentButton;
00477
00478 buttonNumber = *localData;
00479 localData += 1;
00480 maxButton = *localData;
00481 localData += 1;
00482 topHeight = *localData;
00483 localData += 2;
00484
00485 if (topHeight == 0)
00486 {
00487 topHeight = 35;
00488 }
00489 else
00490 {
00491 topHeight = topHeight - (((maxButton - 1) * 6) + ((maxButton) * 50)) / 2;
00492 }
00493
00494 if (maxButton <= 0)
00495 {
00496 return;
00497 }
00498
00499 currentButton = 0;
00500
00501 do
00502 {
00503
00504 menuItemId = (unsigned char) *localData;
00505 localData += 1;
00506 menuItemValue = *localData;
00507 localData += 1;
00508 if (mode != 0)
00509 {
00510 if (currentButton == buttonNumber)
00511 {
00512 draw_button_gfx(MAINMENU_BUTTONWIDTH, topHeight, menuItemId, menuItemValue, 1);
00513 }
00514 }
00515 else
00516 {
00517 if (currentButton == buttonNumber)
00518 {
00519 draw_button_gfx(MAINMENU_BUTTONWIDTH, topHeight, menuItemId, menuItemValue, 1);
00520 }
00521 else
00522 {
00523 draw_button_gfx(MAINMENU_BUTTONWIDTH, topHeight, menuItemId, menuItemValue, 0);
00524 }
00525 }
00526
00527 currentButton++;
00528 topHeight += 56;
00529
00530
00531 fps_cycles(1000);
00532 }
00533 while (currentButton < maxButton);
00534 }
00535
00539 int process_menu(short int * menuSettings)
00540 {
00541 int localTime;
00542 int numEntry;
00543 int buttonNeedRedraw;
00544 int maxButton;
00545 short int *localData = menuSettings;
00546 short int currentButton;
00547 short int id;
00548 int musicChanged;
00549 int buttonReleased = 1;
00550
00551 musicChanged = 0;
00552
00553 buttonNeedRedraw = 1;
00554
00555 numEntry = localData[1];
00556 currentButton = localData[0];
00557 localTime = lbaTime;
00558 maxButton = numEntry - 1;
00559
00560 read_keys();
00561
00562 do
00563 {
00564
00565 if (localData == MainMenuSettings)
00566 {
00567 if (lbaTime - localTime <= 11650)
00568 {
00569 if (skipIntro == 46)
00570 if (skipedKey != 32)
00571 return MAINMENU_BKGIMAGE;
00572 }
00573 else
00574 {
00575 return MAINMENU_BKGIMAGE;
00576 }
00577 }
00578
00579 if (pressedKey == 0)
00580 {
00581 buttonReleased = 1;
00582 }
00583
00584 if (buttonReleased)
00585 {
00586 key = pressedKey;
00587
00588 if (((unsigned char) key & 2))
00589 {
00590 currentButton++;
00591 if (currentButton == numEntry)
00592 {
00593 currentButton = 0;
00594 }
00595 buttonNeedRedraw = 1;
00596 buttonReleased = 0;
00597 }
00598
00599 if (((unsigned char) key & 1))
00600 {
00601 currentButton--;
00602 if (currentButton < 0)
00603 {
00604 currentButton = maxButton;
00605 }
00606 buttonNeedRedraw = 1;
00607 buttonReleased = 0;
00608 }
00609
00610 if (*(localData + 8) <= 5)
00611 {
00612 id = *(localData + currentButton * 2 + 4);
00613
00614 switch (id)
00615 {
00616 case MUSICVOLUME:
00617 {
00618 if (((unsigned char) key & 4))
00619 {
00620 cfgfile.MusicVolume-=4;
00621 }
00622 if (((unsigned char) key & 8))
00623 {
00624 cfgfile.MusicVolume+=4;
00625 }
00626 music_volume(cfgfile.MusicVolume);
00627 break;
00628 }
00629 case SOUNDVOLUME:
00630 {
00631 if (((unsigned char) key & 4))
00632 {
00633 cfgfile.WaveVolume-=4;
00634 }
00635 if (((unsigned char) key & 8))
00636 {
00637 cfgfile.WaveVolume+=4;
00638 }
00639 sample_volume(-1, cfgfile.WaveVolume);
00640 break;
00641 }
00642 case CDVOLUME:
00643 {
00644 if (((unsigned char) key & 4))
00645 {
00646 cfgfile.CDVolume-=4;
00647 }
00648 if (((unsigned char) key & 8))
00649 {
00650 cfgfile.CDVolume+=4;
00651 }
00652 break;
00653 }
00654 case LINEVOLUME:
00655 {
00656 if (((unsigned char) key & 4))
00657 {
00658 cfgfile.LineVolume-=4;
00659 }
00660 if (((unsigned char) key & 8))
00661 {
00662 cfgfile.LineVolume+=4;
00663 }
00664 break;
00665 }
00666 case MASTERVOLUME:
00667 {
00668 if (((unsigned char) key & 4))
00669 {
00670 cfgfile.MasterVolume-=4;
00671 }
00672 if (((unsigned char) key & 8))
00673 {
00674 cfgfile.MasterVolume+=4;
00675 }
00676 music_volume(cfgfile.MusicVolume);
00677 sample_volume(-1, cfgfile.WaveVolume);
00678 break;
00679 }
00680 default:
00681 break;
00682 }
00683 }
00684 }
00685
00686 if (buttonNeedRedraw == 1)
00687 {
00688 *localData = currentButton;
00689
00690 draw_button(localData, 0);
00691 do
00692 {
00693 read_keys();
00694 draw_button(localData, 1);
00695 }
00696 while (pressedKey == 0 && skipedKey == 0 && skipIntro == 0);
00697 buttonNeedRedraw = 0;
00698 }
00699 else
00700 {
00701 if (musicChanged)
00702 {
00703
00704
00705 }
00706
00707 buttonNeedRedraw = 0;
00708 draw_button(localData, 1);
00709 read_keys();
00710
00711 copy_screen(workVideoBuffer,frontVideoBuffer);
00712 }
00713 }
00714 while (!(skipedKey & 2) && !(skipedKey & 1));
00715
00716 currentButton = *(localData + 5 + currentButton * 2);
00717
00718 read_keys();
00719
00720 return currentButton;
00721 }
00722
00724 int advoptions_menu()
00725 {
00726 int ret = 0;
00727
00728 copy_screen(workVideoBuffer, frontVideoBuffer);
00729
00730 do
00731 {
00732 switch(process_menu(AdvOptionsMenuSettings))
00733 {
00734 case OPTIONSMENU_RETURNMENU:
00735 {
00736 ret = 1;
00737 break;
00738 }
00739
00740 default:
00741 break;
00742 }
00743 }
00744 while (ret != 1);
00745
00746 copy_screen(workVideoBuffer, frontVideoBuffer);
00747 flip(workVideoBuffer);
00748
00749 return 0;
00750 }
00751
00753 int savemanage_menu()
00754 {
00755 int ret = 0;
00756
00757 copy_screen(workVideoBuffer, frontVideoBuffer);
00758
00759 do
00760 {
00761 switch(process_menu(SaveManageMenuSettings))
00762 {
00763 case OPTIONSMENU_RETURNMENU:
00764 {
00765 ret = 1;
00766 break;
00767 }
00768
00769 default:
00770 break;
00771 }
00772 }
00773 while (ret != 1);
00774
00775 copy_screen(workVideoBuffer, frontVideoBuffer);
00776 flip(workVideoBuffer);
00777
00778 return 0;
00779 }
00780
00782 int volume_menu()
00783 {
00784 int ret = 0;
00785
00786 copy_screen(workVideoBuffer, frontVideoBuffer);
00787
00788 do
00789 {
00790 switch(process_menu(VolumeMenuSettings))
00791 {
00792 case OPTIONSMENU_RETURNMENU:
00793 {
00794 ret = 1;
00795 break;
00796 }
00797
00798 default:
00799 break;
00800 }
00801 }
00802 while (ret != 1);
00803
00804 copy_screen(workVideoBuffer, frontVideoBuffer);
00805 flip(workVideoBuffer);
00806
00807 return 0;
00808 }
00809
00811 int options_menu()
00812 {
00813 int ret = 0;
00814
00815 copy_screen(workVideoBuffer, frontVideoBuffer);
00816
00817
00818
00819
00820 do
00821 {
00822 switch(process_menu(OptionsMenuSettings))
00823 {
00824 case OPTIONSMENU_RETURNGAME:
00825 case OPTIONSMENU_RETURNMENU:
00826 {
00827 ret = 1;
00828 break;
00829 }
00830 case OPTIONSMENU_VOLUME:
00831 {
00832 copy_screen(workVideoBuffer, frontVideoBuffer);
00833 flip(workVideoBuffer);
00834 volume_menu();
00835 break;
00836 }
00837 case OPTIONSMENU_SAVEMANAGE:
00838 {
00839 copy_screen(workVideoBuffer, frontVideoBuffer);
00840 flip(workVideoBuffer);
00841 savemanage_menu();
00842 break;
00843 }
00844 case OPTIONSMENU_ADVOPTIONS:
00845 {
00846 copy_screen(workVideoBuffer, frontVideoBuffer);
00847 flip(workVideoBuffer);
00848 advoptions_menu();
00849 break;
00850 }
00851 default:
00852 break;
00853 }
00854 }
00855 while (ret != 1);
00856
00857 copy_screen(workVideoBuffer, frontVideoBuffer);
00858 flip(workVideoBuffer);
00859
00860 return 0;
00861 }
00862
00863
00865 void main_menu()
00866 {
00867
00868
00869 copy_screen(frontVideoBuffer, workVideoBuffer);
00870
00871
00872 plasmaEffectPtr = malloc(PLASMA_EFFECT_FILESIZE);
00873 hqr_get_entry(plasmaEffectPtr, HQR_RESS_FILE, RESSHQR_PLASMAEFFECT);
00874
00875 while(!cfgfile.Quit)
00876 {
00877
00878 init_dialogue_bank(0);
00879
00880 play_track_music(9);
00881
00882
00883 switch(process_menu(MainMenuSettings))
00884 {
00885 case MAINMENU_NEWGAME:
00886 {
00887 new_game_menu();
00888 break;
00889 }
00890 case MAINMENU_CONTINUEGAME:
00891 {
00892 break;
00893 }
00894 case MAINMENU_OPTIONS:
00895 {
00896 copy_screen(workVideoBuffer, frontVideoBuffer);
00897 flip(workVideoBuffer);
00898 OptionsMenuSettings[5] = OPTIONSMENU_RETURNMENU;
00899 options_menu();
00900 break;
00901 }
00902 case MAINMENU_QUIT:
00903 {
00904 cfgfile.Quit = 1;
00905 break;
00906 }
00907 case MAINMENU_BKGIMAGE:
00908 {
00909 hqr_get_entry(workVideoBuffer, HQR_RESS_FILE, RESSHQR_MENUIMG);
00910 copy_screen(workVideoBuffer, frontVideoBuffer);
00911 hqr_get_entry(palette, HQR_RESS_FILE, RESSHQR_MAINPAL);
00912 convert_pal_2_RGBA(palette, paletteRGBA);
00913 flip(workVideoBuffer);
00914 fade_2_pal(paletteRGBA);
00915 }
00916 }
00917 fps_cycles(cfgfile.Fps);
00918 }
00919 }
00920
00922 int giveup_menu()
00923 {
00924
00925 int menuId;
00926 short * localMenu;
00927
00928 copy_screen(frontVideoBuffer, workVideoBuffer);
00929
00930
00931 if(cfgfile.UseAutoSaving==1)
00932 localMenu = GiveUpMenuSettings;
00933 else
00934 localMenu = GiveUpMenuSettingsWithSave;
00935
00936 do
00937 {
00938
00939
00940 init_dialogue_bank(0);
00941
00942
00943 menuId = process_menu(localMenu);
00944
00945
00946
00947 init_dialogue_bank(currentTextBank + 3);
00948
00949 fps_cycles(cfgfile.Fps);
00950 }
00951 while (menuId != GIVEUPMENU_QUIT && menuId != GIVEUPMENU_CONTINUE);
00952
00953 if(menuId == GIVEUPMENU_QUIT)
00954 return 1;
00955
00956 return 0;
00957 }
00958