Subversion Repositories Games.Carmageddon

Rev

Rev 18 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include "mainmenu.h"
  2. #include "brender/brender.h"
  3. #include "controls.h"
  4. #include "flicplay.h"
  5. #include "globvars.h"
  6. #include "globvrpb.h"
  7. #include "grafdata.h"
  8. #include "graphics.h"
  9. #include "harness/config.h"
  10. #include "harness/trace.h"
  11. #include "intrface.h"
  12. #include "loading.h"
  13. #include "loadsave.h"
  14. #include "network.h"
  15. #include "newgame.h"
  16. #include "options.h"
  17. #include "pd/sys.h"
  18. #include "sound.h"
  19. #include "structur.h"
  20. #include "utility.h"
  21. #include <stdlib.h>
  22.  
  23. char* gPalette_copy__mainmenu;    // suffix added to avoid duplicate symbol
  24. int gPixel_buffer_size__mainmenu; // suffix added to avoid duplicate symbol
  25. tInterface_spec* gMain_menu_spec;
  26. int gMouse_was_started__mainmenu; // suffix added to avoid duplicate symbol
  27. int gReplace_background;
  28. char* gPixels_copy__mainmenu; // suffix added to avoid duplicate symbol
  29.  
  30. // IDA: int __usercall MainMenuDone1@<EAX>(int pCurrent_choice@<EAX>, int pCurrent_mode@<EDX>, int pGo_ahead@<EBX>, int pEscaped@<ECX>, int pTimed_out)
  31. int MainMenuDone1(int pCurrent_choice, int pCurrent_mode, int pGo_ahead, int pEscaped, int pTimed_out) {
  32.     LOG_TRACE("(%d, %d, %d, %d, %d)", pCurrent_choice, pCurrent_mode, pGo_ahead, pEscaped, pTimed_out);
  33.  
  34.     if (harness_game_info.mode == eGame_carmageddon_demo || harness_game_info.mode == eGame_splatpack_demo || harness_game_info.mode == eGame_splatpack_xmas_demo) {
  35.         if (pCurrent_mode == 0) {
  36.             if (pCurrent_choice == 7) {
  37.                 PreloadBunchOfFlics(7);
  38.             }
  39.         } else {
  40.             return -1;
  41.         }
  42.         return pCurrent_choice;
  43.     }
  44.  
  45.     if (pTimed_out) {
  46.         return -1;
  47.     }
  48.     switch (pCurrent_choice) {
  49.     case 1:
  50.         PreloadBunchOfFlics(4);
  51.         break;
  52.     case 2:
  53.         PreloadBunchOfFlics(5);
  54.         break;
  55.     case 3:
  56.         PreloadBunchOfFlics(1);
  57.         break;
  58.     case 4:
  59.         PreloadBunchOfFlics(3);
  60.         break;
  61.     case 5:
  62.         PreloadBunchOfFlics(2);
  63.         break;
  64.     case 7:
  65.         PreloadBunchOfFlics(7);
  66.         break;
  67.     default:
  68.         return pCurrent_choice;
  69.     }
  70.     return pCurrent_choice;
  71. }
  72.  
  73. // IDA: int __usercall MainMenuDone2@<EAX>(int pCurrent_choice@<EAX>, int pCurrent_mode@<EDX>, int pGo_ahead@<EBX>, int pEscaped@<ECX>, int pTimed_out)
  74. int MainMenuDone2(int pCurrent_choice, int pCurrent_mode, int pGo_ahead, int pEscaped, int pTimed_out) {
  75.     LOG_TRACE("(%d, %d, %d, %d, %d)", pCurrent_choice, pCurrent_mode, pGo_ahead, pEscaped, pTimed_out);
  76.  
  77.     if (harness_game_info.mode == eGame_carmageddon_demo || harness_game_info.mode == eGame_splatpack_demo || harness_game_info.mode == eGame_splatpack_xmas_demo) {
  78.         if (pCurrent_mode == 0) {
  79.             if (pCurrent_choice == 4) {
  80.                 PreloadBunchOfFlics(7);
  81.             }
  82.         } else {
  83.             return -1;
  84.         }
  85.         return pCurrent_choice;
  86.     }
  87.  
  88.     if (pTimed_out) {
  89.         return -1;
  90.     }
  91.     switch (pCurrent_choice) {
  92.     case 0:
  93.         PreloadBunchOfFlics(4);
  94.         break;
  95.     case 1:
  96.         PreloadBunchOfFlics(5);
  97.         break;
  98.     case 2:
  99.         PreloadBunchOfFlics(1);
  100.         break;
  101.     case 3:
  102.         PreloadBunchOfFlics(3);
  103.         break;
  104.     case 4:
  105.         PreloadBunchOfFlics(7);
  106.         break;
  107.     }
  108.     return pCurrent_choice;
  109. }
  110.  
  111. // IDA: void __cdecl StartMainMenu()
  112. void StartMainMenu(void) {
  113.     LOG_TRACE("()");
  114.  
  115.     if (gFaded_palette) {
  116.         PlayFlicsInDarkness();
  117.         RunFlic(10);
  118.     } else {
  119.         RunFlic(11);
  120.     }
  121.     DontLetFlicFuckWithPalettes();
  122.     TurnFlicTransparencyOn();
  123.     if (!gProgram_state.racing) {
  124.         DisableChoice(1);
  125.         RunFlicAt(
  126.             35,
  127.             gMain_menu_spec->flicker_on_flics[1].x[gGraf_data_index],
  128.             gMain_menu_spec->flicker_on_flics[1].y[gGraf_data_index]);
  129.     }
  130.     if (gDisallow_abandon_race) {
  131.         DisableChoice(2);
  132.         RunFlicAt(
  133.             36,
  134.             gMain_menu_spec->flicker_on_flics[2].x[gGraf_data_index],
  135.             gMain_menu_spec->flicker_on_flics[2].y[gGraf_data_index]);
  136.     }
  137.     TurnFlicTransparencyOff();
  138.     LetFlicFuckWithPalettes();
  139.     ReilluminateFlics();
  140. }
  141.  
  142. // IDA: int __usercall DoMainMenuInterface@<EAX>(tU32 pTime_out@<EAX>, int pContinue_allowed@<EDX>)
  143. int DoMainMenuInterface(tU32 pTime_out, int pContinue_allowed) {
  144.     static tFlicette flicker_on1[8] = {
  145.         { 14, { 64, 128 }, { 37, 89 } },
  146.         { 25, { 59, 118 }, { 54, 130 } },
  147.         { 27, { 55, 110 }, { 71, 170 } },
  148.         { 29, { 52, 104 }, { 88, 211 } },
  149.         { 23, { 53, 106 }, { 105, 252 } },
  150.         { 21, { 54, 108 }, { 122, 293 } },
  151.         { 17, { 58, 116 }, { 139, 334 } },
  152.         { 19, { 64, 128 }, { 155, 372 } }
  153.     };
  154.     static tFlicette flicker_off1[8] = {
  155.         { 13, { 64, 128 }, { 37, 89 } },
  156.         { 24, { 59, 118 }, { 54, 130 } },
  157.         { 26, { 55, 110 }, { 71, 170 } },
  158.         { 28, { 52, 104 }, { 88, 211 } },
  159.         { 22, { 53, 106 }, { 105, 252 } },
  160.         { 20, { 54, 108 }, { 122, 293 } },
  161.         { 16, { 58, 116 }, { 139, 334 } },
  162.         { 18, { 64, 128 }, { 155, 372 } }
  163.     };
  164.  
  165.     static tFlicette push1[8] = {
  166.         { 15, { 63, 126 }, { 36, 86 } },
  167.         { 15, { 58, 116 }, { 53, 127 } },
  168.         { 15, { 54, 108 }, { 70, 168 } },
  169.         { 15, { 51, 102 }, { 87, 209 } },
  170.         { 15, { 52, 104 }, { 104, 250 } },
  171.         { 15, { 53, 106 }, { 121, 290 } },
  172.         { 15, { 57, 114 }, { 138, 331 } },
  173.         { 15, { 63, 126 }, { 154, 370 } }
  174.     };
  175.  
  176.     static tMouse_area mouse_areas1[8] = {
  177.         { { 64, 128 }, { 37, 89 }, { 265, 530 }, { 47, 113 }, 0, 0, 0, NULL },
  178.         { { 59, 118 }, { 54, 130 }, { 265, 530 }, { 64, 154 }, 1, 0, 0, NULL },
  179.         { { 55, 110 }, { 71, 170 }, { 265, 530 }, { 81, 194 }, 2, 0, 0, NULL },
  180.         { { 52, 104 }, { 88, 211 }, { 265, 530 }, { 98, 235 }, 3, 0, 0, NULL },
  181.         { { 53, 106 }, { 105, 252 }, { 265, 530 }, { 115, 276 }, 4, 0, 0, NULL },
  182.         { { 54, 108 }, { 122, 293 }, { 265, 530 }, { 132, 317 }, 5, 0, 0, NULL },
  183.         { { 58, 116 }, { 139, 334 }, { 265, 530 }, { 149, 358 }, 6, 0, 0, NULL },
  184.         { { 64, 128 }, { 155, 372 }, { 265, 530 }, { 165, 396 }, 7, 0, 0, NULL }
  185.     };
  186.     static tInterface_spec interface_spec1 = {
  187.         0,                      // initial_imode
  188.         0,                      // first_opening_flic
  189.         0,                      // second_opening_flic
  190.         0,                      // end_flic_go_ahead
  191.         0,                      // end_flic_escaped
  192.         0,                      // end_flic_otherwise
  193.         0,                      // flic_bunch_to_load
  194.         { -1, 0 },              // move_left_new_mode
  195.         { 0, 0 },               // move_left_delta
  196.         { 0, 0 },               // move_left_min
  197.         { 0, 0 },               // move_left_max
  198.         { NULL, NULL },         // move_left_proc
  199.         { -1, 0 },              // move_right_new_mode
  200.         { 0, 0 },               // move_right_delta
  201.         { 0, 0 },               // move_right_min
  202.         { 0, 0 },               // move_right_max
  203.         { NULL, NULL },         // move_right_proc
  204.         { -1, 0 },              // move_up_new_mode
  205.         { -1, 0 },              // move_up_delta
  206.         { 0, 0 },               // move_up_min
  207.         { 7, 0 },               // move_up_max
  208.         { NULL, NULL },         // move_up_proc
  209.         { -1, 0 },              // move_down_new_mode
  210.         { 1, 0 },               // move_down_delta
  211.         { 0, 0 },               // move_down_min
  212.         { 7, 0 },               // move_down_max
  213.         { NULL, NULL },         // move_down_proc
  214.         { 1, 1 },               // go_ahead_allowed
  215.         { NULL, NULL },         // go_ahead_proc
  216.         { 1, 1 },               // escape_allowed
  217.         { NULL, NULL },         // escape_proc
  218.         NULL,                   // exit_proc
  219.         NULL,                   // draw_proc
  220.         0u,                     // time_out
  221.         StartMainMenu,          // start_proc1
  222.         NULL,                   // start_proc2
  223.         MainMenuDone1,          // done_proc
  224.         0,                      // font_needed
  225.         { 0, 0 },               // typeable
  226.         NULL,                   // get_original_string
  227.         0,                      // escape_code
  228.         0,                      // dont_save_or_load
  229.         COUNT_OF(flicker_on1),  // number_of_button_flics
  230.         flicker_on1,            // flicker_on_flics
  231.         flicker_off1,           // flicker_off_flics
  232.         push1,                  // pushed_flics
  233.         COUNT_OF(mouse_areas1), // number_of_mouse_areas
  234.         mouse_areas1,           // mouse_areas
  235.         0,                      // number_of_recopy_areas
  236.         NULL                    // recopy_areas
  237.     };
  238.  
  239.     static tFlicette flicker_on2[5] = {
  240.         { 335, { 58, 116 }, { 51, 122 } },
  241.         { 337, { 53, 106 }, { 74, 178 } },
  242.         { 339, { 51, 102 }, { 96, 230 } },
  243.         { 333, { 52, 104 }, { 119, 286 } },
  244.         { 331, { 58, 116 }, { 142, 341 } }
  245.     };
  246.     static tFlicette flicker_off2[5] = {
  247.         { 334, { 58, 116 }, { 51, 122 } },
  248.         { 336, { 53, 106 }, { 74, 178 } },
  249.         { 338, { 51, 102 }, { 96, 230 } },
  250.         { 332, { 52, 104 }, { 119, 286 } },
  251.         { 330, { 58, 116 }, { 142, 341 } }
  252.     };
  253.     static tFlicette push2[5] = {
  254.         { 15, { 56, 112 }, { 50, 120 } },
  255.         { 15, { 51, 102 }, { 73, 175 } },
  256.         { 15, { 50, 100 }, { 95, 228 } },
  257.         { 15, { 51, 102 }, { 118, 283 } },
  258.         { 15, { 57, 114 }, { 141, 338 } }
  259.     };
  260.     static tMouse_area mouse_areas2[5] = {
  261.         { { 57, 114 }, { 51, 122 }, { 265, 530 }, { 61, 146 }, 0, 0, 0, NULL },
  262.         { { 52, 104 }, { 74, 178 }, { 265, 530 }, { 84, 202 }, 1, 0, 0, NULL },
  263.         { { 51, 102 }, { 96, 230 }, { 265, 530 }, { 106, 254 }, 2, 0, 0, NULL },
  264.         { { 52, 104 }, { 119, 286 }, { 265, 530 }, { 129, 310 }, 3, 0, 0, NULL },
  265.         { { 58, 116 }, { 142, 341 }, { 265, 530 }, { 152, 365 }, 4, 0, 0, NULL }
  266.     };
  267.     static tInterface_spec interface_spec2 = {
  268.         0,                      // initial_imode
  269.         31,                     // first_opening_flic
  270.         30,                     // second_opening_flic
  271.         0,                      // end_flic_go_ahead
  272.         0,                      // end_flic_escaped
  273.         0,                      // end_flic_otherwise
  274.         0,                      // flic_bunch_to_load
  275.         { -1, 0 },              // move_left_new_mode
  276.         { 0, 0 },               // move_left_delta
  277.         { 0, 0 },               // move_left_min
  278.         { 0, 0 },               // move_left_max
  279.         { NULL, NULL },         // move_left_proc
  280.         { -1, 0 },              // move_right_new_mode
  281.         { 0, 0 },               // move_right_delta
  282.         { 0, 0 },               // move_right_min
  283.         { 0, 0 },               // move_right_max
  284.         { NULL, NULL },         // move_right_proc
  285.         { -1, 0 },              // move_up_new_mode
  286.         { -1, 0 },              // move_up_delta
  287.         { 0, 0 },               // move_up_min
  288.         { 4, 0 },               // move_up_max
  289.         { NULL, NULL },         // move_up_proc
  290.         { -1, 0 },              // move_down_new_mode
  291.         { 1, 0 },               // move_down_delta
  292.         { 0, 0 },               // move_down_min
  293.         { 4, 0 },               // move_down_max
  294.         { NULL, NULL },         // move_down_proc
  295.         { 1, 1 },               // go_ahead_allowed
  296.         { NULL, NULL },         // go_ahead_proc
  297.         { 1, 1 },               // escape_allowed
  298.         { NULL, NULL },         // escape_proc
  299.         NULL,                   // exit_proc
  300.         NULL,                   // draw_proc
  301.         0u,                     // time_out
  302.         NULL,                   // start_proc1
  303.         NULL,                   // start_proc2
  304.         &MainMenuDone2,         // done_proc
  305.         0,                      // font_needed
  306.         { 0, 0 },               // typeable
  307.         NULL,                   // get_original_string
  308.         4,                      // escape_code
  309.         0,                      // dont_save_or_load
  310.         COUNT_OF(flicker_on2),  // number_of_button_flics
  311.         flicker_on2,            // flicker_on_flics
  312.         flicker_off2,           // flicker_off_flics
  313.         push2,                  // pushed_flics
  314.         COUNT_OF(mouse_areas2), // number_of_mouse_areas
  315.         mouse_areas2,           // mouse_areas
  316.         0,                      // number_of_recopy_areas
  317.         NULL                    // recopy_areas
  318.     };
  319.  
  320.     int result;
  321.     LOG_TRACE("(%d, %d)", pTime_out, pContinue_allowed);
  322.  
  323.     if (pContinue_allowed) {
  324.         gMain_menu_spec = &interface_spec1;
  325.         result = DoInterfaceScreen(&interface_spec1, gFaded_palette | 2, 0);
  326.         if (result == 0 || result == 1 || result == 2 || result == 7) {
  327.             FadePaletteDown();
  328.         } else {
  329.             RunFlic(12);
  330.         }
  331.         switch (result) {
  332.         case 0:
  333.             return 0;
  334.         case 1:
  335.             return 8;
  336.         case 2:
  337.             return 9;
  338.         case 3:
  339.             return 6;
  340.         case 4:
  341.             return 3;
  342.         case 5:
  343.             return 2;
  344.         case 6:
  345.             return 1;
  346.         case 7:
  347.             return 7;
  348.         default:
  349.             break;
  350.         }
  351.         result = -1;
  352.     } else {
  353.         interface_spec2.time_out = pTime_out;
  354.         result = DoInterfaceScreen(&interface_spec2, gFaded_palette, 0);
  355.         if (result == -1 || result == 4) {
  356.             FadePaletteDown();
  357.         } else {
  358.             RunFlic(32);
  359.         }
  360.         switch (result) {
  361.         case 0:
  362.             result = 4;
  363.             break;
  364.         case 1:
  365.             result = 5;
  366.             break;
  367.         case 2:
  368.             result = 6;
  369.             break;
  370.         case 3:
  371.             result = 3;
  372.             break;
  373.         case 4:
  374.             result = 7;
  375.             break;
  376.         default:
  377.             result = -1;
  378.             break;
  379.         }
  380.     }
  381.     return result;
  382. }
  383.  
  384. // IDA: tMM_result __usercall GetMainMenuOption@<EAX>(tU32 pTime_out@<EAX>, int pContinue_allowed@<EDX>)
  385. tMM_result GetMainMenuOption(tU32 pTime_out, int pContinue_allowed) {
  386.     int result;
  387.  
  388.     result = DoMainMenuInterface(pTime_out, pContinue_allowed);
  389.     if (result < 0) {
  390.         return eMM_timeout;
  391.     }
  392.     if (gProgram_state.prog_status == eProg_game_starting) {
  393.         return eMM_continue;
  394.     }
  395.     switch (result) {
  396.     case 1:
  397.         return eMM_end_game;
  398.     case 2:
  399.         return eMM_save;
  400.     case 3:
  401.         return eMM_loaded;
  402.     case 4:
  403.         return eMM_1_start;
  404.     case 5:
  405.         return eMM_n_start;
  406.     case 6:
  407.         return eMM_options;
  408.     case 7:
  409.         return eMM_quit;
  410.     case 8:
  411.         return eMM_recover;
  412.     case 9:
  413.         return eMM_abort_race;
  414.     default:
  415.         return eMM_continue;
  416.     }
  417. }
  418.  
  419. // IDA: void __cdecl QuitVerifyStart()
  420. void QuitVerifyStart(void) {
  421.     gPixel_buffer_size__mainmenu = gBack_screen->height * gBack_screen->row_bytes;
  422.     gPixels_copy__mainmenu = BrMemAllocate(gPixel_buffer_size__mainmenu, kMem_quit_vfy_pixels);
  423.     gPalette_copy__mainmenu = BrMemAllocate(0x400u, kMem_quit_vfy_pal);
  424.     memcpy(gPixels_copy__mainmenu, gBack_screen->pixels, gPixel_buffer_size__mainmenu);
  425.     memcpy(gPalette_copy__mainmenu, gCurrent_palette_pixels, 0x400u);
  426.     FadePaletteDown();
  427. }
  428.  
  429. // IDA: int __usercall QuitVerifyDone@<EAX>(int pCurrent_choice@<EAX>, int pCurrent_mode@<EDX>, int pGo_ahead@<EBX>, int pEscaped@<ECX>, int pTimed_out)
  430. int QuitVerifyDone(int pCurrent_choice, int pCurrent_mode, int pGo_ahead, int pEscaped, int pTimed_out) {
  431.     FadePaletteDown();
  432.     TurnOnPanelFlics();
  433.     if (gMouse_was_started__mainmenu) {
  434.         RemoveTransientBitmaps(1);
  435.     }
  436.     if (gReplace_background) {
  437.         if (pCurrent_choice) {
  438.             memcpy(gBack_screen->pixels, gPixels_copy__mainmenu, gPixel_buffer_size__mainmenu);
  439.             memcpy(gCurrent_palette_pixels, gPalette_copy__mainmenu, 0x400u);
  440.         } else {
  441.             ClearEntireScreen();
  442.         }
  443.         PDScreenBufferSwap(0);
  444.         FadePaletteUp();
  445.     }
  446.     BrMemFree(gPixels_copy__mainmenu);
  447.     BrMemFree(gPalette_copy__mainmenu);
  448.     return pCurrent_choice == 0;
  449. }
  450.  
  451. // IDA: int __usercall DoVerifyQuit@<EAX>(int pReplace_background@<EAX>)
  452. int DoVerifyQuit(int pReplace_background) {
  453.     static tFlicette flicker_on[2] = { { 43, { 181, 362 }, { 124, 298 } }, { 43, { 84, 168 }, { 124, 298 } } };
  454.     static tFlicette flicker_off[2] = { { 42, { 181, 362 }, { 124, 298 } }, { 42, { 84, 168 }, { 124, 298 } } };
  455.     static tFlicette push[2] = { { 135, { 181, 362 }, { 124, 298 } }, { 45, { 84, 168 }, { 124, 298 } } };
  456.     static tMouse_area mouse_areas[2] = {
  457.         { { 181, 362 }, { 124, 298 }, { 244, 488 }, { 144, 346 }, 0, 0, 0, NULL },
  458.         { { 84, 168 }, { 124, 298 }, { 147, 294 }, { 144, 346 }, 1, 0, 0, NULL }
  459.     };
  460.     static tInterface_spec interface_spec = {
  461.         0,                 // initial_imode
  462.         0,                 // first_opening_flic
  463.         0,                 // second_opening_flic
  464.         0,                 // end_flic_go_ahead
  465.         0,                 // end_flic_escaped
  466.         0,                 // end_flic_otherwise
  467.         0,                 // flic_bunch_to_load
  468.         { 0xFFFFFFFF, 0 }, // move_left_new_mode
  469.         { 0xFFFFFFFF, 0 }, // move_left_delta
  470.         { 0, 0 },          // move_left_min
  471.         { 1, 0 },          // move_left_max
  472.         { NULL, NULL },    // move_left_proc
  473.         { 0xFFFFFFFF, 0 }, // move_right_new_mode
  474.         { 1, 0 },          // move_right_delta
  475.         { 0, 0 },          // move_right_min
  476.         { 1, 0 },          // move_right_max
  477.         { NULL, NULL },    // move_right_proc
  478.         { 0xFFFFFFFF, 0 }, // move_up_new_mode
  479.         { 0, 0 },          // move_up_delta
  480.         { 0, 0 },          // move_up_min
  481.         { 0, 0 },          // move_up_max
  482.         { NULL, NULL },    // move_up_proc
  483.         { 0xFFFFFFFF, 0 }, // move_down_new_mode
  484.         { 0, 0 },          // move_down_delta
  485.         { 0, 0 },          // move_down_min
  486.         { 0, 0 },          // move_down_max
  487.         { NULL, NULL },    // move_down_proc
  488.         { 1, 1 },          // go_ahead_allowed
  489.         { NULL, NULL },    // go_ahead_proc
  490.         { 1, 1 },          // escape_allowed
  491.         { NULL, NULL },    // escape_proc
  492.         NULL,              // exit_proc
  493.         NULL,              // draw_proc
  494.         0u,                // time_out
  495.         QuitVerifyStart,   // start_proc1
  496.         NULL,              // start_proc2
  497.         QuitVerifyDone,    // done_proc
  498.         0,                 // font_needed
  499.         { 0, 0 },          // typeable
  500.         NULL,              // get_original_string
  501.         1,                 // escape_code
  502.         1,                 // dont_save_or_load
  503.         2,                 // number_of_button_flics
  504.         flicker_on,        // flicker_on_flics
  505.         flicker_off,       // flicker_off_flics
  506.         push,              // pushed_flics
  507.         2,                 // number_of_mouse_areas
  508.         mouse_areas,       // mouse_areas
  509.         0,                 // number_of_recopy_areas
  510.         NULL               // recopy_areas
  511.     };
  512.     int result;
  513.     //int switched_res; // Pierre-Marie Baty -- unused variable
  514.     int woz_in_race;
  515.  
  516.     woz_in_race = 0;
  517.     if (gAusterity_mode) {
  518.         return 1;
  519.     }
  520.     if (gProgram_state.racing) {
  521.         FadePaletteDown();
  522.         ClearEntireScreen();
  523.         GoingToInterfaceFromRace();
  524.         woz_in_race = 1;
  525.         gProgram_state.racing = 0;
  526.     }
  527.     result = IRandomBetween(1, 3);
  528.     switch (result) {
  529.     case 1:
  530.         interface_spec.first_opening_flic = 130;
  531.         break;
  532.     case 2:
  533.         interface_spec.first_opening_flic = 131;
  534.         break;
  535.     case 3:
  536.         interface_spec.first_opening_flic = 132;
  537.         break;
  538.     }
  539.     gMouse_was_started__mainmenu = gMouse_started;
  540.     if (gMouse_started) {
  541.         RemoveTransientBitmaps(1);
  542.         EndMouseCursor();
  543.     }
  544.     TurnOffPanelFlics();
  545.     gReplace_background = pReplace_background;
  546.  
  547.     DRS3StopOutletSound(gEffects_outlet);
  548.     LoadInterfaceStuff(woz_in_race);
  549.     result = DoInterfaceScreen(&interface_spec, 0, 0);
  550.     if (gMouse_was_started__mainmenu) {
  551.         LoadInterfaceStuff(woz_in_race);
  552.         StartMouseCursor();
  553.     }
  554.     if (woz_in_race) {
  555.         GoingBackToRaceFromInterface();
  556.         gProgram_state.racing = 1;
  557.     }
  558.     return result;
  559. }
  560.  
  561. // IDA: tMM_result __usercall DoMainMenu@<EAX>(tU32 pTime_out@<EAX>, int pSave_allowed@<EDX>, int pContinue_allowed@<EBX>)
  562. tMM_result DoMainMenu(tU32 pTime_out, int pSave_allowed, int pContinue_allowed) {
  563.     tMM_result the_result;
  564.     LOG_TRACE("(%d, %d, %d)", pTime_out, pSave_allowed, pContinue_allowed);
  565.  
  566.     if (gProgram_state.racing) {
  567.         FadePaletteDown();
  568.     }
  569.     the_result = GetMainMenuOption(pTime_out, pContinue_allowed);
  570.     switch (the_result) {
  571.     case eMM_end_game:
  572.         if (gNet_mode) {
  573.             gProgram_state.prog_status = eProg_idling;
  574.         }
  575.         break;
  576.     case eMM_1_start:
  577.         if (pContinue_allowed || gAusterity_mode) {
  578.             PlayFlicsFromMemory();
  579.         }
  580.         if (!DoOnePlayerStart()) {
  581.             the_result = eMM_none;
  582.         }
  583.         if (pContinue_allowed || gAusterity_mode) {
  584.             PlayFlicsFromDisk();
  585.         }
  586.         break;
  587.     case eMM_n_start:
  588.         if (!DoMultiPlayerStart()) {
  589.             LoadRaces(gRace_list, &gNumber_of_races, -1);
  590.             the_result = eMM_none;
  591.         }
  592.         break;
  593.     case eMM_loaded:
  594.         if (!DoLoadGame()) {
  595.             the_result = eMM_none;
  596.         }
  597.         break;
  598.     case eMM_save:
  599.         DoSaveGame(pSave_allowed);
  600.         the_result = eMM_none;
  601.         break;
  602.     case eMM_options:
  603.         LoadSoundOptionsData();
  604.         DoOptions();
  605.         FreeSoundOptionsData();
  606.         break;
  607.     case eMM_quit:
  608.         if (!DoVerifyQuit(0)) {
  609.             the_result = eMM_none;
  610.         }
  611.         break;
  612.     case eMM_recover:
  613.         SetRecovery();
  614.         break;
  615.     case eMM_abort_race:
  616.         gAbandon_game = 1;
  617.         break;
  618.     default:
  619.         return the_result;
  620.     }
  621.     return the_result;
  622. }
  623.  
  624. // IDA: void __usercall DoMainMenuScreen(tU32 pTime_out@<EAX>, int pSave_allowed@<EDX>, int pContinue_allowed@<EBX>)
  625. void DoMainMenuScreen(tU32 pTime_out, int pSave_allowed, int pContinue_allowed) {
  626.     tPlayer_status old_status;
  627.     LOG_TRACE("(%d, %d, %d)", pTime_out, pSave_allowed, pContinue_allowed);
  628.  
  629.     if (pContinue_allowed || gAusterity_mode) {
  630.         PlayFlicsFromDisk();
  631.     }
  632.     old_status = gNet_players[gThis_net_player_index].player_status;
  633.     NetPlayerStatusChanged(ePlayer_status_main_menu);
  634.     PreloadBunchOfFlics(0);
  635.     switch (DoMainMenu(pTime_out, pSave_allowed, pContinue_allowed)) {
  636.     case eMM_end_game:
  637.         gProgram_state.prog_status = eProg_idling;
  638.         break;
  639.     case eMM_1_start:
  640.     case eMM_n_start:
  641.         gProgram_state.prog_status = eProg_game_starting;
  642.         break;
  643.     case eMM_loaded:
  644.         if (gGame_to_load < 0) {
  645.             gProgram_state.prog_status = eProg_game_starting;
  646.         }
  647.         break;
  648.     case eMM_quit:
  649.         gProgram_state.prog_status = eProg_quit;
  650.         break;
  651.     case eMM_timeout:
  652.         gProgram_state.prog_status = eProg_demo;
  653.         break;
  654.     default:
  655.         break;
  656.     }
  657.     UnlockBunchOfFlics(0);
  658.     if (gNet_players[gThis_net_player_index].player_status == ePlayer_status_main_menu) {
  659.         NetPlayerStatusChanged(old_status);
  660.     }
  661.     if (pContinue_allowed || gAusterity_mode) {
  662.         PlayFlicsFromMemory();
  663.     }
  664. }
  665.