Subversion Repositories Games.Descent

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Portions of this file are copyright Rebirth contributors and licensed as
  3.  * described in COPYING.txt.
  4.  * Portions of this file are copyright Parallax Software and licensed
  5.  * according to the Parallax license below.
  6.  * See COPYING.txt for license details.
  7.  
  8. THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  9. SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
  10. END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  11. ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  12. IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  13. SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  14. FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  15. CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
  16. AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
  17. COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  18. */
  19.  
  20. /*
  21.  *
  22.  * inferno.c: Entry point of program (main procedure)
  23.  *
  24.  * After main initializes everything, most of the time is spent in the loop
  25.  * while (window_get_front())
  26.  * In this loop, the main menu is brought up first.
  27.  *
  28.  * main() for Inferno
  29.  *
  30.  */
  31.  
  32. extern const char copyright[];
  33.  
  34. const
  35. #if defined(DXX_BUILD_DESCENT_I)
  36. char copyright[] = "DESCENT   COPYRIGHT (C) 1994,1995 PARALLAX SOFTWARE CORPORATION";
  37. #elif defined(DXX_BUILD_DESCENT_II)
  38. char copyright[] = "DESCENT II  COPYRIGHT (C) 1994-1996 PARALLAX SOFTWARE CORPORATION";
  39. #endif
  40.  
  41. #include "dxxsconf.h"
  42. //#include <stdio.h>
  43. //#include <stdlib.h>
  44. //#include <string.h>
  45. //#include <limits.h>
  46. #include <SDL.h>
  47.  
  48. #ifdef __unix__
  49. #include <unistd.h>
  50. #include <sys/stat.h>
  51. #include <sys/types.h>
  52. #endif
  53.  
  54. #include <cctype>
  55. #include <locale>
  56. #include "pstypes.h"
  57. #include "strutil.h"
  58. #include "console.h"
  59. #include "gr.h"
  60. #include "key.h"
  61. #include "3d.h"
  62. #include "bm.h"
  63. #include "inferno.h"
  64. #include "dxxerror.h"
  65. #include "player.h"
  66. #include "game.h"
  67. #include "u_mem.h"
  68. #include "screens.h"
  69. #include "texmap.h"
  70. #include "texmerge.h"
  71. #include "menu.h"
  72. #include "digi.h"
  73. #include "palette.h"
  74. #include "args.h"
  75. #include "titles.h"
  76. #include "text.h"
  77. #include "gauges.h"
  78. #include "gamefont.h"
  79. #include "kconfig.h"
  80. #include "newmenu.h"
  81. #include "config.h"
  82. #include "multi.h"
  83. #include "songs.h"
  84. #include "gameseq.h"
  85. #if defined(DXX_BUILD_DESCENT_II)
  86. #include "gamepal.h"
  87. #include "movie.h"
  88. #endif
  89. #include "playsave.h"
  90. #include "collide.h"
  91. #include "newdemo.h"
  92. #include "joy.h"
  93. #if !DXX_USE_OGL
  94. #include "../texmap/scanline.h" //for select_tmap -MM
  95. #endif
  96. #include "event.h"
  97. #include "rbaudio.h"
  98. #if DXX_WORDS_NEED_ALIGNMENT
  99. #include <sys/prctl.h>
  100. #endif
  101. #if DXX_USE_EDITOR
  102. #include "messagebox.h"
  103. #include "editor/editor.h"
  104. #include "editor/kdefs.h"
  105. #include "ui.h"
  106. #endif
  107. #include "vers_id.h"
  108. #if DXX_USE_UDP
  109. #include "net_udp.h"
  110. #endif
  111. #include "dsx-ns.h"
  112.  
  113. #if DXX_USE_SDLIMAGE
  114. #include <SDL_image.h>
  115. #endif
  116. #if DXX_USE_SDLMIXER
  117. #include <SDL_mixer.h>
  118. #endif
  119.  
  120. namespace dsx {
  121.  
  122. int Screen_mode=-1;                                     //game screen or editor screen?
  123.  
  124. #if defined(DXX_BUILD_DESCENT_I)
  125. int HiresGFXAvailable = 0;
  126. int MacHog = 0; // using a Mac hogfile?
  127. #endif
  128.  
  129. //read help from a file & print to screen
  130. static void print_commandline_help()
  131. {
  132. #define DXX_COMMAND_LINE_HELP_FMT(FMT,...)      FMT
  133. #define DXX_COMMAND_LINE_HELP_ARG(FMT,...)      , ## __VA_ARGS__
  134.  
  135. #define DXX_if_defined_placeholder1     ,
  136. #define DXX_if_defined_unwrap(A,...)    A, ## __VA_ARGS__
  137. #define DXX_if_defined(V,F)     DXX_if_defined2(V,F)
  138. #define DXX_if_defined2(V,F)    DXX_if_defined3(DXX_if_defined_placeholder##V, F)
  139. #define DXX_if_defined3(V,F)    DXX_if_defined4(F, V 1, 0)
  140. #define DXX_if_defined4(F,_,V,...)      DXX_if_defined5_##V(F)
  141. #define DXX_if_defined5_0(F)
  142. #define DXX_if_defined5_1(F)    DXX_if_defined_unwrap F
  143. #define DXX_if_defined_01(V,F)  DXX_if_defined4(F,,V)
  144.  
  145. #define DXX_COMMAND_LINE_HELP_unix(V)   DXX_if_defined(__unix__, (V))
  146. #define DXX_COMMAND_LINE_HELP_D1(V)     DXX_if_defined(DXX_BUILD_DESCENT_I, (V))
  147. #define DXX_COMMAND_LINE_HELP_D2(V)     DXX_if_defined(DXX_BUILD_DESCENT_II, (V))
  148. #define DXX_STRINGIZE2(X)       #X
  149. #define DXX_STRINGIZE(X)        DXX_STRINGIZE2(X)
  150.  
  151. #if DXX_USE_OGL
  152. #define DXX_COMMAND_LINE_HELP_OGL(V)    V
  153. #define DXX_COMMAND_LINE_HELP_SDL(V)
  154. #else
  155. #define DXX_COMMAND_LINE_HELP_OGL(V)
  156. #define DXX_COMMAND_LINE_HELP_SDL(V)    V
  157. #endif
  158.  
  159. #define DXX_COMMAND_LINE_HELP(VERB)     \
  160.         VERB("\n System Options:\n\n")  \
  161.         VERB("  -nonicefps                    Don't free CPU-cycles\n") \
  162.         VERB("  -maxfps <n>                   Set maximum framerate to <n>\n\t\t\t\t(default: " DXX_STRINGIZE(MAXIMUM_FPS) ", available: " DXX_STRINGIZE(MINIMUM_FPS) "-" DXX_STRINGIZE(MAXIMUM_FPS) ")\n")     \
  163.         VERB("  -hogdir <s>                   set shared data directory to <s>\n")      \
  164.         DXX_COMMAND_LINE_HELP_unix(     \
  165.                 VERB("  -nohogdir                     don't try to use shared data directory\n")        \
  166.         )       \
  167.         VERB("  -add-missions-dir <s>         Add contents of location <s> to the missions directory\n")        \
  168.         VERB("  -use_players_dir              Put player files and saved games in Players subdirectory\n")      \
  169.         VERB("  -lowmem                       Lowers animation detail for better performance with\n\t\t\t\tlow memory\n")       \
  170.         VERB("  -pilot <s>                    Select pilot <s> automatically\n")        \
  171.         VERB("  -auto-record-demo             Start recording on level entry\n")        \
  172.         VERB("  -record-demo-format           Set demo name automatically\n")   \
  173.         VERB("  -autodemo                     Start in demo mode\n")    \
  174.         VERB("  -window                       Run the game in a window\n")      \
  175.         VERB("  -noborders                    Don't show borders in window mode\n")     \
  176.         DXX_COMMAND_LINE_HELP_D1(       \
  177.                 VERB("  -notitles                     Skip title screens\n")    \
  178.         )       \
  179.         DXX_COMMAND_LINE_HELP_D2(       \
  180.                 VERB("  -nomovies                     Don't play movies\n")     \
  181.         )       \
  182.         VERB("\n Controls:\n\n")        \
  183.         VERB("  -nocursor                     Hide mouse cursor\n")     \
  184.         VERB("  -nomouse                      Deactivate mouse\n")      \
  185.         VERB("  -nojoystick                   Deactivate joystick\n")   \
  186.         VERB("  -nostickykeys                 Make CapsLock and NumLock non-sticky\n")  \
  187.         VERB("\n Sound:\n\n")   \
  188.         VERB("  -nosound                      Disables sound output\n") \
  189.         VERB("  -nomusic                      Disables music output\n") \
  190.         DXX_COMMAND_LINE_HELP_D2(       \
  191.                 VERB("  -sound11k                     Use 11KHz sounds\n")      \
  192.         )       \
  193.         DXX_if_defined_01(DXX_USE_SDLMIXER, (   \
  194.                 VERB("  -nosdlmixer                   Disable Sound output via SDL_mixer\n")    \
  195.         ))      \
  196.         VERB("\n Graphics:\n\n")        \
  197.         VERB("  -lowresfont                   Force use of low resolution fonts\n")     \
  198.         DXX_COMMAND_LINE_HELP_D2(       \
  199.                 VERB("  -lowresgraphics               Force use of low resolution graphics\n")  \
  200.                 VERB("  -lowresmovies                 Play low resolution movies if available (for slow machines)\n")   \
  201.         )       \
  202.         DXX_COMMAND_LINE_HELP_OGL(      \
  203.                 VERB("  -gl_fixedfont                 Don't scale fonts to current resolution\n")       \
  204.                 VERB("  -gl_syncmethod <n>            OpenGL sync method (default: %i)\n", OGL_SYNC_METHOD_DEFAULT)     \
  205.                 VERB("                                    0: Disabled\n")       \
  206.                 VERB("                                    1: Fence syncs, limit GPU latency to at most one frame\n")    \
  207.                 VERB("                                    2: Like 1, but sleep during sync to reduce CPU load\n")       \
  208.                 VERB("                                    3: Immediately sync after buffer swap\n")     \
  209.                 VERB("                                    4: Immediately sync after buffer swap\n")     \
  210.                 VERB("                                    5: Auto: if VSync is enabled and ARB_sync is supported, use mode 2, otherwise mode 0\n")      \
  211.                 VERB("  -gl_syncwait <n>              Wait interval (ms) for sync mode 2 (default: " DXX_STRINGIZE(OGL_SYNC_WAIT_DEFAULT) ")\n")        \
  212.                 VERB("  -gl_darkedges                 Re-enable dark edges around filtered textures (as present in earlier versions of the engine)\n")  \
  213.         )       \
  214.         DXX_if_defined_01(DXX_USE_UDP, (        \
  215.                 VERB("\n Multiplayer:\n\n")     \
  216.                 VERB("  -udp_hostaddr <s>             Use IP address/Hostname <s> for manual game joining\n\t\t\t\t(default: %s)\n", UDP_MANUAL_ADDR_DEFAULT)   \
  217.                 VERB("  -udp_hostport <n>             Use UDP port <n> for manual game joining (default: %hu)\n", UDP_PORT_DEFAULT)     \
  218.                 VERB("  -udp_myport <n>               Set my own UDP port to <n> (default: %hu)\n", UDP_PORT_DEFAULT)   \
  219.                 DXX_if_defined_01(DXX_USE_TRACKER, (    \
  220.                         VERB("  -no-tracker                   Disable tracker (unless overridden by later -tracker_hostaddr)\n")        \
  221.                         VERB("  -tracker_hostaddr <n>         Address of tracker server to register/query games to/from\n\t\t\t\t(default: %s)\n", TRACKER_ADDR_DEFAULT)        \
  222.                         VERB("  -tracker_hostport <n>         Port of tracker server to register/query games to/from\n\t\t\t\t(default: %hu)\n", TRACKER_PORT_DEFAULT)  \
  223.                 ))      \
  224.         ))      \
  225.         DXX_if_defined(EDITOR, (        \
  226.                 VERB("\n Editor:\n\n")  \
  227.                 DXX_COMMAND_LINE_HELP_D1(       \
  228.                         VERB("  -nobm                         Don't load BITMAPS.TBL and BITMAPS.BIN - use internal data\n")    \
  229.                 )       \
  230.                 DXX_COMMAND_LINE_HELP_D2(       \
  231.                         VERB("  -autoload <s>                 Autoload level <s> in the editor\n")      \
  232.                         VERB("  -macdata                      Read and write Mac data files in editor (swap colors)\n") \
  233.                         VERB("  -hoarddata                    Make the Hoard ham file from some files, then exit\n")    \
  234.                 )       \
  235.         ))      \
  236.         VERB("\n Debug (use only if you know what you're doing):\n\n")  \
  237.         VERB("  -debug                        Enable debugging output.\n")      \
  238.         VERB("  -verbose                      Enable verbose output.\n")        \
  239.         VERB("  -safelog                      Write gamelog.txt unbuffered.\n\t\t\t\tUse to keep helpful output to trace program crashes.\n")   \
  240.         VERB("  -norun                        Bail out after initialization\n") \
  241.         VERB("  -no-grab                      Never grab keyboard/mouse\n")     \
  242.         VERB("  -renderstats                  Enable renderstats info by default\n")    \
  243.         VERB("  -text <s>                     Specify alternate .tex file\n")   \
  244.         VERB("  -showmeminfo                  Show memory statistics\n")        \
  245.         VERB("  -nodoublebuffer               Disable Doublebuffering\n")       \
  246.         VERB("  -bigpig                       Use uncompressed RLE bitmaps\n")  \
  247.         VERB("  -16bpp                        Use 16Bpp instead of 32Bpp\n")    \
  248.         DXX_COMMAND_LINE_HELP_OGL(      \
  249.                 VERB("  -gl_oldtexmerge               Use old texmerge, uses more ram, but might be faster\n")  \
  250.                 VERB("  -gl_intensity4_ok <n>         Override DbgGlIntensity4Ok (default: 1)\n")       \
  251.                 VERB("  -gl_luminance4_alpha4_ok <n>  Override DbgGlLuminance4Alpha4Ok (default: 1)\n") \
  252.                 VERB("  -gl_rgba2_ok <n>              Override DbgGlRGBA2Ok (default: 1)\n")    \
  253.                 VERB("  -gl_readpixels_ok <n>         Override DbgGlReadPixelsOk (default: 1)\n")       \
  254.                 VERB("  -gl_gettexlevelparam_ok <n>   Override DbgGlGetTexLevelParamOk (default: 1)\n") \
  255.         )       \
  256.         DXX_COMMAND_LINE_HELP_SDL(      \
  257.                 VERB("  -tmap <s>                     Select texmapper <s> to use\n\t\t\t\t(default: c, available: c, fp, quad)\n")     \
  258.                 VERB("  -hwsurface                    Use SDL HW Surface\n")    \
  259.                 VERB("  -asyncblit                    Use queued blits over SDL. Can speed up rendering\n")     \
  260.         )       \
  261.         VERB("\n Help:\n\n")    \
  262.         VERB("  -help, -h, -?, ?             View this help screen\n")  \
  263.         VERB("\n\n")    \
  264.  
  265.         //printf(DXX_COMMAND_LINE_HELP(DXX_COMMAND_LINE_HELP_FMT) DXX_COMMAND_LINE_HELP(DXX_COMMAND_LINE_HELP_ARG));
  266.         printf("\n");
  267.         printf(" System Options:\n");
  268.         printf("\n");
  269.         printf("  -nonicefps                    Don't free CPU-cycles\n");
  270.         printf("  -maxfps <n>                   Set maximum framerate to <n>\n");
  271.         printf("                                default: " DXX_STRINGIZE(MAXIMUM_FPS) ", available: " DXX_STRINGIZE(MINIMUM_FPS) "-" DXX_STRINGIZE(MAXIMUM_FPS) ")\n");
  272.         printf("  -hogdir <s>                   set shared data directory to <s>\n");
  273. #ifdef __unix__
  274.         printf("  -nohogdir                     don't try to use shared data directory\n");
  275. #endif
  276.         printf("  -add-missions-dir <s>         Add contents of location <s> to the missions directory\n");
  277.         printf("  -use_players_dir              Put player files and saved games in Players subdirectory\n");
  278.         printf("  -lowmem                       Lowers animation detail for better performance with\n");
  279.         printf("                                low memory\n");
  280.         printf("  -pilot <s>                    Select pilot <s> automatically\n");
  281.         printf("  -auto-record-demo             Start recording on level entry\n");
  282.         printf("  -record-demo-format           Set demo name automatically\n");
  283.         printf("  -autodemo                     Start in demo mode\n");
  284.         printf("  -window                       Run the game in a window\n");
  285.         printf("  -noborders                    Don't show borders in window mode\n");
  286. #ifdef DXX_BUILD_DESCENT_I
  287.         printf("  -notitles                     Skip title screens\n");
  288. #endif
  289. #ifdef DXX_BUILD_DESCENT_II
  290.         printf("  -nomovies                     Don't play movies\n");
  291. #endif
  292.         printf("\n");
  293.         printf(" Controls:\n");
  294.         printf("\n");
  295.         printf("  -nocursor                     Hide mouse cursor\n");
  296.         printf("  -nomouse                      Deactivate mouse\n");
  297.         printf("  -nojoystick                   Deactivate joystick\n");
  298.         printf("  -nostickykeys                 Make CapsLock and NumLock non-sticky\n");
  299.         printf("\n");
  300.         printf(" Sound:\n");
  301.         printf("\n");
  302.         printf("  -nosound                      Disables sound output\n");
  303.         printf("  -nomusic                      Disables music output\n");
  304. #ifdef DXX_BUILD_DESCENT_II
  305.         printf("  -sound11k                     Use 11KHz sounds\n");
  306. #endif
  307. #ifdef DXX_USE_SDLMIXER
  308.         printf("  -nosdlmixer                   Disable Sound output via SDL_mixer\n");
  309. #endif
  310.         printf("\n");
  311.         printf(" Graphics:\n");
  312.         printf("\n");
  313.         printf("  -lowresfont                   Force use of low resolution fonts\n");
  314. #ifdef DXX_BUILD_DESCENT_II
  315.         printf("  -lowresgraphics               Force use of low resolution graphics\n");
  316.         printf("  -lowresmovies                 Play low resolution movies if available (for slow machines)\n");
  317. #endif
  318. #ifdef DXX_USE_OGL
  319.         printf("  -gl_fixedfont                 Don't scale fonts to current resolution\n");
  320.         printf("  -gl_syncmethod <n>            OpenGL sync method (default: %i)\n", OGL_SYNC_METHOD_DEFAULT);
  321.         printf("                                    0: Disabled\n");
  322.         printf("                                    1: Fence syncs, limit GPU latency to at most one frame\n");
  323.         printf("                                    2: Like 1, but sleep during sync to reduce CPU load\n");
  324.         printf("                                    3: Immediately sync after buffer swap\n");
  325.         printf("                                    4: Immediately sync after buffer swap\n");
  326.         printf("                                    5: Auto: if VSync is enabled and ARB_sync is supported, use mode 2, otherwise mode 0\n");
  327.         printf("  -gl_syncwait <n>              Wait interval (ms) for sync mode 2 (default: " DXX_STRINGIZE(OGL_SYNC_WAIT_DEFAULT) ")\n");
  328.         printf("  -gl_darkedges                 Re-enable dark edges around filtered textures (as present in earlier versions of the engine)\n");
  329. #endif
  330. #ifdef DXX_USE_UDP
  331.         printf("\n");
  332.         printf(" Multiplayer:\n");
  333.         printf("\n");
  334.         printf("  -udp_hostaddr <s>             Use IP address/Hostname <s> for manual game joining\n");
  335.         printf("                                (default: %s)\n", UDP_MANUAL_ADDR_DEFAULT);
  336.         printf("  -udp_hostport <n>             Use UDP port <n> for manual game joining (default: %hu)\n", UDP_PORT_DEFAULT);
  337.         printf("  -udp_myport <n>               Set my own UDP port to <n> (default: %hu)\n", UDP_PORT_DEFAULT);
  338. #ifdef DXX_USE_TRACKER
  339.         printf("  -no-tracker                   Disable tracker (unless overridden by later -tracker_hostaddr)\n");
  340.         printf("  -tracker_hostaddr <n>         Address of tracker server to register/query games to/from\n"
  341.         printf("                                (default: %s)\n", TRACKER_ADDR_DEFAULT);
  342.         printf("  -tracker_hostport <n>         Port of tracker server to register/query games to/from\n");
  343.         printf("                                (default: %hu)\n", TRACKER_PORT_DEFAULT);
  344. #endif
  345. #endif
  346. #ifdef EDITOR
  347.         printf("\n");
  348.         printf(" Editor:\n");
  349.         printf("\n");
  350. #ifdef DXX_BUILD_DESCENT_I
  351.         printf("  -nobm                         Don't load BITMAPS.TBL and BITMAPS.BIN - use internal data\n");
  352. #endif
  353. #ifdef DXX_BUILD_DESCENT_II
  354.         printf("  -autoload <s>                 Autoload level <s> in the editor\n");
  355.         printf("  -macdata                      Read and write Mac data files in editor (swap colors)\n");
  356.         printf("  -hoarddata                    Make the Hoard ham file from some files, then exit\n");
  357. #endif
  358. #endif
  359.         printf("\n");
  360.         printf(" Debug (use only if you know what you're doing):\n");
  361.         printf("\n");
  362.         printf("  -debug                        Enable debugging output.\n");
  363.         printf("  -verbose                      Enable verbose output.\n");
  364.         printf("  -safelog                      Write gamelog.txt unbuffered.\n");
  365.         printf("                                Use to keep helpful output to trace program crashes.\n");
  366.         printf("  -norun                        Bail out after initialization\n");
  367.         printf("  -no-grab                      Never grab keyboard/mouse\n");
  368.         printf("  -renderstats                  Enable renderstats info by default\n");
  369.         printf("  -text <s>                     Specify alternate .tex file\n");
  370.         printf("  -showmeminfo                  Show memory statistics\n");
  371.         printf("  -nodoublebuffer               Disable Doublebuffering\n");
  372.         printf("  -bigpig                       Use uncompressed RLE bitmaps\n");
  373.         printf("  -16bpp                        Use 16Bpp instead of 32Bpp\n");
  374. #ifdef DXX_USE_OGL
  375.         printf("  -gl_oldtexmerge               Use old texmerge, uses more ram, but might be faster\n");
  376.         printf("  -gl_intensity4_ok <n>         Override DbgGlIntensity4Ok (default: 1)\n");
  377.         printf("  -gl_luminance4_alpha4_ok <n>  Override DbgGlLuminance4Alpha4Ok (default: 1)\n");
  378.         printf("  -gl_rgba2_ok <n>              Override DbgGlRGBA2Ok (default: 1)\n");
  379.         printf("  -gl_readpixels_ok <n>         Override DbgGlReadPixelsOk (default: 1)\n");
  380.         printf("  -gl_gettexlevelparam_ok <n>   Override DbgGlGetTexLevelParamOk (default: 1)\n");
  381. #else /* SDL */
  382.         printf("  -tmap <s>                     Select texmapper <s> to use\n");
  383.         printf("                                (default: c, available: c, fp, quad)\n");
  384.         printf("  -hwsurface                    Use SDL HW Surface\n");
  385.         printf("  -asyncblit                    Use queued blits over SDL. Can speed up rendering\n");
  386. #endif
  387.         printf("\n");
  388.         printf(" Help:\n");
  389.         printf("\n");
  390.         printf("  -help, -h, -?, ?             View this help screen\n");
  391.         printf("\n");
  392.         printf("\n");
  393. }
  394.  
  395. int Quitting = 0;
  396.  
  397. }
  398.  
  399. namespace dcx {
  400.  
  401. // Default event handler for everything except the editor
  402. window_event_result standard_handler(const d_event &event)
  403. {
  404.         int key;
  405.  
  406.         if (Quitting)
  407.         {
  408.                 window *wind = window_get_front();
  409.                 if (!wind)
  410.                         return window_event_result::ignored;    // finished quitting
  411.        
  412.                 if (wind == Game_wind)
  413.                 {
  414.                         int choice;
  415.                         Quitting = 0;
  416.                         choice=nm_messagebox( NULL, 2, TXT_YES, TXT_NO, TXT_ABORT_GAME );
  417.                         if (choice != 0)
  418.                                 return window_event_result::handled;    // aborted quitting
  419.                         else
  420.                         {
  421.                                 CGameArg.SysAutoDemo = false;
  422.                                 Quitting = 1;
  423.                         }
  424.                 }
  425.                
  426.                 // Close front window, let the code flow continue until all windows closed or quit cancelled
  427.                 if (!window_close(wind))
  428.                 {
  429.                         Quitting = 0;
  430.                         return window_event_result::handled;
  431.                 }
  432.                
  433.                 return window_event_result::deleted;    // tell the event system we deleted some window
  434.         }
  435.  
  436.         switch (event.type)
  437.         {
  438.                 case EVENT_MOUSE_BUTTON_DOWN:
  439.                 case EVENT_MOUSE_BUTTON_UP:
  440.                         // No window selecting
  441.                         // We stay with the current one until it's closed/hidden or another one is made
  442.                         // Not the case for the editor
  443.                         break;
  444.  
  445.                 case EVENT_KEY_COMMAND:
  446.                         key = event_key_get(event);
  447.  
  448.                         switch (key)
  449.                         {
  450. #if DXX_USE_SCREENSHOT
  451. #ifdef macintosh
  452.                                 case KEY_COMMAND + KEY_SHIFTED + KEY_3:
  453. #endif
  454.                                 case KEY_PRINT_SCREEN:
  455.                                 {
  456.                                         gr_set_default_canvas();
  457.                                         save_screen_shot(0);
  458.                                         return window_event_result::handled;
  459.                                 }
  460. #endif
  461.  
  462.                                 case KEY_ALTED+KEY_ENTER:
  463.                                 case KEY_ALTED+KEY_PADENTER:
  464.                                         if (Game_wind)
  465.                                                 if (Game_wind == window_get_front())
  466.                                                         return window_event_result::ignored;
  467.                                         gr_toggle_fullscreen();
  468. #if SDL_MAJOR_VERSION == 2
  469.                                         {
  470.                                                 /* Hack to force the canvas to adjust to the new
  471.                                                  * dimensions.  Without this, the canvas
  472.                                                  * continues to use the old window size until
  473.                                                  * the hack of calling `init_cockpit` from
  474.                                                  * `game_handler` fixes the dimensions.  If the
  475.                                                  * window became bigger, the game fails to draw
  476.                                                  * in the full new area.  If the window became
  477.                                                  * smaller, part of the game is outside the
  478.                                                  * cropped area.
  479.                                                  *
  480.                                                  * If the automap is open, the view is still
  481.                                                  * wrong, since the automap uses its own private
  482.                                                  * canvas.  That will need to be fixed
  483.                                                  * separately.  Ideally, the whole window
  484.                                                  * system would be reworked to provide a general
  485.                                                  * notification to every interested canvas when
  486.                                                  * the top level window resizes.
  487.                                                  */
  488.                                                 auto sm = Screen_mode;
  489.                                                 Screen_mode = SCREEN_GAME;
  490.                                                 init_cockpit();
  491.                                                 Screen_mode = sm;
  492.                                         }
  493. #endif
  494.                                         return window_event_result::handled;
  495.  
  496. #if defined(__APPLE__) || defined(macintosh)
  497.                                 case KEY_COMMAND+KEY_Q:
  498.                                         // Alt-F4 already taken, too bad
  499.                                         Quitting = 1;
  500.                                         return window_event_result::handled;
  501. #endif
  502.                                 case KEY_SHIFTED + KEY_ESC:
  503.                                         con_showup();
  504.                                         return window_event_result::handled;
  505.                         }
  506.                         break;
  507.  
  508.                 case EVENT_WINDOW_DRAW:
  509.                 case EVENT_IDLE:
  510.                         //see if redbook song needs to be restarted
  511. #if DXX_USE_SDL_REDBOOK_AUDIO
  512.                         RBACheckFinishedHook();
  513. #endif
  514.                         return window_event_result::handled;
  515.  
  516.                 case EVENT_QUIT:
  517. #if DXX_USE_EDITOR
  518.                         if (SafetyCheck())
  519. #endif
  520.                                 Quitting = 1;
  521.                         return window_event_result::handled;
  522.  
  523.                 default:
  524.                         break;
  525.         }
  526.  
  527.         return window_event_result::ignored;
  528. }
  529.  
  530. #if DXX_HAVE_POISON
  531. d_interface_unique_state::d_interface_unique_state()
  532. {
  533.         DXX_MAKE_VAR_UNDEFINED(PilotName);
  534. }
  535. #endif
  536.  
  537. void d_interface_unique_state::update_window_title()
  538. {
  539. #if SDL_MAJOR_VERSION == 1
  540.         if (!PilotName[0u])
  541.                 SDL_WM_SetCaption(DESCENT_VERSION, DXX_SDL_WINDOW_CAPTION);
  542.         else
  543.         {
  544.                 const char *const pilot = PilotName;
  545.                 std::array<char, 80> wm_caption_name, wm_caption_iconname;
  546.                 snprintf(wm_caption_name.data(), wm_caption_name.size(), "%s: %s", DESCENT_VERSION, pilot);
  547.                 snprintf(wm_caption_iconname.data(), wm_caption_iconname.size(), "%s: %s", DXX_SDL_WINDOW_CAPTION, pilot);
  548.                 SDL_WM_SetCaption(wm_caption_name.data(), wm_caption_iconname.data());
  549.         }
  550. #endif
  551. }
  552.  
  553. }
  554.  
  555. namespace dsx {
  556.  
  557. #define PROGNAME argv[0]
  558. #define DXX_RENAME_IDENTIFIER2(I,N)     I##$##N
  559. #define DXX_RENAME_IDENTIFIER(I,N)      DXX_RENAME_IDENTIFIER2(I,N)
  560. #define argc    DXX_RENAME_IDENTIFIER(argc_gc, DXX_git_commit)
  561. #define argv    DXX_RENAME_IDENTIFIER(argv_gd$b32, DXX_git_describe)
  562.  
  563. //      DESCENT by Parallax Software
  564. //      DESCENT II by Parallax Software
  565. //      (varies based on preprocessor options)
  566. //              Descent Main
  567.  
  568. static int main(int argc, char *argv[])
  569. {
  570.         if (!PHYSFSX_init(argc, argv))
  571.                 return 1;
  572.         con_init();  // Initialise the console
  573.  
  574.         setbuf(stdout, NULL); // unbuffered output via printf
  575. #ifdef _WIN32
  576.         freopen( "CON", "w", stdout );
  577.         freopen( "CON", "w", stderr );
  578. #endif
  579.  
  580.         if (CGameArg.SysShowCmdHelp) {
  581.                 print_commandline_help();
  582.  
  583.                 return(0);
  584.         }
  585.  
  586.         printf("\nType '%s -help' for a list of command-line options.\n\n", PROGNAME);
  587.  
  588.         PHYSFSX_listSearchPathContent();
  589.        
  590.         if (!PHYSFSX_checkSupportedArchiveTypes())
  591.                 return(0);
  592.  
  593. #if defined(DXX_BUILD_DESCENT_I)
  594.         if (! PHYSFSX_contfile_init("descent.hog", 1))
  595. #define DXX_NAME_NUMBER "1"
  596. #define DXX_HOGFILE_NAMES       "descent.hog"
  597. #elif defined(DXX_BUILD_DESCENT_II)
  598.         if (! PHYSFSX_contfile_init("descent2.hog", 1) && ! PHYSFSX_contfile_init("d2demo.hog", 1))
  599. #define DXX_NAME_NUMBER "2"
  600. #define DXX_HOGFILE_NAMES       "descent2.hog or d2demo.hog"
  601. #endif
  602.         {
  603. #if defined(__unix__) && !defined(__APPLE__)
  604. #define DXX_HOGFILE_PROGRAM_DATA_DIRECTORY      \
  605.                               "\t$HOME/.d" DXX_NAME_NUMBER "x-rebirth\n"        \
  606.                                         DXX_HOGFILE_SHAREPATH_INDENTED
  607. #if DXX_USE_SHAREPATH
  608. #define DXX_HOGFILE_SHAREPATH_INDENTED  \
  609.                               "\t" DXX_SHAREPATH "\n"
  610. #else
  611. #define DXX_HOGFILE_SHAREPATH_INDENTED
  612. #endif
  613. #else
  614. #define DXX_HOGFILE_PROGRAM_DATA_DIRECTORY      \
  615.                                   "\tDirectory containing D" DXX_NAME_NUMBER "X\n"
  616. #endif
  617. #if (defined(__APPLE__) && defined(__MACH__)) || defined(macintosh)
  618. #define DXX_HOGFILE_APPLICATION_BUNDLE  \
  619.                                   "\tIn 'Resources' inside the application bundle\n"
  620. #else
  621. #define DXX_HOGFILE_APPLICATION_BUNDLE  ""
  622. #endif
  623. #define DXX_MISSING_HOGFILE_ERROR_TEXT  \
  624.                 "Could not find a valid hog file (" DXX_HOGFILE_NAMES ")\nPossible locations are:\n"    \
  625.                 DXX_HOGFILE_PROGRAM_DATA_DIRECTORY      \
  626.                 "\tIn a subdirectory called 'data'\n"   \
  627.                 DXX_HOGFILE_APPLICATION_BUNDLE  \
  628.                 "Or use the -hogdir option to specify an alternate location."
  629.                 UserError(DXX_MISSING_HOGFILE_ERROR_TEXT);
  630.         }
  631.  
  632. #if defined(DXX_BUILD_DESCENT_I)
  633.         switch (PHYSFSX_fsize("descent.hog"))
  634.         {
  635.                 case D1_MAC_SHARE_MISSION_HOGSIZE:
  636.                 case D1_MAC_MISSION_HOGSIZE:
  637.                         MacHog = 1;     // used for fonts and the Automap
  638.                         break;
  639.         }
  640. #endif
  641.  
  642.         load_text();
  643.  
  644.         //print out the banner title
  645. #if defined(DXX_BUILD_DESCENT_I)
  646.         con_printf(CON_NORMAL, "%s  %s", DESCENT_VERSION, g_descent_build_datetime); // D1X version
  647.         con_puts(CON_NORMAL, "This is a MODIFIED version of Descent, based on " BASED_VERSION ".");
  648.         con_puts(CON_NORMAL, TXT_COPYRIGHT);
  649.         con_puts(CON_NORMAL, TXT_TRADEMARK);
  650.         con_puts(CON_NORMAL, "Copyright (C) 2005-2013 Christian Beckhaeuser, 2013-2017 Kp");
  651. #elif defined(DXX_BUILD_DESCENT_II)
  652.         con_printf(CON_NORMAL, "%s%s  %s", DESCENT_VERSION, PHYSFSX_exists(MISSION_DIR "d2x.hog",1) ? "  Vertigo Enhanced" : "", g_descent_build_datetime); // D2X version
  653.         con_puts(CON_NORMAL, "This is a MODIFIED version of Descent 2, based on " BASED_VERSION ".");
  654.         con_puts(CON_NORMAL, TXT_COPYRIGHT);
  655.         con_puts(CON_NORMAL, TXT_TRADEMARK);
  656.         con_puts(CON_NORMAL, "Copyright (C) 1999 Peter Hawkins, 2002 Bradley Bell, 2005-2013 Christian Beckhaeuser, 2013-2017 Kp");
  657. #endif
  658.  
  659.         if (CGameArg.DbgVerbose)
  660.         {
  661.                 {
  662.                         PHYSFS_Version vc, vl;
  663.                         PHYSFS_VERSION(&vc);
  664.                         PHYSFS_getLinkedVersion(&vl);
  665.                         con_printf(CON_VERBOSE, "D" DXX_NAME_NUMBER "X-Rebirth built with PhysFS %u.%u.%u; loaded with PhysFS %u.%u.%u", vc.major, vc.minor, vc.patch, vl.major, vl.minor, vl.patch);
  666.                 }
  667.                 {
  668.                         SDL_version vc;
  669.                         SDL_VERSION(&vc);
  670. #if SDL_MAJOR_VERSION == 1
  671.                         const auto vl = SDL_Linked_Version();
  672. #else
  673.                         SDL_version vlv;
  674.                         const auto vl = &vlv;
  675.                         SDL_GetVersion(vl);
  676. #endif
  677.                         con_printf(CON_VERBOSE, "D" DXX_NAME_NUMBER "X-Rebirth built with libSDL %u.%u.%u; loaded with libSDL %u.%u.%u", vc.major, vc.minor, vc.patch, vl->major, vl->minor, vl->patch);
  678.                 }
  679. #if DXX_USE_SDLIMAGE
  680.                 {
  681.                         SDL_version vc;
  682.                         SDL_IMAGE_VERSION(&vc);
  683.                         const auto vl = IMG_Linked_Version();
  684.                         con_printf(CON_VERBOSE, "D" DXX_NAME_NUMBER "X-Rebirth built with SDL_image %u.%u.%u; loaded with SDL_image %u.%u.%u", vc.major, vc.minor, vc.patch, vl->major, vl->minor, vl->patch);
  685.                 }
  686. #endif
  687. #if DXX_USE_SDLMIXER
  688.                 {
  689.                         SDL_version vc;
  690.                         SDL_MIXER_VERSION(&vc);
  691.                         const auto vl = Mix_Linked_Version();
  692.                         con_printf(CON_VERBOSE, "D" DXX_NAME_NUMBER "X-Rebirth built with SDL_mixer %u.%u.%u; loaded with SDL_mixer %u.%u.%u", vc.major, vc.minor, vc.patch, vl->major, vl->minor, vl->patch);
  693.                 }
  694. #endif
  695.                 con_puts(CON_VERBOSE, TXT_VERBOSE_1);
  696.         }
  697.        
  698.         ReadConfigFile();
  699.  
  700.         PHYSFSX_addArchiveContent();
  701.  
  702.         const auto &&arch_atexit_result = arch_init();
  703.         /* This variable exists for the side effects that occur when it is
  704.          * destroyed.  clang-9 fails to recognize those side effects as a
  705.          * "use" and warns that the variable is unused.  Cast it to void to
  706.          * create a "use" to suppress the warning.
  707.          */
  708.         (void)arch_atexit_result;
  709.  
  710. #if !DXX_USE_OGL
  711.         select_tmap(CGameArg.DbgTexMap);
  712.  
  713. #if defined(DXX_BUILD_DESCENT_II)
  714.         Lighting_on = 1;
  715. #endif
  716. #endif
  717.  
  718.         con_puts(CON_VERBOSE, "Going into graphics mode...");
  719. #if DXX_USE_OGL
  720.         gr_set_mode_from_window_size();
  721. #else
  722.         gr_set_mode(Game_screen_mode);
  723. #endif
  724.  
  725.         // Load the palette stuff. Returns non-zero if error.
  726.         con_puts(CON_DEBUG, "Initializing palette system...");
  727. #if defined(DXX_BUILD_DESCENT_I)
  728.         gr_use_palette_table( "PALETTE.256" );
  729. #elif defined(DXX_BUILD_DESCENT_II)
  730.         gr_use_palette_table(D2_DEFAULT_PALETTE );
  731. #endif
  732.  
  733.         con_puts(CON_DEBUG, "Initializing font system...");
  734.         gamefont_init();        // must load after palette data loaded.
  735.  
  736. #if defined(DXX_BUILD_DESCENT_II)
  737.         con_puts(CON_DEBUG, "Initializing movie libraries...");
  738.         init_movies();          //init movie libraries
  739. #endif
  740.  
  741.         show_titles();
  742.  
  743.         set_screen_mode(SCREEN_MENU);
  744. #ifdef DEBUG_MEMORY_ALLOCATIONS
  745.         /* Memdebug runs before global destructors, so it incorrectly
  746.          * reports as leaked any allocations that would be freed by a global
  747.          * destructor.  This local will force the newmenu globals to be
  748.          * reset before memdebug scans, which prevents memdebug falsely
  749.          * reporting them as leaked.
  750.          *
  751.          * External tools, such as Valgrind, know to run global destructors
  752.          * before checking for leaks, so this hack is only necessary when
  753.          * memdebug is used.
  754.          */
  755.         struct hack_free_global_backgrounds
  756.         {
  757.                 ~hack_free_global_backgrounds()
  758.                 {
  759.                         newmenu_free_background();
  760.                 }
  761.         };
  762.         hack_free_global_backgrounds hack_free_global_background;
  763. #endif
  764.  
  765.         con_puts(CON_DEBUG, "Doing gamedata_init...");
  766.         gamedata_init();
  767.  
  768. #if defined(DXX_BUILD_DESCENT_II)
  769. #if DXX_USE_EDITOR
  770.         if (GameArg.EdiSaveHoardData) {
  771.                 save_hoard_data();
  772.                 exit(1);
  773.         }
  774.         #endif
  775. #endif
  776.  
  777.         if (CGameArg.DbgNoRun)
  778.                 return(0);
  779.  
  780.         con_puts(CON_DEBUG, "Initializing texture caching system...");
  781.         texmerge_init();                // 10 cache bitmaps
  782.  
  783. #if defined(DXX_BUILD_DESCENT_II)
  784.         piggy_init_pigfile("groupa.pig");       //get correct pigfile
  785. #endif
  786.  
  787.         con_puts(CON_DEBUG, "Running game...");
  788.         init_game();
  789.  
  790. #if defined(DXX_BUILD_DESCENT_I)
  791.         key_flush();
  792. #endif
  793.         {
  794.                 InterfaceUniqueState.PilotName.fill(0);
  795.                 if (!CGameArg.SysPilot.empty())
  796.                 {
  797.                         char filename[sizeof(PLAYER_DIRECTORY_TEXT) + CALLSIGN_LEN + 4];
  798.  
  799.                         /* Step over the literal PLAYER_DIRECTORY_TEXT when it is
  800.                          * present.  Point at &filename[0] when
  801.                          * PLAYER_DIRECTORY_TEXT is absent.
  802.                          */
  803.                         const auto b = &filename[-CGameArg.SysUsePlayersDir];
  804.                         snprintf(filename, sizeof(filename), PLAYER_DIRECTORY_STRING("%.12s"), CGameArg.SysPilot.c_str());
  805.                         /* The pilot name is never used after this.  Clear it to
  806.                          * free the allocated memory, if any.
  807.                          */
  808.                         CGameArg.SysPilot.clear();
  809.                         auto p = b;
  810.                         for (const auto &facet = std::use_facet<std::ctype<char>>(std::locale::classic()); char &c = *p; ++p)
  811.                         {
  812.                                 c = facet.tolower(static_cast<uint8_t>(c));
  813.                         }
  814.                         auto j = p - filename;
  815.                         if (j < sizeof(filename) - 4 && (j <= 4 || strcmp(&filename[j - 4], ".plr"))) // if player hasn't specified .plr extension in argument, add it
  816.                         {
  817.                                 strcpy(&filename[j], ".plr");
  818.                                 j += 4;
  819.                         }
  820.                         if(PHYSFSX_exists(filename,0))
  821.                         {
  822.                                 InterfaceUniqueState.PilotName.copy(b, std::distance(b, &filename[j - 4]));
  823.                                 InterfaceUniqueState.update_window_title();
  824.                                 read_player_file();
  825.                                 WriteConfigFile();
  826.                         }
  827.                 }
  828.         }
  829.  
  830. #if defined(DXX_BUILD_DESCENT_II)
  831. #if DXX_USE_EDITOR
  832.         if (!GameArg.EdiAutoLoad.empty()) {
  833.                 /* Any number >= FILENAME_LEN works */
  834.                 Level_names[0].copy_if(GameArg.EdiAutoLoad.c_str(), GameArg.EdiAutoLoad.size());
  835.                 LoadLevel(1, 1);
  836.         }
  837.         else
  838. #endif
  839. #endif
  840.         {
  841.                 Game_mode = GM_GAME_OVER;
  842.                 DoMenu();
  843.         }
  844.  
  845.         while (window_get_front())
  846.                 // Send events to windows and the default handler
  847.                 event_process();
  848.        
  849.         // Tidy up - avoids a crash on exit
  850.         {
  851.                 window *wind;
  852.  
  853.                 show_menus();
  854.                 while ((wind = window_get_front()))
  855.                         window_close(wind);
  856.         }
  857.  
  858.         WriteConfigFile();
  859.         show_order_form();
  860.  
  861.         con_puts(CON_DEBUG, "Cleanup...");
  862.         close_game();
  863.         texmerge_close();
  864.         gamedata_close();
  865.         gamefont_close();
  866.         Current_mission.reset();
  867.         PHYSFSX_removeArchiveContent();
  868.  
  869.         return(0);              //presumably successful exit
  870. }
  871.  
  872. }
  873.  
  874. int main(int argc, char *argv[])
  875. {
  876.         mem_init();
  877. #if DXX_WORDS_NEED_ALIGNMENT
  878.         prctl(PR_SET_UNALIGN, PR_UNALIGN_NOPRINT, 0, 0, 0);
  879. #endif
  880. #if defined(WIN32) || defined(__APPLE__) || defined(__MACH__)
  881. #if DXX_USE_EDITOR
  882.         set_warn_func(msgbox_warning);
  883. #endif
  884. #ifdef WIN32
  885.         void d_set_exception_handler();
  886.         d_set_exception_handler();
  887. #endif
  888. #endif
  889.         return dsx::main(argc, argv);
  890. }
  891.  
  892. #undef argv
  893. #undef argc
  894.