Files
Descent3/Descent3/init.cpp
2025-06-02 23:13:54 +02:00

2177 lines
60 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Descent 3
* Copyright (C) 2024 Parallax Software
* Copyright (C) 20242025 Descent Developers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
--- HISTORICAL COMMENTS FOLLOW ---
* $Logfile: /DescentIII/Main/init.cpp $
* $Revision: 323 $
* $Date: 10/22/01 12:42p $
* $Author: Matt $
*
* Initialization of D3 systems
*
* $Log: /DescentIII/Main/init.cpp $
*
* 323 10/22/01 12:42p Matt
* Added MercInstalled() function.
*
* 322 10/03/01 12:45a Kevin
* Smaller version of pxo packets
*
* 321 9/15/01 1:46p Kevin
* Added -nocrashbox to suppress crash dialog box
*
* 320 9/14/01 4:47p Matt
* Cleaned up problems when screen bit depth set to 32.
*
* 319 9/14/01 12:50p Matt
* Took out code that bashed the missile view ot left if it was set to
* center. It's now not possible to set the view to center in the config
* menu.
*
* 318 4/19/00 5:36p Matt
* Added command-line option to adjust mouse sensitivity
*
* 317 3/20/00 12:11p Matt
* Merge of Duane's post-1.3 changes.
* Misc Mac stuff: movie, int'l keyboards, loading screens (Mac only)
*
* 316 1/26/00 9:20p Jeff
* added support for IntelliVIBE DLL
*
* 315 12/01/99 3:58p Jeff
* one last time...linux pregamecdcheck bug fix
*
* 314 12/01/99 3:30p Jeff
* set CD_inserted to 1 for Linux
*
* 313 11/30/99 5:07p Jeff
* no pregame cd check for Linux (for now)
*
* 312 10/26/99 3:30p Jeff
* handle extra.gam addon tablefile
*
* 311 10/25/99 3:09p Kevin
* added -mlooksens
*
* 310 10/25/99 9:48a Matt
* Mac code that should enable the dynamic allocation of lightmap_info
* structures. This should be disabled for editor builds.
*
* 309 10/25/99 12:47a Chris
* Fixed a long overdue bug with zero rad wall collison objects and
* colliding
*
* 308 10/22/99 10:52p Matt
* Mac merge
*
* 307 10/22/99 10:43p Jeff
* put in a variable to detect whether we are running the editor (needed
* in manage system, which can't use EDITOR define)
*
* 306 10/19/99 4:55p Jeff
* removed compiler warning
*
* 305 10/19/99 12:44p Chris
* Fixed a small bug with the registery check
*
* 304 10/18/99 1:59p Chris
* Added the ability to load the merc. hog
*
* 303 10/17/99 3:55p Jeff
* Linux movie stuff
*
* 302 10/12/99 11:03a Jeff
* if there is a -mission command line option, open that mn3 right after
* d3.hog for any overridables
*
* 301 10/06/99 2:04p Kevin
* copy protection fix to match the 1.2 full cd
*
* 300 10/05/99 10:11a Kevin
* Don't show tantrum logo on macintosh demo (per GraphSim's Request)
*
* 299 10/05/99 9:46a Kevin
* copy protection can now handle US/AUS & ROW no LL versions in one exe
*
* 298 9/29/99 8:05a Kevin
* Changes to copy protection to allow for us and ROW-NONLL versions to
* use the same exe
*
* 297 9/24/99 12:01p Samir
* use directinput when -alternatejoy is selected (like 1.0)
*
* 296 9/23/99 2:59p Kevin
* mac dll hog file
*
* 295 9/20/99 5:35p Jeff
* added -nosparkles command line option to turn off powerup sparkles
*
* 294 9/18/99 9:21p Jeff
* Init motion blur if we are a Katmai
*
* 293 8/20/99 9:45a Kevin
* Rankings changes!
*
* 292 7/30/99 5:24p Samir
* use no joystick emulation by default.
*
* 291 7/29/99 12:27p Chris
* FIxed a mismatched paren
*
* 290 7/28/99 5:11p Kevin
* Mac merges
*
* 289 7/26/99 5:19p Kevin
* fixed copy protection for DVD drives
*
* 288 7/12/99 6:44p Jeff
* create a lock file in the temp directory, if one already exists (for a
* program in use), then don't allow the use of the temp directory
*
* 287 7/08/99 5:44p Jason
* added default framecap of 60 to deal with stuttering issues
*
* 286 7/06/99 5:54p Kevin
* more foriegn versions....
*
* 285 6/24/99 8:10p Jeff
* added support for OpenGL renderer
*
* 284 6/24/99 3:15p Jeff
* don't check renderer in Linux if dedicated
*
* 283 6/22/99 7:03p Jeff
* added command line arguments to set renderer for Linux (Glide only
* right now)
*
* 282 6/21/99 2:12p Kevin
* South american version changes
*
* 281 6/17/99 11:34a Kevin
*
* 280 6/16/99 12:04p Kevin
* Warning!!! This is a laserlocked version!
*
* 279 6/11/99 1:15a Samir
* localization issues.
*
* 278 6/08/99 1:00p Jason
* changes for bumpmapping
*
* 277 6/03/99 8:48a Kevin
* fixes for new OEM version....
*
* 276 5/24/99 6:20a Kevin
* fixed dedicated server & copy protection
*
* 275 5/24/99 2:13a Matt
* Fixed -superlowmem switch.
*
* 274 5/23/99 3:03p Kevin
* real dist. checksums
*
* 273 5/23/99 2:38a Kevin
* Lame ass(tm) copy protection
*
* 272 5/21/99 10:05a Kevin
* Added stuff for a future DVD version
*
* 271 5/19/99 11:47a Kevin
* made the parent window of the message box actually be Descent 3.
*
* 270 5/18/99 10:31a Kevin
* made the us version only work with US english and US canadian languages
*
* 269 5/12/99 2:24p Jeff
* Descent3 now has a setable temp directory for all temp files
*
* 268 5/12/99 1:18p Samir
* play music during game too when in menus.
*
* 267 5/11/99 1:19a Samir
* upped music volume, set default to 0.5
*
* 266 5/10/99 9:25p Jeff
* first phase of Rock 'n' Ride support added
*
* 265 5/10/99 8:49p Jason
* added vsync command line switch
*
* 264 5/10/99 5:35p Kevin
* New command line options for heat and scoring API enhancements
*
* 263 5/07/99 6:54p Jason
* fixed some gamegauge issues
*
* 262 5/07/99 12:04p Samir
* added support for foreign keyboards and error text.
*
* 261 5/06/99 6:11p Kevin
* fixes for save/load game syste. Also require CD again and added some
* heat.net stuff
*
* 260 5/05/99 11:16p Kevin
* heat.net stuff among other things
*
* 259 5/05/99 5:46p Samir
* took out call to ResumeSounds when restoring from an Alt-tab.
*
* 258 5/02/99 9:13a Jeff
* added system specific hog files (d3-linux.hog for Linux)
*
* 257 5/01/99 4:24p Jeff
* fixed some windows specific code for Linux (*grrrr*)
*
* 256 4/30/99 10:53p Samir
* store pilot settings in a temporary buffer when multitasking.
*
* 255 4/30/99 5:06p Kevin
* misc dedicated server, networking and low memory enhancements
*
* 254 4/29/99 10:01p Samir
* use emulation mode of joystick first.
*
* 253 4/29/99 5:53p Kevin
* Made it so Japanese people can't play D3... well that is only if their
* computers have the Japanese language installed. I'm not prejudice or
* anything....It's just that Interplay doesn't want the english version
* selling in Japan or something like that. :)
*
* 252 4/29/99 2:28p Kevin
* Laserlock implementation
*
* 251 4/27/99 9:59p Kevin
* CD not requred for dedicated server. Also improved demo playback
*
* 250 4/27/99 2:10p Samir
* added code to set the desired sound card given the descriptive name of
* a sound card.
*
* 249 4/26/99 9:11p Matt
* Use small font instead of old UI font.
*
* 248 4/26/99 11:34a Samir
* don't resume sounds if game was paused when alt-tabbing back
* (ResumeGame will do the trick.)
*
* 247 4/25/99 6:14p Kevin
* added "-timetest file.dem" to behave like gamegauge does
*
* 246 4/25/99 4:15p Matt
* Added code to manually allow the user to specifiy the screen aspect
* ratio, to make the game work with wide-screen TVs.
*
* 245 4/25/99 1:27p Matt
* Fixed small bug
*
* 244 4/22/99 9:53a Kevin
* Fixed some dedicated server crashes
*
* 243 4/20/99 11:44a Jeff
* get the language type from the registry
*
* 242 4/17/99 7:42p Samir
* Don't save out renderer and sound mixer in release version since the
* launcher should only do this.
*
* 241 4/17/99 6:15p Samir
* replaced gr.h with grdefs.h and fixed resulting compile bugs.
*
* 240 4/16/99 12:03a Jeff
* removed cd check for Linux
*
* 239 4/15/99 3:48p Samir
* set mouse mode when ddio is initialized.
*
* 238 4/15/99 2:32p Kevin
* Added some code for the Demo
*
* 237 4/15/99 10:57a Kevin
* cd check only in release builds
*
* 236 4/15/99 9:25a Kevin
* CD check fixes and updates
*
* 235 4/14/99 3:07p Kevin
* Fixed some multiple CD bugs
*
* 234 4/14/99 12:35p Samir
* localization issues.
*
* 233 4/14/99 11:48a Matt
* Don't set messagebox title for release builds
*
* 232 4/14/99 2:50a Jeff
* fixed some case mismatched #includes
*
* 231 4/12/99 7:15p Samir
* added ability to configure number of sounds played at one time.
*
* 230 4/09/99 12:02p Samir
* joystick changes (Win32 DirectInput support)
*
* 229 4/06/99 4:15p Nate
* Fixed UpdateInitMessage in editor (samir)
*
* 228 4/06/99 1:53p Samir
* added improved progress bar.
*
* 227 4/05/99 9:53a Kevin
* Took out the splash screens Craig made me add while he was smoking
* crack.
*
* 226 4/04/99 8:15p Jeff
* added debug graph stuff
*
* 225 4/03/99 1:24p Jason
* changed some wording for loading screen
*
* 224 4/02/99 7:04p Kevin
* Added splash screens do release builds
*
* 223 4/02/99 5:08p Matt
* Added intro movie.
*
* 222 4/02/99 3:49p Kevin
* Added profanity filter code
*
* 221 4/02/99 1:26p Matt
* Changes I made for the OEM version but forgot to check in. Oops.
*
* 220 3/19/99 4:08p Kevin
* Multiple CD installation support
*
* 219 3/09/99 12:34p Jeff
* extract scripts to custom\cache
*
* 218 3/08/99 3:29p Samir
* RestartD3 ddio_Init key emulation = true.
*
* 217 3/05/99 5:23p Jeff
* extract scripts from extra.hog before d3.hog
*
* 216 3/04/99 1:15p Jeff
* erase temporary files that may have been left over from last run
*
* 215 3/02/99 5:21p Jason
* fixed some flip bugs
*
* 214 3/02/99 2:21p Samir
* windows 95 and NT both use same keyboard handler due to flaky
* directinput.
*
* 213 3/02/99 1:49a Mark
* put ifdefs around showstaticscreen
*
* 212 3/02/99 12:16a Jeff
*
* 211 3/02/99 12:06a Kevin
*
* 210 3/01/99 11:48p Jeff
* fixed prototype placement
*
* 209 3/01/99 11:47p Kevin
*
* 208 3/01/99 11:38p Kevin
*
* 207 3/01/99 9:03p Kevin
* OEM Beta 4
*
* 206 2/19/99 10:31p Samir
* added music volume.
*
* 205 2/17/99 12:38p Kevin
* Added -framecap <fps> to limit frame and fixed timer bug and old
* framerate limiter code.
*
* 204 2/16/99 12:00p Samir
* added new video resolution swtich test.
*
* 203 2/16/99 12:36a Kevin
* Fixes for release builds of OEM V3 and KAtmai
*
* 202 2/15/99 3:24p Kevin
*
* 201 2/15/99 3:23p Kevin
* Disabled procedurals for gamegauge
*
* 200 2/15/99 3:20p Kevin
* Fixed bug with dlls in a hog
*
* 199 2/15/99 1:22p Kevin
* Changes for GameGauge
*
* 198 2/11/99 10:35p Jeff
* added support for multiple languages in string table files
*
* 197 2/10/99 3:29p Jeff
* extracted dll manager knows difference between game hogs and miission
* hogs
*
* 196 2/09/99 1:29a Jeff
* added code to let D3 process multiplayer games in the background if
* game is not in focus.
*
* 195 2/08/99 2:24p Kevin
* Display bundler.mve and bundler.tga if they are included in the OEM
* package.
*
* 194 2/05/99 7:23p Kevin
* OEM Changes
*
* 193 2/04/99 9:46a Kevin
* OEM version changes
*
* 192 1/31/99 8:51p Jeff
* new in game cinematics system finished
*
* 191 1/29/99 5:22p Jeff
* localization
*
* 190 1/27/99 6:08p Jason
* first pass at markers
*
* 189 1/27/99 2:58p Jason
* fixed center small view
*
* 188 1/25/99 6:47p Samir
* allow slow keyboard
*
* 187 1/25/99 11:02a Samir
* revamped mouse and key controls.
*
* 186 1/25/99 12:33a Jeff
* save out scorch marks and weapon corona detail settings
*
* 185 1/21/99 11:15p Jeff
* pulled out some structs and defines from header files and moved them
* into separate header files so that multiplayer dlls don't require major
* game headers, just those new headers. Side effect is a shorter build
* time. Also cleaned up some header file #includes that weren't needed.
* This affected polymodel.h, object.h, player.h, vecmat.h, room.h,
* manage.h and multi.h
*
* 184 1/17/99 10:41p Kevin
* Added command line options for setting the renderer in GAMEGAUGE mode.
*
* 183 1/13/99 3:25p Jason
* fixed vsync problem
*
* 182 1/08/99 2:58p Kevin
* Added TCP mprintf support so you can log to a remote machine.
*
* 181 1/08/99 2:55p Samir
* Ripped out OSIRIS1.
*
* 180 1/07/99 12:28p Samir
* Call to InitD3Music added parameter.
*
* 179 1/05/99 3:59p Kevin
*
* 178 1/05/99 3:55p Kevin
* Added structured exception handling
*
* 177 1/04/99 5:43p Kevin
* new command line args
*
* 176 12/23/98 6:38p Kevin
* All UDP data (except gamespy) now uses one (registered) port number
*
* 175 12/16/98 12:04p Kevin
* GameSpy!
*
* 174 12/14/98 4:48p Jeff
* call to intialize Osiris module manager
*
* 173 12/10/98 3:41p Jeff
* implemented settings for 16 or 32 bit depth (in config)
*
* 172 12/07/98 11:30a Kevin
* Added some features from the 1.1 demo patch
*
* 171 12/02/98 1:07p Jason
* made vsync work correctly, finally
*
* 170 11/24/98 5:17p Jeff
* initialize Pilot Pics
*
* 169 11/23/98 12:31p Jeff
* save out force feedback stuff (bad merge, we lost it earlier)
*
* 168 11/13/98 2:29p Samir
* new music code.
*
* 166 11/09/98 2:59p Kevin
* Added command line option for disabling multiplayer bitmap exchange
*
* 165 11/03/98 6:43p Jeff
* new low-level & high level Force Feedback system implemented, handles
* window losing focus, etc.
*
* 164 10/24/98 2:18p Samir
* don't do mouse stuff for dedicated server.
*
* 163 10/22/98 2:42p Samir
* fixed ALT-TAB pause issue.
*
* 162 10/22/98 1:58p Kevin
* Fixed the working directory (-setdir) command
*
* 161 10/22/98 1:39p Jeff
* autolevel is default full
*
* 160 10/20/98 6:24p Jason
* added super low memory mode
*
* 159 10/20/98 10:56a Sean
* fixed #ifdef editor thingy
*
* 158 10/20/98 12:58a Jeff
* added a way to force a lo-resolution timer
*
* 157 10/20/98 12:10a Samir
* this should fix the problem of the mouse not working properly in game.
*
* 156 10/19/98 6:30p Jeff
* changes made for detail variables. Put in preset values. Preset
* options. Removed terrain_cast from detail. Put new callbacks in
* UIListBox and UISlider
*
* 153 10/18/98 9:12p Matt
* Use new symbolic constant for the program name.
*
* 152 10/18/98 8:51p Matt
* Revamped debug/error system.
*
* 151 10/18/98 3:36p Jeff
* if _DEBUG isn't defined than the rtp_enable/disableflags call gets
* compiled out
*
* 150 10/18/98 2:50p Kevin
* Use low memory mode in dedicated server mode.
*
* 149 10/17/98 5:50p Jeff
* hooked in rtperformance (run time performance) library
*
* 148 10/17/98 12:46p Kevin
* Beta 4 fixes
*
* 147 10/16/98 2:44p Kevin
* working on getting demo compiling
*
* 146 10/16/98 1:54p Kevin
* Changes for Demo Beta 4
*
* 145 10/15/98 1:33p Jeff
* removed amount of debris detail level. Added powerup halo detail
* level. Added predef detail level settings
*
* 144 10/15/98 11:58a Kevin
* checked for low mem
*
* 143 10/14/98 4:37p Matt
* Made InitD3System() exit with error if there's a problem instead of
* returning a status value. Also moved some editor-specific code from
* init.cpp to mainfrm.cpp, and cleaned up some other initialization and
* error-handling code.
*
* 142 10/13/98 3:47p Samir
* added function to check if a cursor is visible
*
* 141 10/13/98 3:41p Kevin
* bug fixes
*
* 140 10/13/98 2:49p Matt
* Open "extra.hog" (if it exists" at startup so we can put any extra data
* in there.
*
* 139 10/12/98 3:01p Jeff
* added vsync and more detail level settings
*
* 138 10/12/98 2:51p Samir
* use main menu background for loading data screen.
*
* 137 10/09/98 8:47p Samir
* don't kill sound library when shutting down game.
*
* 136 10/08/98 7:27p Samir
* don't change defer handlers when shuting down or restarting.
*
* 135 10/08/98 5:55p Matt
* Set main hogfile.
*
* 134 10/08/98 3:36p Jason
* fixes for the demo
*
* 133 10/08/98 1:23p Samir
* shutdown and reinit now do so with ddio systems.
*
* 132 10/07/98 2:54p Jeff
* General UI fixes and additions
*
* 131 10/07/98 12:55p Jason
* fixed some defaults
*
* 130 10/03/98 11:21p Matt
* Added system to separately control outline mode for mine, terrain, sky,
* & objects
*
* 129 10/01/98 11:57a Matt
* Added some mprintf()s
*
* 128 9/30/98 10:36a Kevin
* Added command line launching of URLs and command line directory
* specification
*
* 127 9/25/98 2:53p Jason
* added progress bar
*
* 126 9/25/98 12:31p Samir
* in main game, hide cursor when starting.
*
* 125 9/23/98 3:08p Jeff
*
* 124 9/22/98 6:58p Samir
* Render_floating_triggers is _DEBUG code, so make it so.
*
* 123 9/22/98 3:55p Samir
* ifdef out stuff for non-debug version.
*
* 122 9/22/98 10:32a Jason
* made preferred renderer default to OpenGL
*
* 121 9/21/98 11:10a Jeff
* Calls to init/close forcefeedback
*
* 120 9/18/98 7:38p Jeff
* creation of low-level forcefeedback and beginning of high-level
* forcefeedback
*
* 119 9/18/98 1:27p Jason
* cleaned up renderer initting
*
* 118 9/16/98 6:07p Jason
* made dedicated server use standard mouse mode
*
* 117 9/15/98 4:31p Jason
* added more functionality for the dedicated server
*
* 116 9/14/98 6:28p Jason
* first pass at getting dedicated server working
*
* 115 9/03/98 12:11p Chris
* Adding matcen support
*
* 114 8/31/98 12:39p Samir
* added code to resume controllers when restoring game mode.
*
* 113 8/27/98 6:23p Jeff
* changed autoleveling in config so it is a slider...had to convert
* global from bool->uint8_t. Added fast headlight and mirrored surfaces to
* config menu
*
* 112 8/19/98 2:19p Jeff
* moved detail globals to a struct
*
* 111 8/17/98 6:40p Matt
* Added ambient sound system
*
* 110 8/15/98 5:16p Matt
* Added new Base_directory variable. Got rid of D3_LOCAL check and
* 'local directory' registry variable.
*
* 109 8/10/98 5:52p Samir
* took out briefings search path.
*
* 108 7/31/98 11:51a Jason
* added player ship choosing to multiplayer games
*
* 107 7/24/98 5:32p Samir
* added initializer for D3 Music.
*
* 106 7/13/98 12:42p Samir
* don't do initmessage if graphics system not initialized.
*
* 105 7/08/98 6:27p Samir
* stream library integrated with highlevel sound system.
*
* 104 7/01/98 4:56p Samir
* redid init code.
*
* 103 6/24/98 11:14a Chris
* Added more support and bug fixes
*
* 102 6/23/98 6:00p Chris
* DirectSound 16 mixer is active with 8 bit samples
*
* 101 6/22/98 12:00p Chris
* Working on sound system to make it in a nice shape.
*
* 100 6/19/98 6:42p Jason
* made specular mapping a config detail item
*
* 99 6/19/98 6:04p Jeff
* variables to turn on/off voices
*
* 98 6/18/98 5:22p Jeff
* initialize streaming audio system
*
* 97 6/17/98 3:58p Jeff
* put in PilotInit(). String table loaded near begining for Main exe,
* after tables are loaded for editor
*
* 96 6/16/98 3:48p Chris
* Updated the sound system and added the start of sound streaming
*
* 95 6/16/98 11:49a Jeff
* string table loaded after manage system
*
* 94 6/16/98 10:54a Jeff
*
* 93 6/12/98 5:56p Jeff
* Load string tables during init
*
* 92 6/08/98 3:56p Jeff
* added initializing functions for compressed audio and voice systems
*
* 91 6/02/98 6:03p Jason
* added specular lightmaps
*
* 90 6/02/98 4:37p Samir
* multiple joysticks supported.
*
* 89 6/01/98 11:37a Chris
*
* 88 5/19/98 3:43p Samir
* must move mem_Init after error_Init.
*
* 87 5/19/98 3:37p Samir
* added mem_Init
*
* 86 5/14/98 11:49a Chris
* Bettered the sound paging system
*
* 85 5/12/98 2:05p Craig
* errror
*
* 84 5/12/98 11:45a Samir
* added logfile init.
*
* 83 5/06/98 6:34p Jeff
* Added Terrain casting to config
*
* 82 5/06/98 4:32p Samir
* moved ui init back to its proper place.
*
* 81 5/06/98 12:44p Jeff
* added saving/restoring video resolution
*
* 80 5/05/98 5:16p Samir
* took out calls to init UI system (that's done now in SetScreenMode)
*
* 79 5/05/98 3:02p Jason
* attempting to add different screen resolutions
*
* 78 5/04/98 3:42p Matt
* Page in all sounds at init time, so you don't have to wait when you're
* starting a game
*
* 77 5/01/98 4:48p Jeff
* Added autoleveling into the configuration
*
* 76 4/28/98 6:42p Matt
* If registry says renderer is software, force it to be glide.
*
* 75 4/28/98 11:56a Jeff
* moved things from config (d3.cfg) into the registry
*
* 74 4/24/98 1:53a Samir
* added trigger init and free.
*
* 73 4/16/98 6:53a Samir
* added default script warning system.
*
* 72 4/16/98 12:23a Samir
* fixed bug when checking if script compiled in editor.
*
* 71 4/14/98 7:31p Matt
* Changed code to use ddio_MakePath() instead of sprintf() to create file
* spec
*
* 70 4/10/98 7:48p Samir
* make sure to set default values for outlining, etc.
*
* 69 4/09/98 5:30p Samir
* new main menu art.
*
* 68 4/08/98 7:19p Samir
* Added runtime debugging option.
*
* 67 4/07/98 9:20p Samir
* Changes to debug stuff.
*
* 66 4/06/98 5:13p Chris
* Sounds page in at the beginning of a level
*
* 65 4/02/98 7:58p Samir
* make sure to pause game and close/init control system when application
* looses focus.
*
* 64 3/27/98 5:18p Samir
* initialize debug break handlers differently for editor.
*
* 63 3/27/98 3:29p Brent
* if joy init fails, don't try initializing joystick. (samir)
*
* 62 3/27/98 2:44p Samir
* Restore joystick initialization.
*
* 61 3/23/98 8:03p Samir
* A bunch of changes to allow for ALT-TAB to work.
*
* 60 3/20/98 5:51p Jason
* more changes for multiplayer
*
* 59 3/20/98 1:19p Jeff
* Changes made to use Default_pilot string for pilot filename to use.
*
* 58 3/19/98 11:27a Samir
* Better error checking.
*
* 57 3/13/98 1:22p Jason
* Moved UseHardware flag to the renderer lib where it belongs
*
* 56 3/10/98 5:16p Samir
* Got debug callbacks working when you hit an Int3.
*
* 55 3/05/98 6:39p Samir
* Initialize ui system with UI_FONT
*
* 54 3/04/98 12:00p Jason
* added default gamma settings
*
* 53 2/27/98 5:35p Jeff
* Added in loading and saving of a game configuration file
*
* 52 2/18/98 1:33a Jason
* don't do mip mapping by default
*
* 51 2/18/98 1:11a Samir
* Some game window mess.
*
* 50 2/17/98 2:21p Samir
* Added d3xdebug.h
*
* 49 2/14/98 10:48p Jason
* got preferred rendering working
*
* 46 2/11/98 5:55p Samir
* Now InitD3XDebug and CloseD3XDebug are called when you enter and leave
* the game. This as well as ui_Init and ui_Close
*
* 45 2/02/98 7:34p Samir
* Moved D3X Initialization to PlayGame.
*
* 44 1/29/98 12:24p Samir
* Added logfile support.
*
* 43 1/27/98 1:20p Samir
* Fixed initialization for main game.
*
* 42 1/13/98 12:31p Samir
* only register small font for editor.
*
* 41 1/02/98 5:32p Chris
* More radical changes to the sound system
*
* 40 12/31/97 1:01a Chris
* Removed old dead code
*
*
*
* $NoKeywords: $
*/
// Initialization routines for Descent3/Editor
#include <cstring>
#include <ctime>
#include <filesystem>
#include <regex>
#include "mono.h"
#include "gametexture.h"
#include "object.h"
#include "vecmat.h"
#include "init.h"
#include "config.h"
#include "3d.h"
#include "d3_platform_path.h"
#include "hlsoundlib.h"
#include "manage.h"
#include "bitmap.h"
#include "ddio.h"
#include "render.h"
#include "descent.h"
#include "renderer.h"
#include "vclip.h"
#include "grdefs.h"
#include "pserror.h"
#include "lighting.h"
#include "polymodel.h"
#include "door.h"
#include "terrain.h"
#include "soundload.h"
#include "ship.h"
#include "controls.h"
#include "Mission.h"
#include "findintersection.h"
#include "appdatabase.h"
#include "room.h"
#include "game.h"
#include "gamefile.h"
#include "gamespy.h"
#include "TelCom.h"
#include "objinfo.h"
#include "cinematics.h"
#include "lightmap_info.h"
#include "fireball.h"
#include "networking.h"
#include "args.h"
#include "pilot.h"
#include "gameloop.h"
#include "trigger.h"
#include "physics.h"
#include "special_face.h"
#include "voice.h"
#include "localization.h"
#include "log.h"
#include "stringtable.h"
#include "player.h"
#include "psrand.h"
#include "ambient.h"
#include "matcen.h"
#include "dedicated_server.h"
#include "D3ForceFeedback.h"
#include "newui.h"
#include "SmallViews.h"
#include "uisys.h"
#include "rtperformance.h"
#include "d3music.h"
#include "PilotPicsAPI.h"
#include "osiris_dll.h"
#include "mem.h"
#include "multi.h"
#include "marker.h"
#include "gamecinematics.h"
#include "debuggraph.h"
#include <algorithm>
// Uncomment this to allow all languages
#define ALLOW_ALL_LANG 1
#ifdef EDITOR
#include "editor\HFile.h"
#include "editor\d3edit.h"
#include "slew.h"
#include "gr.h"
#define INIT_MESSAGE(c) SplashMessage c
#else
void IntroScreen();
#define INIT_MESSAGE(c) InitMessage(c)
#endif
#if defined(EDITOR) || defined(NEWEDITOR)
bool Running_editor = true; // didn't we have a variable like this somewhere
#else
bool Running_editor = false; // didn't we have a variable like this somewhere
#endif
static bool Init_in_editor = false;
// Base directory from configuration path
std::filesystem::path config_base_directory;
// used to update load bar.
static void SetInitMessageLength(const char *c, float amount); // portion of total bar to fill (0 to 1)
extern void UpdateInitMessage(float amount); // amount is 0 to 1
static void SetupTempDirectory(void);
// Delete all temp files with regex "d3[smocti].+\\.tmp"
static void DeleteTempFiles();
static void InitIOSystems(bool editor);
static void InitStringTable();
static void InitGraphics(bool editor);
static void InitGameSystems(bool editor);
static void InitDedicatedServer();
#define TEMPBUFFERSIZE 256
// If there's a joystick, this is the stick number. Else, this is -1
char App_ddvid_subsystem[8];
// other info.
static chunked_bitmap Title_bitmap;
static bool Init_systems_init = false;
static bool Graphics_init = false;
static bool Title_bitmap_init = false;
uint8_t Use_motion_blur = 0;
extern int Min_allowed_frametime;
extern bool Render_powerup_sparkles;
extern int Use_file_xfer;
static const float kDefaultMouselookSensitivity = 9.102f;
static const float kAnglesPerDegree = 65536.0f / 360.0f;
float Mouselook_sensitivity = kAnglesPerDegree * kDefaultMouselookSensitivity;
float Mouse_sensitivity = 1.0f;
int merc_hid = -1;
/*
Initializes all the subsystems that need to be initialized BEFORE application creation.
Returns 1 if all is good, 0 if something is wrong
*/
void PreInitD3Systems() {
// initialize error system
bool debugging = false;
#ifndef RELEASE
debugging = (FindArg("-debug") != 0);
#endif
#ifdef DAJ_DEBUG
debugging = true;
#endif
error_Init(debugging, PRODUCT_NAME);
if (FindArg("-lowmem"))
Mem_low_memory_mode = true;
if (FindArg("-superlowmem"))
Mem_low_memory_mode = Mem_superlow_memory_mode = true;
if (FindArg("-dedicated"))
Mem_low_memory_mode = true;
mem_Init();
if (FindArg("-himem")) {
Mem_low_memory_mode = false;
Mem_superlow_memory_mode = false;
}
// For the client and the server, this turns off the bitmap exchange system.
if (FindArg("-nomultibmp"))
Use_file_xfer = 0;
int iframelmtarg = FindArg("-limitframe");
if (iframelmtarg) {
Min_allowed_frametime = atoi(GameArgs[iframelmtarg + 1]);
LOG_INFO.printf("Using %d as a minimum frametime", Min_allowed_frametime);
} else {
if (FindArg("-dedicated"))
Min_allowed_frametime = 30;
else
Min_allowed_frametime = 0;
}
iframelmtarg = FindArg("-framecap");
if (iframelmtarg) {
Min_allowed_frametime = ((float)1.0 / (float)atoi(GameArgs[iframelmtarg + 1])) * 1000;
LOG_INFO.printf("Using %d as a minimum frametime", Min_allowed_frametime);
} else {
// Default to a framecap of 60
Min_allowed_frametime = (1.0 / 60.0) * 1000;
LOG_INFO.printf("Using default framecap of 60");
}
// Mouselook sensitivity!
int msensearg = FindArg("-mlooksens");
if (msensearg) {
Mouselook_sensitivity = kAnglesPerDegree * atof(GameArgs[msensearg + 1]);
LOG_INFO.printf("Using mouselook sensitivity of %f", Mouselook_sensitivity);
}
// Mouse sensitivity (non-mouselook)
msensearg = FindArg("-mousesens");
if (msensearg) {
Mouse_sensitivity = atof(GameArgs[msensearg + 1]);
LOG_INFO.printf("Using mouse sensitivity of %f", Mouse_sensitivity);
}
grtext_Init();
#ifndef RELEASE
SetMessageBoxTitle(PRODUCT_NAME " Message");
#endif
}
void SaveGameSettings() {
char tempbuffer[TEMPBUFFERSIZE];
int tempint;
snprintf(tempbuffer, sizeof(tempbuffer), "%f", Render_preferred_state.gamma);
Database->write("RS_gamma", tempbuffer, strlen(tempbuffer) + 1);
snprintf(tempbuffer, sizeof(tempbuffer), "%f", Sound_system.GetMasterVolume());
Database->write("SND_mastervol", tempbuffer, strlen(tempbuffer) + 1);
snprintf(tempbuffer, sizeof(tempbuffer), "%f", D3MusicGetVolume());
Database->write("MUS_mastervol", tempbuffer, strlen(tempbuffer) + 1);
snprintf(tempbuffer, sizeof(tempbuffer), "%f", Detail_settings.Pixel_error);
Database->write("RS_pixelerror", tempbuffer, strlen(tempbuffer) + 1);
snprintf(tempbuffer, sizeof(tempbuffer), "%f", Detail_settings.Terrain_render_distance / ((float)TERRAIN_SIZE));
Database->write("RS_terraindist", tempbuffer, strlen(tempbuffer) + 1);
Database->write("Dynamic_Lighting", Detail_settings.Dynamic_lighting);
#ifdef _DEBUG
Database->write("Outline_mode", Outline_mode);
Database->write("Lighting_on", Lighting_on);
Database->write("Render_floating_triggers", Render_floating_triggers);
#endif
Database->write("TerrLeveling", Default_player_terrain_leveling);
Database->write("RoomLeveling", Default_player_room_leveling);
// Database->write("Terrain_casting",Detail_settings.Terrain_casting);
Database->write("Specmapping", Detail_settings.Specular_lighting);
Database->write("FastHeadlight", Detail_settings.Fast_headlight_on);
Database->write("MirrorSurfaces", Detail_settings.Mirrored_surfaces);
Database->write("MissileView", Missile_camera_window);
Database->write("RS_vsync", Render_preferred_state.vsync_on);
Database->write("DetailScorchMarks", Detail_settings.Scorches_enabled);
Database->write("DetailWeaponCoronas", Detail_settings.Weapon_coronas_enabled);
Database->write("DetailFog", Detail_settings.Fog_enabled);
Database->write("DetailCoronas", Detail_settings.Coronas_enabled);
Database->write("DetailProcedurals", Detail_settings.Procedurals_enabled);
Database->write("DetailObjectComp", Detail_settings.Object_complexity);
Database->write("DetailPowerupHalos", Detail_settings.Powerup_halos);
Database->write("RS_resolution", Current_video_resolution_id);
Database->write("RS_fov", static_cast<int>(Render_FOV_setting));
Database->write("RS_fullscreen", static_cast<int>(Game_fullscreen));
Database->write("RS_bitdepth", Render_preferred_bitdepth);
Database->write("RS_bilear", Render_preferred_state.filtering);
Database->write("RS_mipping", Render_preferred_state.mipping);
Database->write("RS_color_model", Render_state.cur_color_model);
Database->write("RS_light", Render_state.cur_light_state);
Database->write("RS_texture_quality", Render_state.cur_texture_quality);
Database->write("VoicePowerup", PlayPowerupVoice);
Database->write("VoiceAll", PlayVoices);
// Write out force feedback
Database->write("EnableJoystickFF", D3Use_force_feedback);
Database->write("ForceFeedbackAutoCenter", D3Force_auto_center);
uint8_t force_gain;
if (D3Force_gain < 0.0f)
D3Force_gain = 0.0f;
if (D3Force_gain > 1.0f)
D3Force_gain = 1.0f;
force_gain = (uint8_t)((100.0f * D3Force_gain) + 0.5f);
Database->write("ForceFeedbackGain", force_gain);
#ifndef RELEASE // never save this value out in release.
Database->write("SoundMixer", Sound_mixer);
Database->write("PreferredRenderer", PreferredRenderer);
#endif
tempint = Sound_quality;
Database->write("SoundQuality", tempint);
Database->write("SoundQuantity", Sound_system.GetLLSoundQuantity());
if (!Default_pilot.empty())
Database->write("Default_pilot", Default_pilot.c_str(), strlen(Default_pilot.c_str()) + 1);
else
Database->write("Default_pilot", " ", 2);
Database->write("GAME_base_directory", (const char*)config_base_directory.u8string().c_str(),
strlen((const char*)config_base_directory.u8string().c_str()) + 1);
}
/*
Read game variables from the registry
*/
void LoadGameSettings() {
char tempbuffer[TEMPBUFFERSIZE], *stoptemp;
int templen = TEMPBUFFERSIZE;
int tempint;
// set defaults
#ifdef _DEBUG
Outline_mode = OM_ALL;
Lighting_on = true;
#endif
Detail_settings.Specular_lighting = false;
Detail_settings.Dynamic_lighting = true;
Detail_settings.Fast_headlight_on = true;
Detail_settings.Mirrored_surfaces = true;
Detail_settings.Scorches_enabled = true;
Detail_settings.Weapon_coronas_enabled = true;
Render_preferred_state.mipping = true;
Render_preferred_state.filtering = true;
Render_preferred_state.bit_depth = 16;
Render_preferred_bitdepth = 16;
Default_player_terrain_leveling = 2;
Default_player_room_leveling = 2;
Render_preferred_state.gamma = 1.5;
PreferredRenderer = RENDERER_OPENGL;
Sound_system.SetLLSoundQuantity(MIN_SOUNDS_MIXED + (MAX_SOUNDS_MIXED - MIN_SOUNDS_MIXED) / 2);
D3MusicSetVolume(0.5f);
Detail_settings.Pixel_error = 8.0;
Sound_system.SetMasterVolume(1.0);
Detail_settings.Terrain_render_distance = 70.0 * TERRAIN_SIZE;
D3Use_force_feedback = true;
D3Force_gain = 1.0f;
D3Force_auto_center = true;
Current_video_resolution_id = Default_resolution_id;
PlayPowerupVoice = true;
PlayVoices = true;
Sound_mixer = SOUND_MIXER_SOFTWARE_16;
Sound_quality = SQT_NORMAL;
Missile_camera_window = SVW_LEFT;
Render_preferred_state.vsync_on = true;
Detail_settings.Fog_enabled = true;
Detail_settings.Coronas_enabled = true;
Detail_settings.Procedurals_enabled = true;
Detail_settings.Object_complexity = 1;
Detail_settings.Powerup_halos = true;
ddio_SetKeyboardLanguage(KBLANG_AMERICAN);
if (Database->read("KeyboardType", tempbuffer, &templen)) {
if (stricmp(tempbuffer, "French") == 0) {
ddio_SetKeyboardLanguage(KBLANG_FRENCH);
} else if (stricmp(tempbuffer, "German") == 0) {
ddio_SetKeyboardLanguage(KBLANG_GERMAN);
}
}
templen = TEMPBUFFERSIZE;
if (Database->read("GAME_base_directory", tempbuffer, &templen)) {
config_base_directory = tempbuffer;
}
templen = TEMPBUFFERSIZE;
if (Database->read("RS_gamma", tempbuffer, &templen)) {
Render_preferred_state.gamma = strtod(tempbuffer, &stoptemp);
}
templen = TEMPBUFFERSIZE;
if (Database->read("SND_mastervol", tempbuffer, &templen)) {
Sound_system.SetMasterVolume(strtod(tempbuffer, &stoptemp));
}
templen = TEMPBUFFERSIZE;
if (Database->read("MUS_mastervol", tempbuffer, &templen)) {
D3MusicSetVolume(strtod(tempbuffer, &stoptemp));
}
templen = TEMPBUFFERSIZE;
if (Database->read("RS_pixelerror", tempbuffer, &templen)) {
Detail_settings.Pixel_error = strtod(tempbuffer, &stoptemp);
}
templen = TEMPBUFFERSIZE;
if (Database->read("RS_terraindist", tempbuffer, &templen)) {
Detail_settings.Terrain_render_distance = strtod(tempbuffer, &stoptemp) * TERRAIN_SIZE;
}
templen = TEMPBUFFERSIZE;
Database->read_int("Dynamic_Lighting", &Detail_settings.Dynamic_lighting);
#ifdef _DEBUG
Database->read_int("Outline_mode", &Outline_mode);
Database->read("Lighting_on", &Lighting_on);
Database->read("Render_floating_triggers", &Render_floating_triggers);
#endif
Database->read_int("TerrLeveling", &Default_player_terrain_leveling);
Database->read_int("RoomLeveling", &Default_player_room_leveling);
Database->read("Specmapping", &Detail_settings.Specular_lighting);
Database->read("RS_bitdepth", &Render_preferred_bitdepth, sizeof(Render_preferred_bitdepth));
Database->read_int("RS_resolution", &tempint);
if (tempint >= 0 && tempint < std::size(Video_res_list))
Current_video_resolution_id = tempint;
else
LOG_WARNING << "Game settings contain a display resolution index that is out of bounds. Starting with default resolution.";
int tempval = 0;
Database->read_int("RS_fov", &tempval);
tempval = std::clamp(tempval, static_cast<int>(D3_DEFAULT_FOV), 90);
Render_FOV_setting = static_cast<float>(tempval);
Render_FOV = Render_FOV_setting;
Database->read_int("RS_fullscreen", &tempval);
Game_fullscreen = tempval != 0;
Database->read_int("RS_bilear", &Render_preferred_state.filtering);
Database->read_int("RS_mipping", &Render_preferred_state.mipping);
Database->read_int("RS_color_model", &Render_state.cur_color_model);
Database->read_int("RS_light", &Render_state.cur_light_state);
Database->read_int("RS_texture_quality", &Render_state.cur_texture_quality);
// force feedback stuff
Database->read("EnableJoystickFF", &D3Use_force_feedback);
Database->read("ForceFeedbackAutoCenter", &D3Force_auto_center);
uint8_t force_gain;
Database->read("ForceFeedbackGain", &force_gain, sizeof(force_gain));
if (force_gain > 100)
force_gain = 100;
D3Force_gain = ((float)force_gain) / 100.0f;
Database->read_int("PreferredRenderer", &PreferredRenderer);
Database->read_int("MissileView", &Missile_camera_window);
Database->read("FastHeadlight", &Detail_settings.Fast_headlight_on);
Database->read("MirrorSurfaces", &Detail_settings.Mirrored_surfaces);
Database->read_int("RS_vsync", &Render_preferred_state.vsync_on);
if (FindArg("-vsync"))
Render_preferred_state.vsync_on = true;
//@@ // Base missile camera if in wrong window
//@@ if (Missile_camera_window==SVW_CENTER)
//@@ Missile_camera_window=SVW_LEFT;
Database->read("VoicePowerup", &PlayPowerupVoice);
Database->read("VoiceAll", &PlayVoices);
Database->read("DetailScorchMarks", &Detail_settings.Scorches_enabled);
Database->read("DetailWeaponCoronas", &Detail_settings.Weapon_coronas_enabled);
Database->read("DetailFog", &Detail_settings.Fog_enabled);
Database->read("DetailCoronas", &Detail_settings.Coronas_enabled);
Database->read("DetailProcedurals", &Detail_settings.Procedurals_enabled);
Database->read_int("DetailObjectComp", &tempint);
Detail_settings.Object_complexity = tempint;
if (Detail_settings.Object_complexity < 0 || Detail_settings.Object_complexity > 2)
Detail_settings.Object_complexity = 1;
Database->read("DetailPowerupHalos", &Detail_settings.Powerup_halos);
if (Database->read_int("SoundMixer", &tempint))
Sound_mixer = tempint;
if (Database->read_int("SoundQuality", &tempint))
Sound_quality = tempint;
if (Database->read_int("SoundQuantity", &tempint)) {
Sound_system.SetLLSoundQuantity(tempint);
}
Sound_card_name[0] = 0;
templen = TEMPBUFFERSIZE;
if (Database->read("SoundcardName", tempbuffer, &templen)) {
strcpy(Sound_card_name, tempbuffer);
}
int len = _MAX_PATH;
char temp_str[_MAX_PATH] = "";
if (Database->read("Default_pilot", temp_str, &len)) {
Default_pilot = temp_str;
}
// Now that we have read in all the data, set the detail level if it is a predef setting (custom is ignored in
// function)
int level;
level = DETAIL_LEVEL_MED;
Database->read_int("PredefDetailSetting", &level);
ConfigSetDetailLevel(level);
// Motion blur
Use_motion_blur = 0;
if (Katmai || FindArg("-motionblur")) {
if (!FindArg("-nomotionblur")) {
Use_motion_blur = 1;
}
}
Render_powerup_sparkles = false;
if (Katmai && !FindArg("-nosparkles")) {
Render_powerup_sparkles = true;
}
}
/*
I/O systems initialization
*/
void InitIOSystems(bool editor) {
// Read in stuff from the registry
INIT_MESSAGE(("Reading settings."));
LoadGameSettings();
/*
* Populate base directories. In result, we have the following list of directories (in priority order):
* - Writable preference path
* - User defined paths (cmd-line and configuration)
* - Platform defined paths (such as /usr/share/Descent3 on Linux or Steam installation paths)
* - Directory of executable
*/
// Writable preference path
std::filesystem::path pref_path = ddio_GetPrefPath(D3_PREF_ORG, D3_PREF_APP);
if (pref_path.empty()) {
Error("Failed to get preference path!");
}
LOG_INFO << "Setting writable preference path " << pref_path;
cf_AddBaseDirectory(pref_path);
// Set the default base directories
cf_AddDefaultBaseDirectories();
// Additional paths
int additionaldirarg = 0;
while (0 != (additionaldirarg = FindArg("-additionaldir", additionaldirarg))) {
const auto dir_to_add = GetArg(additionaldirarg + 1);
if (dir_to_add == nullptr) {
LOG_WARNING << "-additionaldir requires directory path as value.";
break;
} else {
cf_AddBaseDirectory(dir_to_add);
additionaldirarg += 2;
}
}
// Path from configuration
if (!config_base_directory.empty()) {
cf_AddBaseDirectory(config_base_directory);
}
// Platform dependent paths
std::filesystem::path platform_dir = std::filesystem::canonical(D3_DATADIR);
cf_AddBaseDirectory(platform_dir);
// TODO: add Steam/registry locations
// Add path of executable
std::filesystem::path exec_path = ddio_GetBasePath();
// Populate exec_path with the executable path
if (exec_path.empty() || exec_path == platform_dir) {
LOG_DEBUG << "Skipping adding executable path (empty or redundant path).";
} else {
cf_AddBaseDirectory(exec_path);
}
LOG_INFO << "Base directories: " << cf_LocateMultiplePaths("");
Descent->set_defer_handler(D3DeferHandler);
#ifndef RELEASE
if (!editor && !FindArg("-windowed")) {
if (Dedicated_server) {
ddio_MouseMode(MOUSE_STANDARD_MODE);
} else {
ddio_MouseMode(MOUSE_EXCLUSIVE_MODE);
}
}
#else
ddio_MouseMode(MOUSE_EXCLUSIVE_MODE);
#endif
// do io init stuff
ddio_init_info io_info{};
io_info.obj = Descent;
INIT_MESSAGE(("Initializing DDIO systems."));
if (!ddio_Init(&io_info)) {
Error("I/O initialization failed.");
}
rtp_Init();
RTP_ENABLEFLAGS(RTI_FRAMETIME | RTI_RENDERFRAMETIME | RTI_MULTIFRAMETIME | RTI_MUSICFRAMETIME |
RTI_AMBSOUNDFRAMETIME);
RTP_ENABLEFLAGS(RTI_WEATHERFRAMETIME | RTI_PLAYERFRAMETIME | RTI_DOORFRAMETIME | RTI_LEVELGOALTIME |
RTI_MATCENFRAMETIME);
RTP_ENABLEFLAGS(RTI_OBJFRAMETIME | RTI_AIFRAMETIME | RTI_PROCESSKEYTIME);
// Setup temp directory
INIT_MESSAGE(("Setting up temp directory."));
SetupTempDirectory();
LOG_DEBUG << "Removing any temp files left over from last execution";
DeleteTempFiles();
// create directory system.
if (!mng_InitTableFiles()) {
#ifdef EDITOR
Error("Couldn't successfully initialize the table files. I'm shutting down!");
#else
Error(TXT_INITTABLEERR);
#endif
}
// Init hogfiles
INIT_MESSAGE(("Checking for HOG files."));
int d3_hid, extra_hid, sys_hid, extra13_hid;
std::filesystem::path hog_name;
#ifdef DEMO
// DAJ d3_hid = cf_OpenLibrary("d3demo.hog");
hog_name = "d3demo.hog";
#else
hog_name = "d3.hog";
#endif
d3_hid = cf_OpenLibrary(hog_name);
// JC: Steam release uses extra1.hog instead of extra.hog, so try loading it first
// Open this file if it's present for stuff we might add later
extra_hid = cf_OpenLibrary("extra1.hog");
if (extra_hid == 0) {
extra_hid = cf_OpenLibrary("extra.hog");
}
// JC: Steam release uses extra.hog instead of merc.hog, so try loading it last (so we don't conflict with the above)
// Open mercenary hog if it exists
merc_hid = cf_OpenLibrary("merc.hog");
if (merc_hid == 0) {
merc_hid = cf_OpenLibrary("extra.hog");
}
// Open this for extra 1.3 code (Black Pyro, etc)
extra13_hid = cf_OpenLibrary("extra13.hog");
// last library opened is the first to be searched for dynamic libs, so put
// this one at the end to find our newly build script libraries first
sys_hid = cf_OpenLibrary(PRIMARY_HOG);
// Initialize debug graph early incase any system uses it in its init
INIT_MESSAGE(("Initializing debug graph."));
DebugGraph_Initialize();
// initialize all the OSIRIS systems
// extract from extra.hog first, so its DLL files are listed ahead of d3.hog's
INIT_MESSAGE(("Initializing OSIRIS."));
Osiris_InitModuleLoader();
// Scripts from original HOGs are outdated and useless.
// Just extracting our compiled scripts from platform-dependent HOG.
Osiris_ExtractScriptsFromHog(sys_hid, false);
}
bool MercInstalled() { return merc_hid > 0; }
extern int Num_languages;
void InitStringTable() {
int language = LANGUAGE_ENGLISH;
Database->read("LanguageType", &language, sizeof(language));
if (language < 0 || language >= Num_languages) {
Int3();
language = LANGUAGE_ENGLISH;
}
Localization_SetLanguage(language);
int string_count = LoadStringTables();
if (string_count == 0)
Error("Couldn't find the string table.");
else
LOG_INFO.printf("%d strings loaded from the string tables", string_count);
}
void InitGraphics(bool editor) {
// Init our bitmaps, must be called before InitTextures
bm_InitBitmaps();
// Init our textures
if (!InitTextures())
Error("Failed to initialize texture system.");
// Init fullscreen/windowed mode from CLI arguments
rend_InitWindowMode();
#ifdef EDITOR
char *driver = "GDIX";
if (!ddgr_Init(Descent, driver, editor ? false : true))
Error("DDGR graphic system init failed.");
// Init our renderer
grSurface::init_system();
rend_Init(RENDERER_OPENGL, Descent, NULL);
Desktop_surf = new grSurface(0, 0, 0, SURFTYPE_VIDEOSCREEN, 0);
#else
strcpy(App_ddvid_subsystem, "GDIX");
INIT_MESSAGE("Loading fonts.");
LoadAllFonts();
#endif
Graphics_init = true;
}
void InitGameSystems(bool editor) {
// do other joint editor/game initialization.
SetInitMessageLength(TXT_INITCOLLATING, 0.4f);
TelComInit();
InitFrameTime();
// Check for aspect ratio override
int t = FindArg("-aspect");
if (t) {
float aspect = atof(GameArgs[t + 1]);
if (aspect > 0.0)
g3_SetAspectRatio(aspect);
}
// Initialize force feedback effects (if we can)
ForceInit();
if (!editor) {
tUIInitInfo uiinit;
uiinit.window_font = SMALL_FONT;
uiinit.w = 640;
uiinit.h = 480;
ui_Init(Descent, &uiinit);
ui_UseCursor("StdCursor.ogf");
NewUIInit();
InitControls();
atexit(CloseControls);
atexit(ui_Close);
}
}
//////////////////////////////////////////////////////////////////////////////
static float Init_messagebar_portion = 0.0f, Init_messagebar_offset = 0.0f;
static const char *Init_messagebar_text = NULL;
// portion of total bar to fill (0 to 1)
void SetInitMessageLength(const char *c, float amount) {
Init_messagebar_text = c;
Init_messagebar_offset += Init_messagebar_portion;
Init_messagebar_portion = amount;
}
// amount is 0 to 1
void UpdateInitMessage(float amount) {
if (Init_in_editor)
return;
InitMessage(Init_messagebar_text, (amount * Init_messagebar_portion) + Init_messagebar_offset);
}
void InitMessage(const char *c, float progress) {
int x = Game_window_w / 2 - Title_bitmap.pw / 2;
int y = Game_window_h / 2 - Title_bitmap.ph / 2;
int i, rx, ry, rw, rh;
if (Dedicated_server) {
PrintDedicatedMessage("%s\n", c);
return;
}
if (!Graphics_init)
return;
StartFrame();
if (Title_bitmap_init) {
rend_ClearScreen(GR_BLACK);
rend_DrawChunkedBitmap(&Title_bitmap, x, y, 255);
}
if (c) {
g3Point *pntlist[4], points[4];
// Set our four corners to cover the screen
grtext_SetFont(MONITOR9_NEWUI_FONT);
rw = Game_window_w;
rh = grfont_GetHeight(MONITOR9_NEWUI_FONT) + 8;
rx = 0;
ry = Game_window_h - rh;
points[0].p3_sx = rx;
points[0].p3_sy = ry;
points[1].p3_sx = rx + rw;
points[1].p3_sy = ry;
points[2].p3_sx = rx + rw;
points[2].p3_sy = ry + rh;
points[3].p3_sx = rx;
points[3].p3_sy = ry + rh;
for (i = 0; i < 4; i++) {
points[i].p3_z = 0;
points[i].p3_flags = PF_PROJECTED;
pntlist[i] = &points[i];
}
rend_SetZBufferState(0);
rend_SetTextureType(TT_FLAT);
rend_SetAlphaType(AT_CONSTANT);
rend_SetLighting(LS_NONE);
rend_SetFlatColor(GR_BLACK);
rend_SetAlphaValue(230);
rend_DrawPolygon2D(0, pntlist, 4);
if (progress >= 0) {
points[0].p3_sx = rx;
points[0].p3_sy = ry + rh - (rh / 2) + 2;
points[1].p3_sx = rx + ((float)rw * progress);
points[1].p3_sy = ry + rh - (rh / 2) + 2;
points[2].p3_sx = rx + ((float)rw * progress);
points[2].p3_sy = ry + rh;
points[3].p3_sx = rx;
points[3].p3_sy = ry + rh;
rend_SetFlatColor(GR_RGB(255, 0, 0));
rend_SetAlphaValue(230);
rend_DrawPolygon2D(0, pntlist, 4);
}
grtext_SetAlpha(255);
grtext_SetColor(NEWUI_MONITORFONT_COLOR);
// grtext_CenteredPrintf(0, ry, c);
grtext_Puts(0, ry, c);
grtext_Flush();
}
EndFrame();
Descent->defer();
rend_Flip();
}
//////////////////////////////////////////////////////////////////////////////
void IntroScreen() {
// #if (defined(OEM) || defined(DEMO) )
#ifdef DEMO
ShowStaticScreen("tantrum.ogf", true, 3.0);
ShowStaticScreen("outrage.ogf", true, 3.0);
#else
#endif
#ifdef DEMO
int bm_handle = bm_AllocLoadFileBitmap("demomenu.ogf", 0);
#else
int bm_handle = bm_AllocLoadFileBitmap("oemmenu.ogf", 0);
#endif
LOG_INFO << "Intro screen!";
if (bm_handle > -1) {
if (!bm_CreateChunkedBitmap(bm_handle, &Title_bitmap))
Error("Failed to slice up d3.ogf!");
bm_FreeBitmap(bm_handle);
Title_bitmap_init = true;
InitMessage(NULL);
} else {
LOG_WARNING << "Unable to find d3.tga.";
}
}
void InitDedicatedServer() {
Game_mode |= GM_MULTI;
Netgame.local_role = LR_SERVER;
int ok = LoadServerConfigFile();
if (!ok) {
PrintDedicatedMessage(TXT_SHUTTINGDOWN);
Error("Cannot load Dedicated Server config file.");
exit(0);
}
}
/*
The D3 Initialization Mess
This initialization sequence will occur after the application and debug systems
are set up.
From here, we initialize all systems.
Initializes all the subsystems that D3/Editor needs to run.
Returns 1 if all is good, 0 if something is wrong
*/
int ServerTimeout = 0;
float LastPacketReceived;
uint16_t Gameport = D3_DEFAULT_PORT;
uint16_t PXOPort = 0;
// Initialiaze everything before data load
void InitD3Systems1(bool editor) {
#if defined(RELEASE)
SetDebugBreakHandlers(NULL, NULL);
#else
SetDebugBreakHandlers(D3DebugStopHandler, D3DebugResumeHandler);
#endif
Init_in_editor = editor;
// Gamespy command to specify the port to listen on
int gameportarg = FindArg("+host");
if (!gameportarg) {
gameportarg = FindArg("-useport");
}
if (gameportarg) {
Gameport = atoi(GameArgs[gameportarg + 1]);
}
int pxoportarg = FindArg("-pxoport");
if (pxoportarg)
PXOPort = atoi(GameArgs[pxoportarg + 1]);
// perform user i/o system initialization
INIT_MESSAGE(("Initializing I/O system."));
InitIOSystems(editor);
// load the string table
InitStringTable();
INIT_MESSAGE(("Initializing GFX"));
InitGraphics(editor);
// initialize data structures
InitObjectInfo();
InitVClips();
InitRooms();
// initialize lighting systems
InitLightmapInfo();
InitSpecialFaces();
InitDynamicLighting();
// Initialize missions
InitMission();
InitDefaultMissionFromCLI();
// Initializes the ship structure
InitShips();
// Initializes the fvi structures for quicker operation
InitFVI();
// Initializes the matcens
InitMatcens();
// This function needs be called before ANY 3d stuff can get done. I mean it.
InitMathTables();
// Initialize a random seed.
ps_srand(time(nullptr));
// This function has to be done before any sound stuff is called
InitSounds();
// Allocate memory and stuff for our terrain engine, objects, etc.
InitTerrain();
InitModels();
InitDoors();
InitGamefiles();
// network initialization
if (!FindArg("-nonetwork")) {
nw_InitNetworking();
nw_InitSockets(Gameport);
}
int timeoutarg = FindArg("-timeout");
if (timeoutarg) {
ServerTimeout = atoi(GameArgs[timeoutarg + 1]);
LastPacketReceived = timer_GetTime();
}
gspy_Init();
// Sound initialization
Sound_system.InitSoundLib(Descent, Sound_mixer, Sound_quality, false);
// Initialize Cinematics system
InitCinematics();
}
// Initialize rest of stuff
void InitD3Systems2(bool editor) {
// Initialize In-Game Cinematics system
Cinematic_Init();
// initialize slewing
#ifdef EDITOR
SlewControlInit();
#endif
int tables_loaded = 0;
// load in all data headers.
INIT_MESSAGE((TXT_INITDATA));
tables_loaded = mng_LoadTableFiles(!editor);
if (!tables_loaded)
Error("Cannot load table file.");
INIT_MESSAGE((TXT_INITCOLLATING));
// Initialize the pilot system
PilotInit();
// Setup our object system. By object I mean stuff in our world, not those silly C++ things.
// This call must come after InitTableFiles(), so we have a player ship for the user
InitObjects();
// Fireball initting must come after LoadTableFiles
SetInitMessageLength(TXT_INITCOLLATING, 0.1f);
InitFireballs();
UpdateInitMessage(1.0f);
// initializes triggers
InitTriggers();
// the remaining sound system
InitVoices();
InitD3Music(FindArg("-nomusic") || FindArg("-nosound") ? false : true);
InitAmbientSoundSystem();
InitGameSystems(editor);
InitPlayers();
SetInitMessageLength(TXT_INITCOLLATING, 0.5f);
InitMarkers();
UpdateInitMessage(1.0f);
PPic_InitDatabase();
// Set next logical function for game.
if (editor)
SetFunctionMode(EDITOR_MODE);
else
SetFunctionMode(MENU_MODE);
if (Dedicated_server)
InitDedicatedServer();
Init_systems_init = true;
// free title screen bitmap.
if (Title_bitmap_init) {
bm_DestroyChunkedBitmap(&Title_bitmap);
Title_bitmap_init = false;
}
// initialize localized text for controller system.
extern void Localize_ctl_bindings();
Localize_ctl_bindings();
}
void SetupTempDirectory(void) {
// NOTE: No string tables are available at this point
//--------------------------------------------------
LOG_INFO << "Setting up temp directory";
int t_arg = FindArg("-tempdir");
if (t_arg) {
Descent3_temp_directory = GameArgs[t_arg + 1];
} else {
std::error_code ec;
std::filesystem::path tempPath = std::filesystem::temp_directory_path(ec);
if (ec) {
Error("Could not find temporary directory: \"%s\"", ec.message().c_str());
exit(1);
}
Descent3_temp_directory = tempPath / "Descent3" / "cache";
}
std::error_code ec;
std::filesystem::create_directories(Descent3_temp_directory, ec);
if (ec) {
Error("Could not create temporary directory: \"%s\"", Descent3_temp_directory.u8string().c_str());
exit(1);
}
std::filesystem::path tempfilename = ddio_GetTmpFileName(Descent3_temp_directory, "d3t");
// verify that we can write to the temp directory
if (tempfilename.empty()) {
LOG_WARNING << "Unable to get temp file name";
Error("Unable to set temporary directory to: \"%s\"", Descent3_temp_directory.u8string().c_str());
exit(1);
}
// try to create a file in temp directory
CFILE *file = cfopen(tempfilename, "wb");
if (!file) {
// unable to open file for writing
LOG_WARNING << "Unable to open temp file name for writing";
Error("Unable to set temporary directory to: \"%s\"", Descent3_temp_directory.u8string().c_str());
exit(1);
}
cf_WriteInt(file, 0x56);
cfclose(file);
// now open up the file and make sure it is correct
file = cfopen(tempfilename, "rb");
if (!file) {
// unable to open file for reading
LOG_WARNING << "Unable to open temp file name for reading";
std::filesystem::remove(tempfilename);
Error("Unable to set temporary directory to: \"%s\"", Descent3_temp_directory.u8string().c_str());
exit(1);
}
if (cf_ReadInt(file) != 0x56) {
// verify failed
LOG_WARNING << "Temp file verify failed";
cfclose(file);
std::filesystem::remove(tempfilename);
Error("Unable to set temporary directory to: \"%s\"", Descent3_temp_directory.u8string().c_str());
exit(1);
}
cfclose(file);
// temp directory is valid!
std::filesystem::remove(tempfilename);
LOG_INFO << "Temp directory set to: " << Descent3_temp_directory;
// Lock the directory
if (!ddio_CreateLockFile(std::filesystem::path(Descent3_temp_directory))) {
LOG_WARNING << "Lock file NOT created in temp dir " << Descent3_temp_directory;
Error("Unable to set temporary directory to: \"%s\"\nUnable to create lock file",
Descent3_temp_directory.u8string().c_str());
exit(1);
}
// restore working dir
ddio_SetWorkingDir((const char*)cf_GetWritableBaseDirectory().u8string().c_str());
}
void DeleteTempFiles() {
ddio_DoForeachFile(Descent3_temp_directory, std::regex("d3[smocti].+\\.tmp"), [](const std::filesystem::path &path) {
std::error_code ec;
std::filesystem::remove(path, ec);
LOG_WARNING_IF(ec).printf("Unable to remove temporary file %s: %s\n", (const char*)path.u8string().c_str(),
(const char*)ec.message().c_str());
});
}
/*
*
* These functions handle shutting down and restarting all systems in D3
*
*/
static int Init_old_screen_mode;
static void (*Init_old_ui_callback)() = NULL;
static bool Init_old_control_mode;
static bool Init_ui_cursor_visible;
static bool Init_was_game_paused = false;
static pilot Init_old_pilot;
// TODO: MTS: Unused in project
void ShutdownD3() {
if (!Init_systems_init)
return;
LOG_INFO << "Shutting down D3...";
// Close forcefeedback effects
ForceShutdown();
// shutdown game systems
Init_old_control_mode = Control_poll_flag;
// JEFF: only pause game if not in multi, so we can background process
if (GetFunctionMode() == GAME_MODE) {
if (!(Game_mode & GM_MULTI)) {
Init_was_game_paused = Game_paused;
if (!Init_was_game_paused) {
PauseGame();
} else {
D3MusicPause();
}
}
} else {
D3MusicPause();
Sound_system.PauseSounds();
}
SaveControlConfig(&Init_old_pilot);
CloseControls();
// shutdown cinematics.
// shutdown screen.
Init_ui_cursor_visible = ui_IsCursorVisible();
Init_old_screen_mode = GetScreenMode();
Init_old_ui_callback = GetUICallback();
SetScreenMode(SM_NULL);
// shutdown IO
ddio_Close();
}
// TODO: MTS: unused in project
// This function restarts all game systems
void RestartD3() {
ddio_init_info io_info;
if (!Init_systems_init)
return;
LOG_INFO << "Restarting D3...";
if (!FindArg("-windowed")) {
if (Dedicated_server) {
ddio_MouseMode(MOUSE_STANDARD_MODE);
} else {
ddio_MouseMode(MOUSE_EXCLUSIVE_MODE);
}
}
// startup io
io_info.obj = Descent;
if (!ddio_Init(&io_info)) {
Error("I/O initialization failed.");
}
// startup screen.
ddio_KeyFlush();
SetScreenMode(Init_old_screen_mode);
SetUICallback(Init_old_ui_callback);
if (Init_ui_cursor_visible)
ui_ShowCursor();
// startup game systems
InitControls();
LoadControlConfig(&Init_old_pilot);
// resume game sounds and time as needed
if (GetFunctionMode() == GAME_MODE) {
if (!(Game_mode & GM_MULTI)) {
if (!Init_was_game_paused) {
ResumeGame();
} else {
D3MusicResume();
}
}
} else {
Sound_system.ResumeSounds();
D3MusicResume();
}
// resume controller if it was active before alt-tabbing out.
if (Init_old_control_mode) {
ResumeControls();
}
// Restart Force Feedback
ForceRestart();
// startup cinematics.
// startup sound.
// Sound_system.ResumeSounds();
// Sound_system.InitSoundLib(Descent, Sound_mixer, Sound_quality, false);
}