DOOM64-RE

DOOM 64 Reverse Engineering
Log | Files | Refs | README | LICENSE

m_main.c (75974B)


      1 /* m_main.c -- menu routines */
      2 
      3 #include "doomdef.h"
      4 #include "r_local.h"
      5 #include "st_main.h"
      6 
      7 //intermission
      8 int DrawerStatus;
      9 
     10 #define CT_TXT00	"default: %d"
     11 #define CT_TXT01	"right"
     12 #define CT_TXT02	"left"
     13 #define CT_TXT03	"forward"
     14 #define CT_TXT04	"backward"
     15 #define CT_TXT05	"attack"
     16 #define CT_TXT06	"use"
     17 #define CT_TXT07	"map"
     18 #define CT_TXT08	"speed"
     19 #define CT_TXT09	"strafe on"
     20 #define CT_TXT10	"strafe left"
     21 #define CT_TXT11	"strafe right"
     22 #define CT_TXT12	"weapon backward"
     23 #define CT_TXT13	"weapon forward"
     24 
     25 char *ControlText[] =   //8007517C
     26 {
     27     CT_TXT00, CT_TXT01, CT_TXT02, CT_TXT03, CT_TXT04,
     28 	CT_TXT05, CT_TXT06, CT_TXT07, CT_TXT08, CT_TXT09,
     29 	CT_TXT10, CT_TXT11, CT_TXT12, CT_TXT13
     30 };
     31 
     32 #define M_TXT00	"Control Pad"
     33 #define M_TXT01	"Volume"
     34 #define M_TXT02	"Display"
     35 #define M_TXT03	"Password"
     36 #define M_TXT04	"Main Menu"
     37 #define M_TXT05	"Restart Level"
     38 #define M_TXT06	"\x90 Return"
     39 #define M_TXT07 "Music Volume"
     40 #define M_TXT08 "Sound Volume"
     41 #define M_TXT09 "Brightness"
     42 #define M_TXT10 "Resume"
     43 #define M_TXT11 "Options"
     44 #define M_TXT12 "Default"
     45 #define M_TXT13 "Default"
     46 #define M_TXT14 "New Game"
     47 #define M_TXT15 "Be Gentle!"
     48 #define M_TXT16 "Bring it on!"
     49 #define M_TXT17 "I own Doom!"
     50 #define M_TXT18 "Watch me die!"
     51 #define M_TXT19 "Nightmare!"
     52 #define M_TXT20 "Yes"
     53 #define M_TXT21 "No"
     54 #define M_TXT22 "Features"
     55 #define M_TXT23 "WARP TO LEVEL"
     56 #define M_TXT24 "INVULNERABLE"
     57 #define M_TXT25 "HEALTH BOOST"
     58 #define M_TXT26 "SECURITY KEYS"
     59 #define M_TXT27 "WEAPONS"
     60 #define M_TXT28 "Exit"
     61 #define M_TXT29 "DEBUG"
     62 #define M_TXT30 "TEXTURE TEST"
     63 #define M_TXT31 "WALL BLOCKING"
     64 #define M_TXT32 "Center Display"
     65 #define M_TXT33 "Messages:"
     66 #define M_TXT34 "Status Bar:"
     67 #define M_TXT35 "LOCK MONSTERS"
     68 #define M_TXT36 "SCREENSHOT"
     69 #define M_TXT37 "MAP EVERYTHING"
     70 #define M_TXT38 "MACRO PEEK"
     71 #define M_TXT39 "MUSIC TEST"
     72 #define M_TXT40 "WARP TO FUN"
     73 #define M_TXT41 "Control Stick"
     74 #define M_TXT42 "Default"
     75 #define M_TXT43 "Sensitivity"
     76 #define M_TXT44 "Manage Pak"
     77 #define M_TXT45 "Do not use Pak"
     78 #define M_TXT46 "Try again"
     79 #define M_TXT47 "Create game note"
     80 
     81 #define M_TXT48 "COLORS"     // [GEC] NEW CHEAT CODE
     82 #define M_TXT49 "FULL BRIGHT"   // [GEC] NEW CHEAT CODE
     83 #define M_TXT50 "FILTER"   // [GEC] NEW CHEAT CODE
     84 
     85 char *MenuText[] =   // 8005ABA0
     86 {
     87     M_TXT00, M_TXT01, M_TXT02, M_TXT03, M_TXT04,
     88     M_TXT05, M_TXT06, M_TXT07, M_TXT08, M_TXT09,
     89     M_TXT10, M_TXT11, M_TXT12, M_TXT13, M_TXT14,
     90     M_TXT15, M_TXT16, M_TXT17, M_TXT18, M_TXT19,
     91     M_TXT20, M_TXT21, M_TXT22, M_TXT23, M_TXT24,
     92     M_TXT25, M_TXT26, M_TXT27, M_TXT28, M_TXT29,
     93     M_TXT30, M_TXT31, M_TXT32, M_TXT33, M_TXT34,
     94     M_TXT35, M_TXT36, M_TXT37, M_TXT38, M_TXT39,
     95     M_TXT40, M_TXT41, M_TXT42, M_TXT43, M_TXT44,
     96     M_TXT45, M_TXT46, M_TXT47,
     97     M_TXT48, M_TXT49, M_TXT50  // [GEC] NEW
     98 };
     99 
    100 menuitem_t Menu_Title[2] = // 8005A978
    101 {
    102     { 14, 115, 190 },   // New Game
    103 	{ 11, 115, 210 },   // Options
    104 };
    105 
    106 #if ENABLE_NIGHTMARE == 1
    107 menuitem_t Menu_Skill[5] = // 8005A990
    108 #else
    109 menuitem_t Menu_Skill[4] = // 8005A990
    110 #endif // ENABLE_NIGHTMARE
    111 {
    112     { 15, 102, 80 },    // Be Gentle!
    113     { 16, 102, 100},    // Bring it on!
    114     { 17, 102, 120},    // I own Doom!
    115     { 18, 102, 140},    // Watch me die!
    116     /* Disable on Doom 64 Original */
    117     #if ENABLE_NIGHTMARE == 1
    118     { 19, 102, 160},    // Nightmare
    119     #endif // ENABLE_NIGHTMARE
    120 };
    121 
    122 menuitem_t Menu_Options[6] = // 8005A9C0
    123 {
    124     {  0, 102, 60 },    // Control Pad
    125     { 41, 102, 80 },    // Control Stick
    126     {  1, 102, 100},    // Volume
    127     {  2, 102, 120},    // Display
    128     {  3, 102, 140},    // Password
    129     {  6, 102, 160},    // Return
    130 };
    131 
    132 menuitem_t Menu_Volume[4] = // 8005AA08
    133 {
    134     {  7, 102, 60 },    // Music Volume
    135     {  8, 102, 100},    // Sound Volume
    136     { 12, 102, 140},    // Default Volume
    137     {  6, 102, 160},    // Return
    138 };
    139 
    140 menuitem_t Menu_ControlStick[3] = // 8005AA38
    141 {
    142     { 43, 102, 90 },    // Sensitivity
    143     { 42, 102, 130},    // Default Sensitivity
    144     {  6, 102, 150},    // Return
    145 };
    146 
    147 menuitem_t Menu_Display[6] = // 8005AA5C
    148 {
    149     {  9, 102, 60 },    // Brightness
    150     { 32, 102, 100},    // Center Display
    151     { 33, 102, 120},    // Messages
    152     { 34, 102, 140},    // Status Bar
    153     { 13, 102, 160},    // Default Display
    154     {  6, 102, 180},    // Return
    155 };
    156 
    157 menuitem_t Menu_Game[4] = // 8005AAA4
    158 {
    159     { 11, 122, 80 },    // Options
    160     {  4, 122, 100},    // Main Menu
    161     {  5, 122, 120},    // Restart Level
    162     { 22, 122, 140},    // Features
    163 };
    164 
    165 menuitem_t Menu_Quit[2] = // 8005AAD4
    166 {
    167     { 20, 142, 100},    // Yes
    168     { 21, 142, 120},    // No
    169 };
    170 
    171 menuitem_t Menu_DeleteNote[2] = // 8005AAEC
    172 {
    173     { 20, 142, 100},    // Yes
    174     { 21, 142, 120},    // No
    175 };
    176 
    177 menuitem_t Menu_ControllerPakBad[2] = // 8005AB04
    178 {
    179     { 46, 120, 100},    // Try again
    180     { 45, 120, 120},    // Do not use Pak
    181 };
    182 
    183 menuitem_t Menu_ControllerPakFull[3] = // 8005AB1C
    184 {
    185     { 44, 110, 90 },    // Manage Pak
    186     { 47, 110, 110},    // Create game note
    187     { 45, 110, 130},    // Do not use Pak
    188 };
    189 
    190 menuitem_t Menu_CreateNote[3] = // 8005AB40
    191 {
    192     { 20, 110, 90 },    // Yes
    193     { 45, 110, 110},    // Do not use Pak
    194     { 44, 110, 130},    // Manage Pak
    195 };
    196 
    197 //#define MAXFEATURES 5
    198 //#define MAXFEATURES 9
    199 #define MAXFEATURES 12
    200 menuitem_t Menu_Features[MAXFEATURES] = // 8005AB64
    201 {
    202     { 23, 40, 50},      // WARP TO LEVEL
    203     { 24, 40, 60},      // INVULNERABLE
    204     { 25, 40, 70},      // HEALTH BOOST
    205     { 27, 40, 80},      // WEAPONS
    206     { 37, 40, 90},      // MAP EVERYTHING
    207     //
    208     { 26, 40, 100},      // SECURITY KEYS
    209     { 31, 40, 110},      // WALL BLOCKING
    210     { 35, 40, 120},      // LOCK MONSTERS
    211     { 39, 40, 130},      // MUSIC TEST
    212     //
    213     { 48, 40, 140},      // COLORS [GEC] NEW CHEAT CODE
    214     { 49, 40, 150},      // FULL BRIGHT [GEC] NEW CHEAT CODE
    215     { 50, 40, 160},      // FILTER [GEC] NEW CHEAT CODE
    216 
    217     // no usados
    218 //#define M_TXT26 "SECURITY KEYS"
    219 //#define M_TXT28 "Exit"
    220 //#define M_TXT29 "DEBUG"
    221 //#define M_TXT30 "TEXTURE TEST"
    222 //#define M_TXT31 "WALL BLOCKING"
    223 //#define M_TXT35 "LOCK MONSTERS"
    224 //#define M_TXT36 "SCREENSHOT"
    225 //#define M_TXT38 "MACRO PEEK"
    226 //#define M_TXT39 "MUSIC TEST"
    227 //#define M_TXT40 "WARP TO FUN"
    228 
    229 };
    230 
    231 menudata_t MenuData[8]; // 800A54F0
    232 int MenuAnimationTic;   // 800a5570
    233 int cursorpos;          // 800A5574
    234 int m_vframe1;          // 800A5578
    235 menuitem_t *MenuItem;   // 800A5578
    236 int itemlines;          // 800A5580
    237 menufunc_t MenuCall;    // 800A5584
    238 
    239 int linepos;            // 800A5588
    240 int text_alpha_change_value;    // 800A558C
    241 int MusicID;            // 800A5590
    242 int m_actualmap;        // 800A5594
    243 int last_ticon;         // 800A5598
    244 
    245 skill_t startskill;     // 800A55A0
    246 int startmap;           // 800A55A4
    247 int EnableExpPak;       // 800A55A8
    248 
    249 //-----------------------------------------
    250 
    251 int MenuIdx = 0;                // 8005A7A4
    252 int text_alpha = 255;           // 8005A7A8
    253 int ConfgNumb = 0;              // 8005A7AC
    254 int Display_X = 0;              // 8005A7B0
    255 int Display_Y = 0;              // 8005A7B4
    256 boolean enable_messages = true; // 8005A7B8
    257 boolean enable_statusbar = true;// 8005A7BC
    258 int SfxVolume = 80;             // 8005A7C0
    259 int MusVolume = 80;             // 8005A7C4
    260 int brightness = 0;             // 8005A7C8
    261 int M_SENSITIVITY = 0;          // 8005A7CC
    262 boolean FeaturesUnlocked = false; // 8005A7D0
    263 
    264 int TempConfiguration[13] = // 8005A80C
    265 {
    266     PAD_LEFT, PAD_RIGHT, PAD_UP, PAD_DOWN,
    267     PAD_LEFT_C, PAD_RIGHT_C, PAD_UP_C, PAD_DOWN_C,
    268     PAD_L_TRIG, PAD_R_TRIG, PAD_A, PAD_B, PAD_Z_TRIG
    269 };
    270 
    271 int ActualConfiguration[13] = // 8005A840
    272 {
    273     PAD_RIGHT, PAD_LEFT, PAD_UP, PAD_DOWN,
    274     PAD_Z_TRIG,
    275     PAD_RIGHT_C, PAD_UP_C, PAD_LEFT_C, PAD_DOWN_C,
    276     PAD_L_TRIG, PAD_R_TRIG, PAD_A, PAD_B
    277 };
    278 
    279 int DefaultConfiguration[5][13] = // 8005A840
    280 {
    281     // Default 1
    282     {
    283         PAD_RIGHT, PAD_LEFT, PAD_UP, PAD_DOWN,
    284         PAD_Z_TRIG,
    285         PAD_RIGHT_C, PAD_UP_C, PAD_LEFT_C, PAD_DOWN_C,
    286         PAD_L_TRIG, PAD_R_TRIG, PAD_A, PAD_B
    287     },
    288 
    289     // Default 2
    290     {
    291         PAD_RIGHT, PAD_LEFT, PAD_UP, PAD_DOWN,
    292         PAD_Z_TRIG,
    293         PAD_RIGHT_C, PAD_UP_C,
    294         PAD_R_TRIG, PAD_L_TRIG,
    295         PAD_A, PAD_DOWN_C,
    296         PAD_B, PAD_LEFT_C
    297     },
    298 
    299     // Default 3
    300     {
    301         PAD_RIGHT, PAD_LEFT, PAD_UP, PAD_DOWN,
    302         PAD_Z_TRIG,
    303         PAD_UP_C, PAD_UP,
    304         PAD_R_TRIG,
    305         PAD_DOWN, PAD_LEFT_C, PAD_RIGHT_C,
    306         PAD_A, PAD_B
    307     },
    308 
    309     // Default 4
    310     {
    311         PAD_RIGHT_C, PAD_LEFT_C,
    312         PAD_UP, PAD_DOWN,
    313         PAD_Z_TRIG,
    314         PAD_UP, PAD_UP_C,
    315         PAD_L_TRIG,
    316         PAD_DOWN_C, PAD_LEFT, PAD_RIGHT,
    317         PAD_A, PAD_B
    318     },
    319 
    320     // Default 5
    321     {
    322         PAD_RIGHT, PAD_LEFT, PAD_UP, PAD_DOWN,
    323         PAD_A, PAD_RIGHT_C, PAD_UP_C, PAD_DOWN_C,
    324         PAD_Z_TRIG, PAD_L_TRIG, PAD_R_TRIG,
    325         PAD_B, PAD_LEFT_C
    326     }
    327 };
    328 
    329 //-----------------------------------------
    330 
    331 int M_RunTitle(void) // 80007630
    332 {
    333     int exit;
    334 
    335     DrawerStatus = 0;
    336     startskill = sk_easy;
    337     startmap = 1;
    338     MenuIdx = 0;
    339     MenuItem = Menu_Title;
    340     MenuCall = M_MenuTitleDrawer;
    341     text_alpha = 0;
    342     itemlines = 2;
    343     cursorpos = 0;
    344     last_ticon = 0;
    345 
    346     S_StartMusic(116);
    347 
    348     exit = MiniLoop(M_FadeInStart, M_MenuClearCall, M_MenuTicker, M_MenuGameDrawer);
    349     I_WIPE_FadeOutScreen();
    350     S_StopMusic();
    351 
    352     if (exit == ga_timeout)
    353         return ga_timeout;
    354 
    355     G_InitNew(startskill, startmap, ga_nothing);
    356     G_RunGame();
    357 
    358     return 0;
    359 }
    360 
    361 int M_ControllerPak(void) // 80007724
    362 {
    363     int exit;
    364     int ret;
    365     boolean PakBad;
    366 
    367     PakBad = false;
    368 
    369     while(1)
    370     {
    371         ret = I_CheckControllerPak();
    372 
    373         if ((ret != PFS_ERR_NOPACK) && (ret != PFS_ERR_ID_FATAL))
    374             PakBad = true;
    375 
    376         if(ret == 0)
    377         {
    378             ret = I_ReadPakFile();
    379 
    380             // Free Pak_Data
    381             if (Pak_Data)
    382             {
    383                 Z_Free(Pak_Data);
    384                 Pak_Data = NULL;
    385             }
    386 
    387             if(ret == 0)
    388             {
    389                 exit = ga_nothing;
    390                 break;
    391             }
    392 
    393             // Create Controller Pak Note
    394             MenuItem = Menu_CreateNote;
    395             itemlines = 3;
    396             MenuCall = M_MenuTitleDrawer;
    397             cursorpos = 0;
    398 
    399             MiniLoop(M_FadeInStart, NULL, M_MenuTicker, M_MenuGameDrawer);
    400             M_FadeOutStart(8);
    401 
    402             if (cursorpos != 0)
    403             {
    404                 exit = ga_exit;
    405                 break;
    406             }
    407 
    408             // Check Memory and Files Used on Controller Pak
    409             if ((Pak_Memory > 0) && (FilesUsed != 16))
    410             {
    411                 if (I_CreatePakFile() != 0)
    412                     goto ControllerPakBad;
    413 
    414                 exit = ga_nothing;
    415                 break;
    416             }
    417 
    418             // Show Controller Pak Full
    419             MenuItem = Menu_ControllerPakFull;
    420             itemlines = 3;
    421             MenuCall = M_MenuTitleDrawer;
    422             cursorpos = 0;
    423 
    424             MiniLoop(M_FadeInStart, NULL, M_MenuTicker, M_MenuGameDrawer);
    425             M_FadeOutStart(8);
    426 
    427             if (cursorpos != 1)
    428             {
    429                 exit = ga_exit;
    430                 break;
    431             }
    432         }
    433         else
    434         {
    435             if (PakBad == false)
    436             {
    437                 exit = ga_exit;
    438                 break;
    439             }
    440 
    441             // Show Controller Pak Bad
    442         ControllerPakBad:
    443             MenuItem = Menu_ControllerPakBad;
    444             itemlines = 2;
    445             MenuCall = M_MenuTitleDrawer;
    446             cursorpos = 0;
    447 
    448             MiniLoop(M_FadeInStart, NULL, M_MenuTicker, M_MenuGameDrawer);
    449             M_FadeOutStart(8);
    450 
    451             if (cursorpos != 0)
    452             {
    453                 exit = ga_exit;
    454                 break;
    455             }
    456         }
    457     }
    458 
    459     return exit;
    460 }
    461 
    462 #define MAXSENSIVITY    20
    463 
    464 int M_ButtonResponder(int buttons) // 80007960
    465 {
    466     int sensitivity;
    467     int NewButtons;
    468 
    469     /* Copy Default Buttons */
    470     NewButtons = (buttons);
    471 
    472     /* Analyze Analog Stick (up / down) */
    473     sensitivity = (int)((buttons) << 24) >> 24;
    474 
    475     if (sensitivity <= -MAXSENSIVITY)
    476         NewButtons |= PAD_DOWN;
    477     else if (sensitivity >= MAXSENSIVITY)
    478         NewButtons |= PAD_UP;
    479 
    480     /* Analyze Analog Stick (left / right) */
    481     sensitivity = (int)(((buttons & 0xff00) >> 8) << 24) >> 24;
    482 
    483     if (sensitivity <= -MAXSENSIVITY)
    484         NewButtons |= PAD_LEFT;
    485     else if (sensitivity >= MAXSENSIVITY)
    486         NewButtons |= PAD_RIGHT;
    487 
    488     return NewButtons & 0xffff0000;
    489 }
    490 
    491 void M_AlphaInStart(void) // 800079E0
    492 {
    493     text_alpha = 0;
    494     text_alpha_change_value = 20;
    495 }
    496 
    497 void M_AlphaOutStart(void) // 800079F8
    498 {
    499     text_alpha = 255;
    500     text_alpha_change_value = -20;
    501 }
    502 
    503 int M_AlphaInOutTicker(void) // 80007A14
    504 {
    505     if ((gamevbls < gametic) && ((gametic & 3) == 0)) {
    506         MenuAnimationTic = MenuAnimationTic + 1 & 7;
    507     }
    508 
    509     text_alpha += text_alpha_change_value;
    510     if (text_alpha_change_value < 0)
    511     {
    512         if (text_alpha < 0)
    513         {
    514             text_alpha = 0;
    515             return 8;
    516         }
    517     }
    518     else
    519     {
    520         if ((text_alpha_change_value > 0) && (text_alpha >= 256))
    521         {
    522             text_alpha = 255;
    523             return 8;
    524         }
    525     }
    526 
    527     return 0;
    528 }
    529 
    530 void M_FadeInStart(void) // 80007AB4
    531 {
    532     MiniLoop(M_AlphaInStart, NULL, M_AlphaInOutTicker, M_MenuGameDrawer);
    533 }
    534 
    535 void M_FadeOutStart(int exitmode) // 80007AEC
    536 {
    537     if (exitmode == 8)
    538         MiniLoop(M_AlphaOutStart, NULL, M_AlphaInOutTicker, M_MenuGameDrawer);
    539 }
    540 
    541 void M_SaveMenuData(void) // 80007B2C
    542 {
    543     menudata_t *mdat;
    544 
    545     // Save Actual Menu Page
    546     mdat = &MenuData[MenuIdx];
    547     MenuIdx += 1;
    548 
    549     mdat->menu_item  = MenuItem;
    550     mdat->item_lines = itemlines;
    551     mdat->menu_call  = MenuCall;
    552     mdat->cursor_pos = cursorpos;
    553 
    554     // Start Menu Fade Out
    555     MiniLoop(M_AlphaOutStart, NULL, M_AlphaInOutTicker, M_MenuGameDrawer);
    556 }
    557 
    558 void M_RestoreMenuData(boolean alpha_in) // 80007BB8
    559 {
    560     menudata_t *mdat;
    561 
    562     // Restore Previous Save Menu Page
    563     MenuIdx -= 1;
    564     mdat = &MenuData[MenuIdx];
    565 
    566     MenuItem  = mdat->menu_item;
    567     itemlines = mdat->item_lines;
    568     MenuCall  = mdat->menu_call;
    569     cursorpos = mdat->cursor_pos;
    570 
    571     // Start Menu Fade In
    572     if (alpha_in)
    573         MiniLoop(M_AlphaInStart, NULL, M_AlphaInOutTicker, M_MenuGameDrawer);
    574 }
    575 
    576 void M_MenuGameDrawer(void) // 80007C48
    577 {
    578     if (DrawerStatus == 1) {
    579         P_Drawer();
    580     }
    581     else if (DrawerStatus == 2) {
    582         F_DrawerIntermission();
    583     }
    584     else if (DrawerStatus == 3) {
    585         F_Drawer();
    586     }
    587     else
    588     {
    589         I_ClearFrame();
    590 
    591         gDPPipeSync(GFX1++);
    592         gDPSetCycleType(GFX1++, G_CYC_FILL);
    593         gDPSetRenderMode(GFX1++,G_RM_NOOP,G_RM_NOOP2);
    594         gDPSetColorImage(GFX1++, G_IM_FMT_RGBA, G_IM_SIZ_32b, SCREEN_WD, OS_K0_TO_PHYSICAL(cfb[vid_side]));
    595         gDPSetFillColor(GFX1++, GPACK_RGBA5551(0,0,0,0) << 16 | GPACK_RGBA5551(0,0,0,0));
    596         gDPFillRectangle(GFX1++, 0, 0, SCREEN_WD-1, SCREEN_HT-1);
    597 
    598         M_DrawBackground(56, 57, 80, "TITLE");
    599 
    600         if (MenuItem != Menu_Title) {
    601             M_DrawOverlay(0, 0, 320, 240, 96);
    602         }
    603 
    604         MenuCall();
    605         I_DrawFrame();
    606     }
    607 }
    608 
    609 extern mobj_t mobjhead;
    610 extern mapthing_t *spawnlist;   // 800A5D74
    611 extern int spawncount;          // 800A5D78
    612 extern int gobalcheats; // [GEC]
    613 
    614 int M_MenuTicker(void) // 80007E0C
    615 {
    616     unsigned int buttons, oldbuttons;
    617     int exit;
    618     int truebuttons;
    619     int ret;
    620     int i;
    621     mobj_t *m;
    622 
    623     /* animate skull */
    624     if ((gamevbls < gametic) && ((gametic & 3) == 0))
    625         MenuAnimationTic = MenuAnimationTic + 1 & 7;
    626 
    627     buttons = M_ButtonResponder(ticbuttons[0]);
    628     oldbuttons = oldticbuttons[0] & 0xffff0000;
    629 
    630     /* exit menu if button press */
    631     if (buttons != 0)
    632         last_ticon = ticon;
    633 
    634     /* exit menu if time out */
    635     if ((MenuItem == Menu_Title) && ((ticon - last_ticon) >= 900)) // 30 * TICRATE
    636     {
    637         exit = ga_timeout;
    638     }
    639     else
    640     {
    641         /* check for movement */
    642         if (!(buttons & (PAD_Z_TRIG|ALL_JPAD)))
    643             m_vframe1 = 0;
    644         else
    645         {
    646             m_vframe1 = m_vframe1 - vblsinframe[0];
    647             if (m_vframe1 <= 0)
    648             {
    649                 m_vframe1 = 0xf; // TICRATE / 2
    650 
    651                 if (buttons & PAD_DOWN)
    652                 {
    653                     cursorpos += 1;
    654 
    655                     if (cursorpos >= itemlines)
    656                         cursorpos = 0;
    657 
    658                     S_StartSound(NULL, sfx_switch1);
    659                 }
    660                 else if (buttons & PAD_UP)
    661                 {
    662                     cursorpos -= 1;
    663 
    664                     if (cursorpos < 0)
    665                         cursorpos = itemlines-1;
    666 
    667                     S_StartSound(NULL, sfx_switch1);
    668                 }
    669             }
    670         }
    671 
    672         if ((buttons & PAD_START) && !(oldticbuttons[0] & PAD_START))
    673         {
    674             if ((MenuItem == Menu_Title) ||
    675                 (MenuItem == Menu_ControllerPakBad) ||
    676                 (MenuItem == Menu_CreateNote) ||
    677                 (MenuItem == Menu_ControllerPakFull))
    678             {
    679                 return ga_nothing;
    680             }
    681             else
    682             {
    683                 if (MenuIdx != 0)
    684                     S_StartSound(NULL, sfx_pistol);
    685 
    686                 return ga_exit;
    687             }
    688         }
    689         else
    690         {
    691                 truebuttons = (0 < (buttons ^ oldbuttons));
    692 
    693                 if (truebuttons)
    694                     truebuttons = (0 < (buttons & ALL_BUTTONS));
    695 
    696                 switch(MenuItem[cursorpos].casepos)
    697                 {
    698 
    699                 case 0: // Control Pad
    700                     if (truebuttons)
    701                     {
    702                         S_StartSound(NULL, sfx_pistol);
    703                         M_SaveMenuData();
    704 
    705                         MenuCall = M_ControlPadDrawer;
    706                         cursorpos = 0;
    707                         linepos = 0;
    708 
    709                         MiniLoop(M_FadeInStart,M_FadeOutStart,M_ControlPadTicker,M_MenuGameDrawer);
    710                         M_RestoreMenuData(true);
    711                         return ga_nothing;
    712                     }
    713                     break;
    714 
    715                 case 1: // Volume
    716                     if (truebuttons)
    717                     {
    718                         S_StartSound(NULL, sfx_pistol);
    719                         M_SaveMenuData();
    720 
    721                         MenuItem = Menu_Volume;
    722                         itemlines = 4;
    723                         MenuCall = M_VolumeDrawer;
    724                         cursorpos = 0;
    725 
    726                         MiniLoop(M_FadeInStart,M_FadeOutStart,M_MenuTicker,M_MenuGameDrawer);
    727                         M_RestoreMenuData(true);
    728                         return ga_nothing;
    729                     }
    730                     break;
    731 
    732                 case 2: // Display
    733                     if (truebuttons)
    734                     {
    735                         S_StartSound(NULL, sfx_pistol);
    736                         M_SaveMenuData();
    737 
    738                         MenuItem = Menu_Display;
    739                         itemlines = 6;
    740                         MenuCall = M_DisplayDrawer;
    741                         cursorpos = 0;
    742 
    743                         MiniLoop(M_FadeInStart,M_FadeOutStart,M_MenuTicker,M_MenuGameDrawer);
    744                         M_RestoreMenuData(true);
    745                         return ga_nothing;
    746                     }
    747                     break;
    748 
    749                 case 3: // Password
    750                     if (truebuttons)
    751                     {
    752                         S_StartSound(NULL, sfx_pistol);
    753                         M_SaveMenuData();
    754 
    755                         ret = I_CheckControllerPak();
    756                         exit = ga_exit;
    757 
    758                         if (ret == 0)
    759                         {
    760                             if (I_ReadPakFile() == 0)
    761                             {
    762                                 EnableExpPak = 1;
    763                                 MenuCall = M_LoadPakDrawer;
    764                                 exit = MiniLoop(M_LoadPakStart,M_LoadPakStop,M_LoadPakTicker,M_MenuGameDrawer);
    765                             }
    766                             else
    767                                 exit = ga_exit;
    768                         }
    769 
    770                         if (exit == ga_exit)
    771                         {
    772                             MenuCall = M_PasswordDrawer;
    773                             exit = MiniLoop(M_PasswordStart,M_PasswordStop,M_PasswordTicker,M_MenuGameDrawer);
    774                         }
    775 
    776                         if (exit == ga_exit)
    777                         {
    778                             M_RestoreMenuData(true);
    779                             return ga_nothing;
    780                         }
    781 
    782                         if (EnableExpPak != 0)
    783                         {
    784                             return exit;
    785                         }
    786 
    787                         EnableExpPak = (M_ControllerPak() == 0);
    788                         return exit;
    789                     }
    790                     break;
    791 
    792                 case 4: // Main Menu
    793                     if (truebuttons)
    794                     {
    795                         S_StartSound(NULL, sfx_pistol);
    796                         M_SaveMenuData();
    797 
    798                         MenuItem = Menu_Quit;
    799                         itemlines = 2;
    800                         MenuCall = M_MenuTitleDrawer;
    801                         cursorpos = 1;
    802 
    803                         exit = MiniLoop(M_FadeInStart,M_FadeOutStart,M_MenuTicker,M_MenuGameDrawer);
    804                         M_RestoreMenuData((exit == ga_exit));
    805                         if (exit == ga_exit) {
    806                             return ga_nothing;
    807                         }
    808 
    809                         return 5;//ga_exitdemo;
    810                     }
    811                     break;
    812 
    813                 case 5: // Restart Level
    814                     if (truebuttons)
    815                     {
    816                         S_StartSound(NULL, sfx_pistol);
    817                         M_SaveMenuData();
    818 
    819                         MenuItem = Menu_Quit;
    820                         itemlines = 2;
    821                         MenuCall = M_MenuTitleDrawer;
    822                         cursorpos = 1;
    823 
    824                         exit = MiniLoop(M_FadeInStart, M_FadeOutStart, M_MenuTicker, M_MenuGameDrawer);
    825                         M_RestoreMenuData((exit == ga_exit));
    826 
    827                         if (exit == ga_exit)
    828                             return ga_nothing;
    829 
    830                         return ga_restart;
    831                     }
    832                     break;
    833 
    834                 case 6: // Return
    835                     if (truebuttons)
    836                     {
    837                         S_StartSound(NULL, sfx_pistol);
    838                         return ga_exit;
    839                     }
    840                     break;
    841 
    842                 case 7: // Music Volume
    843                     if (buttons & PAD_RIGHT)
    844                     {
    845                         MusVolume += 1;
    846                         if (MusVolume <= 100)
    847                         {
    848                             S_SetMusicVolume(MusVolume);
    849                             if (MusVolume & 1)
    850                             {
    851                                 S_StartSound(NULL, sfx_secmove);
    852                                 return ga_nothing;
    853                             }
    854                         }
    855                         else
    856                         {
    857                             MusVolume = 100;
    858                         }
    859                     }
    860                     else if (buttons & PAD_LEFT)
    861                     {
    862                         MusVolume -= 1;
    863                         if (MusVolume < 0)
    864                         {
    865                             MusVolume = 0;
    866                         }
    867                         else
    868                         {
    869                             S_SetMusicVolume(MusVolume);
    870                             if (MusVolume & 1)
    871                             {
    872                                 S_StartSound(NULL, sfx_secmove);
    873                                 return ga_nothing;
    874                             }
    875                         }
    876                     }
    877                     break;
    878 
    879                 case 8: // Sound Volume
    880                     if (buttons & PAD_RIGHT)
    881                     {
    882                         SfxVolume += 1;
    883                         if (SfxVolume <= 100)
    884                         {
    885                             S_SetSoundVolume(SfxVolume);
    886                             if (SfxVolume & 1)
    887                             {
    888                                 S_StartSound(NULL, sfx_secmove);
    889                                 return ga_nothing;
    890                             }
    891                         }
    892                         else
    893                         {
    894                             SfxVolume = 100;
    895                         }
    896                     }
    897                     else if (buttons & PAD_LEFT)
    898                     {
    899                         SfxVolume -= 1;
    900                         if (SfxVolume < 0)
    901                         {
    902                             SfxVolume = 0;
    903                         }
    904                         else
    905                         {
    906                             S_SetSoundVolume(SfxVolume);
    907                             if (SfxVolume & 1)
    908                             {
    909                                 S_StartSound(NULL, sfx_secmove);
    910                                 return ga_nothing;
    911                             }
    912                         }
    913                     }
    914                     break;
    915 
    916                 case 9: // Brightness
    917                     if (buttons & PAD_RIGHT)
    918                     {
    919                         brightness += 1;
    920                         if (brightness <= 100)
    921                         {
    922                             P_RefreshBrightness();
    923                             if (brightness & 1)
    924                             {
    925                                 S_StartSound(NULL, sfx_secmove);
    926                                 return ga_nothing;
    927                             }
    928                         }
    929                         else
    930                         {
    931                             brightness = 100;
    932                         }
    933                     }
    934                     else if (buttons & PAD_LEFT)
    935                     {
    936                         brightness -= 1;
    937                         if (brightness < 0)
    938                         {
    939                             brightness = 0;
    940                         }
    941                         else
    942                         {
    943                             P_RefreshBrightness();
    944                             if (brightness & 1)
    945                             {
    946                                 S_StartSound(NULL, sfx_secmove);
    947                                 return ga_nothing;
    948                             }
    949                         }
    950                     }
    951                     break;
    952 
    953                 case 11: // Options
    954                     if (truebuttons)
    955                     {
    956                         S_StartSound(NULL, sfx_pistol);
    957                         M_SaveMenuData();
    958 
    959                         MenuItem = Menu_Options;
    960                         itemlines = 6;
    961                         MenuCall = M_MenuTitleDrawer;
    962                         cursorpos = 0;
    963 
    964                         exit = MiniLoop(M_FadeInStart, M_FadeOutStart, M_MenuTicker, M_MenuGameDrawer);
    965                         M_RestoreMenuData((exit == ga_exit));
    966 
    967                         if (exit == ga_exit)
    968                             return ga_nothing;
    969 
    970                         return exit;
    971                     }
    972                     break;
    973 
    974                 case 12: // Default Volume
    975                     if (truebuttons)
    976                     {
    977                         S_StartSound(NULL, sfx_switch2);
    978 
    979                         SfxVolume = 0x50;
    980                         MusVolume = 0x50;
    981 
    982                         S_SetMusicVolume(MusVolume);
    983                         S_SetSoundVolume(SfxVolume);
    984 
    985                         return ga_nothing;
    986                     }
    987                     break;
    988 
    989                 case 13: // Default Display
    990                     if (truebuttons)
    991                     {
    992                         S_StartSound(NULL, sfx_switch2);
    993 
    994                         Display_X = 0;
    995                         Display_Y = 0;
    996 
    997                         enable_messages = true;
    998                         enable_statusbar = true;
    999 
   1000                         brightness = 0;
   1001                         I_MoveDisplay(0,0);
   1002                         P_RefreshBrightness();
   1003                         return ga_nothing;
   1004                     }
   1005                     break;
   1006 
   1007                 case 14: // New Game
   1008                     if (truebuttons)
   1009                     {
   1010                         S_StartSound(NULL, sfx_pistol);
   1011                         M_FadeOutStart(8);
   1012 
   1013                         // Check ControllerPak
   1014                         EnableExpPak = (M_ControllerPak() == 0);
   1015 
   1016                         MenuItem = Menu_Skill;
   1017                         #if ENABLE_NIGHTMARE == 1
   1018                         itemlines = 5;
   1019                         #else
   1020                         itemlines = 4;
   1021                         #endif // ENABLE_NIGHTMARE
   1022                         MenuCall = M_MenuTitleDrawer;
   1023                         cursorpos = 1;  // Set Default Bring it on!
   1024 
   1025                         MiniLoop(M_FadeInStart, M_MenuClearCall, M_MenuTicker, M_MenuGameDrawer);
   1026                         startskill = MenuItem[cursorpos].casepos - 15;
   1027 
   1028                         return ga_exit;
   1029                     }
   1030                     break;
   1031 
   1032                 case 15: // Be Gentle!
   1033                 case 16: // Bring it on!
   1034                 case 17: // I own Doom!
   1035                 case 18: // Watch me die!
   1036 				case 19: // Nightmare!
   1037                 
   1038                     if (truebuttons)
   1039                     {
   1040                         S_StartSound(NULL, sfx_pistol);
   1041                         return ga_exit;
   1042                     }
   1043                     break;
   1044 
   1045                 case 20: // Yes
   1046                 case 46: // Try again
   1047                 case 47: // Create game note
   1048                     if (truebuttons)
   1049                     {
   1050                         S_StartSound(NULL, sfx_pistol);
   1051                         return 5; //ga_exitdemo;
   1052                     }
   1053                     break;
   1054 
   1055                 case 21: // No
   1056                 case 45: // Do not use Pak
   1057                     if (truebuttons)
   1058                     {
   1059                         S_StartSound(NULL, sfx_pistol);
   1060                         return ga_exit;
   1061                     }
   1062                     break;
   1063 
   1064                 case 22: // Features
   1065                     if (truebuttons)
   1066                     {
   1067                         S_StartSound(NULL, sfx_pistol);
   1068                         M_SaveMenuData();
   1069 
   1070                         players[0].cheats &= 0xffff1fff;
   1071 
   1072                         MenuItem = Menu_Features;
   1073                         itemlines = MAXFEATURES;
   1074                         MenuCall = M_FeaturesDrawer;
   1075                         cursorpos = 0;
   1076                         m_actualmap = gamemap;
   1077 
   1078                         exit = MiniLoop(M_FadeInStart,M_FadeOutStart,M_MenuTicker,M_MenuGameDrawer);
   1079                         M_RestoreMenuData((exit == 8));
   1080 
   1081                         if (exit == 8)
   1082                             return ga_nothing;
   1083 
   1084                         return exit;
   1085                     }
   1086                     break;
   1087 
   1088                 case 23: // WARP TO LEVEL
   1089                     if (buttons ^ oldbuttons)
   1090                     {
   1091                         if (buttons & PAD_LEFT)
   1092                         {
   1093                             m_actualmap -= 1;
   1094                             if (m_actualmap > 27)
   1095                                 m_actualmap = 27;
   1096 
   1097                             if (m_actualmap > 0)
   1098                             {
   1099                                 S_StartSound(NULL, sfx_switch2);
   1100                                 return ga_nothing;
   1101                             }
   1102                             m_actualmap = 1;
   1103                         }
   1104                         else if (buttons & PAD_RIGHT)
   1105                         {
   1106                             m_actualmap += 1;
   1107                             if (m_actualmap < 28)
   1108                             {
   1109                                 S_StartSound(NULL, sfx_switch2);
   1110                                 return ga_nothing;
   1111                             }
   1112                             m_actualmap = 27;
   1113                         }
   1114                         else if (buttons & ALL_CBUTTONS)
   1115                         {
   1116                             gamemap = m_actualmap;
   1117                             startmap = m_actualmap;
   1118                             return ga_warped;
   1119                         }
   1120                     }
   1121                     break;
   1122 
   1123                 case 24: // INVULNERABLE
   1124                     if (((gamemap != 32) & truebuttons))
   1125                     {
   1126                         players[0].cheats ^= CF_GODMODE;
   1127                         S_StartSound(NULL, sfx_switch2);
   1128                         return ga_nothing;
   1129                     }
   1130                     break;
   1131 
   1132                 case 25: // HEALTH BOOST
   1133                     if (truebuttons)
   1134                     {
   1135                         players[0].cheats |= CF_HEALTH;
   1136                         players[0].health = 100;
   1137                         players[0].mo->health = 100;
   1138                         S_StartSound(NULL, sfx_switch2);
   1139                         return ga_nothing;
   1140                     }
   1141                     break;
   1142 
   1143                 case 26: // SECURITY KEYS
   1144                     /* Not available in the release code */
   1145                     /*
   1146                     Reconstructed code based on Psx Doom
   1147                     */
   1148                     if (truebuttons)
   1149                     {
   1150                         players[0].cheats |= CF_ALLKEYS;
   1151 
   1152                         for (m = mobjhead.next; m != &mobjhead; m = m->next)
   1153                         {
   1154                             switch (m->type)
   1155                             {
   1156                             case MT_ITEM_BLUECARDKEY:
   1157                                 players[0].cards[it_bluecard] = true;
   1158                                 break;
   1159                             case MT_ITEM_REDCARDKEY:
   1160                                 players[0].cards[it_redcard] = true;
   1161                                 break;
   1162                             case MT_ITEM_YELLOWCARDKEY:
   1163                                 players[0].cards[it_yellowcard] = true;
   1164                                 break;
   1165                             case MT_ITEM_YELLOWSKULLKEY:
   1166                                 players[0].cards[it_yellowskull] = true;
   1167                                 break;
   1168                             case MT_ITEM_REDSKULLKEY:
   1169                                 players[0].cards[it_redskull] = true;
   1170                                 break;
   1171                             case MT_ITEM_BLUESKULLKEY:
   1172                                 players[0].cards[it_blueskull] = true;
   1173                                 break;
   1174                             default:
   1175                                 break;
   1176                             }
   1177                         }
   1178 
   1179                         for (i = 0; i < spawncount; i++)
   1180                         {
   1181                             switch (spawnlist[i].type)
   1182                             {
   1183                             case 5:
   1184                                 players[0].cards[it_bluecard] = true;
   1185                                 break;
   1186                             case 13:
   1187                                 players[0].cards[it_redcard] = true;
   1188                                 break;
   1189                             case 6:
   1190                                 players[0].cards[it_yellowcard] = true;
   1191                                 break;
   1192                             case 39:
   1193                                 players[0].cards[it_yellowskull] = true;
   1194                                 break;
   1195                             case 38:
   1196                                 players[0].cards[it_redskull] = true;
   1197                                 break;
   1198                             case 40:
   1199                                 players[0].cards[it_blueskull] = true;
   1200                                 break;
   1201                             default:
   1202                                 break;
   1203                             }
   1204                         }
   1205 
   1206                         S_StartSound(NULL, sfx_switch2);
   1207                         return ga_nothing;
   1208                     }
   1209                     break;
   1210 
   1211                 case 27: // WEAPONS
   1212                     if (truebuttons)
   1213                     {
   1214                         players[0].cheats |= CF_WEAPONS;
   1215 
   1216                         for(i = 0; i < NUMWEAPONS; i++) {
   1217                             players[0].weaponowned[i] = true;
   1218                         }
   1219 
   1220                         for(i = 0; i < NUMAMMO; i++) {
   1221                             players[0].ammo[i] = players[0].maxammo[i];
   1222                         }
   1223 
   1224                         S_StartSound(NULL, sfx_switch2);
   1225                         return ga_nothing;
   1226                     }
   1227                     break;
   1228 
   1229                 case 28: // Exit
   1230                     /* nothing special */
   1231                     break;
   1232 
   1233                 case 29: // DEBUG
   1234                     /* Not available in the release code */
   1235                     if (truebuttons)
   1236                     {
   1237                         players[0].cheats ^= CF_DEBUG;
   1238                         S_StartSound(NULL, sfx_switch2);
   1239                         return ga_nothing;
   1240                     }
   1241                     break;
   1242 
   1243                 case 30: // TEXTURE TEST
   1244                     /* Not available in the release code */
   1245                     if (truebuttons)
   1246                     {
   1247                         players[0].cheats ^= CF_TEX_TEST;
   1248                         S_StartSound(NULL, sfx_switch2);
   1249                         return ga_nothing;
   1250                     }
   1251                     break;
   1252 
   1253                 case 31: // WALL BLOCKING
   1254                     /* Not available in the release code */
   1255                     /*
   1256                     In my opinion it must have been the NOCLIP cheat code
   1257                     */
   1258                     if (truebuttons)
   1259                     {
   1260                         players[0].cheats ^= CF_WALLBLOCKING;
   1261                         players[0].mo->flags ^= MF_NOCLIP;
   1262                         S_StartSound(NULL, sfx_switch2);
   1263                         return ga_nothing;
   1264                     }
   1265                     break;
   1266 
   1267                 case 32: // Center Display
   1268                     if (truebuttons)
   1269                     {
   1270                         S_StartSound(NULL, sfx_pistol);
   1271                         M_SaveMenuData();
   1272 
   1273                         MenuCall = M_CenterDisplayDrawer;
   1274 
   1275                         MiniLoop(M_FadeInStart,M_FadeOutStart,M_CenterDisplayTicker,M_MenuGameDrawer);
   1276                         M_RestoreMenuData(true);
   1277 
   1278                         return ga_nothing;
   1279                     }
   1280                     break;
   1281 
   1282                 case 33: // Messages
   1283                     if (truebuttons)
   1284                     {
   1285                         S_StartSound(NULL, sfx_switch2);
   1286                         enable_messages ^= true;
   1287                     }
   1288                     break;
   1289 
   1290                 case 34: // Status Bar
   1291                     if (truebuttons)
   1292                     {
   1293                         S_StartSound(NULL, sfx_switch2);
   1294                         enable_statusbar ^= true;
   1295                     }
   1296                     break;
   1297 
   1298                 case 35: // LOCK MONSTERS
   1299                     /* Not available in the release code */
   1300                     /*
   1301                     Reconstructed code based on Doom 64 Ex
   1302                     */
   1303                     if (truebuttons)
   1304                     {
   1305                         players[0].cheats ^= CF_LOCKMOSTERS;
   1306                         S_StartSound(NULL, sfx_switch2);
   1307                         return ga_nothing;
   1308                     }
   1309                     break;
   1310 
   1311                 case 36: // SCREENSHOT
   1312                     /* Not available in the release code */
   1313                     if (truebuttons)
   1314                     {
   1315                         players[0].cheats ^= CF_SCREENSHOT;
   1316                         S_StartSound(NULL, sfx_switch2);
   1317                         return ga_nothing;
   1318                     }
   1319                     break;
   1320 
   1321                 case 37: // MAP EVERYTHING
   1322                     if (truebuttons)
   1323                     {
   1324                         players[0].cheats ^= CF_ALLMAP;
   1325                         S_StartSound(NULL, sfx_switch2);
   1326                         return ga_nothing;
   1327                     }
   1328                     break;
   1329 
   1330                 case 38: // MACRO PEEK
   1331                     /* Not available in the release code */
   1332                     if (truebuttons)
   1333                     {
   1334                         players[0].cheats ^= CF_MACROPEEK;
   1335                         S_StartSound(NULL, sfx_switch2);
   1336                         return ga_nothing;
   1337                     }
   1338                     break;
   1339 
   1340                 case 39: // MUSIC TEST
   1341                     /* Not available in the release code */
   1342                     /*
   1343                     Reconstructed code in my interpretation
   1344                     */
   1345                     if (buttons ^ oldbuttons)
   1346                     {
   1347                         if (buttons & PAD_LEFT)
   1348                         {
   1349                             MusicID -= 1;
   1350                             if (MusicID > 0)
   1351                             {
   1352                                 S_StartSound(NULL, sfx_switch2);
   1353                                 return ga_nothing;
   1354                             }
   1355                             MusicID = 1;
   1356                         }
   1357                         else if (buttons & PAD_RIGHT)
   1358                         {
   1359                             MusicID += 1;
   1360                             if (MusicID < 25)
   1361                             {
   1362                                 S_StartSound(NULL, sfx_switch2);
   1363                                 return ga_nothing;
   1364                             }
   1365                             MusicID = 24;
   1366                         }
   1367                         else if (buttons & ALL_CBUTTONS)
   1368                         {
   1369                             S_StopMusic();
   1370                             S_StartMusic(MusicID+92);
   1371                             return ga_nothing;
   1372                         }
   1373                     }
   1374                     break;
   1375 
   1376                 case 41: // Control Stick
   1377                     if (truebuttons)
   1378                     {
   1379                         S_StartSound(NULL, sfx_pistol);
   1380                         M_SaveMenuData();
   1381 
   1382                         MenuItem = Menu_ControlStick;
   1383                         itemlines = 3;
   1384                         MenuCall = M_ControlStickDrawer;
   1385                         cursorpos = 0;
   1386 
   1387                         MiniLoop(M_FadeInStart, M_FadeOutStart, M_MenuTicker, M_MenuGameDrawer);
   1388                         M_RestoreMenuData(true);
   1389 
   1390                         return ga_nothing;
   1391                     }
   1392                     break;
   1393 
   1394                 case 42: // Default Sensitivity
   1395                     if (truebuttons)
   1396                     {
   1397                         S_StartSound(NULL, sfx_switch2);
   1398                         M_SENSITIVITY = 0;
   1399                     }
   1400                     break;
   1401 
   1402                 case 43: // Sensitivity
   1403                     if (buttons & PAD_RIGHT)
   1404                     {
   1405                         M_SENSITIVITY += 1;
   1406                         if (M_SENSITIVITY <= 100)
   1407                         {
   1408                             if (M_SENSITIVITY & 1)
   1409                             {
   1410                                 S_StartSound(NULL, sfx_secmove);
   1411                                 return ga_nothing;
   1412                             }
   1413                         }
   1414                         else
   1415                         {
   1416                             M_SENSITIVITY = 100;
   1417                         }
   1418                     }
   1419                     else if (buttons & PAD_LEFT)
   1420                     {
   1421                         M_SENSITIVITY -= 1;
   1422                         if (M_SENSITIVITY < 0)
   1423                         {
   1424                             M_SENSITIVITY = 0;
   1425                         }
   1426                         else
   1427                         {
   1428                             if (M_SENSITIVITY & 1)
   1429                             {
   1430                                 S_StartSound(NULL, sfx_secmove);
   1431                                 return ga_nothing;
   1432                             }
   1433                         }
   1434                     }
   1435                     break;
   1436 
   1437                 case 44: // Manage Pak
   1438                     if (truebuttons)
   1439                     {
   1440                         S_StartSound(NULL, sfx_pistol);
   1441                         M_SaveMenuData();
   1442 
   1443                         MenuCall = M_ControllerPakDrawer;
   1444                         linepos = 0;
   1445                         cursorpos = 0;
   1446 
   1447                         exit = MiniLoop(M_FadeInStart, M_FadeOutStart, M_ScreenTicker, M_MenuGameDrawer);
   1448                         M_RestoreMenuData((exit == 8));
   1449 
   1450                         if (exit == 8)
   1451                             return ga_nothing;
   1452 
   1453                         return exit;
   1454                     }
   1455                     break;
   1456 
   1457                 case 48: // COLORS [GEC] NEW CHEAT CODE
   1458                     if (truebuttons)
   1459                     {
   1460                     players[0].cheats ^= CF_NOCOLORS;
   1461                     gobalcheats ^= CF_NOCOLORS;
   1462                     P_RefreshBrightness();
   1463                     S_StartSound(NULL, sfx_switch2);
   1464                     return ga_nothing;
   1465                     }
   1466                     break;
   1467 
   1468                 case 49: // FULL BRIGHT [GEC] NEW CHEAT CODE
   1469                     if (truebuttons)
   1470                     {
   1471                         players[0].cheats ^= CF_FULLBRIGHT;
   1472                         gobalcheats ^= CF_FULLBRIGHT;
   1473                         P_RefreshBrightness();
   1474                         S_StartSound(NULL, sfx_switch2);
   1475                         return ga_nothing;
   1476                     }
   1477                     break;
   1478 
   1479                 case 50: // FILTER [GEC] NEW CHEAT CODE
   1480                     if (truebuttons)
   1481                     {
   1482                         players[0].cheats ^= CF_FILTER;
   1483                         gobalcheats ^= CF_FILTER;
   1484                         S_StartSound(NULL, sfx_switch2);
   1485                         return ga_nothing;
   1486                     }
   1487                     break;
   1488                 }
   1489 
   1490             exit = ga_nothing;
   1491         }
   1492     }
   1493 
   1494     return exit;
   1495 }
   1496 
   1497 void M_MenuClearCall(void) // 80008E6C
   1498 {
   1499     MenuCall = NULL;
   1500 }
   1501 
   1502 void M_MenuTitleDrawer(void) // 80008E7C
   1503 {
   1504     menuitem_t *item;
   1505     int i;
   1506 
   1507     if (MenuItem == Menu_Game)
   1508     {
   1509         ST_DrawString(-1, 20, "Pause", text_alpha | 0xc0000000);
   1510         ST_DrawString(-1, 200, "press \x8d to resume", text_alpha | 0xffffff00);
   1511     }
   1512     else if (MenuItem == Menu_Skill)
   1513     {
   1514         ST_DrawString(-1, 20, "Choose Your Skill...", text_alpha | 0xc0000000);
   1515     }
   1516     else if (MenuItem == Menu_Options)
   1517     {
   1518         ST_DrawString(-1, 20, "Options", text_alpha | 0xc0000000);
   1519     }
   1520     else if (MenuItem == Menu_Quit)
   1521     {
   1522         ST_DrawString(-1, 20, "Quit Game?", text_alpha | 0xc0000000);
   1523     }
   1524     else if (MenuItem == Menu_DeleteNote)
   1525     {
   1526         ST_DrawString(-1, 20, "Delete Game Note?", text_alpha | 0xc0000000);
   1527     }
   1528     else if (MenuItem == Menu_ControllerPakBad)
   1529     {
   1530         ST_DrawString(-1, 20, "Controller Pak Bad", text_alpha | 0xc0000000);
   1531     }
   1532     else if (MenuItem == Menu_ControllerPakFull)
   1533     {
   1534         ST_DrawString(-1, 20, "Controller Pak Full", text_alpha | 0xc0000000);
   1535     }
   1536     else if (MenuItem == Menu_CreateNote)
   1537     {
   1538         ST_DrawString(-1, 20, "Create Game Note?", text_alpha | 0xc0000000);
   1539     }
   1540 
   1541     item = MenuItem;
   1542     for(i = 0; i < itemlines; i++)
   1543     {
   1544         ST_DrawString(item->x, item->y, MenuText[item->casepos], text_alpha | 0xc0000000);
   1545         item++;
   1546     }
   1547 
   1548     ST_DrawSymbol(MenuItem[0].x -37, MenuItem[cursorpos].y -9, MenuAnimationTic + 70, text_alpha | 0xffffff00);
   1549 }
   1550 
   1551 void M_FeaturesDrawer(void) // 800091C0
   1552 {
   1553     char *text, textbuff[16];
   1554     menuitem_t *item;
   1555     int i;
   1556 
   1557     ST_DrawString(-1, 20, "Features", text_alpha | 0xc0000000);
   1558     item = MenuItem;
   1559 
   1560     for(i = 0; i < itemlines; i++)
   1561     {
   1562         if ((item->casepos == 23) && ((m_actualmap >= 25) && (m_actualmap <= 27)))
   1563         {
   1564             /* Show "WARP TO FUN" text */
   1565             ST_Message(item->x, item->y, MenuText[40], text_alpha | 0xffffff00);
   1566         }
   1567         else
   1568         {
   1569             /* Show "WARP TO LEVEL" text */
   1570             ST_Message(item->x, item->y, MenuText[item->casepos], text_alpha | 0xffffff00);
   1571         }
   1572 
   1573         text = textbuff;
   1574         switch(item->casepos)
   1575         {
   1576             case 23: /* WARP TO LEVEL */
   1577                 sprintf(textbuff, "%s", MapInfo[m_actualmap].name);
   1578                 break;
   1579             case 24: /* INVULNERABLE */
   1580                 text = (!(players[0].cheats & CF_GODMODE)) ? "OFF": "ON";
   1581                 break;
   1582             case 25: /* HEALTH BOOST */
   1583                 text = (!(players[0].cheats & CF_HEALTH)) ? "-" : "100%";
   1584                 break;
   1585             case 26: /* SECURITY KEYS */
   1586                 text = (!(players[0].cheats & CF_ALLKEYS)) ? "-" : "100%";
   1587                 break;
   1588             case 27: /* WEAPONS */
   1589                 text = (!(players[0].cheats & CF_WEAPONS)) ? "-" : "100%";
   1590                 break;
   1591             case 28: /* Exit */
   1592                 break;
   1593             case 29: /* DEBUG */
   1594                 text = (!(players[0].cheats & CF_DEBUG)) ? "OFF": "ON";
   1595                 break;
   1596             case 30: /* TEXTURE TEST */
   1597                 text = (!(players[0].cheats & CF_TEX_TEST)) ? "OFF": "ON";
   1598                 break;
   1599             case 31: /* WALL BLOCKING */
   1600                 text = (!(players[0].cheats & CF_WALLBLOCKING)) ? "ON": "OFF";
   1601                 break;
   1602             case 35: /* LOCK MONSTERS */
   1603                 text = (!(players[0].cheats & CF_LOCKMOSTERS)) ? "OFF": "ON";
   1604                 break;
   1605             case 36: /* SCREENSHOT */
   1606                 text = (!(players[0].cheats & CF_SCREENSHOT)) ? "OFF": "ON";
   1607                 break;
   1608             case 37: /* MAP EVERYTHING */
   1609                 text = (!(players[0].cheats & CF_ALLMAP)) ? "OFF": "ON";
   1610                 break;
   1611             case 38: /* MACRO PEEK */
   1612                 text = ((players[0].cheats & CF_MACROPEEK)) ? "ON": "OFF";
   1613                 break;
   1614             case 39: /* MUSIC TEST */
   1615                 sprintf(textbuff, "%d", MusicID);
   1616                 break;
   1617 
   1618             // [GEC] NEW CHEAT CODES
   1619             case 48: /* COLORS */
   1620                 text = (!(players[0].cheats & CF_NOCOLORS)) ? "ON": "OFF";
   1621                 break;
   1622 
   1623             case 49: /* FULL BRIGHT */
   1624                 text = (!(players[0].cheats & CF_FULLBRIGHT)) ? "OFF": "ON";
   1625                 break;
   1626 
   1627             case 50: /* FILTER */
   1628                 text = (!(players[0].cheats & CF_FILTER)) ? "LINEAR": "NEAREST";
   1629                 break;
   1630 
   1631             default:
   1632                 text = "NOT IMPLEMENTED";
   1633                 break;
   1634         }
   1635 
   1636         ST_Message(item->x + 130, item->y, text, text_alpha | 0xffffff00);
   1637         item++;
   1638     }
   1639 
   1640     ST_DrawSymbol(MenuItem->x -10, MenuItem[cursorpos].y -1, 78, text_alpha | 0xffffff00);
   1641 }
   1642 
   1643 void M_VolumeDrawer(void) // 800095B4
   1644 {
   1645     menuitem_t *item;
   1646     int i;
   1647 
   1648     ST_DrawString(-1, 20, "Volume", text_alpha | 0xc0000000);
   1649     item = Menu_Volume;
   1650 
   1651     for(i = 0; i < itemlines; i++)
   1652     {
   1653         ST_DrawString(item->x, item->y, MenuText[item->casepos], text_alpha | 0xc0000000);
   1654         item++;
   1655     }
   1656 
   1657     ST_DrawSymbol(MenuItem->x - 37, MenuItem[cursorpos].y - 9, MenuAnimationTic + 70, text_alpha | 0xffffff00);
   1658 
   1659     ST_DrawSymbol(102, 80, 68, text_alpha | 0xffffff00);
   1660     ST_DrawSymbol(MusVolume + 103, 80, 69, text_alpha | 0xffffff00);
   1661 
   1662     ST_DrawSymbol(102, 120, 68, text_alpha | 0xffffff00);
   1663     ST_DrawSymbol(SfxVolume + 103, 120, 69, text_alpha | 0xffffff00);
   1664 }
   1665 
   1666 void M_ControlStickDrawer(void) // 80009738
   1667 {
   1668     menuitem_t *item;
   1669     int i;
   1670 
   1671     ST_DrawString(-1, 20, "Control Stick", text_alpha | 0xc0000000);
   1672 
   1673     item = Menu_ControlStick;
   1674 
   1675     for(i = 0; i < itemlines; i++)
   1676     {
   1677         ST_DrawString(item->x, item->y, MenuText[item->casepos], text_alpha | 0xc0000000);
   1678         item++;
   1679     }
   1680 
   1681     ST_DrawSymbol(MenuItem->x - 37, MenuItem[cursorpos].y - 9, MenuAnimationTic + 70, text_alpha | 0xffffff00);
   1682 
   1683     ST_DrawSymbol(102,110,68,text_alpha | 0xffffff00);
   1684     ST_DrawSymbol(M_SENSITIVITY + 103, 110, 69, text_alpha | 0xffffff00);
   1685 }
   1686 
   1687 void M_DisplayDrawer(void) // 80009884
   1688 {
   1689     char *text;
   1690     menuitem_t *item;
   1691     int i, casepos;
   1692 
   1693     ST_DrawString(-1, 20, "Display", text_alpha | 0xc0000000);
   1694 
   1695     item = Menu_Display;
   1696 
   1697     for(i = 0; i < 6; i++)
   1698     {
   1699         casepos = item->casepos;
   1700 
   1701         if (casepos == 33) // Messages:
   1702         {
   1703             if (enable_messages)
   1704                 text = "On";
   1705             else
   1706                 text = "Off";
   1707         }
   1708         else if (casepos == 34) // Status Bar:
   1709         {
   1710             if (enable_statusbar)
   1711                 text = "On";
   1712             else
   1713                 text = "Off";
   1714         }
   1715         else
   1716         {
   1717             text = NULL;
   1718         }
   1719 
   1720         if (text)
   1721             ST_DrawString(item->x + 140, item->y, text, text_alpha | 0xc0000000);
   1722 
   1723         ST_DrawString(item->x, item->y, MenuText[casepos], text_alpha | 0xc0000000);
   1724 
   1725         item++;
   1726     }
   1727 
   1728     ST_DrawSymbol(102, 80, 68, text_alpha | 0xffffff00);
   1729     ST_DrawSymbol(brightness + 103, 80, 69, text_alpha | 0xffffff00);
   1730 
   1731     ST_DrawSymbol(Menu_Display[0].x - 37, Menu_Display[cursorpos].y - 9, MenuAnimationTic + 70, text_alpha | 0xffffff00);
   1732 }
   1733 
   1734 void M_DrawBackground(int x, int y, int color, char *name) // 80009A68
   1735 {
   1736     int width, height;
   1737     int yh, xh, t;
   1738     int offset;
   1739     byte *data;
   1740 
   1741     data = (byte *)W_CacheLumpName(name, PU_CACHE, dec_jag);
   1742 
   1743     gDPPipeSync(GFX1++);
   1744     gDPSetCycleType(GFX1++, G_CYC_1CYCLE);
   1745 
   1746     gDPSetTextureLUT(GFX1++, G_TT_RGBA16);
   1747     gDPSetTexturePersp(GFX1++, G_TP_NONE);
   1748 
   1749     gDPSetAlphaCompare(GFX1++, G_AC_THRESHOLD);
   1750 
   1751     gDPSetBlendColor(GFX1++, 0, 0, 0, 0);
   1752     gDPSetCombineMode(GFX1++, G_CC_D64COMB03, G_CC_D64COMB03);
   1753 
   1754     if (color == 0xff)
   1755     {
   1756         gDPSetRenderMode(GFX1++, G_RM_TEX_EDGE, G_RM_TEX_EDGE2);
   1757     }
   1758     else
   1759     {
   1760         gDPSetRenderMode(GFX1++, G_RM_XLU_SURF, G_RM_XLU_SURF2);
   1761     }
   1762 
   1763     gDPSetPrimColorD64(GFX1++, 0, 0, color);
   1764 
   1765     width = ((gfxN64_t*)data)->width;
   1766     height = ((gfxN64_t*)data)->height;
   1767 
   1768     // Load Palette Data
   1769     offset = (width * height);
   1770     offset = (offset + 7) & ~7;
   1771     gDPSetTextureImage(GFX1++, G_IM_FMT_RGBA, G_IM_SIZ_16b ,
   1772                         1, data + offset + sizeof(gfxN64_t));
   1773 
   1774     gDPTileSync(GFX1++);
   1775     gDPSetTile(GFX1++, G_IM_FMT_RGBA, G_IM_SIZ_4b, 0, 256, G_TX_LOADTILE, 0, 0, 0, 0, 0, 0, 0);
   1776 
   1777     gDPLoadSync(GFX1++);
   1778     gDPLoadTLUTCmd(GFX1++, G_TX_LOADTILE, 255);
   1779 
   1780     gDPPipeSync(GFX1++);
   1781 
   1782     xh = (width + 7) & ~7;
   1783 
   1784     t = 0;
   1785     while (height != 0)
   1786     {
   1787         if ((2048 / xh) < height)
   1788             yh = (2048 / xh);
   1789         else
   1790             yh = height;
   1791 
   1792         // Load Image Data
   1793         gDPSetTextureImage(GFX1++, G_IM_FMT_CI, G_IM_SIZ_8b ,
   1794                         width, data + sizeof(gfxN64_t));
   1795 
   1796          // Clip Rectangle From Image
   1797         gDPSetTile(GFX1++, G_IM_FMT_CI, G_IM_SIZ_8b,
   1798                         (width + 7) / 8, 0, G_TX_LOADTILE, 0, 0, 0, 0, 0, 0, 0);
   1799 
   1800         gDPLoadSync(GFX1++);
   1801         gDPLoadTile(GFX1++, G_TX_LOADTILE,
   1802                     (0 << 2), (t << 2),
   1803                     ((width - 1) << 2), (((t + yh) - 1) << 2));
   1804 
   1805         gDPPipeSync(GFX1++);
   1806         gDPSetTile(GFX1++, G_IM_FMT_CI, G_IM_SIZ_8b,
   1807                     (width + 7) / 8, 0, G_TX_RENDERTILE, 0, 0, 0, 0, 0, 0, 0);
   1808 
   1809         gDPSetTileSize(GFX1++, G_TX_RENDERTILE,
   1810                        (0 << 2), (t << 2),
   1811                        ((width - 1) << 2), (((t + yh) - 1) << 2));
   1812 
   1813         gSPTextureRectangle(GFX1++,
   1814             (x << 2), (y << 2),
   1815             ((width + x) << 2), ((yh + y) << 2),
   1816             G_TX_RENDERTILE,
   1817             (0 << 5), (t << 5),
   1818             (1 << 10), (1 << 10));
   1819 
   1820         height -= yh;
   1821         t += yh;
   1822         y += yh;
   1823     }
   1824 
   1825     globallump = -1;
   1826 }
   1827 
   1828 void M_DrawOverlay(int x, int y, int w, int h, int color) // 80009F58
   1829 {
   1830     I_CheckGFX();
   1831 
   1832     gDPPipeSync(GFX1++);
   1833 
   1834     gDPSetCycleType(GFX1++, G_CYC_1CYCLE);
   1835 
   1836     gDPSetTextureLUT(GFX1++, G_TT_RGBA16);
   1837     gDPSetTexturePersp(GFX1++, G_TP_NONE);
   1838 
   1839     gDPSetAlphaCompare(GFX1++, G_AC_THRESHOLD);
   1840 
   1841     gDPSetBlendColor(GFX1++, 0, 0, 0, 0);
   1842     gDPSetCombineMode(GFX1++, G_CC_D64COMB05, G_CC_D64COMB05);
   1843     gDPSetRenderMode(GFX1++, G_RM_XLU_SURF, G_RM_XLU_SURF2);
   1844 
   1845     gDPSetPrimColorD64(GFX1++, 0, 0, color);
   1846 
   1847     gDPFillRectangle(GFX1++, x, y, w, h);
   1848     globallump = -1;
   1849 }
   1850 
   1851 int M_ScreenTicker(void) // 8000A0F8
   1852 {
   1853     int exit;
   1854     unsigned int buttons;
   1855     unsigned int oldbuttons;
   1856     OSPfsState *fState;
   1857 
   1858     if ((FilesUsed == -1) && (I_CheckControllerPak() == 0))
   1859     {
   1860         cursorpos = 0;
   1861         linepos = 0;
   1862     }
   1863 
   1864     if ((gamevbls < gametic) && ((gametic & 3) == 0))
   1865         MenuAnimationTic = MenuAnimationTic + 1 & 7;
   1866 
   1867     buttons = M_ButtonResponder(ticbuttons[0]);
   1868     oldbuttons = oldticbuttons[0] & 0xffff0000;
   1869 
   1870     if (!(buttons & ALL_JPAD))
   1871     {
   1872         m_vframe1 = 0;
   1873     }
   1874     else
   1875     {
   1876         m_vframe1 -= vblsinframe[0];
   1877 
   1878         if (m_vframe1 <= 0)
   1879         {
   1880             m_vframe1 = 0xf; // TICRATE/2
   1881 
   1882             if (buttons & PAD_DOWN)
   1883             {
   1884                 cursorpos += 1;
   1885 
   1886                 if (cursorpos < 16)
   1887                     S_StartSound(NULL, sfx_switch1);
   1888                 else
   1889                     cursorpos = 15;
   1890 
   1891                 if ((linepos + 5) < cursorpos)
   1892                     linepos += 1;
   1893             }
   1894             else if (buttons & PAD_UP)
   1895             {
   1896                 cursorpos -= 1;
   1897 
   1898                 if (cursorpos < 0)
   1899                     cursorpos = 0;
   1900                 else
   1901                     S_StartSound(NULL, sfx_switch1);
   1902 
   1903                 if(cursorpos < linepos)
   1904                     linepos -= 1;
   1905             }
   1906         }
   1907     }
   1908 
   1909     if (!(buttons ^ oldbuttons) || !(buttons & PAD_START))
   1910     {
   1911         if (buttons ^ oldbuttons)
   1912         {
   1913             if(buttons == (PAD_LEFT_C|PAD_RIGHT_C))
   1914             {
   1915                 fState = &FileState[cursorpos];
   1916 
   1917                 if(fState->file_size != 0)
   1918                 {
   1919                     S_StartSound(NULL, sfx_pistol);
   1920                     M_SaveMenuData();
   1921 
   1922                     MenuItem = Menu_DeleteNote;
   1923                     itemlines = 2;
   1924                     MenuCall = M_MenuTitleDrawer;
   1925                     cursorpos = 1;
   1926                     MiniLoop(M_FadeInStart, NULL, M_MenuTicker, M_MenuGameDrawer);
   1927 
   1928                     M_FadeOutStart(8);
   1929                     if (cursorpos == 0)
   1930                     {
   1931                         if (I_DeletePakFile(cursorpos) == 0)
   1932                         {
   1933                             fState->file_size = 0;
   1934                         }
   1935                         else
   1936                         {
   1937                             FilesUsed = -1;
   1938                         }
   1939                     }
   1940                     M_RestoreMenuData(true);
   1941                 }
   1942             }
   1943         }
   1944         exit = 0;
   1945     }
   1946     else
   1947     {
   1948         S_StartSound(NULL, sfx_pistol);
   1949         exit = 8;
   1950     }
   1951     return exit;
   1952 }
   1953 
   1954 void M_ControllerPakDrawer(void) // 8000A3E4
   1955 {
   1956     byte idx;
   1957     int i,j;
   1958     OSPfsState *fState;
   1959     char buffer [32];
   1960     char *tmpbuf;
   1961 
   1962     ST_DrawString(-1, 20, "Controller Pak", text_alpha | 0xc0000000);
   1963 
   1964     if (FilesUsed == -1)
   1965     {
   1966         if ((MenuAnimationTic & 2) != 0)
   1967             ST_DrawString(-1, 114, "Controller Pak removed!", text_alpha | 0xc0000000);
   1968 
   1969         ST_DrawString(-1, 210, "press \x8d to exit", text_alpha | 0xffffff00);
   1970     }
   1971     else
   1972     {
   1973         fState = &FileState[linepos];
   1974 
   1975         for(i = linepos; i < (linepos + 6); i++)
   1976         {
   1977             if (fState->file_size == 0)
   1978             {
   1979                 D_memmove(buffer, "empty");
   1980             }
   1981             else
   1982             {
   1983                 tmpbuf = buffer;
   1984 
   1985                 for(j = 0; j < 16; j++)
   1986                 {
   1987                     idx = (byte) fState->game_name[j];
   1988                     if(idx == 0)
   1989                         break;
   1990 
   1991                     tmpbuf[0] = Pak_Table[idx];
   1992                     tmpbuf++;
   1993                 }
   1994 
   1995                 idx = (byte) fState->ext_name[0];
   1996                 if (idx != 0)
   1997                 {
   1998                     tmpbuf[0] = '.';
   1999                     tmpbuf[1] = Pak_Table[idx];
   2000                     tmpbuf += 2;
   2001                 }
   2002 
   2003                 *tmpbuf = '\0';
   2004             }
   2005 
   2006             ST_DrawString(60, (i - linepos) * 15 + 60, buffer, text_alpha | 0xc0000000);
   2007 
   2008             fState++;
   2009         }
   2010 
   2011         if (linepos != 0)
   2012         {
   2013             ST_DrawString(60, 45, "\x8F more...", text_alpha | 0xffffff00);
   2014         }
   2015 
   2016         if ((linepos + 6) < 16)
   2017         {
   2018             ST_DrawString(60, 150, "\x8E more...", text_alpha | 0xffffff00);
   2019         }
   2020 
   2021         sprintf(buffer, "pages used: %d   free: %d", FileState[cursorpos].file_size >> 8, Pak_Memory);
   2022 
   2023         ST_DrawString(-1, 170, buffer, text_alpha | 0xc0000000);
   2024         ST_DrawSymbol(23, (cursorpos - linepos) * 15 + 51, MenuAnimationTic + 70, text_alpha | 0xffffff00);
   2025 
   2026         ST_DrawString(-1, 200, "press \x8d to exit", text_alpha | 0xffffff00);
   2027         ST_DrawString(-1, 215, "press \x84\x85 to delete", text_alpha | 0xffffff00);
   2028     }
   2029 }
   2030 
   2031 void M_SavePakStart(void) // 8000A6E8
   2032 {
   2033     int i;
   2034     int ret;
   2035     int size;
   2036 
   2037     cursorpos = 0;
   2038     linepos = 0;
   2039     last_ticon = 0;
   2040 
   2041     ret = I_CheckControllerPak();
   2042     if (ret == 0)
   2043     {
   2044         if (I_ReadPakFile() == 0)
   2045         {
   2046             size = Pak_Size / 32;
   2047 
   2048             i = 0;
   2049             if (size != 0)
   2050             {
   2051                 do
   2052                 {
   2053                     if (Pak_Data[i * 32] == 0)
   2054                         break;
   2055 
   2056                     i++;
   2057                 } while (i != size);
   2058             }
   2059 
   2060             if (i < size)
   2061             {
   2062                 cursorpos = i;
   2063 
   2064                 if (!(size < (i+6)))
   2065                     linepos = i;
   2066                 else
   2067                     linepos = (size-6);
   2068             }
   2069         }
   2070     }
   2071     else
   2072     {
   2073         FilesUsed = -1;
   2074     }
   2075 }
   2076 
   2077 void M_SavePakStop(void) // 8000A7B4
   2078 {
   2079     S_StartSound(NULL, sfx_pistol);
   2080 
   2081     if (Pak_Data)
   2082     {
   2083         Z_Free(Pak_Data);
   2084         Pak_Data = NULL;
   2085     }
   2086 }
   2087 
   2088 int M_SavePakTicker(void) // 8000A804
   2089 {
   2090     unsigned int buttons;
   2091     unsigned int oldbuttons;
   2092     int size;
   2093 
   2094     if ((gamevbls < gametic) && ((gametic & 3) == 0)) {
   2095         MenuAnimationTic = MenuAnimationTic + 1 & 7;
   2096     }
   2097 
   2098     buttons = M_ButtonResponder(ticbuttons[0]);
   2099     oldbuttons = oldticbuttons[0] & 0xffff0000;
   2100 
   2101     if ((buttons != oldbuttons) && (buttons & PAD_START)) {
   2102         return ga_exit;
   2103     }
   2104 
   2105     if (FilesUsed == -1)
   2106     {
   2107         if (I_CheckControllerPak()) {
   2108             return ga_nothing;
   2109         }
   2110 
   2111         if (I_ReadPakFile()) {
   2112             FilesUsed = -1;
   2113             return ga_nothing;
   2114         }
   2115 
   2116         cursorpos = 0;
   2117         linepos = 0;
   2118     }
   2119 
   2120     if (!(buttons & ALL_JPAD)) {
   2121         m_vframe1 = 0;
   2122     }
   2123     else
   2124     {
   2125         m_vframe1 -= vblsinframe[0];
   2126 
   2127         if (m_vframe1 <= 0)
   2128         {
   2129             m_vframe1 = 0xf; // TICRATE/2
   2130 
   2131             if (buttons & PAD_DOWN)
   2132             {
   2133                 cursorpos += 1;
   2134 
   2135                 size = (Pak_Size / 32) - 1;
   2136 
   2137                 if (size < cursorpos)
   2138                     cursorpos = size;
   2139                 else
   2140                     S_StartSound(NULL, sfx_switch1);
   2141 
   2142 
   2143                 if ((linepos + 5) < cursorpos)
   2144                     linepos += 1;
   2145             }
   2146             else if (buttons & PAD_UP)
   2147             {
   2148                 cursorpos -= 1;
   2149 
   2150                 if (cursorpos < 0)
   2151                     cursorpos = 0;
   2152                 else
   2153                     S_StartSound(NULL, sfx_switch1);
   2154 
   2155                 if(cursorpos < linepos)
   2156                     linepos -= 1;
   2157             }
   2158         }
   2159     }
   2160 
   2161     if (last_ticon == 0)
   2162     {
   2163         if ((buttons != oldbuttons) && (buttons == (PAD_RIGHT_C|PAD_LEFT_C)))
   2164         {
   2165             // save the next level number and password data in text format
   2166             sprintf(&Pak_Data[cursorpos * 32], "level %2.2d", nextmap);
   2167             D_memcpy(&Pak_Data[(cursorpos * 32) + 16], &Passwordbuff, 16);
   2168 
   2169             if (I_SavePakFile(File_Num, PFS_WRITE, Pak_Data, Pak_Size) == 0) {
   2170                 last_ticon = ticon;
   2171             }
   2172             else
   2173             {
   2174                 FilesUsed = -1;
   2175                 if (Pak_Data)
   2176                 {
   2177                     Z_Free(Pak_Data);
   2178                     Pak_Data = NULL;
   2179                 }
   2180             }
   2181         }
   2182     }
   2183     else if ((ticon - last_ticon) >= 60) // 2 * TICRATE
   2184     {
   2185         return ga_exit;
   2186     }
   2187 
   2188     return ga_nothing;
   2189 }
   2190 
   2191 void M_SavePakDrawer(void) // 8000AB44
   2192 {
   2193     int i;
   2194     char buffer[36];
   2195 
   2196     I_ClearFrame();
   2197 
   2198     gDPPipeSync(GFX1++);
   2199     gDPSetCycleType(GFX1++, G_CYC_FILL);
   2200     gDPSetRenderMode(GFX1++,G_RM_NOOP,G_RM_NOOP2);
   2201     gDPSetColorImage(GFX1++, G_IM_FMT_RGBA, G_IM_SIZ_32b, SCREEN_WD, OS_K0_TO_PHYSICAL(cfb[vid_side]));
   2202     // Fill borders with black
   2203     gDPSetFillColor(GFX1++, GPACK_RGBA5551(0,0,0,0) << 16 | GPACK_RGBA5551(0,0,0,0)) ;
   2204     gDPFillRectangle(GFX1++, 0, 0, SCREEN_WD-1, SCREEN_HT-1);
   2205 
   2206     M_DrawBackground(63, 25, 128, "EVIL");
   2207 
   2208     ST_DrawString(-1, 20, "Controller Pak", text_alpha | 0xc0000000);
   2209 
   2210     if (FilesUsed == -1)
   2211     {
   2212         if (MenuAnimationTic & 2)
   2213         {
   2214             ST_DrawString(-1, 100, "Controller Pak removed!", 0xc00000ff);
   2215             ST_DrawString(-1, 120, "Game cannot be saved.", 0xc00000ff);
   2216         }
   2217 
   2218         ST_DrawString(-1, 210, "press \x8d to exit", text_alpha | 0xffffff00);
   2219     }
   2220     else
   2221     {
   2222         for(i = linepos; i < (linepos + 6); i++)
   2223         {
   2224             if (Pak_Data[i * 32] == 0) {
   2225                 D_memmove(buffer, "empty");
   2226             }
   2227             else {
   2228                 D_memmove(buffer, &Pak_Data[i * 32]);
   2229             }
   2230 
   2231             ST_DrawString(60, (i - linepos) * 15 + 65, buffer, text_alpha | 0xc0000000);
   2232         }
   2233 
   2234         if (linepos != 0) {
   2235             ST_DrawString(60, 50, "\x8f more...", text_alpha | 0xffffff00);
   2236         }
   2237 
   2238         if ((linepos + 6) <= ((Pak_Size >> 5) - 1)) {
   2239             ST_DrawString(60, 155, "\x8e more...", text_alpha | 0xffffff00);
   2240         }
   2241 
   2242         ST_DrawSymbol(23, (cursorpos - linepos) * 15 + 56, MenuAnimationTic + 70, text_alpha | 0xffffff00);
   2243 
   2244         ST_DrawString(-1, 195, "press \x8d to exit", text_alpha | 0xffffff00);
   2245         ST_DrawString(-1, 210, "press \x84\x85 to save", text_alpha | 0xffffff00);
   2246     }
   2247 
   2248     I_DrawFrame();
   2249 }
   2250 
   2251 void M_LoadPakStart(void) // 8000AEEC
   2252 {
   2253     int i;
   2254     int size;
   2255 
   2256     cursorpos = 0;
   2257     linepos = 0;
   2258 
   2259     size = Pak_Size / 32;
   2260 
   2261     i = 0;
   2262     if (size != 0)
   2263     {
   2264         do
   2265         {
   2266             if (Pak_Data[i * 32])
   2267                 break;
   2268 
   2269             i++;
   2270         } while (i != size);
   2271     }
   2272 
   2273     if (i < size)
   2274     {
   2275         cursorpos = i;
   2276 
   2277         if (!(size < (i+6)))
   2278             linepos = i;
   2279         else
   2280             linepos = (size-6);
   2281     }
   2282 
   2283     M_FadeInStart();
   2284 }
   2285 
   2286 void M_LoadPakStop(void) // 8000AF8C
   2287 {
   2288     S_StartSound(NULL, sfx_pistol);
   2289     M_FadeOutStart(ga_exit);
   2290 
   2291     if (Pak_Data)
   2292     {
   2293         Z_Free(Pak_Data);
   2294         Pak_Data = NULL;
   2295     }
   2296 }
   2297 
   2298 int M_LoadPakTicker(void) // 8000AFE4
   2299 {
   2300     unsigned int buttons;
   2301     unsigned int oldbuttons;
   2302     int size;
   2303     int skill;
   2304     int levelnum;
   2305     int exit;
   2306 
   2307     if ((gamevbls < gametic) && ((gametic & 3U) == 0)) {
   2308         MenuAnimationTic = MenuAnimationTic + 1 & 7;
   2309     }
   2310 
   2311     buttons = M_ButtonResponder(ticbuttons[0]);
   2312     oldbuttons = oldticbuttons[0] & 0xffff0000;
   2313 
   2314     if (!(buttons & ALL_JPAD))
   2315     {
   2316         m_vframe1 = 0;
   2317     }
   2318     else
   2319     {
   2320         m_vframe1 -= vblsinframe[0];
   2321 
   2322         if (m_vframe1 <= 0)
   2323         {
   2324             m_vframe1 = 0xf; // TICRATE/2
   2325 
   2326             if (buttons & PAD_DOWN)
   2327             {
   2328                 cursorpos += 1;
   2329 
   2330                 size = (Pak_Size / 32) - 1;
   2331 
   2332                 if (size < cursorpos)
   2333                     cursorpos = size;
   2334                 else
   2335                     S_StartSound(NULL, sfx_switch1);
   2336 
   2337                 if ((linepos + 5) < cursorpos)
   2338                     linepos += 1;
   2339 
   2340             }
   2341             else if (buttons & PAD_UP)
   2342             {
   2343                 cursorpos -= 1;
   2344 
   2345                 if (cursorpos < 0)
   2346                     cursorpos = 0;
   2347                 else
   2348                     S_StartSound(NULL, sfx_switch1);
   2349 
   2350                 if(cursorpos < linepos)
   2351                     linepos -= 1;
   2352             }
   2353         }
   2354     }
   2355 
   2356     if (!(buttons ^ oldbuttons) || !(buttons & PAD_START))
   2357     {
   2358         if (!(buttons ^ oldbuttons) || buttons != (PAD_RIGHT_C|PAD_LEFT_C) ||
   2359             (Pak_Data[cursorpos * 32] == 0))
   2360         {
   2361             exit = ga_nothing;
   2362         }
   2363         else
   2364         {
   2365             // load the password data in text format
   2366             D_memcpy(&Passwordbuff, &Pak_Data[((cursorpos * 32) + 16)], 16);
   2367 
   2368             if (M_DecodePassword(Passwordbuff, &levelnum, &skill, 0) == 0)
   2369             {
   2370                 CurPasswordSlot = 0;
   2371                 exit = ga_exit;
   2372             }
   2373             else
   2374             {
   2375                 doPassword = true;
   2376                 CurPasswordSlot = 16;
   2377 
   2378                 startmap = gamemap = levelnum;
   2379                 startskill = gameskill = skill;
   2380 
   2381                 exit = ga_warped;
   2382             }
   2383         }
   2384     }
   2385     else
   2386     {
   2387         exit = ga_exit;
   2388     }
   2389 
   2390     return exit;
   2391 }
   2392 
   2393 void M_LoadPakDrawer(void) // 8000B270
   2394 {
   2395     int i;
   2396     char buffer[32];
   2397 
   2398     ST_DrawString(-1, 20, "Controller Pak", text_alpha | 0xc0000000);
   2399 
   2400     for(i = linepos; i < (linepos + 6); i++)
   2401     {
   2402         if (FilesUsed == -1) {
   2403             D_memmove(buffer, "-");
   2404         }
   2405         else if (Pak_Data[i * 32] == 0) {
   2406             D_memmove(buffer, "no save");
   2407         }
   2408         else {
   2409             D_memmove(buffer, &Pak_Data[i * 32]);
   2410         }
   2411 
   2412         ST_DrawString(60, (i - linepos) * 15 + 65, buffer, text_alpha | 0xc0000000);
   2413     }
   2414 
   2415     if (linepos != 0) {
   2416         ST_DrawString(60, 50, "\x8f more...", text_alpha | 0xffffff00);
   2417     }
   2418 
   2419     if ((linepos + 6) <= ((Pak_Size >> 5) - 1)) {
   2420         ST_DrawString(60, 155, "\x8e more...", text_alpha | 0xffffff00);
   2421     }
   2422 
   2423     ST_DrawSymbol(23, (cursorpos - linepos) * 15 + 56, MenuAnimationTic + 70, text_alpha | 0xffffff00);
   2424 
   2425     ST_DrawString(-1, 195, "press \x8D to exit", text_alpha | 0xffffff00);
   2426     ST_DrawString(-1, 210, "press \x84\x85 to load", text_alpha | 0xffffff00);
   2427 }
   2428 
   2429 int M_CenterDisplayTicker(void) // 8000B4C4
   2430 {
   2431     unsigned int buttons, oldbuttons;
   2432     int exit;
   2433 
   2434     buttons = M_ButtonResponder(ticbuttons[0]);
   2435     oldbuttons = oldticbuttons[0] & 0xffff0000;
   2436 
   2437     if ((buttons == oldbuttons) || !(buttons & PAD_START))
   2438     {
   2439         if (buttons & PAD_LEFT)
   2440         {
   2441             Display_X -= 1;
   2442             if (Display_X < -16)
   2443                 Display_X = -16;
   2444         }
   2445         else if (buttons & PAD_RIGHT)
   2446         {
   2447             Display_X += 1;
   2448             if (Display_X > 24)
   2449                 Display_X = 24;
   2450         }
   2451 
   2452         if (buttons & PAD_UP)
   2453         {
   2454             Display_Y -= 1;
   2455             if (Display_Y < -20)
   2456                 Display_Y = -20;
   2457         }
   2458         else if (buttons & PAD_DOWN)
   2459         {
   2460             Display_Y += 1;
   2461             if (Display_Y > 12)
   2462                 Display_Y = 12;
   2463         }
   2464 
   2465         if (buttons & ALL_JPAD)
   2466             I_MoveDisplay(Display_X, Display_Y);
   2467 
   2468         exit = 0;
   2469     }
   2470     else
   2471     {
   2472         S_StartSound(NULL, sfx_pistol);
   2473         exit = 8;
   2474     }
   2475 
   2476     return exit;
   2477 }
   2478 
   2479 void M_CenterDisplayDrawer(void) // 8000B604
   2480 {
   2481     ST_DrawString(-1, 20, "Center Display", text_alpha | 0xc0000000);
   2482     ST_DrawString(-1, 114, "use control pad to adjust", text_alpha | 0xffffff00);
   2483     ST_DrawString(-1, 210, "press \x8d to exit", text_alpha | 0xffffff00);
   2484 }
   2485 
   2486 int M_ControlPadTicker(void) // 8000B694
   2487 {
   2488     unsigned int buttons;
   2489     unsigned int oldbuttons;
   2490     int exit;
   2491     int *tmpcfg, code;
   2492 
   2493     if ((gamevbls < gametic) && ((gametic & 3U) == 0)) {
   2494         MenuAnimationTic = MenuAnimationTic + 1 & 7;
   2495     }
   2496 
   2497     buttons = M_ButtonResponder(ticbuttons[0] & 0xffff);
   2498 
   2499     if (!(buttons & ALL_JPAD))
   2500     {
   2501         m_vframe1 = 0;
   2502     }
   2503     else
   2504     {
   2505         m_vframe1 = m_vframe1 - vblsinframe[0];
   2506         if (m_vframe1 <= 0)
   2507         {
   2508             m_vframe1 = 0xf; // TICRATE / 2
   2509 
   2510             if (buttons & PAD_DOWN)
   2511             {
   2512                 cursorpos += 1;
   2513                 if (cursorpos < 14)
   2514                     S_StartSound(NULL, sfx_switch1);
   2515                 else
   2516                     cursorpos = 13;
   2517 
   2518                 if (cursorpos > (linepos + 5))
   2519                     linepos += 1;
   2520             }
   2521             else
   2522             {
   2523                 if (buttons & PAD_UP)
   2524                 {
   2525                     cursorpos -= 1;
   2526                     if (cursorpos < 0)
   2527                         cursorpos = 0;
   2528                     else
   2529                         S_StartSound(NULL, sfx_switch1);
   2530 
   2531                     if (cursorpos < linepos)
   2532                         linepos -= 1;
   2533                 }
   2534             }
   2535         }
   2536     }
   2537 
   2538     buttons = ticbuttons[0] & 0xffff0000;
   2539     oldbuttons = oldticbuttons[0] & 0xffff0000;
   2540 
   2541     if (buttons & PAD_START)
   2542     {
   2543         S_StartSound(NULL, sfx_pistol);
   2544         exit = 8;
   2545     }
   2546     else
   2547     {
   2548         if (buttons == oldbuttons)
   2549             exit = 0;
   2550         else
   2551         {
   2552             tmpcfg = TempConfiguration;
   2553 
   2554             if (cursorpos == 0) // Set Default Configuration
   2555             {
   2556                 if (!(buttons & (PAD_UP|PAD_LEFT)))
   2557                 {
   2558                     if (buttons & (PAD_DOWN|PAD_RIGHT))
   2559                     {
   2560                         ConfgNumb += 1;
   2561                         if(ConfgNumb > 4)
   2562                             ConfgNumb = 0;
   2563                     }
   2564                 }
   2565                 else
   2566                 {
   2567                     ConfgNumb -= 1;
   2568                     if (ConfgNumb < 0)
   2569                         ConfgNumb = 4;
   2570                 }
   2571 
   2572                 if ((buttons & (ALL_BUTTONS|ALL_JPAD)) != 0)
   2573                 {
   2574                     D_memcpy(ActualConfiguration, DefaultConfiguration[ConfgNumb], (13 * sizeof(int)));
   2575                     S_StartSound(NULL, sfx_switch2);
   2576                     return 0;
   2577                 }
   2578             }
   2579             else // Set Custom Configuration
   2580             {
   2581                 do
   2582                 {
   2583                     code = *tmpcfg++;
   2584                     if ((code & buttons) != 0)
   2585                     {
   2586                         TempConfiguration[cursorpos + 12] = code;
   2587                         S_StartSound(NULL,sfx_switch2);
   2588                         return 0;
   2589                     }
   2590                 } while (tmpcfg != (int*)(TempConfiguration+13));
   2591             }
   2592             exit = 0;
   2593         }
   2594     }
   2595     return exit;
   2596 }
   2597 
   2598 void M_ControlPadDrawer(void) // 8000B988
   2599 {
   2600     int i, lpos;
   2601     int *tmpcfg;
   2602     char **text;
   2603     char buffer [44];
   2604 
   2605     ST_DrawString(-1, 20, "Control Pad", text_alpha | 0xc0000000);
   2606 
   2607     if (linepos < (linepos + 6))
   2608     {
   2609         text = &ControlText[linepos];
   2610         lpos = linepos;
   2611         do
   2612         {
   2613             if (lpos != 0)
   2614             {
   2615                 i = 0;
   2616                 if(lpos != cursorpos || ((ticon & 8U) == 0))
   2617                 {
   2618                     tmpcfg = TempConfiguration;
   2619                     do
   2620                     {
   2621                         if ((*tmpcfg & TempConfiguration[lpos + 12]) != 0) break;
   2622 
   2623                         i += 1;
   2624                         tmpcfg++;
   2625                     } while (i != 13);
   2626 
   2627                     ST_DrawSymbol(60, ((lpos - linepos) * 18) + 68, i + 80, text_alpha | 0xffffff00);
   2628                 }
   2629             }
   2630 
   2631             sprintf(buffer, *text, ConfgNumb + 1);
   2632             ST_DrawString(80, ((lpos - linepos) * 18) + 68, buffer, text_alpha | 0xc0000000);
   2633 
   2634             lpos += 1;
   2635             text += 1;
   2636         } while (lpos < (linepos + 6));
   2637     }
   2638 
   2639     if (linepos != 0) {
   2640         ST_DrawString(80, 50, "\x8f more...", text_alpha | 0xffffff00);
   2641     }
   2642 
   2643     if ((linepos + 6) < 14) {
   2644         ST_DrawString(80, 176, "\x8e more...", text_alpha | 0xffffff00);
   2645     }
   2646 
   2647     ST_DrawSymbol(23,(cursorpos - linepos) * 0x12 + 0x3b, MenuAnimationTic + 0x46, text_alpha | 0xffffff00);
   2648 
   2649     ST_DrawString(-1, 210, "press \x8d to exit", text_alpha | 0xffffff00);
   2650 }