diff --git a/sc2/.gitignore b/sc2/.gitignore new file mode 100644 index 000000000..b17924ab1 --- /dev/null +++ b/sc2/.gitignore @@ -0,0 +1,9 @@ +.DS_Store +*.app +build.vars +config.state +config_unix.h +obj +uqm-debug +uqm-wrapper +uqm diff --git a/sc2/AUTHORS b/sc2/AUTHORS index e34b166dd..993f955d9 100644 --- a/sc2/AUTHORS +++ b/sc2/AUTHORS @@ -7,7 +7,7 @@ The Ur-Quan Masters port: ------------------------- Core team (in alphabetical order): - Serge van den Boom + Serge van den Boom Mika Kolehmainen Michael Chapman Martin Chris Nelson @@ -19,13 +19,18 @@ Additional programming (in alphabetical order): Music remixers (in alphabetical order): Jouni Airaksinen - Tore Aune Fjellstad - Espen Gätzschmann + András Barják + Matt Bentley + Tore Aune Fjellstad + Espen Gätzschmann Aaron J. Grier + A. Keren + Casey Monroe Dan Nicholson George Nowik - Riku Nuottajärvi + Riku Nuottajärvi Erol Otus + Greg Szymanski Other contributions (in alphabetical order): Jouni Airaksinen (Startup Menu) @@ -138,7 +143,7 @@ Additional writing: Music: Burke Treischmann Dan Nicholson - Riku Nuottajärvi + Riku Nuottajärvi Eric Berge Erol Otus Marc Brown diff --git a/sc2/ChangeLog b/sc2/ChangeLog index ca7edce34..eb902e9c6 100644 --- a/sc2/ChangeLog +++ b/sc2/ChangeLog @@ -1,4 +1,58 @@ -Changes towards version 0.7.1: +0.7.2: +- Some added documentation for UIO. +- Added a StringHashTable type. +- A few superficial fixes to charhashtable. +- Removed GraphicsLock and made comm callbacks queued - Alex +- Split debug key function into sync and async parts, paving the way + for GraphicsLock removal - Alex +- PageUp/PageDown now add/remove 10 fuel in the shipyard, from + Scott A. Colcord, Nic +- Annihigate flash thread - SvdB +- Switch SetFlashRect() to the new flash code - SvdB +- Add C++ support to the build system, from Scott A. Colcord +- Cleaning up DoModifyShips() - SvdB +- Added Valgrind suppression file, from Louis Delacroix +- Fix several memory leaks, from Loius Delacroix +- Some cleanups / warnings fixes, from Louis Delacroix +- Added a free callback function for the values of the key-value pairs + in hash tables - SvdB +- Annigilate ActivateStarShip() - SvdB +- Removed obsolete RESPONSE_TO_REF() - SvdB +- Don't require the 'shadow' dir in addon packs, from Alex +- Make use of GAME_STATE_FILE consistently, from Scott A. Colcord +- Fixed unconst(), from Scott A. Colcord +- Fixes to a few small bugs in UIO which shouldn't have had an impact on + UQM, but would in the future, from Alex +- Allow F6 as a default alternate search key, from related projects. +- "Player 1" and "Player 2" are now "Bottom" and "Top" player (#954) - McM +- Fix Utwig dialog inconsistency (#756) - McM +- Use a deterministic seed for Melnorme modules-for-fuel deals (#567) - McM +- Various warnings cleanup (bug #50), from Scott A. Colcord +- Fixed various Pkunk reincarnation and Shofixti Glory device interactions; + Pkunk ditty plays in a simultaneous destruction (bug #666) - Alex +- Preparing for linking with C++ code, from Scott A. Colcord +- Fixed player's phrase leading to Tanaka's response about a solitary + vigil (bug #859) - Alex +- Added the Ur-Quan to the list of starfaring races on which Commander + Hayes provides info (bug #865) - Alex +- Commander Hayes now advises the player correctly on the number of + landers one needs (bug #1098) - Alex +- All Sound Options are now preserved between visits to the setup menu. + Some options still require a restart (bug #1132) - Alex +- Removed the remnants of the --music option (bug #1133) - Alex +- Fixed flagship re-entering the inner system after an encounter in the + outer system, thus trapping the player (bug #1135) - Alex +- Fixed starmap fuel range circle shrinking (bug #1130) - Alex +- Added gamma correction to the setup menu (bug #977) - Alex, Nic +- Refactor Melnorme comm code to make modding easier; step 1 (bug #1128), + from Scott A. Colcord +- Added aspect ratio option to the setup menu - Alex +- Positional audio setup menu option now has an immediate effect - Alex +- Added speech option which controls loading of 3dovoice addon (no need + to set speech volume to 0 anymore) - Alex +- Added the MetaChron story to the no-voice Melnorme script (bug #43) - Alex + +0.7.1: - New SDL2 backend for modern operating systems - Micahel - Fixed netplay when compiling against modern versions of Visual Studio, from Ala-lala diff --git a/sc2/Contributing b/sc2/Contributing index fcbdb1d81..985a6af81 100644 --- a/sc2/Contributing +++ b/sc2/Contributing @@ -5,7 +5,7 @@ These guidelines are there so that you won't waste both our and your time. Before making changes: - Read this entire document -- See if the the Bugzilla bug database at +- See if the Bugzilla bug database at http://bugs.uqm.stack.nl/ contains any comments on what you're planning to do. - Make sure you're using the most recent Subversion version @@ -26,9 +26,9 @@ Making changes: we don't even always do, but we've accepted this as our standard. The main reason is that this is very close to the original style. Trying to start a discussion about the standard is pointless and is - definately NOT appreciated. + definitely NOT appreciated. - Use 1 tab per indentation level - - Use no more than 76 chars on a line, when using a tabsize of 4. + - Use no more than 76 chars on a line, when using a tab size of 4. - Use 2 extra indentation levels for the continuation of a broken line, like this: if (blablablabla || foobar || @@ -47,7 +47,7 @@ Making changes: } (Though in this particular case, I personally would repeat the 'long', or place l and m on the same line) - - Put { on a seperate line, both for the start of a function and + - Put { on a separate line, both for the start of a function and for the start of a block. - one space around binary operators, and after commas. - one space between the function name and following '(', both in @@ -65,8 +65,8 @@ Making changes: because you think that would be easier than trying to understand the original. If you don't have the skills or patience to do so, this is not the place for you. -- Only use portable functions. The code is intended to work on Windows, - Linux, FreeBSD, BeOS and MacOS X. +- Only use portable functions. The code is intended to work on Windows + (MSVC 6), Linux (GCC 4), FreeBSD (GCC 4) and MacOS X (GCC 4). Try to avoid unnecessary system-dependant code, but use #ifdefs if you really have to. - No shortcuts. Don't assume anything about user input (like the length), @@ -101,7 +101,7 @@ Getting the patches committed: mentioning an URL where we can get the patch. The committers are listed below (in alphabetical order), with their particular field of expertise with the source. Though all of us - should have enough experience to deal with most issues not explicitely + should have enough experience to deal with most issues not explicitly mentioned. Serge van den Boom (svdb at stack.nl), SvdB at #sc2 - Resource system @@ -113,7 +113,7 @@ Getting the patches committed: - Graphics - Sound - General issues - Michael Martin (mcmartin at stanford.edu), McMartin at #sc2 + Michael Martin (mcmartin at mail.com), McMartin at #sc2 - Threading - Graphics - Input system diff --git a/sc2/Makefile.build b/sc2/Makefile.build index cdfe47cec..cf55fde2b 100644 --- a/sc2/Makefile.build +++ b/sc2/Makefile.build @@ -42,6 +42,13 @@ $(OBJDIR)%.c.d: $(BUILD_ROOT)%.c fi $(call act,act_mkdep_c,MKDEP ,$@) +$(OBJDIR)%.cpp.d: $(BUILD_ROOT)%.cpp + @DIR=$(dir $@); \ + if [ ! -d $$DIR ]; then \ + mkdir -p "$$DIR"; \ + fi + $(call act,act_mkdep_cxx,MKDEP ,$@) + $(OBJDIR)%.m.d: $(BUILD_ROOT)%.m @DIR=$(dir $@); \ if [ ! -d $$DIR ]; then \ @@ -63,6 +70,13 @@ $(OBJDIR)%.m.d: $(BUILD_ROOT)%.m fi $(call act,act_cc,CC ,$@) +%.cpp.o: + @DIR=$(dir $@); \ + if [ ! -d $$DIR ]; then \ + mkdir -p "$$DIR"; \ + fi + $(call act,act_cxx,CXX ,$@) + %.m.o: @DIR=$(dir $@); \ if [ ! -d $$DIR ]; then \ diff --git a/sc2/Makeproject b/sc2/Makeproject index 6717bf248..23d5ec07e 100644 --- a/sc2/Makeproject +++ b/sc2/Makeproject @@ -17,8 +17,10 @@ case "$HOST_SYSTEM" in ;; esac uqm_CFLAGS="$uqm_CFLAGS -Isrc" +uqm_CXXFLAGS="$uqm_CXXFLAGS -Isrc" if [ "$uqm_HAVE_REGEX" = 0 ]; then uqm_CFLAGS="$uqm_CFLAGS -Isrc/regex" + uqm_CXXFLAGS="$uqm_CXXFLAGS -Isrc/regex" fi # Stuff to install under the directory for libraries, as specified during diff --git a/sc2/build.vars.in b/sc2/build.vars.in index c0f512492..552faa256 100644 --- a/sc2/build.vars.in +++ b/sc2/build.vars.in @@ -20,6 +20,9 @@ HOST_SYSTEM='@HOST_SYSTEM@' PREPROC_C='@PREPROC_C@' MKDEP_C='@MKDEP_C@' COMPILE_C='@COMPILE_C@' +PREPROC_CXX='@PREPROC_CXX@' +MKDEP_CXX='@MKDEP_CXX@' +COMPILE_CXX='@COMPILE_CXX@' PREPROC_OBJC='@PREPROC_OBJC@' MKDEP_OBJC='@MKDEP_OBJC@' COMPILE_OBJC='@COMPILE_OBJC@' @@ -30,6 +33,7 @@ SED='@SED@' REZ='@REZ@' WINDRES='@WINDRES@' uqm_CFLAGS='@CFLAGS@' +uqm_CXXFLAGS='@CXXFLAGS@' uqm_LDFLAGS='@LDFLAGS@' uqm_INSTALL_BINDIR='@INSTALL_BINDIR@' uqm_INSTALL_LIBDIR='@INSTALL_LIBDIR@' @@ -54,8 +58,8 @@ MACRO_WIN32='@MACRO_WIN32@' MACRO___MINGW32__='@MACRO___MINGW32__@' export BUILD_SYSTEM HOST_SYSTEM DEBUG export MACRO_WIN32 MACRO___MINGW32__ -export uqm_SOUNDMODULE uqm_USE_INTERNAL_MIKMOD uqm_HAVE_GETOPT_LONG -export uqm_OGGVORBIS -export uqm_HAVE_REGEX uqm_USE_WINSOCK uqm_GFXMODULE uqm_HAVE_OPENGL +export uqm_SOUNDMODULE uqm_OGGVORBIS uqm_USE_INTERNAL_MIKMOD +export uqm_HAVE_GETOPT_LONG uqm_HAVE_REGEX uqm_USE_WINSOCK uqm_GFXMODULE +export uqm_HAVE_OPENGL export uqm_USE_ZIP_IO uqm_USE_PLATFORM_ACCEL uqm_THREADLIB uqm_NETPLAY diff --git a/sc2/build/msvc6/UrQuanMasters.dsp b/sc2/build/msvc6/UrQuanMasters.dsp index 340d311b7..8bf05f845 100644 --- a/sc2/build/msvc6/UrQuanMasters.dsp +++ b/sc2/build/msvc6/UrQuanMasters.dsp @@ -74,7 +74,7 @@ PostBuild_Cmds=rebase -b 0x400000 -x . "../../uqm.exe" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "..\..\src" /I "..\..\src\regex" /D "DEBUG" /D "_DEBUG" /D "DEBUG_TRACK_SEM" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D _VW=320 /D _VH=240 /D "HAVE_OPENGL" /D "GFXMODULE_SDL" /D "THREADLIB_SDL" /D "HAVE_OPENAL" /D "HAVE_ZIP" /D "HAVE_JOYSTICK" /D "NETPLAY" /D "ZLIB_DLL" /D "USE_INTERNAL_MIKMOD" /D "USE_PLATFORM_ACCEL" /FR /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "..\..\src" /I "..\..\src\regex" /D "DEBUG" /D "_DEBUG" /D "DEBUG_TRACK_SEM" /D "DEBUG_DCQ_THREADS" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D _VW=320 /D _VH=240 /D "HAVE_OPENGL" /D "GFXMODULE_SDL" /D "THREADLIB_SDL" /D "HAVE_OPENAL" /D "HAVE_ZIP" /D "HAVE_JOYSTICK" /D "NETPLAY" /D "ZLIB_DLL" /D "USE_INTERNAL_MIKMOD" /D "USE_PLATFORM_ACCEL" /FR /FD /GZ /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" @@ -101,7 +101,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "..\..\src" /I "..\..\src\regex" /D "DEBUG" /D "_DEBUG" /D "DEBUG_TRACK_SEM" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D _VW=320 /D _VH=240 /D "HAVE_OPENGL" /D "GFXMODULE_SDL" /D "THREADLIB_SDL" /D "HAVE_OPENAL" /D "HAVE_ZIP" /D "HAVE_JOYSTICK" /D "NETPLAY" /D "ZLIB_DLL" /D "USE_INTERNAL_MIKMOD" /FR /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "..\..\src" /I "..\..\src\regex" /D "DEBUG" /D "_DEBUG" /D "DEBUG_TRACK_SEM" /D "DEBUG_DCQ_THREADS" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D _VW=320 /D _VH=240 /D "HAVE_OPENGL" /D "GFXMODULE_SDL" /D "THREADLIB_SDL" /D "HAVE_OPENAL" /D "HAVE_ZIP" /D "HAVE_JOYSTICK" /D "NETPLAY" /D "ZLIB_DLL" /D "USE_INTERNAL_MIKMOD" /FR /FD /GZ /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" @@ -215,6 +215,14 @@ SOURCE=..\..\src\libs\callback\alarm.h # End Source File # Begin Source File +SOURCE=..\..\src\libs\callback\async.c +# End Source File +# Begin Source File + +SOURCE=..\..\src\libs\callback\async.h +# End Source File +# Begin Source File + SOURCE=..\..\src\libs\callback\callback.c # End Source File # Begin Source File @@ -1490,6 +1498,10 @@ SOURCE=..\..\src\libs\alarm.h # End Source File # Begin Source File +SOURCE=..\..\src\libs\async.h +# End Source File +# Begin Source File + SOURCE=..\..\src\libs\callback.h # End Source File # Begin Source File @@ -2237,6 +2249,10 @@ SOURCE=..\..\src\uqm\planets\solarsys.c # End Source File # Begin Source File +SOURCE=..\..\src\uqm\planets\solarsys.h +# End Source File +# Begin Source File + SOURCE=..\..\src\uqm\planets\sundata.h # End Source File # Begin Source File @@ -3138,6 +3154,10 @@ SOURCE=..\..\src\uqm\controls.h # End Source File # Begin Source File +SOURCE=..\..\src\uqm\corecode.h +# End Source File +# Begin Source File + SOURCE=..\..\src\uqm\credits.c # End Source File # Begin Source File @@ -3494,6 +3514,10 @@ SOURCE=..\..\src\uqm\starmap.c # End Source File # Begin Source File +SOURCE=..\..\src\uqm\starmap.h +# End Source File +# Begin Source File + SOURCE=..\..\src\uqm\state.c # End Source File # Begin Source File @@ -3650,10 +3674,6 @@ SOURCE=..\..\doc\devel\glossary # End Source File # Begin Source File -SOURCE=..\..\doc\devel\graphicslock -# End Source File -# Begin Source File - SOURCE=..\..\doc\devel\input # End Source File # Begin Source File diff --git a/sc2/build/unix/build.config b/sc2/build/unix/build.config index 3a1ff12a1..d3ccaa570 100644 --- a/sc2/build/unix/build.config +++ b/sc2/build/unix/build.config @@ -10,6 +10,7 @@ uqm_requirements() { # Some requirements: have_build_tools_language C || exit 1 + have_build_tools_language CXX || exit 1 have_build_tool LINK || exit 1 case "$HOST_SYSTEM" in MINGW32*|cegcc) @@ -118,16 +119,16 @@ uqm_prepare_config() nodebug_action() { case "$HOST_SYSTEM" in WINSCW) - CFLAGS="$CFLAGS -O2 -d NDEBUG" + CCOMMONFLAGS="$CCOMMONFLAGS -O2 -d NDEBUG" ;; ARMV5) - CFLAGS="$CFLAGS -O3 -Otime -DNDEBUG" + CCOMMONFLAGS="$CCOMMONFLAGS -O3 -Otime -DNDEBUG" ;; GCCE) - CFLAGS="$CFLAGS -O3 -DNDEBUG" + CCOMMONFLAGS="$CCOMMONFLAGS -O3 -DNDEBUG" ;; *) - CFLAGS="$CFLAGS -O3 -DNDEBUG" + CCOMMONFLAGS="$CCOMMONFLAGS -O3 -DNDEBUG" ;; esac DEBUG=0 @@ -137,13 +138,13 @@ uqm_prepare_config() debug_action() { case "$HOST_SYSTEM" in WINSCW) - CFLAGS="$CFLAGS -g -O0 -W all -d DEBUG -d _DEBUG" + CCOMMONFLAGS="$CCOMMONFLAGS -g -O0 -W all -d DEBUG -d _DEBUG" ;; ARMV5|GCCE) - CFLAGS="$CFLAGS -g -O0 -DDEBUG -D_DEBUG" + CCOMMONFLAGS="$CCOMMONFLAGS -g -O0 -DDEBUG -D_DEBUG" ;; *) - CFLAGS="$CFLAGS -g -O0 -W -Wall -DDEBUG" + CCOMMONFLAGS="$CCOMMONFLAGS -g -O0 -W -Wall -DDEBUG" LDFLAGS="$LDFLAGS -O0" ;; esac @@ -154,40 +155,46 @@ uqm_prepare_config() strictdebug_action() { case "$HOST_SYSTEM" in WINSCW) - CFLAGS="$CFLAGS -g -O0 -W all -d DEBUG -d _DEBUG" + CCOMMONFLAGS="$CCOMMONFLAGS -g -O0 -W all -d DEBUG -d _DEBUG" ;; ARMV5|GCCE) - CFLAGS="$CFLAGS -g -O0 -DDEBUG -D_DEBUG" + CCOMMONFLAGS="$CCOMMONFLAGS -g -O0 -DDEBUG -D_DEBUG" ;; *) - CFLAGS="$CFLAGS -O1" # This is needed for -Wunitialized - CFLAGS="$CFLAGS -g -DDEBUG -W -Wall \ - -Wbad-function-cast -Wcast-qual -Wmissing-prototypes \ - -Wstrict-prototypes -Wmissing-declarations \ + CCOMMONFLAGS="$CCOMMONFLAGS -g -O0 -DDEBUG -W -Wall" +# CCOMMONFLAGS="$CCOMMONFLAGS -O1" + # This is needed for -Wunitialized with gcc 3.4 + CCOMMONFLAGS="$CCOMMONFLAGS -Wcast-qual -Wmissing-declarations \ -Wwrite-strings -Wimplicit -Wreturn-type -Wformat \ -Wswitch -Wcomment -Wchar-subscripts \ - -Wparentheses -Wcast-align \ - -Wuninitialized" -# CFLAGS="$CFLAGS -Waggregate-return" + -Wparentheses -Wcast-align -Wuninitialized" + CFLAGS="$CFLAGS -Wbad-function-cast -Wmissing-prototypes \ + -Wstrict-prototypes" + # CFLAGS is for flags not valid in C++. + CFLAGS="$CFLAGS -Wdeclaration-after-statement" + # Until we abandon MSVC 6 +# CCOMMONFLAGS="$CCOMMONFLAGS -Waggregate-return" # It's not unreasonable to return structs at times. -# CFLAGS="$CFLAGS "-Wpointer-arith" +# CCOMMONFLAGS="$CCOMMONFLAGS "-Wpointer-arith" # Some standard header won't even compile with this on -# CFLAGS="$CFLAGS -Wshadow" +# CCOMMONFLAGS="$CCOMMONFLAGS -Wshadow" # This gives absurd conflicts with standard files, # like from 'y0 and y1' -# CFLAGS="$CFLAGS -Werror" +# CCOMMONFLAGS="$CCOMMONFLAGS -Werror" # We shouldn't do this until we actually nail them # all in the original code. Then we can enforce them # on ourselves. -# CFLAGS="$CFLAGS -pedantic-errors -ansi -trigraphs" # ANSI -# CFLAGS="$CFLAGS -Wnested-externs" +# CCOMMONFLAGS="$CCOMMONFLAGS -pedantic-errors -ansi -trigraphs" # ANSI +# CCOMMONFLAGS="$CCOMMONFLAGS -Wnested-externs" # We know they're in the code, and though we'd like to # get rid of them, they're not bugs. -# CFLAGS="$CFLAGS -Winline" +# CCOMMONFLAGS="$CCOMMONFLAGS -Winline" # This gives too many warnings which we can do nothing # about, obscuring legitimate warnings. CFLAGS=`echo $CFLAGS` - # Remove all the unnecessary spaces from $CFLAGS, + CXXFLAGS=`echo $CXXFLAGS` + CCOMMONFLAGS=`echo $CCOMMONFLAGS` + # Remove all the unnecessary spaces from the flags vars # for more readable messages. LDFLAGS="$LDFLAGS -O0" ;; @@ -211,6 +218,7 @@ uqm_prepare_config() CHOICE_graphics_OPTION_pure_PRECOND='have_library SDL 1.2.8' graphics_pure_action() { CFLAGS="$CFLAGS -DGFXMODULE_SDL -DSDL_DIR=SDL" + CCOMMONFLAGS="$CCOMMONFLAGS -DGFXMODULE_SDL" GFXMODULE=sdl HAVE_OPENGL=0 use_library SDL 1.2.8 @@ -252,7 +260,7 @@ uqm_prepare_config() CHOICE_sound_OPTION_openal_PRECOND="have_library openal" CHOICE_sound_OPTION_openal_ACTION=sound_openal_action sound_openal_action() { - CFLAGS="$CFLAGS -DHAVE_OPENAL" + CCOMMONFLAGS="$CCOMMONFLAGS -DHAVE_OPENAL" SOUNDMODULE=openal use_library openal } @@ -271,14 +279,14 @@ uqm_prepare_config() CHOICE_ovcodec_OPTION_tremor_PRECOND="have_library tremor" CHOICE_ovcodec_OPTION_tremor_ACTION=ovcodec_tremor_action ovcodec_tremor_action() { - CFLAGS="$CFLAGS -DOVCODEC_TREMOR" + CCOMMONFLAGS="$CCOMMONFLAGS -DOVCODEC_TREMOR" OGGVORBIS=tremor use_library tremor } CHOICE_ovcodec_OPTION_none_TITLE="No Ogg Vorbis support" CHOICE_ovcodec_OPTION_none_ACTION=ovcodec_none_action ovcodec_none_action() { - CFLAGS="$CFLAGS -DOVCODEC_NONE" + CCOMMONFLAGS="$CCOMMONFLAGS -DOVCODEC_NONE" OGGVORBIS=none } CHOICE_ovcodec_DEFAULT=standard @@ -288,7 +296,7 @@ uqm_prepare_config() CHOICE_mikmod_OPTION_internal_TITLE="Included libmikmod" CHOICE_mikmod_OPTION_internal_ACTION=mikmod_internal_action mikmod_internal_action() { - CFLAGS="$CFLAGS -DUSE_INTERNAL_MIKMOD" + CCOMMONFLAGS="$CCOMMONFLAGS -DUSE_INTERNAL_MIKMOD" USE_INTERNAL_MIKMOD=1 } CHOICE_mikmod_OPTION_external_TITLE="System libmikmod" @@ -307,7 +315,7 @@ uqm_prepare_config() # TODO: Check whether SDL has joystick support. CHOICE_joystick_OPTION_enabled_ACTION=joystick_enabled_action joystick_enabled_action() { - CFLAGS="$CFLAGS -DHAVE_JOYSTICK" + CCOMMONFLAGS="$CCOMMONFLAGS -DHAVE_JOYSTICK" } CHOICE_joystick_OPTION_disabled_TITLE="disabled" case "$HOST_SYSTEM" in @@ -331,7 +339,7 @@ uqm_prepare_config() CHOICE_netplay_OPTION_full_PRECOND="have_library netlibs" CHOICE_netplay_OPTION_full_ACTION=netplay_full_action netplay_full_action() { - CFLAGS="$CFLAGS -DNETPLAY=NETPLAY_FULL" + CCOMMONFLAGS="$CCOMMONFLAGS -DNETPLAY=NETPLAY_FULL" if [ -n "$MACRO_WIN32" ]; then LDFLAGS="$LDFLAGS -lws2_32" fi @@ -342,7 +350,7 @@ uqm_prepare_config() CHOICE_netplay_OPTION_ipv4_PRECOND="have_library netlibs" CHOICE_netplay_OPTION_ipv4_ACTION=netplay_ipv4_action netplay_ipv4_action() { - CFLAGS="$CFLAGS -DNETPLAY=NETPLAY_IPV4" + CCOMMONFLAGS="$CCOMMONFLAGS -DNETPLAY=NETPLAY_IPV4" NETPLAY="IPV4" use_library netlibs } @@ -355,7 +363,7 @@ uqm_prepare_config() CHOICE_ioformat_OPTION_stdio_zip_PRECOND="have_library zlib" CHOICE_ioformat_OPTION_stdio_zip_ACTION="ioformat_stdio_zip_action" ioformat_stdio_zip_action() { - CFLAGS="$CFLAGS -DHAVE_ZIP=1" + CCOMMONFLAGS="$CCOMMONFLAGS -DHAVE_ZIP=1" USE_ZIP_IO=1 use_library zlib } @@ -366,7 +374,7 @@ uqm_prepare_config() CHOICE_accel_OPTION_asm_TITLE="Platform acceleration (asm, etc.)" CHOICE_accel_OPTION_asm_ACTION="accel_asm_action" accel_asm_action() { - CFLAGS="$CFLAGS -DUSE_PLATFORM_ACCEL" + CCOMMONFLAGS="$CCOMMONFLAGS -DUSE_PLATFORM_ACCEL" USE_PLATFORM_ACCEL=1 } CHOICE_accel_OPTION_plainc_TITLE="Only plain C code" @@ -381,14 +389,14 @@ uqm_prepare_config() CHOICE_threadlib_OPTION_sdl_TITLE="SDL-controlled thread library" CHOICE_threadlib_OPTION_sdl_ACTION="threadlib_sdl_action" threadlib_sdl_action() { - CFLAGS="$CFLAGS -DTHREADLIB_SDL" + CCOMMONFLAGS="$CCOMMONFLAGS -DTHREADLIB_SDL" THREADLIB="SDL" } CHOICE_threadlib_OPTION_pthread_TITLE="Pthread thread library" CHOICE_threadlib_OPTION_pthread_PRECOND="have_library pthread" CHOICE_threadlib_OPTION_pthread_ACTION="threadlib_pthread_action" threadlib_pthread_action() { - CFLAGS="$CFLAGS -DTHREADLIB_PTHREAD" + CCOMMONFLAGS="$CCOMMONFLAGS -DTHREADLIB_PTHREAD" THREADLIB="PTHREAD" use_library pthread } @@ -441,7 +449,16 @@ uqm_process_config() { # Set the content dir CONTENTDIR="${INSTALL_SHAREDIR}uqm/content" - CFLAGS="$CFLAGS -I\"$BUILD_WORK\"" + CCOMMONFLAGS="$CCOMMONFLAGS -I\"$BUILD_WORK\"" + + # Set C++ only flags + # These allow use of C++ without the standard library + CXXFLAGS="$CXXFLAGS -fno-rtti -fno-exceptions -nostdinc++" + + # At this point, all the compiler flags must be set. + CFLAGS="$CFLAGS $CCOMMONFLAGS" + CXXFLAGS="$CXXFLAGS $CCOMMONFLAGS" + CCOMMONFLAGS="" # Export the HAVE_ symbols to config_unix.h, using config_unix.h.in # as template (or config_win.h/config_win.h.in). @@ -457,8 +474,9 @@ uqm_process_config() { substitute_vars SUBSTITUTE_VARS SUBSTITUTE_FILES src "$BUILD_WORK" # Make build.vars from build.vars.in, substituting variables. - SUBSTITUTE_VARS="BUILD_SYSTEM HOST_SYSTEM CFLAGS LDFLAGS LINK \ + SUBSTITUTE_VARS="BUILD_SYSTEM HOST_SYSTEM CFLAGS CXXFLAGS LDFLAGS LINK \ PREPROC_C MKDEP_C COMPILE_C \ + PREPROC_CXX MKDEP_CXX COMPILE_CXX \ PREPROC_OBJC MKDEP_OBJC COMPILE_OBJC \ MAKE ECHON SED DEBUG JOYSTICK NETPLAY \ OGGVORBIS SOUNDMODULE USE_INTERNAL_MIKMOD \ @@ -470,7 +488,7 @@ uqm_process_config() { SUBSTITUTE_FILES="build.vars" substitute_vars SUBSTITUTE_VARS SUBSTITUTE_FILES . "$BUILD_WORK" - # Make 'uqm' shell script from build.vars.in, substituting variables. + # Make 'uqm' shell script from uqm-wrapper.in, substituting variables. SUBSTITUTE_VARS="INSTALL_LIBDIR INSTALL_BINDIR INSTALL_SHAREDIR uqm_NAME" SUBSTITUTE_FILES="uqm-wrapper" substitute_vars SUBSTITUTE_VARS SUBSTITUTE_FILES build/unix "$BUILD_WORK" @@ -601,7 +619,7 @@ uqm_install_osx() { $PREPROC_C -D__MACOSX__ -include $HEADER - | \ awk '(/'$HEADER_FILE'/ && $2 == 1) { print $3; exit }' | \ $SED 's/.Headers.*$/"/'` - cp -r "$FRAMEWORK" "$INSTROOT/Frameworks" + cp -a "$FRAMEWORK" "$INSTROOT/Frameworks" done # Install game content (it should probably make a zipfile) diff --git a/sc2/build/unix/build.sh b/sc2/build/unix/build.sh index 291d29ac2..d384e926e 100644 --- a/sc2/build/unix/build.sh +++ b/sc2/build/unix/build.sh @@ -99,8 +99,8 @@ if [ -z "$TARGET" ]; then fi BUILD_PROJECT="$TARGET" export TARGET BUILD_PROJECT ECHON -export PREPROC_C MKDEP_C COMPILE_C PREPROC_OBJC MKDEP_OBJC COMPILE_OBJC LINK -export "${BUILD_PROJECT}_CFLAGS" "${BUILD_PROJECT}_LDFLAGS" +export PREPROC_C MKDEP_C COMPILE_C PREPROC_CXX MKDEP_CXX COMPILE_CXX PREPROC_OBJC MKDEP_OBJC COMPILE_OBJC LINK +export "${BUILD_PROJECT}_CFLAGS" "${BUILD_PROJECT}_CXXFLAGS" "${BUILD_PROJECT}_LDFLAGS" # Add trailing / from objs dir eval ${BUILD_PROJECT}_OBJS=\${${BUILD_PROJECT}_OBJS%/}/ diff --git a/sc2/build/unix/build_functions b/sc2/build/unix/build_functions index ded52ab16..5f5d20bc9 100644 --- a/sc2/build/unix/build_functions +++ b/sc2/build/unix/build_functions @@ -106,9 +106,10 @@ build_depend() { # $1 - additional arguments to pass to make (at the moment just # an optional -j arg for parallel builds). build_compile() { - local CFLAGS LDFLAGS TARGET_FILE DEPEND_FILE OBJDIR + local CFLAGS CXXFLAGS LDFLAGS TARGET_FILE DEPEND_FILE OBJDIR eval CFLAGS="\${${BUILD_PROJECT}_CFLAGS}" + eval CXXFLAGS="\${${BUILD_PROJECT}_CXXFLAGS}" eval LDFLAGS="\${${BUILD_PROJECT}_LDFLAGS}" eval OBJDIR=\""\$BUILD_WORK/\${${BUILD_PROJECT}_OBJS}"\" eval TARGET_FILE=\""\$BUILD_WORK/\${${BUILD_PROJECT}_NAME}"\" @@ -116,7 +117,7 @@ build_compile() { eval "${TARGET}_pre_build" - CFLAGS=$CFLAGS LDFLAGS=$LDFLAGS \ + CFLAGS=$CFLAGS CXXFLAGS=$CXXFLAGS LDFLAGS=$LDFLAGS \ OBJDIR=$OBJDIR \ BUILD_ROOT= \ TARGET_FILE=$TARGET_FILE DEPEND_FILE=$DEPEND_FILE \ @@ -133,6 +134,7 @@ build_clean() { eval DEPEND_FILE="\$BUILD_WORK/\${${BUILD_PROJECT}_OBJS}${DEPEND_NAME}" rm -f "$DEPEND_FILE" "$BUILD_WORK/build.vars" \ + "$BUILD_WORK/uqm-wrapper" \ "$BUILD_WORK/config.state" eval "${TARGET}_clean" } diff --git a/sc2/build/unix/config_proginfo_build b/sc2/build/unix/config_proginfo_build index 2bc25dbc0..b01cf09c5 100644 --- a/sc2/build/unix/config_proginfo_build +++ b/sc2/build/unix/config_proginfo_build @@ -26,6 +26,9 @@ # CFLAGS SYSTEM_BUILD_CFLAGS="" +# CXXFLAGS +SYSTEM_BUILD_CXXFLAGS="" + # LDFLAGS SYSTEM_BUILD_LDFLAGS="" @@ -33,6 +36,9 @@ SYSTEM_BUILD_LDFLAGS="" BUILDTOOL_PREPROC_C_NAME="C preprocessor" BUILDTOOL_MKDEP_C_NAME="C dependency generator" BUILDTOOL_COMPILE_C_NAME="C compiler" +BUILDTOOL_PREPROC_CXX_NAME="C++ preprocessor" +BUILDTOOL_MKDEP_CXX_NAME="C++ dependency generator" +BUILDTOOL_COMPILE_CXX_NAME="C++ compiler" BUILDTOOL_PREPROC_OBJC_NAME="Objective-C preprocessor" BUILDTOOL_MKDEP_OBJC_NAME="Objective-C dependency generator" BUILDTOOL_COMPILE_OBJC_NAME="Objective-C compiler" @@ -48,6 +54,15 @@ useGccBuildTools() { BUILDTOOL_COMPILE_C_COMMAND="\$PROG_gcc_FILE -c $EXTRA_PLATFORM_GCC_FLAGS_COMPILE_C" BUILDTOOL_COMPILE_C_DEPEND='gcc' + BUILDTOOL_PREPROC_CXX_COMMAND="\$PROG_gcc_FILE -E $EXTRA_PLATFORM_GCC_FLAGS_PREPROC_CXX" + BUILDTOOL_PREPROC_CXX_DEPEND='gcc' + + BUILDTOOL_MKDEP_CXX_COMMAND="\$PROG_gcc_FILE -MM $EXTRA_PLATFORM_GCC_FLAGS_MKDEP_CXX" + BUILDTOOL_MKDEP_CXX_DEPEND='gcc' + + BUILDTOOL_COMPILE_CXX_COMMAND="\$PROG_gcc_FILE -c $EXTRA_PLATFORM_GCC_FLAGS_COMPILE_CXX" + BUILDTOOL_COMPILE_CXX_DEPEND='gcc' + BUILDTOOL_PREPROC_OBJC_COMMAND="\$PROG_gcc_FILE -E $EXTRA_PLATFORM_GCC_FLAGS_PREPROC_OBJC" BUILDTOOL_PREPROC_OBJC_DEPEND='gcc' @@ -303,6 +318,12 @@ PROG_gcce_ACTION="" PROG_gcce_VERSION='$(arm-none-symbianelf-gcc --version)' +### mingw-gcc ### +PROG_mingw_gcc_NAME="GNU C MinGW Cross-compiler" +PROG_mingw_gcc_FILE="i686-pc-mingw32-gcc" +PROG_mingw_gcc_ACTION="" +PROG_mingw_gcc_VERSION='$(i686-pc-mingw32-gcc --version)' + ############################################################################## # Describe the libaries (possibly) used: # diff --git a/sc2/build/unix/config_proginfo_host b/sc2/build/unix/config_proginfo_host index 0654b95e5..748ffbdc5 100644 --- a/sc2/build/unix/config_proginfo_host +++ b/sc2/build/unix/config_proginfo_host @@ -24,17 +24,7 @@ # CFLAGS -case "$HOST_SYSTEM" in - CYGWIN*) - # HACK: sdl-config on Cygwin supplies -mno-cygwin which means that - # dependencies detected without that flag may not be available at - # the actual build. - SYSTEM_HOST_CFLAGS="-mno-cygwin" - ;; - *) - SYSTEM_HOST_CFLAGS="" - ;; -esac +SYSTEM_HOST_CFLAGS="" # LDFLAGS SYSTEM_HOST_LDFLAGS="" diff --git a/sc2/build/unix/make/buildtools-armv5 b/sc2/build/unix/make/buildtools-armv5 index 0711d89c3..bf7368929 100644 --- a/sc2/build/unix/make/buildtools-armv5 +++ b/sc2/build/unix/make/buildtools-armv5 @@ -7,6 +7,10 @@ define act_mkdep_c $(MKDEP_C) $(CFLAGS) -o "$(@D)/$( $@ + @cat "$@.tmp" >> $@ + @rm -f "$@.tmp" +endef + diff --git a/sc2/build/win32_install/packages.nsh b/sc2/build/win32_install/packages.nsh index c9c782dd1..36893d516 100644 --- a/sc2/build/win32_install/packages.nsh +++ b/sc2/build/win32_install/packages.nsh @@ -18,3 +18,6 @@ !define PKG_REMIX3_FILE "uqm-remix-disc3.uqm" !define PKG_REMIX3_MD5SUM "5ccc6d4ac301ae98e172ac6835dcdead" !define PKG_REMIX3_SIZE 38989 +!define PKG_REMIX4_FILE "uqm-remix-disc4.uqm" +!define PKG_REMIX4_MD5SUM "d3dc6036588662391a3820ca6b222dd6" +!define PKG_REMIX4_SIZE 84517 \ No newline at end of file diff --git a/sc2/build/win32_install/uqm-3do.cfg b/sc2/build/win32_install/uqm-3do.cfg new file mode 100644 index 000000000..4e002b797 --- /dev/null +++ b/sc2/build/win32_install/uqm-3do.cfg @@ -0,0 +1,11 @@ +3domusic = BOOLEAN:true +textmenu = BOOLEAN:false +textgradients = BOOLEAN:false +subtitles = BOOLEAN:false +iconicscan = BOOLEAN:true +3domovies = BOOLEAN:true +speechvol = INT32:100 +pulseshield = BOOLEAN:true +smoothmelee = BOOLEAN:true +smoothscroll = BOOLEAN:true +remixmusic = BOOLEAN:false diff --git a/sc2/build/win32_install/uqm-installer.nsi b/sc2/build/win32_install/uqm-installer.nsi index c8b5a4a92..a2340ee2b 100644 --- a/sc2/build/win32_install/uqm-installer.nsi +++ b/sc2/build/win32_install/uqm-installer.nsi @@ -14,6 +14,10 @@ Var UQMUSERDATA !define PRODUCT_UNINST_ROOT_KEY "HKLM" !define PRODUCT_STARTMENU_REGVAL "NSIS:StartMenuDir" +; The INSTALLER_VERSION is a suffix to the version number for installer patches or to mark +; alpha/beta/release candidate status. In normal releases it is the empty string. +!define INSTALLER_VERSION "-1" + ; UQM Package definitions !include "packages.nsh" @@ -80,7 +84,7 @@ var ICONS_GROUP ; MUI end ------ Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" -OutFile "uqm-${PRODUCT_VERSION}-installer.exe" +OutFile "uqm-${PRODUCT_VERSION}${INSTALLER_VERSION}-installer.exe" InstallDir "$PROGRAMFILES\The Ur-Quan Masters\" InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" "" ShowInstDetails show @@ -125,114 +129,74 @@ FunctionEnd Function RandomServer Push $0 - Push 27 + Push 17 Call Random Pop $0 IntCmp $0 0 0 +4 +4 - StrCpy $0 "ovh" - Exch $0 - Return - IntCmp $0 1 0 +4 +4 - StrCpy $0 "mesh" - Exch $0 - Return - IntCmp $0 2 0 +4 +4 StrCpy $0 "aarnet" Exch $0 Return - IntCmp $0 3 0 +4 +4 - StrCpy $0 "switch" + IntCmp $0 1 0 +4 +4 + StrCpy $0 "citylan" Exch $0 Return - IntCmp $0 4 0 +4 +4 - StrCpy $0 "superb-sea2" - Exch $0 - Return - IntCmp $0 5 0 +4 +4 - StrCpy $0 "jaist" - Exch $0 - Return - IntCmp $0 6 0 +4 +4 - StrCpy $0 "voxel" - Exch $0 - Return - IntCmp $0 7 0 +4 +4 - StrCpy $0 "heanet" - Exch $0 - Return - IntCmp $0 8 0 +4 +4 - StrCpy $0 "cdnetworks-us-1" - Exch $0 - Return - IntCmp $0 9 0 +4 +4 - StrCpy $0 "cdnetworks-us-2" - Exch $0 - Return - IntCmp $0 10 0 +4 +4 - StrCpy $0 "cdnetworks-kr-1" - Exch $0 - Return - IntCmp $0 11 0 +4 +4 - StrCpy $0 "surfnet" - Exch $0 - Return - IntCmp $0 12 0 +4 +4 - StrCpy $0 "cdnetworks-kr-2" - Exch $0 - Return - IntCmp $0 13 0 +4 +4 - StrCpy $0 "kent" - Exch $0 - Return - IntCmp $0 14 0 +4 +4 - StrCpy $0 "nchc" - Exch $0 - Return - IntCmp $0 15 0 +4 +4 - StrCpy $0 "dfn" - Exch $0 - Return - IntCmp $0 16 0 +4 +4 + IntCmp $0 2 0 +4 +4 StrCpy $0 "freefr" Exch $0 Return - IntCmp $0 17 0 +4 +4 + IntCmp $0 3 0 +4 +4 StrCpy $0 "garr" Exch $0 Return - IntCmp $0 18 0 +4 +4 + IntCmp $0 4 0 +4 +4 + StrCpy $0 "heanet" + Exch $0 + Return + IntCmp $0 5 0 +4 +4 + StrCpy $0 "hivelocity" + Exch $0 + Return + IntCmp $0 6 0 +4 +4 StrCpy $0 "ignum" Exch $0 Return - IntCmp $0 19 0 +4 +4 + IntCmp $0 7 0 +4 +4 StrCpy $0 "internode" Exch $0 Return - IntCmp $0 20 0 +4 +4 + IntCmp $0 8 0 +4 +4 StrCpy $0 "iweb" Exch $0 Return - IntCmp $0 21 0 +4 +4 + IntCmp $0 9 0 +4 +4 + StrCpy $0 "jaist" + Exch $0 + Return + IntCmp $0 10 0 +4 +4 + StrCpy $0 "nchc" + Exch $0 + Return + IntCmp $0 11 0 +4 +4 StrCpy $0 "netcologne" Exch $0 Return - IntCmp $0 22 0 +4 +4 - StrCpy $0 "leaseweb" + IntCmp $0 12 0 +4 +4 + StrCpy $0 "switch" Exch $0 Return - IntCmp $0 23 0 +4 +4 - StrCpy $0 "ncu" - Exch $0 - Return - IntCmp $0 24 0 +4 +4 + IntCmp $0 13 0 +4 +4 StrCpy $0 "tenet" Exch $0 Return - IntCmp $0 25 0 +4 +4 - StrCpy $0 "transact" + IntCmp $0 14 0 +4 +4 + StrCpy $0 "ufpr" Exch $0 Return - StrCpy $0 "citylan" + IntCmp $0 15 0 +4 +4 + StrCpy $0 "voxel" + Exch $0 + Return + StrCpy $0 "waix" Exch $0 FunctionEnd @@ -251,6 +215,7 @@ Function HandlePackage Exch $1 # File name Push $2 Push $3 + StrCpy $R9 0 # failure count # Check to make sure the file wasn't already installed IfFileExists "$0\$1" 0 NotThere md5dll::GetFileMD5 "$0\$1" @@ -289,6 +254,12 @@ AttemptDownload: StrCmp $2 "success" DownloadSuccessful StrCmp $2 "cancel" DownloadCanceled StrCpy $2 "Could not install the package $1 due to the following error: $\"$2$\"." + # Only actually display the error every third try, unless it's a user cancellation. We can't + # really rely on SF.net to have everything at every mirror. + IntOp $R9 $R9 + 1 + IntCmp $R9 3 0 AttemptDownload + # If we fell through, reset the count. + StrCpy $R9 0 Goto CheckMandatory DownloadCanceled: StrCpy $2 "Download was canceled by user." @@ -411,7 +382,7 @@ SectionGroup "!UQM" SECGRP01 AddSize ${PKG_CONTENT_SIZE} StrCpy $MANDATORY 1 StrCpy $MD5SUM "${PKG_CONTENT_MD5SUM}" - File "content\version" + File "..\..\content\version" StrCpy $DOWNLOADPATH "UQM/0.7/" Push "${PKG_CONTENT_FILE}" Push "$INSTDIR\content\packages" @@ -504,20 +475,20 @@ SectionGroup "Modern Remixes" SECGRP03 !insertmacro MUI_STARTMENU_WRITE_END SectionEnd -# Section "Pack 4" SEC08 -# SectionIn 6 -# AddSize ${PKG_REMIX4_SIZE} -# StrCpy $MANDATORY 0 -# StrCpy $MD5SUM "${PKG_REMIX4_MD5SUM}" -# StrCpy $DOWNLOADPATH "UQM%20Remix%20Packs/UQM%20Remix%20Pack%204/" -# Push "${PKG_REMIX4_FILE}" -# Push "$INSTDIR\content\addons" -# Call HandlePackage -# Call EnableRemixes -# ; Shortcuts -# !insertmacro MUI_STARTMENU_WRITE_BEGIN Application -# !insertmacro MUI_STARTMENU_WRITE_END -# SectionEnd + Section "Pack 4" SEC08 + SectionIn 6 + AddSize ${PKG_REMIX4_SIZE} + StrCpy $MANDATORY 0 + StrCpy $MD5SUM "${PKG_REMIX4_MD5SUM}" + StrCpy $DOWNLOADPATH "UQM%20Remix%20Packs/UQM%20Remix%20Pack%204/" + Push "${PKG_REMIX4_FILE}" + Push "$INSTDIR\content\addons" + Call HandlePackage + Call EnableRemixes + ; Shortcuts + !insertmacro MUI_STARTMENU_WRITE_BEGIN Application + !insertmacro MUI_STARTMENU_WRITE_END + SectionEnd SectionGroupEnd Section -ShortcutsAndIcons @@ -588,7 +559,7 @@ SectionEnd !insertmacro MUI_DESCRIPTION_TEXT ${SEC05} `Ur-Quan Masters Remix Pack 1 - 'Super Melee!' Optional add-on music package. If this package is selected and not present in the packages directory, the installer will attempt to download it.` !insertmacro MUI_DESCRIPTION_TEXT ${SEC06} `Ur-Quan Masters Remix Pack 2 - 'Neutral Aliens - Don't Shoot!' Optional add-on music package. If this package is selected and not present in the packages directory, the installer will attempt to download it.` !insertmacro MUI_DESCRIPTION_TEXT ${SEC07} `Ur-Quan Masters Remix Pack 3 - 'The Ur-Quan Hierarchy.' Optional add-on music package. If this package is selected and not present in the packages directory, the installer will attempt to download it.` -# !insertmacro MUI_DESCRIPTION_TEXT ${SEC08} `Ur-Quan Masters Remix Pack 4 - 'The New Alliance of Free Stars.' Optional add-on music package. If this package is selected and not present in the packages directory, the installer will attempt to download it.` + !insertmacro MUI_DESCRIPTION_TEXT ${SEC08} `Ur-Quan Masters Remix Pack 4 - 'The New Alliance of Free Stars.' Optional add-on music package. If this package is selected and not present in the packages directory, the installer will attempt to download it.` !insertmacro MUI_FUNCTION_DESCRIPTION_END diff --git a/sc2/build/win32_install/uqm-pc.cfg b/sc2/build/win32_install/uqm-pc.cfg new file mode 100644 index 000000000..09aa53afb --- /dev/null +++ b/sc2/build/win32_install/uqm-pc.cfg @@ -0,0 +1,11 @@ +3domusic = BOOLEAN:false +textmenu = BOOLEAN:true +textgradients = BOOLEAN:true +subtitles = BOOLEAN:true +iconicscan = BOOLEAN:false +3domovies = BOOLEAN:false +positionalsfx = BOOLEAN:false +pulseshield = BOOLEAN:false +smoothmelee = BOOLEAN:false +smoothscroll = BOOLEAN:false +remixmusic = BOOLEAN:false diff --git a/sc2/content/addons/3dovoice/3dovoice.rmp b/sc2/content/addons/3dovoice/3dovoice.rmp index 029ee90ed..d1b068db5 100644 --- a/sc2/content/addons/3dovoice/3dovoice.rmp +++ b/sc2/content/addons/3dovoice/3dovoice.rmp @@ -4,7 +4,7 @@ comm.commander.dialogue = CONVERSATION:base/comm/commander/commander.txt:addons/ comm.druuge.dialogue = CONVERSATION:base/comm/druuge/druuge.txt:addons/3dovoice/druuge/:addons/3dovoice/druuge/druuge.ts comm.ilwrath.dialogue = CONVERSATION:base/comm/ilwrath/ilwrath.txt:addons/3dovoice/ilwrath/:addons/3dovoice/ilwrath/ilwrath.ts comm.kohrah.dialogue = CONVERSATION:base/comm/kohrah/kohrah.txt:addons/3dovoice/kohrah/:addons/3dovoice/kohrah/kohrah.ts -comm.melnorme.dialogue = CONVERSATION:base/comm/melnorme/melnorme.txt:addons/3dovoice/melnorme/:addons/3dovoice/melnorme/melnorme.ts +comm.melnorme.dialogue = CONVERSATION:addons/3dovoice/melnorme/melnorme.txt:addons/3dovoice/melnorme/:addons/3dovoice/melnorme/melnorme.ts comm.mycon.dialogue = CONVERSATION:addons/3dovoice/mycon/mycon.txt:addons/3dovoice/mycon/:addons/3dovoice/mycon/mycon.ts comm.orz.dialogue = CONVERSATION:base/comm/orz/orz.txt:addons/3dovoice/orz/:addons/3dovoice/orz/orz.ts comm.pkunk.dialogue = CONVERSATION:base/comm/pkunk/pkunk.txt:addons/3dovoice/pkunk/:addons/3dovoice/pkunk/pkunk.ts diff --git a/sc2/content/addons/3dovoice/melnorme/melnorme.txt b/sc2/content/addons/3dovoice/melnorme/melnorme.txt new file mode 100644 index 000000000..fc450d134 --- /dev/null +++ b/sc2/content/addons/3dovoice/melnorme/melnorme.txt @@ -0,0 +1,1388 @@ +#(HELLO_NOW_DOWN_TO_BUSINESS_1) melnorme-000.ogg +I am Trade Master Greenish in command of the Melnorme starship +`Inevitably Successful in All Circumstances.' +I bid you a formal welcome, Captain. +Though we Melnorme have just recently arrived in this region of space +we have long desired to make contact with your species +and look forward to an extended profitable relationship. + +#(HELLO_NOW_DOWN_TO_BUSINESS_2) melnorme-001.ogg +As a master trader in the Melnorme merchant fleet, I greet you, Captain. +News of your species and your unusual vessel has travelled quickly. +I need not say how eager we are to trade with you and your kind! +Now, how can I be of service to you? + +#(HELLO_NOW_DOWN_TO_BUSINESS_3) melnorme-002.ogg +Hello again, human space captain. +Perhaps during this encounter, we will be able to establish a successful, businesslike relationship. + +#(KNOW_OF_YOU) melnorme-003.ogg +Even before our first meeting, we knew of you, Captain. +Though your struggle to free Earth shall be a long and difficult challenge +fraught with great danger and mystery +we have great confidence in you and your abilities. + +#(how_know) +How did you know about us before meeting us? + +#(KNOW_BECAUSE) melnorme-004.ogg +We gather information from a thousand secret sources in space and time. +Our charge for revealing even one of these sources would be so high +that your species would be in debt to us for centuries. + +#(what_about_yourselves) +What can you tell us about yourselves? + +#(NO_TALK_ABOUT_OURSELVES) melnorme-005.ogg +Our origins and purposes are, frankly, mysterious and due to several unavoidable factors +we are unable to discuss ourselves in any great detail. + +#(what_factors) +What are these 'unavoidable factors'? + +#(FACTORS_ARE) melnorme-006.ogg +First and foremost among these factors +is our unwillingness to GIVE away information +about our history, psychology and mental powers, +our unique physiology, +the exact locations of homeworlds, +or our potentially ominous, long-range plans. +However, these important and relevant pieces of information +ARE available, for a nominal sum of Credits. + +#(what_about_universe) +Do you have any information which might be useful to us? + +#(NO_FREE_LUNCH) melnorme-007.ogg +Absolutely. +Our primary trade good IS information. +Why, right here on my display screen, I have something +which I am certain would be of incalculable value to you! +We can discuss the details of this VERY significant information +later, when we have established normal trading procedures +at which time we shall also discuss the nature of our fees. + +#(giving_is_good_1) +Fees! Surely your culture is far beyond such pettiness as money? + +#(GIVING_IS_BAD_1) melnorme-008.ogg +You are of course correct. +We long ago abandoned currency, +and now only deal with commodities that have intrinsic value, such as valuable information. + +#(giving_is_good_2) +But our cause is just! Isn't altruism the highest pinnacle of morality? + +#(GIVING_IS_BAD_2) melnorme-009.ogg +No, it is not. +In fact, in our culture, `giving' +with no fair exchange of goods or services, +is considered vulgar and inappropriate. +Please do not mention this subject again. + +#(get_on_with_business) +Shall we begin trading now? + +#(trade_is_for_the_weak) +`Trade' is for the weak. We TAKE what we want! + +#(WERE_NOT_AFRAID) melnorme-010.ogg +We reel with inchoate fear, and are thrown into a sudden panic. +Being peaceful by nature +we would no doubt be unprepared for your sudden hostility +were it not for the excellent weapon system we bought from the Keel-Verezy just last month. +A weapon system which is fully locked on your command bridge, by the way. + +#(no_trade_now) +We cannot continue this conversation. Goodbye. + +#(OK_NO_TRADE_NOW_BYE) melnorme-011.ogg +When you wish to trade with us, seek any supergiant star system. +We shall be there. + +#(HELLO_AND_DOWN_TO_BUSINESS_1) melnorme-012.ogg +Yes, let us get down to business. + +#(HELLO_AND_DOWN_TO_BUSINESS_2) melnorme-013.ogg +How nice to see you again, Captain. + +#(HELLO_AND_DOWN_TO_BUSINESS_3) melnorme-014.ogg +I had itchy pods this morning, Captain, and here you are! + +#(HELLO_AND_DOWN_TO_BUSINESS_4) melnorme-015.ogg +What a coincidence! I was just talking about you with a Keel-Verezy captain. +They expressed great interest in your explorations and struggles against the Ur-Quan +but, like all Verezy, I'm afraid they were hesitant to introduce themselves for fear of +well, frightening you. +In any event, it is our pleasure to meet you once again. + +#(HELLO_AND_DOWN_TO_BUSINESS_5) melnorme-016.ogg +Once again we meet to exchange valuable tangibles. +Isn't this fun?! + +#(HELLO_AND_DOWN_TO_BUSINESS_6) melnorme-017.ogg +Your arrival was predicted by our Tzo crystal's vibrations. +We already know why you are here and what you need from us; however +etiquette requires that we act as though we are ignorant of your desires. + +#(HELLO_AND_DOWN_TO_BUSINESS_7) melnorme-018.ogg +This very morning, I was just saying to subordinate Ochre +`Fe-Fi-Fo-Fum! I smell the feet of a Hu-Hu-Man!' +We laughed and laughed. What a synchronicity! + +#(HELLO_AND_DOWN_TO_BUSINESS_8) melnorme-019.ogg +I must warn you, Captain +this is the time of the month we Melnorme drive exceptionally hard bargains. +Beware! + +#(HELLO_AND_DOWN_TO_BUSINESS_9) melnorme-020.ogg +LOOK OUT! +Hoy! What a close call! +Captain, why did you try to run down that Keel-Verezy vessel!? +You almost smashed it into flinders! +What!? You didn't see it? Surely you -- oh +Never mind. + +#(HELLO_AND_DOWN_TO_BUSINESS_10) melnorme-021.ogg +Welcome back, Captain! You are our favorite customer. + +#(whats_my_credit) +What's my Credit balance, if you please? + +#(HELLO_SLIGHTLY_ANGRY_1) melnorme-022.ogg +So, the violent one has returned. +Have you come back to seek our forgiveness +or to attack our defenseless vessel once more? + +#(HELLO_SLIGHTLY_ANGRY_2) melnorme-023.ogg +You have disappointed us +though to be truthful +we had some hints that our relationship would be difficult at first +due to your species' emotional immaturity. + +#(HELLO_SLIGHTLY_ANGRY_3) melnorme-024.ogg +We require a formal apology. + +#(explore_relationship) +Can we discuss establishing an alliance? + +#(EXAMPLE_OF_RELATIONSHIP) melnorme-025.ogg +Your question reveals a certain lack of understanding +about the nature of friendly, inter-species relationships. +We shall clarify the situation. +If you wish to be friends with someone +never, EVER +shoot wads of super-heated plasma at them. +Is this clear? + +#(excuse_1) +Look, mistakes happen. Don't get so bent out of shape! + +#(NO_EXCUSE_1) melnorme-026.ogg +The Spathi once used a similar excuse +after an unfortunate incident at their base on Algol IV. +They didn't like the climate there +so they decided to make `just a few minor, climatic adjustments.' +Their equipment went haywire, they panicked and fled +and the entire atmosphere was stripped off the planet +much to the native Algolites sincere, +though short-lived, regret. + +#(excuse_2) +Let's just forget our battle ever happened, ok? + +#(NO_EXCUSE_2) melnorme-027.ogg +No. + +#(excuse_3) +What do you want from me, a formal apology? + +#(NO_EXCUSE_3) melnorme-028.ogg +There is a small possibility that an apology would set things right. +But it would have to be genuine. + +#(we_apologize) +I apologize. I'm sorry. Please forgive me, I beg you. + +#(APOLOGY_ACCEPTED) melnorme-029.ogg +Well, since you put it so nicely +you seem so genuinely repentant +we'll give you another chance to become trading partners with us. +But don't ever attack us again +Or the next time we won't be such nice guys. + +#(so_we_can_attack) +This seems like a great opportunity to attack you again. + +#(DECEITFUL_HUMAN) melnorme-030.ogg +Deceitful human! + +#(bye_melnorme_slightly_angry) +I'm leaving now. Goodbye. + +#(MELNORME_SLIGHTLY_ANGRY_GOODBYE) melnorme-031.ogg +Farewell, violent human. + +#(HELLO_HATE_YOU_1) melnorme-032.ogg +We thought you were a nice guy. +Boy, were we wrong! +Now go away and leave us alone. + +#(HELLO_HATE_YOU_2) melnorme-033.ogg +So, the jerk is back. +What do you want from us this time? +Never mind, we don't want to know. + +#(HELLO_HATE_YOU_3) melnorme-034.ogg +We will hate you forever. +It is no use coming back here in the hopes that we will ever change our minds. +We won't! + +#(well_if_thats_the_way_you_feel) +Die, eye-freak. + +#(you_hate_us_so_we_go_away) +Goodbye. + +#(HATE_YOU_GOODBYE) melnorme-035.ogg +Don't ever come back! + +#(WE_FIGHT_AGAIN) melnorme-036.ogg +This time you shall pay for your transgressions! + +#(RESCUE_EXPLANATION) melnorme-037.ogg +According to our scanners and other sensitive devices +you are immobile in HyperSpace with no fuel reserves. +This is a serious situation. +Without fuel you shall drift here until your batteries exhaust themselves +then your life-support will fail +and you will expire +unless, of course +a hostile alien vessel finds you here helpless +and annihilates you mercilessly. +This has been known to happen. + +However +as a gesture of good will, and in the spirit of friendship, we offer our assistance! +For a nominal fee. + +#(RESCUE_AGAIN_1) melnorme-038.ogg +Once more we find ourselves in a position to help you. +How wonderful. + +#(RESCUE_AGAIN_2) melnorme-039.ogg +Have you ever considered buying more fuel tanks? +Just a friendly suggestion, Captain. + +#(RESCUE_AGAIN_3) melnorme-040.ogg +We have come to help you once more, Captain. + +#(RESCUE_AGAIN_4) melnorme-041.ogg +We MUST stop meeting like this, Captain! +Ha, ha, ha! + +#(RESCUE_AGAIN_5) melnorme-042.ogg +Out of fuel again, eh, Captain? + +#(CHANGED_MIND) melnorme-043.ogg +Have you changed your mind +and decided to accept our offer of assistance? + +#(no_changed_mind) +No thanks, I don't need your help right now. + +#(yes_changed_mind) +Perhaps I was hasty in refusing your offer. What was it again? + +#(SHOULD_WE_HELP_YOU) melnorme-044.ogg +Would you like us to help you at this time? + +#(yes_help) +Yes, I would appreciate your assistance. What is your fee? + +#(no_help) +I don't need your help at this time. Maybe later, though. + +#(RESCUE_OFFER) melnorme-045.ogg +You have no Credit balance in our mercantile computer +and our scanners show that you possess no useful trade goods +but, perhaps we can work out a special deal. +In exchange for our giving you enough fuel to + +#(RESCUE_TANKS) melnorme-046.ogg +fill your tanks, we will take: + +#(RESCUE_HOME) melnorme-047.ogg +get you home, we will take: + +#(take_it) +I find I have no choice. I accept your offer... grudgingly. + +#(leave_it) +This offer is absurd! I refuse. + +#(HAPPY_TO_HAVE_RESCUED) melnorme-048.ogg +The exchange of fuel for equipment is complete. +As always, it is a pleasure doing business with you. +Goodbye, Captain. + +#(MAYBE_SEE_YOU_LATER) melnorme-049.ogg +Well then, we bid you farewell. +We hope to see you again +though with you sitting here, dead in space +vulnerable and alone +we won't hold our breath. + +#(GOODBYE_AND_GOODLUCK) melnorme-050.ogg +Good luck, Captain. + +#(GOODBYE_AND_GOODLUCK_AGAIN) melnorme-051.ogg +Until we meet again, Captain. + +#(HELLO_PISSED_OFF_1) melnorme-052.ogg +The Human has returned. +He hopes to either convince us of his sorrow over his past wrong-doings +or he intends to compel us to give/render unreasonable bargains by force. + +#(HELLO_PISSED_OFF_2) melnorme-053.ogg +Ahhh-YING!! Ahhh-YING! Ahhh-YING! Ahhh-Y +Oh sorry, Captain. I was just meditating on the sorry state of your consciousness. +Do you perceive any improvement? + +#(HELLO_PISSED_OFF_3) melnorme-054.ogg +Perhaps I can be of some assistance to you in this time of confusion and travail +either make a sincere apology to us, or depart. + +#(beg_forgiveness) +We beg your forgiveness for our unwarranted aggression. + +#(LOTS_TO_MAKE_UP_FOR) melnorme-055.ogg +Even if we were to accept your words as truth +you have a lot to make up for. + +#(you_are_so_right) +We stand prepared to make reparations for our previous conduct. + +#(ONE_LAST_CHANCE) melnorme-056.ogg +Hmm +hmm... hmm... hmm. +Oh, very well then. +We will give you a single opportunity to compensate us +for the damages you have inflicted upon our mercantile fleet +with your unreasonable attacks in the past. +We will not make this offer a second time. +You will give us all non-essential hardware from your vessel +immediately! +Do you accept? + +#(ok_strip_me) +Ok, it's a deal, but ONLY the non-essentials! + +#(no_strip_now) +What kind of sucker do you think I am? Forget it! + +#(NOT_WORTH_STRIPPING) melnorme-057.ogg +It's not worth stripping. + +#(FAIR_JUSTICE) melnorme-058.ogg +Removal of non-essential equipment is complete. +We are satisfied with the exchange, and believe that we can now pursue +a productive business relationship. +We shall forget the mistakes you made in the past. Mostly. + +#(bye_melnorme_pissed_off) +Goodbye. + +#(MELNORME_PISSED_OFF_GOODBYE) melnorme-059.ogg +Good riddance. + +#(fight_some_more) +Prepare to be destroyed. + +#(OK_FIGHT_SOME_MORE) melnorme-060.ogg +No, YOU prepare to be destroyed! + +#(why_blue_light) +Why did your bridge just turn blue? + +#(BLUE_IS_MAD) melnorme-061.ogg +To us, blue ambience signifies a response to an unexpected threat +it shows that we are under emotional distress +and not incidentally +it also lets us see our weapon consoles more clearly. + +#(we_strong_1) +We have no fear of you, Melnorme! + +#(YOU_NOT_STRONG_1) melnorme-062.ogg +Oh, you should. +Once the Dramya thought they could steal from us. +You don't see too many Dramya around these days, do you? + +#(we_strong_2) +We have the most powerful ship in this part of the galaxy. + +#(YOU_NOT_STRONG_2) melnorme-063.ogg +Perhaps that is true, but you have only one ship. + +#(we_strong_3) +Why shouldn't we just take what we want from you by force? + +#(YOU_NOT_STRONG_3) melnorme-064.ogg +Because it's against the law, and besides +if you steal from us, the other Melnorme ships will have to raise their prices +and other innocent space aliens will have to pay for your wrong-doing. +Now that's not fair, is it? + +#(just_testing) +Look, we were just testing your intentions. We're actually peaceful and friendly. + +#(REALLY_TESTING) melnorme-065.ogg +You have an odd way of making friends, Captain. +Are you certain that you aren't just tricking us +so that you can attack us the moment our back is turned? + +#(yes_really_testing) +I promise, we won't do anything sneaky like that. + +#(TEST_RESULTS) melnorme-066.ogg +We believe you. + +#(youre_on) +Let's just test out that weapon system, shall we?... IN COMBAT! + +#(YOU_GIVE_US_NO_CHOICE) melnorme-067.ogg +You give us no choice. + +#(TRADING_INFO) melnorme-068.ogg +Since this is your first time trading with us, let me explain how our system works. +We are interested in purchasing certain items, specifically +biological data on alien life forms +and the coordinates of certain strange worlds whose radiant energies defy all scanners +producing a rainbow-like image. +In exchange, we have many interesting and valuable commodities, such as +fuel compatible with your starship's HyperDrive thrusters, +technological specifications, allowing you to build new devices for your ship +and many important secrets which may help you in your travels. +To facilitate trade, we translate all your sales into Interstar Credits +with which you may make purchases. +If you have any questions, don't hesitate to ask. + +#(BUY_OR_SELL) melnorme-069.ogg +Now, what can we do for you today? + +#(goodbye) +Goodbye, Trade Master. + +#(why_turned_purple) +Why did your bridge turn purple? + +#(buy) +I would like to make some purchases. + +#(sell) +I have some items I would like to sell. + +#(TURNED_PURPLE_BECAUSE) melnorme-070.ogg +That's a good question with a very interesting answer! +The fee for this information is 12,000,000 Credits. + +#(NOTHING_TO_SELL) melnorme-071.ogg +We appreciate your intentions, but you have nothing we wish to buy. + +#(WHAT_TO_SELL) melnorme-072.ogg +What would you like to sell, Captain? + +#(OK_DONE_SELLING) melnorme-073.ogg +As you wish. + +#(sell_life_data) +I have some data on alien lifeforms. + +#(SOLD_LIFE_DATA1) melnorme-074.ogg +The + +#(SOLD_LIFE_DATA2) melnorme-203.ogg + units of biological data we downloaded from your ship earn you + +#(SOLD_LIFE_DATA3) melnorme-204.ogg + Credits. + +#(sell_rainbow_locations) +I wish to sell you Rainbow world locations. + +#(SOLD_RAINBOW_LOCATIONS1) melnorme-075.ogg +Your ship's log indicates that you discovered the whereabouts of + +#(SOLD_RAINBOW_LOCATIONS2) melnorme-205.ogg + of the Rainbow worlds which so fascinate us. +In exchange, we will give you + +#(SOLD_RAINBOW_LOCATIONS3) melnorme-204.ogg + Credits. + +#(sell_precursor_find) +We found a Precursor artifact. Do you want it? + +#(SOLD_PRECURSOR_FIND) melnorme-076.ogg +Always! Absolutely! +In exchange we will give you +N Credits + +#(changed_mind_no_sell) +On second thought, I don't think I want to sell anything. + +#(done_selling) +I am done selling, for now. + +#(NEED_CREDIT) melnorme-077.ogg +You need Credits to purchase our trade items. +To earn Credits you must sell us the items we desire, which are: +biological data on alien lifeforms +and the coordinates of certain strange worlds whose radiant energies defy all scanners +producing a rainbow-like image. + +#(WHAT_TO_BUY) melnorme-078.ogg +What trade items would you like to buy today? + +#(WHAT_MORE_TO_BUY) melnorme-079.ogg +Would you like to purchase anything else? + +#(OK_DONE_BUYING) melnorme-080.ogg +Very well then. + +#(buy_fuel) +I'd like to buy some fuel. + +#(done_buying) +I am done buying, for now. + +#(be_leaving_now) +I shall be leaving now. + +#(HOW_MUCH_FUEL) melnorme-081.ogg +How much fuel do you wish to purchase? + +#(buy_1_fuel) +1 unit of fuel. + +#(GOT_FUEL) melnorme-082.ogg +Fuel transferred to your vessel. + +#(buy_5_fuel) +5 units of fuel. + +#(buy_10_fuel) +10 units of fuel. + +#(buy_25_fuel) +25 units of fuel. + +#(done_buying_fuel) +I am done buying fuel. + +#(FRIENDLY_GOODBYE) melnorme-083.ogg +It has been a pleasure dealing with you, Captain. +We look forward to your next visit. + +#(CREDIT_IS0) +Your present balance is +#(CREDIT_IS1) + Credits. + +#(NEED_MORE_CREDIT0) melnorme-084.ogg +Unfortunately this purchase requires +#(NEED_MORE_CREDIT1) melnorme-206.ogg + additional Credits. + +#(BUY_FUEL_INTRO) melnorme-085.ogg +As you know, we carry a large supply of fuel on board which is compatible with your engine system. +We will be happy to sell this substance to you at a cost of 1 Credit per fuel unit. + +#(NO_ROOM_FOR_FUEL) melnorme-086.ogg +Your ship's capacity is insufficient to hold that much fuel. + +#(buy_info) +I wish to buy information. + +#(buy_technology) +I am interested in purchasing new technology. + +#(buy_current_events) +I wish to buy information about current events. + +#(buy_alien_races) +I will pay for useful data on alien races. + +#(buy_history) +Please sell us historical information. + +#(done_buying_info) +I am done buying information. + +#(no_buy_info) +I do not wish to buy information at this time. + +#(BUY_INFO_INTRO) melnorme-087.ogg +As you know, in our many centuries of star-trading +we Melnorme have come to learn much about what happens in our galaxy +both now and in the ancient past. +We have also kept records on the diverse alien races in your region of space. +We will share this crucial knowledge with you for a fee of 75 Credits per informative fact. +No refunds. + +#(OK_BUY_INFO) melnorme-088.ogg +How wonderful, Captain! + +#(OK_NO_BUY_INFO) melnorme-089.ogg +What else would you like to buy? + +#(OK_DONE_BUYING_INFO) melnorme-090.ogg +What else would you like to buy? + +#(OK_BUY_EVENT_1) melnorme-091.ogg +While you probably believe that the Shofixti are extinct +having caused their sun to flare with a device identical to the Utwig's super-bomb +the truth is not so simple. +There yet exists a chance to resuscitate this meta-marsupial species, though it will not be easy. +The problem at hand seems simple: bring together two Shofixti of different sexes +and the carnal gymnastics proceed. Given the short gestation and maturation time of the Shofixti +you will have thousands of the creatures in ten years, and millions in twenty. +Finding a male of the species is easier than flup +simply visit the Shofixti's blasted star system at Delta Gorno. +Captain Tanaka or its sibling Katana shall greet you on your arrival. +A warning! -- These warriors are old and fly in barely functional ships. +If they mistakenly identify you as the enemy, do not return fire! +Retreat and try to talk with them on their own level. +The females of the species will be more difficult to obtain. +The only supply of such remaining in the galaxy is at Alpha Cerenkov I +included as part of General ZEX's bizarre and beloved menagerie. +Fortunately for you, Captain, ZEX is considered... well... perverse, by his fellow VUX. +This is because ZEX actually enjoys the presence of human beings. +To acquire the Shofixti females, you will have to appease ZEX, or kill him. + +#(OK_BUY_EVENT_2) melnorme-092.ogg +The Ur-Quan are presently at war with a race called the Kohr-Ah. +They are fighting within a large spherical region of space centered around the Crateris star group. +Although it is probably too early to tell, it would appear that the Kohr-Ah are winning. + +#(OK_BUY_EVENT_3) melnorme-093.ogg +No doubt you are familiar with an alien race called the Umgah who live in the Orionis constellation. +While they are renowned for their potent and often cruel sense of humor +they have outdone themselves in recent years. +Specifically, they have used an unusual HyperWave `Caster +to impersonate the Ilwrath gods Dogar and Kazon. +When the Ilwrath began tuning-in to `the voices of their gods' on their HyperWave receivers +their priest caste was understandably skeptical +and counselled their many followers to ignore the blasphemous signals. +However, in a surprise move, the majority of the Ilwrath then rose up +and slaughtered the entire priest caste. +Their reasons for this ghastly move included over-taxation, lack of `quality death in ceremony' +and the general feeling that the priests had made Dogar and Kazon's pronouncements overly complex. + +#(OK_BUY_EVENT_4) melnorme-094.ogg +As you know, there are weaknesses in the division between dimensions. +For example, your vessel uses such weaknesses to enter HyperSpace. +However, there are other weak spots in the galaxy which lead to yet different dimensions. +One such portal exists nearby, between the Chandrasekhar and Columbae constellations. +The portal opens only a short time each month starting on the 17th. +Since we have never entered the portal, we can give no more information on this subject. + +#(OK_BUY_EVENT_5) melnorme-095.ogg +As you are probably aware, Ur-Quan starships -- you call them `Dreadnoughts', I believe +possess effective self-annihilation circuits which prevent other races +from reverse-engineering Ur-Quan technological secrets. +However, we have become aware of a shipwrecked dreadnought which has remained largely intact. +You will find the remains of the ship on the surface of a blue world orbiting Alpha Pavonis. +We suspect you will find at least one item of interest there, possibly two. + +#(OK_BUY_EVENT_6) melnorme-096.ogg +You may have noticed the presence of an increasingly large number of red probe vessels +which move with great speed and attack relentlessly. +We are sorry to say that this is our catalog item 2418-B. +Do not blame us! We are not responsible for this violent folly! +The product is not being used in a correct manner. +Should you wish to confront the actual wrong-doers +we suggest you search the planets in Beta Corvi for the probes' owners. + +#(OK_BUY_EVENT_7) melnorme-097.ogg +Not more than fifty years ago +the Druuge were informed by the now-extinct Burvixese race +of a powerful alien nation called the Utwig. +The Utwig, the Burvixese explained, were pleasant, sophisticated creatures +but they were also terminally depressed and often spoke about ending their lives +by activating a super-weapon, some kind of gigantic bomb +which they had found on one of their worlds -- Zeta Hyades VI-B I think it was. +The Druuge recognized the description of the bomb as a Precursor planeteering tool +which indeed was an explosive device of unrivaled power, and they set out to make it their own. +Though the revolting, criminal, insidious Druuge rarely leave their sphere of influence +(it encompasses Algol, Almagest, and the Persei stars) +they made a special trip on this occasion to the Aquarii constellation, where they made contact with the Utwig. +There is a device commonly known as the `Ultron'. +Is it now in your possession? Ah... I see. +The Druuge sold this device to the Utwig, explaining that it was a Precursor `Personal Magnifier' +which would enrich the lives of their entire culture in too many ways to describe specifically. +The Utwig, I am sorry to say, fell for the Druuge's foul ruse, and snapped up the Ultron immediately. +Fortunately for us all, the Utwig did not pay the Druuge's requested price -- the super-bomb +and instead gave them a collection of `historical oddments and genuine artifacts' +which to this day, the Druuge are trying to unload on unwary buyers. + +#(OK_BUY_EVENT_8) melnorme-098.ogg +The Utwig, who live in the Aquarii constellation, have grown very depressed of late. +They accidentally broke the supposed `Ultron' sold to them by the felonious Druuge. +As a consequence, they are morose and melancholic +and will probably be unwilling to help you fight the Ur-Quan. +If you wish to gain them as allies, we recommend that you acquire the broken Ultron +(as if it EVER worked) +and find some suitable replacement parts. +Our information indicates that you can find these items in three different places: +a Rosy Sphere at the Druuge trade world +an Aqua Helix somewhere in Thraddash space +and a Clear Spindle, which is currently in the possession of the Pkunk. +Captain, that was the last current event we have for sale. + +#(OK_BUY_ALIEN_RACE_1) melnorme-099.ogg +The Zoq-Fot-Pik are a friendly co-op of three alien species all native to the same world. +They are presently suffering severe collateral damage +from the ritual combat between the Ur-Quan and the Kohr-Ah. +While this is unfortunate for the Zoq-Fot-Pik -- they have been forced to abandon many of their worlds +this close proximity to the inter-Ur-Quan war will give them insights into the conflict +which will be of great use to you. +In addition, the Zoq-Fot-Pik met the Chenjesu early on in the war, and are eager to make allies +who can protect them from their enemies. +In case you are interested, the Zoq-Fot-Pik homeworld is at coordinates 400.0:543.7, planet I. + +#(OK_BUY_ALIEN_RACE_2) melnorme-100.ogg +The Ilwrath are presently attacking the Pkunk in the Lacaille and Krueger constellations. +These beings have slavish devotion to their dark gods Dogar and Kazon +which in the past few years has been used against them by the Umgah. +If you need to manipulate the Ilwrath, we suggest you discover the Umgah's technique +and duplicate it. + +#(OK_BUY_ALIEN_RACE_3) melnorme-101.ogg +The Pkunk are a mystical off-shoot of the Yehat species +who left their bird-brothers long ago to found a peaceful enclave in the Krueger and Giclas stars. +At the present time, the Pkunk are defending themselves against the Ilwrath +who have been commanded to attack the happy birds by Dogar and Kazon. +The Pkunk may be unwilling to make a formal alliance with you +but we have confidence that if you explain yourself honestly +they will help your efforts against the Ur-Quan. + +#(OK_BUY_ALIEN_RACE_4) melnorme-102.ogg +The creatures presently fighting the Ur-Quan are called the Kohr-Ah. +They are an Ur-Quan sub-species who split off from the main species many thousands of years ago. +Their present fight is a ritual reenacting of a major difference of opinion +between two, rival Ur-Quan leaders after the Ur-Quan overwhelmed their slave-masters, the Dnyarri. +The Kohr-Ah are immune to reason, having long ago lost the ability to see their situation objectively. +They live in a self-maintained paradox: to ensure their safety and security +the Kohr-Ah fight an endless battle against all other sentient species. + +#(OK_BUY_ALIEN_RACE_5) melnorme-103.ogg +I must warn you about some very bad people. +`Is this worth so many credits?' you ask yourself. +I assure you, it is! +The creatures are called the `Druuge' and they are a callous and evil race. +They care for nothing but profit and personal gain through unfair mercantile exchanges.. +Why are you looking at me like that, Captain? It is not appropriate. +As I was saying, these wicked creatures will try to sell you commodities at unreasonably low prices. +Hoy! -- they almost give away fuel! +Do not fall for their tricks! There are hidden costs -- secret tariffs! +So that you may avoid them, I will tell you that their main trade world is Zeta Persei I. +Why are you smiling, Captain? + +#(OK_BUY_ALIEN_RACE_6) melnorme-104.ogg +The Burvixese race evolved on the planet Arcturus I. +They lived there in a relatively benevolent manner +until the Kohr-Ah came and destroyed them during the course of 2 or 3 unfortunate days. +The Druuge were largely responsible for the Kohr-Ah finding the Burvixese. +You see, the Burvixese were in long-distance HyperWave contact +with a race known simply as the Gg. +For decades the Gg and the Burvixese traded much valuable information +until the Gg came under attack by an invading race who you may know as the Kohr-Ah. +The Gg warned the Burvixese that the Kohr-Ah located races by their HyperWave transmissions +and that they had already discovered the radiations from the Druuge. +When the Burvixese were kind enough to warn the Druuge that a hostile alien race +was homing in on their HyperWave radiations, the Druuge shut down all their transmitters +and erected a powerful HyperWave beacon on the surface of the Burvixese moon. +The Kohr-Ah changed course, attacked the poor Burvixese and sadly, destroyed them all. + +#(OK_BUY_ALIEN_RACE_7) melnorme-105.ogg +The Thraddash are an arrogant, stubborn, and thick-skinned species +who reside in the Draconis and Apodis star systems. +They have little or no respect for anything but force, which they admire greatly. +To make the Thraddash your friends, you should consider killing most, but not all of them. +In addition, they guard some kind of sacred relic at the star system Zeta Draconis +though we do not know the true nature of this artifact. +The Thraddash homeworld is at Delta Draconis. + +#(OK_BUY_ALIEN_RACE_8) melnorme-106.ogg +After the war, the Chenjesu and the Mmrnmhrm chose to be slave-shielded +on the Chenjesu's homeworld at Procyon. +We suspect that they are melding their two species to form some kind of new, hybrid race +a race which may well be powerful enough to destroy the Ur-Quan single-handedly. +However, by our calculations, this process will take many decades, if not centuries. +Should you wish to talk to them, we recommend you invest in a +HyperWave broadcasting system which is powerful enough to penetrate the shield around their world. + +#(OK_BUY_ALIEN_RACE_9) melnorme-107.ogg +The Mycon are using this time while the Ur-Quan have their attention elsewhere +to expand their sphere of influence as fast as possible. +The Mycon colonize planets by launching tough spore-pods from orbit +and injecting them under the planet's surface. +Months later, after the spores have grown hundreds of thick, fibrous tendrils under the planet's crust +the tendrils suddenly thrust up out of the planet and create huge calderas +not incidentally filling the planet's atmosphere with the Mycon's preferred gases +clouds of super-heated steam and sulphuric acid. + +#(OK_BUY_ALIEN_RACE_10) melnorme-108.ogg +Following the end of the War, the Androsynth began experimenting with Inter-Dimensional Fatigue +a process which is related to your faster-than-light drive +but involves dimensions far more alien than HyperSpace. +They had just made a major breakthrough when they were suddenly wiped out by a race called the Orz +who appeared seemingly out of nowhere. +Actually, we don't know what the Orz did to the Androsynth -- they're just all gone. + +#(OK_BUY_ALIEN_RACE_11) melnorme-109.ogg +The Arilou Lalee'lay are a mysterious race of IDF beings +IDF meaning, Inter-Dimensional Fatigue. +They do not reside in this galaxy, or in fact, anywhere in this universe. +While it is true that the Arilou are rarely seen far from the Columbae star group +they do make regular, secret visits to your world, and have done so for centuries. +Ever since Earth was slave-shielded, they have focused their attention +on the humans aboard the starbase, many of whom are now members of your crew. +Though the Arilou Lalee'lay always smile and are never overtly hostile +we believe that they have a secret agenda which somehow involves your planet, Earth. +These secret plans may or may not cause grief and woe to you Earthlings. + +#(OK_BUY_ALIEN_RACE_12) melnorme-110.ogg +Just under 20 years ago, the brave and suicidal Shofixti annihilated their species +by exploding a Precursor device -- some kind of bomb -- in the interior of their sun. +The resulting storm of solar flares cooked the life off the Shofixti homeworld +and incinerated over a hundred Ur-Quan Dreadnoughts +which had just entered the system to conquer the Shofixti. +In actuality, there are still at least a dozen Shofixti left alive in the galaxy. +One or two are at Delta Gorno, guarding the dead hulk of their once beautiful world. +Others can be found in VUX space. + +#(OK_BUY_ALIEN_RACE_13) melnorme-111.ogg +The Slylandro are a mostly non-solid, sentient race who live in a gas giant at Beta Corvi. +We recently sold them a self-replicating exploration probe +which has somehow turned hostile and attacks everything it detects. +If such encounters have angered you, Captain, please do NOT address your concerns to us. +We possess a formal Waiver of Damages, authorized by a Slylandro Speaker +and are in no way responsible for the situation. + +#(OK_BUY_ALIEN_RACE_14) melnorme-112.ogg +The cowardly Spathi live at the single planet orbiting Epsilon Gruis. +They do not actually live on their world, rather they reside on its airless moon. +The reason? A xenomorphic species, which craves the sweet-flavored flesh of the Spathi +has been transported to the surface of their planet +and makes every attempt to devour the poor Spathi. +I am certain that the Spathi would be forever in your debt +if you were to eliminate these creatures from their planet. +What? You fear the alien creatures will find you a treat also? +Fear not. Our data reveals the beasts are not interested in your species. +Should you wish to consult with the Spathi Ruling Council +you will need to know the Secret Spathi Cypher -- a password, which is +`Huffi-Muffi-Guffi'. + +#(OK_BUY_ALIEN_RACE_15) melnorme-113.ogg +Like you Earthlings, when the war with the Ur-Quan was lost +the Syreen chose to be slave-shielded. Their new world is at Betelgeuse. +The Syreen's starbase is crewed by the starship commanders and crew +who were decommissioned at the end of the war. +Though the Syreen hate the Ur-Quan with a vengeance, they are unlikely to offer you assistance +unless you reveal to them the truth behind the tragedy of their original homeworld, Syra +which was destroyed by the birth of a Mycon `Deep Child' a century ago. + +#(OK_BUY_ALIEN_RACE_16) melnorme-114.ogg +When the Ur-Quan entered Gamma Serpentis -- the home star of the Yehat +their Queen made a sudden change of allegiance and allied with the Ur-Quan Hierarchy. +They became Ur-Quan combat thralls. +This act was viewed by most Yehat starship officers as ultimately dishonorable +the desperate act of a corrupt regent to maintain her throne. +The Yehat's shame was greatly magnified by the Shofixti's show of courage +when they destroyed their own star system to slow down the Ur-Quan Armada. +Captain, you have heard all that we have to say about aliens indigenous to this region. +Should we learn more in the near future, we shall be certain to sell it to you. + +#(OK_BUY_HISTORY_1) melnorme-115.ogg +Almost twenty-five thousand of your years ago, there existed near this region of space +an association of starfaring races called the `Sentient Milieu'. +This group formed over several thousand years to mutually enrich their respective cultures +to provide a safe creche for emerging sentient species +and to afford themselves a degree of protection from external hostilities via military alliance. +Of the seven most active Milieu members, the most famous race -- indeed you know them well, Captain +were the Ur-Quan. + +#(OK_BUY_HISTORY_2) melnorme-116.ogg +The Ur-Quan evolved on a harsh planet orbiting a star outside this region of space. +They were solitary predators, like your praying mantis, Captain, or polar bear +who had a very limited set of social behaviors, most of which dealt with sex. +Since they had to compete for survival against many physically superior species +the Ur-Quan evolved intelligence and tool use, in much the same way as your own species. +The Ur-Quan also learned to master their fierce territoriality to build a cooperative planetary culture. +When the Ur-Quan were discovered by the Taalo, they had just begun exploring their solar system +in crude atomic vehicles. +Although the Ur-Quan attacked what they thought to be an invader, the Taalo were patient. +They explained the purpose of the Sentient Milieu, and offered the Ur-Quan membership. +The Ur-Quan recognized the benefits that such a system provided +and once more conquered the hunting beast within themselves +to become cooperative, productive members of the Milieu. This lasted for several thousands of years. + +#(OK_BUY_HISTORY_3) melnorme-117.ogg +Just over twenty thousand years ago +when your ancestors were learning to chart the course of the moon and stars on animal horns +the Sentient Milieu spanned five hundred light years and included the membership of a hundred worlds. +Like all other star-travellers, they had discovered ruins and relics of a far more ancient culture +which your species calls the `Precursors'. +Explorers from many species spent their lives trying to piece together this ancient mystery +but of all races, the Ur-Quan were the most bold adventurers. +Their scouts, flying single-ships, penetrated far into uncharted space, and landed on a million worlds. +On one such mission, a young Ur-Quan made planetfall on a small, life-bearing alien world +to identify some anomalous energy readings, occasionally a sign of Precursor installations. +Instead the Ur-Quan found a small, hideous creature -- a Dnyarri. +Before the scout was able to defend itself, the Dnyarri creature took control of the Ur-Quan's mind +and commanded the scout to place the Dnyarri aboard the Ur-Quan's ship, along with hundreds of its evil brood. +Then the Ur-Quan returned to the heart of the Milieu, landing on its capital planet. +Within hours, every resident of the planet was a Dnyarri slave. +Within a month, Dnyarri-compelled starships had spread the evil, psychic creatures across the entire Milieu. + +#(OK_BUY_HISTORY_4) melnorme-118.ogg +When the Dnyarri took control over the Milieu, one race fought back -- the Taalo. +These slow, quiet creatures were silicon-based life forms +but bore little resemblance to the modern Chenjesu. +The Taalo were natural immunes to the Dnyarri psychic compulsion; they were unaffected by the creatures' power +and the Dnyarri would not permit anyone to exist outside their control +so they ordered the remaining races of the Milieu to attack and destroy the Taalo home planet. +This planet was one of the few Milieu worlds located in this region of space. +I believe you call their star Delta Vulpeculae. Their home was a moon revolving about the second planet. +I am sad to say that the Taalo were, indeed, eliminated. +However, at the time of their devastation they had completed a device +which they thought would give other races psychic immunity like their own. +What happened to this device, this shield? It's hard to say. +Maybe it was destroyed in the attack on their homeworld, maybe not. + +#(OK_BUY_HISTORY_5) melnorme-119.ogg +In the Dnyarri's new empire, the Ur-Quan were the favored slaves. +This is probably because the Ur-Quan were the most psychically sensitive, the most easily compelled. +As the centuries of Dnyarri dominance passed, what was once the Sentient Milieu +deteriorated and degenerated into a great galactic gulag. +Alien races which did not serve with the efficiency and speed demanded by the Dnyarri +were ruthlessly burned from the faces of their worlds. +The agents of this genocide were inevitably the Dnyarri's favored pet, the Ur-Quan. +After almost twenty-five hundred years of unrelenting Dnyarri control +there were only four living member races of the once-great Sentient Milieu. +By this point, the Dnyarri had used genetic manipulation to split the Ur-Quan into two sub-species: +the Green Ur-Quan -- scientists, technicians, and administrators +who were responsible for maintaining the limited infrastructure of the Dnyarri civilization +and the Black Ur-Quan, who filled the ranks of basic laborer and combat soldier. +Then, a chance discovery by an Ur-Quan named Kzer-Za +led to the violent overthrow of the Dnyarri Slave Empire. + +#(OK_BUY_HISTORY_6) melnorme-120.ogg +The Ur-Quan named Kzer-Za was a Green, a researcher specializing in repairing the mental damage +inflicted by long-term exposure to the Dnyarri's psychic compulsion. +By this point in history, the Dnyarri had grown lax in their dominance +and on occasion accidentally permitted their slaves moments of self-direction. +Kzer-Za was able to use those few scattered minutes to compose a theory. +From its observations, Kzer-Za realized that when a slave died +the Dnyarri `disconnected' from the slave's mind, lest it too be dragged down to death. +Further, the Ur-Quan scientist uncovered the fact that when a slave underwent great pain +the Dnyarri temporarily disconnected -- but that the degree of pain had to be extreme, nearly lethal. +Kzer-Za chose its moment carefully -- it waited until it was near an open transmission unit. +Then, in a short moment of mental freedom, the Ur-Quan injected itself with a dose of acidic poison +sending incredible waves of pain through its long body. +In the few moments before its death, Kzer-Za was able to wrest control of the transmitter +to send word of its discovery across the planet, and into space as well. +Before the Dnyarri knew what was happening +Ur-Quan everywhere were hacking at their own bodies with chunks of glass, burning themselves horribly +doing anything that would give them the few seconds of freedom necessary to find the nearest Dnyarri +and crush the bleating creature. +As they gained longer and longer periods of control, the Ur-Quan developed new tools and weapons +to destroy their evil masters. The most gruesome of these devices was the Excruciator +a mechanism which was inserted directly into the brain, and generated a constant stream of agony. +The Dnyarri could not bring themselves to make the necessary mental connection with these tortured Ur-Quan. +They were slaughtered by the thousands. +The Ur-Quan Slave revolt was won. + +#(OK_BUY_HISTORY_7) melnorme-121.ogg +When the last Ur-Quan was free of psychic compulsion -- when the last free Dnyarri was dead +the combined might of the Ur-Quan star fleets met in orbit above the Dnyarri homeworld. +They had come together to make two important decisions. +First -- how to punish the few frightened Dnyarri left below on the planet's surface. +Second -- how to ensure that never again would the Ur-Quan be made slaves. +The first decision was made swiftly. The Dnyarri would not be allowed to die; +ah, that was too kind a fate. +Instead, the creatures would be genetically modified into sub-sentience +they would become dumb animals. +These low creatures would be further debased by serving the Ur-Quan for all eternity +in the most demeaning way the Ur-Quan could imagine +acting as translators, making physical contact with other species +whom the Ur-Quan now considered grossly inferior to themselves and revolting. +The second decision -- how to ensure their freedom permanently -- caused great turmoil. + +#(OK_BUY_HISTORY_8) melnorme-122.ogg +Following the successful Ur-Quan slave revolt +the Ur-Quan met to decide how to ensure their freedom. +The Green Ur-Quan, who called themselves the Kzer-Za in honor of the Ur-Quan who triggered the revolt +wished to establish the `Path of Now and Forever' +which required that all other sentient species must become slaves of the Ur-Quan +or be forever imprisoned beneath an impenetrable force shield. +Leading the opposition to this plan was Kohr-Ah, a charismatic fleet officer. +Kohr-Ah proposed a simpler alternative, the `Eternal Doctrine.' +Simply put, this scheme called for the systematic eradication of all sentient life in the universe +aside from the Ur-Quan. +Captain, if these positions seem to you extreme or unwarranted +you must remember that the Ur-Quan had been unwilling slaves for millenia +and that each of them had to remain in agony for years in order to defeat the Dnyarri. +The followers of Kzer-Za and Kohr-Ah were all on the brink of madness +but neither side would submit, and so they fought a bloody civil war. + +#(OK_BUY_HISTORY_9) melnorme-123.ogg +This is the last historical item we have for sale. +The civil war between the Green Ur-Quan, the followers of Kzer-Za +and their opponents, the death-dealing Kohr-Ah, lasted for decades. +It is likely that they would have annihilated each other +were it not for a chance discovery by a Kzer-Za -- a Precursor Battleship! +The vessel was huge, many times the size of the Ur-Quan's vessels. +The Precursor ship sliced through the Kohr-Ah forces in days -- the Kohr-Ah were defeated. +However, in their victory the Kzer-Za were humble +they realized that there was a chance that they were wrong, and the Kohr-Ah were right. +Instead of destroying the Kohr-Ah, the Kzer-Za let them go +directing them to make their way through the stars, travelling against the spin of the galaxy. +The Kzer-Za would travel in the opposite direction +and when the two Ur-Quan forces met, they would fight again in ritual combat +with the Precursor Battleship given to the winner. +Captain, this is happening here and now. +The Kzer-Za, the Ur-Quan who enslaved Earth, are fighting their ritual battle against the Kohr-Ah +in a large area centered near the Crateris constellation. +If the Kohr-Ah win this battle, Captain, the Kzer-Za will stand aside and let them kill us all. +We believe it is your destiny to prevent this from happening. + +#(INFO_ALL_GONE) melnorme-124.ogg +We regret to say that you have exhausted our supply of genuinely valuable information. +However we DO have many thousands of useless facts and that we will gladly sell you +at a substantial discount. Are you interested? +Hmm, we thought not. + +#(buy_new_tech) +I would like to buy the technology you described. + +#(no_buy_new_tech) +I do not want to purchase any more technology. + +#(done_buying_new_tech) +I do not want to purchase any more technology. + +#(fill_me_up) +Fill all my fuel tanks to maximum capacity. + +#(OK_FILL_YOU_UP) melnorme-125.ogg +Yes sir, fill 'er up, right away! + +#(BUY_NEW_TECH_INTRO) melnorme-126.ogg +Investment! Ah yes, you are so right. +These technological breakthroughs don't cost you Credit +they EARN you Credit! +Of course... there is an initial charge +but each technological system item is GUARANTEED +to be useful for something important +somewhere in the galaxy +at some point in the future. +All technologies cost 150 Credits. + +#(OK_BUY_NEW_TECH) melnorme-127.ogg +Right now we are offering + +#(OK_NO_BUY_NEW_TECH) melnorme-128.ogg +What else would you like to buy? + +#(OK_DONE_BUYING_NEW_TECH) melnorme-129.ogg +Would you like to purchase anything else? + +#(OK_DONE_BUYING_FUEL) melnorme-130.ogg +Would you like to purchase anything else? + +#(NEW_TECH_1) melnorme-131.ogg +The technology we are now offering includes plans for building +blaster weapons twice as powerful as your ion-bolt guns. + +#(NEW_TECH_2) melnorme-132.ogg +The technology we are now offering includes specifications for constructing +modifications to your planet landers which will double their speed. + +#(NEW_TECH_3) melnorme-133.ogg +The technology we are now offering includes details on how to add +'point-defense' laser defense systems for your flagship. + +#(NEW_TECH_4) melnorme-134.ogg +The technology we are now offering includes plans for building +improvements to your planet landers which make them resistant to hostile alien lifeforms. + +#(NEW_TECH_5) melnorme-135.ogg +The technology we are now offering includes blueprints +which show how to increase your lander's cargo space +to double its present volume. + +#(NEW_TECH_6) melnorme-136.ogg +The technology we are now offering includes blueprints which show how to add +double-capacity fuel tanks. + +#(NEW_TECH_7) melnorme-137.ogg +The technology we are now offering includes plans for improving the rate of fire +on your lander's stunray bolt-beamer gun. + +#(NEW_TECH_8) melnorme-138.ogg +The technology we are now offering includes details for building +modifications to your planet landers which make them resistant to earthquakes. + +#(NEW_TECH_9) melnorme-139.ogg +The technology we are now offering includes plans for adding +auto-tracking modules which improve the aim of all your weapons. + +#(NEW_TECH_10) melnorme-140.ogg +The technology we are now offering includes plans for adding +improvements to your planet landers which make them resistant to inclement planet weather. + +#(NEW_TECH_11) melnorme-141.ogg +The technology we are now offering is everything you need to know to assemble +modifications to your planet landers which make them resistant to planetary hot-spots. + +#(NEW_TECH_12) melnorme-142.ogg +The technology we are now offering is plans for building +'Hellbore Cannons', a weapon much more destructive than a simple blaster. + +#(NEW_TECH_13) melnorme-143.ogg +The technology we are now offering includes details on how to develop +Shiva Furnace modules which generate energy for your combat batteries +twice as fast as your standard dynamos. + +#(OK_BUY_NEW_TECH_1) melnorme-144.ogg +Please remember that these weapons consume energy from your combat batteries +faster than your familiar ion-bolt guns. +You may wish to compensate for this by building additional dynamo modules for your flagship. + +#(OK_BUY_NEW_TECH_2) melnorme-145.ogg +Ah yes, speed! An excellent choice for the relentless hunter +and craven coward as well. +These modifications are simple enough to be put in place immediately. +Your landers should be properly equipped in no time. + +#(OK_BUY_NEW_TECH_3) melnorme-146.ogg +These little babies are great for defense, but because of their limited range +they may not make a good offensive weapon. +However, the more you build for your vessel the more damage each laser strike will do. + +#(OK_BUY_NEW_TECH_4) melnorme-147.ogg +Our reinforcement procedures on your landers are complete. +Now, provided your crew will stop putting their hands out the windows +they will be much better protected against hostile lifeforms. + +#(OK_BUY_NEW_TECH_5) melnorme-148.ogg +I hope this makes your resource gathering more cost-effective, Captain. + +#(OK_BUY_NEW_TECH_6) melnorme-149.ogg +We hope that these improved tanks will make more module slots available on your flagship +which you can fill with other, more useful equipment. + +#(OK_BUY_NEW_TECH_7) melnorme-150.ogg +After some wild game, hmmm? Well, the changes we made should really make a difference! +Unless of course that wiring went in backwards +in which case you won't be able to shoot at all, or take off for that matter. +Don't worry, Captain. We stand behind our work. If something goes wrong +just bring it back to us, and we'll fix it pronto! + +#(OK_BUY_NEW_TECH_8) melnorme-151.ogg +With the addition of these safety belts and heavy-duty shock absorbers +your lander occupants should be much safer when an untimely earthquake strikes. +The job is complete. Your landers are ready. + +#(OK_BUY_NEW_TECH_9) melnorme-152.ogg +You are preparing for a mighty battle, eh? +Well, let me give you some advice. +You should consider using multiple Tracking modules, since this will greatly improve your aim +however, never add more than three to your ship. Any more would be useless. + +#(OK_BUY_NEW_TECH_10) melnorme-153.ogg +A little superconductive spray-paint and Presto! +Your lander can sustain a direct hit by a lightning bolt +without crisping the passengers inside... usually. +Since the job is so easy that a nymph could do it +I expect all your landers will be treated in less than an hour. + +#(OK_BUY_NEW_TECH_11) melnorme-154.ogg +With these new ablative-plasma heat shields, your crew will be substantially safer on hot worlds +but like all our lander modifications, this protection is not perfect, so remain cautious. +Since the changes to your landers are straightforward +your landers should be fitted with the heat shields by the time you return to your ship. + +#(OK_BUY_NEW_TECH_12) melnorme-155.ogg +Captain, just a suggestion! +Hellbore Cannon are energy gulpers, so unless you want to have a long delay between shots +I would suggest you add Dynamos or even Shiva Furnaces to your ship. + +#(OK_BUY_NEW_TECH_13) melnorme-156.ogg +I am certain you will appreciate this new module, Captain! +With it you should be able to destroy and devastate twice as fast as before. + +#(CHARITY) melnorme-157.ogg +Since you have no useful, easily removeable equipment on your vessel +we have decided to provide you with fuel at no cost. +Please do not make the mistake of thinking of this as a `gift' or act of altruism +we are merely investing in our relationship with you, the customer. +We are certain that in the long run, this will prove to be a most profitable investment. + +#(NEW_TECH_ALL_GONE) melnorme-158.ogg +Commander, that is the limit of the new technology we can offer you. +If I may say so, you have been an excellent customer. +Thank you! + +#(we_are_from_alliance0) +We come in peace, representing + +#(STRIP_HEAD) melnorme-159.ogg +We will take + +#(LANDERS) melnorme-160.ogg + of your Planet Landers + +#(THRUSTERS) melnorme-161.ogg + of your Fusion Thrusters + +#(JETS) melnorme-162.ogg + of your Turning Jets + +#(PODS) melnorme-163.ogg + of your empty Crew Pods + +#(BAYS) melnorme-164.ogg + of your empty Storage Bays + +#(DYNAMOS) melnorme-165.ogg + of your Dynamo modules + +#(FURNACES) melnorme-166.ogg + of your Shiva Furnaces + +#(GUNS) melnorme-167.ogg + of your Ion-Bolt Guns + +#(BLASTERS) melnorme-168.ogg + of your Blasters + +#(CANNONS) melnorme-169.ogg + of your Hellbore Cannons + +#(TRACKERS) melnorme-170.ogg + of your Auto-Tracking Modules + +#(DEFENSES) melnorme-171.ogg + of your Point-Defense Lasers + +#(name_1) +The New Alliance of Free Stars! + +#(name_2) +The Concordance of Alien Nations! + +#(name_3) +The United Federation of Worlds! + +#(name_40) +The Empire of +#(name_41) +! + +#(ENUMERATE_ONE) melnorme-172.ogg +one + +#(ENUMERATE_TWO) melnorme-173.ogg +two + +#(ENUMERATE_THREE) melnorme-174.ogg +three + +#(ENUMERATE_FOUR) melnorme-175.ogg +four + +#(ENUMERATE_FIVE) melnorme-176.ogg +five + +#(ENUMERATE_SIX) melnorme-177.ogg +six + +#(ENUMERATE_SEVEN) melnorme-178.ogg +seven + +#(ENUMERATE_EIGHT) melnorme-179.ogg +eight + +#(ENUMERATE_NINE) melnorme-180.ogg +nine + +#(ENUMERATE_TEN) melnorme-181.ogg +ten + +#(ENUMERATE_ELEVEN) melnorme-182.ogg +eleven + +#(ENUMERATE_TWELVE) melnorme-183.ogg +twelve + +#(ENUMERATE_THIRTEEN) melnorme-184.ogg +thirteen + +#(ENUMERATE_FOURTEEN) melnorme-185.ogg +fourteen + +#(ENUMERATE_FIFTEEN) melnorme-186.ogg +fifteen + +#(ENUMERATE_SIXTEEN) melnorme-187.ogg +sixteen + +#(END_LIST_WITH_AND) melnorme-188.ogg +and + +#(ENUMERATE_ZERO) +zero + +#(ENUMERATE_SEVENTEEN) melnorme-190.ogg +seventeen + +#(ENUMERATE_EIGHTEEN) melnorme-191.ogg +eighteen + +#(ENUMERATE_NINETEEN) melnorme-192.ogg +nineteen + +#(ENUMERATE_TWENTY) melnorme-193.ogg +twenty + +#(ENUMERATE_THIRTY) melnorme-194.ogg +thirty + +#(ENUMERATE_FOURTY) melnorme-195.ogg +fourty + +#(ENUMERATE_FIFTY) melnorme-196.ogg +fifty + +#(ENUMERATE_SIXTY) melnorme-197.ogg +sixty + +#(ENUMERATE_SEVENTY) melnorme-198.ogg +seventy + +#(ENUMERATE_EIGHTY) melnorme-199.ogg +eighty + +#(ENUMERATE_NINETY) melnorme-200.ogg +ninety + +#(ENUMERATE_HUNDRED) melnorme-201.ogg +hundred + +#(ENUMERATE_THOUSAND) melnorme-202.ogg +thousand diff --git a/sc2/content/addons/3dovoice/starbase/starbase.txt b/sc2/content/addons/3dovoice/starbase/starbase.txt index f3af882af..d89908f26 100644 --- a/sc2/content/addons/3dovoice/starbase/starbase.txt +++ b/sc2/content/addons/3dovoice/starbase/starbase.txt @@ -1324,7 +1324,7 @@ No more history, thank you. The members of the old Alliance. #(what_about_hierarchy) -The battle thralls in the Hierarchy. +The Hierarchy and their battle thralls. #(what_about_other) Were there any alien races who weren't in the War? diff --git a/sc2/content/base/comm/melnorme/melnorme.txt b/sc2/content/base/comm/melnorme/melnorme.txt index 84f3a21b0..87631df5b 100644 --- a/sc2/content/base/comm/melnorme/melnorme.txt +++ b/sc2/content/base/comm/melnorme/melnorme.txt @@ -89,7 +89,7 @@ Shall we begin trading now? #(WERE_NOT_AFRAID) melnorme-010.ogg We reel with inchoate fear, and are thrown into a sudden panic. Being peaceful by nature -We would no doubt be unprepared for your sudden hostility +we would no doubt be unprepared for your sudden hostility were it not for the excellent weapon system we bought from the Keel-Verezy just last month. A weapon system which is fully locked on your command bridge, by the way. @@ -105,6 +105,22 @@ Yes, let us get down to business. #(HELLO_AND_DOWN_TO_BUSINESS_2) melnorme-013.ogg How nice to see you again, Captain. +Before we go on, I have a small announcement. +As you may know, in our travels throughout the galaxy +we Melnorme have found many strange and interesting alien artifacts. +One of these devices is the MetaChron, a kind of trans-time alarm system. +In a nutshell, it warns me of future dangers by predicting its own demise +which is most likely linked to my own well being, since I keep it under my pillow. +The unit is a small pyramid and, when all is well, white in color. +But if we are proceeding along a timeline which will eventually result in the destruction of the MetaChron +the unit slowly darkens. Presumably, it will be destroyed at the same time as it turns completely black. +When we first entered this region of space, the MetaChron was white. +Now it is light gray. +At its present rate of change, something will destroy the MetaChron +in the early part of the year 2159. +In order to avoid this unpleasantness, we may be leaving just before this time +so if you have business you wish to conduct with us +I suggest you do so before January 2159, or February at the latest. #(HELLO_AND_DOWN_TO_BUSINESS_3) melnorme-014.ogg I had itchy pods this morning, Captain, and here you are! @@ -305,7 +321,7 @@ I don't need your help at this time. Maybe later, though. #(RESCUE_OFFER) melnorme-045.ogg You have no Credit balance in our mercantile computer -and our scanners show you that you possess no useful trade goods +and our scanners show that you possess no useful trade goods but, perhaps we can work out a special deal. In exchange for our giving you enough fuel to @@ -844,7 +860,7 @@ Actually, we don't know what the Orz did to the Androsynth -- they're just all g #(OK_BUY_ALIEN_RACE_11) melnorme-109.ogg The Arilou Lalee'lay are a mysterious race of IDF beings -IDF meaning, Inter-Dimensional Fatigue +IDF meaning, Inter-Dimensional Fatigue. They do not reside in this galaxy, or in fact, anywhere in this universe. While it is true that the Arilou are rarely seen far from the Columbae star group they do make regular, secret visits to your world, and have done so for centuries. @@ -952,8 +968,8 @@ Within a month, Dnyarri-compelled starships had spread the evil, psychic creatur When the Dnyarri took control over the Milieu, one race fought back -- the Taalo. These slow, quiet creatures were silicon-based life forms but bore little resemblance to the modern Chenjesu. -The Taalo were natural immunes to the Dynarri psychic compulsion; they were unaffected by the creatures' power -and the Dynarri would not permit anyone to exist outside their control +The Taalo were natural immunes to the Dnyarri psychic compulsion; they were unaffected by the creatures' power +and the Dnyarri would not permit anyone to exist outside their control so they ordered the remaining races of the Milieu to attack and destroy the Taalo home planet. This planet was one of the few Milieu worlds located in this region of space. I believe you call their star Delta Vulpeculae. Their home was a moon revolving about the second planet. @@ -970,7 +986,7 @@ As the centuries of Dnyarri dominance passed, what was once the Sentient Milieu deteriorated and degenerated into a great galactic gulag. Alien races which did not serve with the efficiency and speed demanded by the Dnyarri were ruthlessly burned from the faces of their worlds. -The agents of this genocide were inevitably the Dynarri's favored pet, the Ur-Quan. +The agents of this genocide were inevitably the Dnyarri's favored pet, the Ur-Quan. After almost twenty-five hundred years of unrelenting Dnyarri control there were only four living member races of the once-great Sentient Milieu. By this point, the Dnyarri had used genetic manipulation to split the Ur-Quan into two sub-species: @@ -987,7 +1003,7 @@ By this point in history, the Dnyarri had grown lax in their dominance and on occasion accidentally permitted their slaves moments of self-direction. Kzer-Za was able to use those few scattered minutes to compose a theory. From its observations, Kzer-Za realized that when a slave died -the Dynarri `disconnected' from the slave's mind, lest it too be dragged down to death. +the Dnyarri `disconnected' from the slave's mind, lest it too be dragged down to death. Further, the Ur-Quan scientist uncovered the fact that when a slave underwent great pain the Dnyarri temporarily disconnected -- but that the degree of pain had to be extreme, nearly lethal. Kzer-Za chose its moment carefully -- it waited until it was near an open transmission unit. diff --git a/sc2/content/base/comm/pkunk/pkunk.txt b/sc2/content/base/comm/pkunk/pkunk.txt index 1c17f2573..e33e55c0e 100644 --- a/sc2/content/base/comm/pkunk/pkunk.txt +++ b/sc2/content/base/comm/pkunk/pkunk.txt @@ -551,8 +551,7 @@ a material quaintness, if you will. We will be somewhat disappointed to have to leave it. #(how_goes_war) -I seem to be having a little trouble defeating the Ur-Quan Hierarchy. -Do you have any helpful advice for me? +I seem to be having a little trouble defeating the Ur-Quan Hierarchy. Do you have any helpful advice for me? #(WAR_GOES_1) pkunk-071.ogg Well, not advice exactly, but I can offer you plenty of moral support. diff --git a/sc2/content/base/comm/shofixti/shofixti.txt b/sc2/content/base/comm/shofixti/shofixti.txt index 026f71d2f..3bfab496c 100644 --- a/sc2/content/base/comm/shofixti/shofixti.txt +++ b/sc2/content/base/comm/shofixti/shofixti.txt @@ -215,11 +215,11 @@ No, wait, Shofixti! I have an important duty for you to perform. What might that be? #(need_you_for_duty) -Shofixti, I am now your new commander. I order you not to kill yourself. You are to remain here and guard your solar system. +Shofixti, I am now your new commander. I order you not to kill yourself. Instead, join our fleet. Fight with us! #(OK_WILL_BE_SENTRY) shofixti-033.ogg -To fight again? Against the Ur-Quan? -Yes. But no +To fight again? Against the UR-QUAN!? +YES!!... But no. I cannot leave my homeworld unguarded. I will remain here and keep a solitary vigil. Goodbye. diff --git a/sc2/content/base/comm/starbase/starbase.txt b/sc2/content/base/comm/starbase/starbase.txt index 7081b25e6..76840df2c 100644 --- a/sc2/content/base/comm/starbase/starbase.txt +++ b/sc2/content/base/comm/starbase/starbase.txt @@ -1324,7 +1324,7 @@ No more history, thank you. The members of the old Alliance. #(what_about_hierarchy) -The battle thralls in the Hierarchy. +The Hierarchy and their battle thralls. #(what_about_other) Were there any alien races who weren't in the War? diff --git a/sc2/content/base/cutscene/credits/credits.txt b/sc2/content/base/cutscene/credits/credits.txt index 2395a57ed..dfbeac652 100644 --- a/sc2/content/base/cutscene/credits/credits.txt +++ b/sc2/content/base/cutscene/credits/credits.txt @@ -61,13 +61,18 @@ MUSIC REMIXERS #(Music remixers) 13 C Jouni Airaksinen +András Barják +Matt Bentley Tore Aune Fjellstad Espen Gätzschmann Aaron J. Grier +A. Keren +Casey Monroe Dan Nicholson George Nowik Riku Nuottajärvi Erol Otus +Greg Szymanski #(Other contrib caption) 13 C diff --git a/sc2/content/base/gamestrings.txt b/sc2/content/base/gamestrings.txt index 3ed6e6766..adc10e55a 100644 --- a/sc2/content/base/gamestrings.txt +++ b/sc2/content/base/gamestrings.txt @@ -1,4 +1,4 @@ -#(Vega) +#(Vega) -- STAR_STRING_BASE Vega @@ -530,7 +530,7 @@ Lentilis UNKNOWN -#(devices) +#(devices) -- DEVICE_STRING_BASE devices @@ -646,7 +646,7 @@ Glowing Rod Moon Base -#(cargo) +#(cargo) -- CARGO_STRING_BASE cargo @@ -686,7 +686,7 @@ Radioactive Exotic -#(Hydrogen) +#(Hydrogen) -- ELEMENTS_STRING_BASE Hydrogen @@ -1218,7 +1218,7 @@ Calcium Compounds Nitric Acid -#(MINERAL SCAN) +#(MINERAL SCAN) -- SCAN_STRING_BASE MINERAL SCAN @@ -1442,7 +1442,7 @@ World Gas Giant -#(Alpha) +#(Alpha) -- STAR_NUMBER_BASE Alpha @@ -1498,7 +1498,7 @@ Nu Xi -#(Mercury) +#(Mercury) -- PLANET_NUMBER_BASE Mercury @@ -1625,10 +1625,12 @@ Planet XV #(Planet XVI) Planet XVI + #(Sa-Matra) Sa-Matra -#(JAN) + +#(JAN) -- MONTHS_STRING_BASE JAN @@ -1676,7 +1678,7 @@ NOV DEC -#((In response to your statement)) +#((In response to your statement)) -- FEEDBACK_STRING_BASE (In response to your statement) @@ -1684,7 +1686,7 @@ DEC MORE -#(Starbase) +#(Starbase) -- STARBASE_STRING_BASE Starbase @@ -1704,7 +1706,7 @@ Shipyard Depart StarBase -#(ENCOUNTER IN) +#(ENCOUNTER IN) -- ENCOUNTER_STRING_BASE ENCOUNTER IN @@ -1736,7 +1738,7 @@ Debris Scavenged -#(HyperSpace) +#(HyperSpace) -- NAVIGATION_STRING_BASE HyperSpace @@ -1760,7 +1762,7 @@ Fuel: Fuel Use: -#(Enter name) +#(Enter name) -- NAMING_STRING_BASE Enter name @@ -1776,7 +1778,7 @@ Vindicator Zelnick -#(Empty) +#(Empty) -- MELEE_STRING_BASE Empty @@ -1812,7 +1814,7 @@ Behemoth Zenith The Peeled Eyes -#(Saving . . .) +#(Saving . . .) -- SAVEGAME_STRING_BASE Saving . . . @@ -1832,7 +1834,7 @@ Empty Slot Saved Game - Date: -#(Sound) +#(Sound) -- OPTION_STRING_BASE Sound @@ -1852,7 +1854,7 @@ OFF ON -#(Really Quit) +#(Really Quit) -- QUITMENU_STRING_BASE Really Quit? @@ -1864,7 +1866,7 @@ Yes No -#(Cr) +#(Cr) -- STATUS_STRING_BASE Cr @@ -1888,7 +1890,7 @@ CREW CAPTAIN -#(nose:) +#(nose:) -- FLAGSHIP_STRING_BASE nose: @@ -1940,7 +1942,7 @@ n/a none -#(Orbit: ) +#(Orbit: ) -- ORBITSCAN_STRING_BASE Orbit: @@ -2016,7 +2018,7 @@ Day: Tilt: -#(scan) +#(scan) -- MAINMENU_STRING_BASE scan @@ -2237,7 +2239,7 @@ Use the keyboard or joystick instead. Please press ENTER or SPACE to return. -#(Unconnected. Press LEFT to connect.) +#(Unconnected. Press LEFT to connect.) -- NETMELEE_STRING_BASE Unconnected. Press LEFT to connect. diff --git a/sc2/content/base/ui/setupmenu.txt b/sc2/content/base/ui/setupmenu.txt index fb469baf6..bf18cd198 100644 --- a/sc2/content/base/ui/setupmenu.txt +++ b/sc2/content/base/ui/setupmenu.txt @@ -30,10 +30,12 @@ Positional Audio Sound Driver Sound Quality Slave Shields -Player One -Player Two +Bottom Player +Top Player Control Set UQM Remixes +Speech +Aspect Ratio #(CAT_0_OPTS) 320x240 @@ -314,28 +316,28 @@ Placeholder Placeholder #(CAT_18_OPT_0_DESC) -Player 1 controls the bottom player in -Super Melee, and the entire Full Game. +Controls the bottom player in Super +Melee, and the entire Full Game. #(CAT_18_OPT_1_DESC) -Player 1 controls the bottom player in -Super Melee, and the entire Full Game. +Controls the bottom player in Super +Melee, and the entire Full Game. #(CAT_18_OPT_2_DESC) -Player 1 controls the bottom player in -Super Melee, and the entire Full Game. +Controls the bottom player in Super +Melee, and the entire Full Game. #(CAT_18_OPT_3_DESC) -Player 1 controls the bottom player in -Super Melee, and the entire Full Game. +Controls the bottom player in Super +Melee, and the entire Full Game. #(CAT_18_OPT_4_DESC) -Player 1 controls the bottom player in -Super Melee, and the entire Full Game. +Controls the bottom player in Super +Melee, and the entire Full Game. #(CAT_18_OPT_5_DESC) -Player 1 controls the bottom player in -Super Melee, and the entire Full Game. +Controls the bottom player in Super +Melee, and the entire Full Game. #(CAT_19_OPTS) Placeholder @@ -346,27 +348,27 @@ Placeholder Placeholder #(CAT_19_OPT_0_DESC) -Player 2 controls the top player +Controls the top player in Super Melee. #(CAT_19_OPT_1_DESC) -Player 2 controls the top player +Controls the top player in Super Melee. #(CAT_19_OPT_2_DESC) -Player 2 controls the top player +Controls the top player in Super Melee. #(CAT_19_OPT_3_DESC) -Player 2 controls the top player +Controls the top player in Super Melee. #(CAT_19_OPT_4_DESC) -Player 2 controls the top player +Controls the top player in Super Melee. #(CAT_19_OPT_5_DESC) -Player 2 controls the top player +Controls the top player in Super Melee. #(CAT_20_OPTS) @@ -420,10 +422,39 @@ Overrides PC or 3do soundtrack with the modern soundtrack written by The Precursors. Requires a restart of UQM to take effect. +#(CAT_22_OPTS) +Disabled +Enabled + +#(CAT_22_OPT_0_DESC) +Do not load the 3DO Speech Pack. +Uses script closer to PC version. +Requires a restart of UQM to take effect. + +#(CAT_22_OPT_1_DESC) +Use 3DO speech. The script is closer to 3DO +version where there are differences. +Requires a restart of UQM to take effect. + +#(CAT_23_OPTS) +Any +Force 4:3 + +#(CAT_23_OPT_0_DESC) +Allow any aspect ratio. The game may be +stretched in windows that are not 4:3. +Currently only meaningful in OpenGL mode. + +#(CAT_23_OPT_1_DESC) +Display the game with 4:3 aspect even when +the window is not. +Currently only meaningful in OpenGL mode. + #(SLIDERS) Music Volume SFX Volume Speech Volume +Gamma Correction #(SLIDER_0_DESC) Sets the music volume. @@ -434,6 +465,10 @@ Sets the sound effects volume. #(SLIDER_2_DESC) Sets the speech volume. +#(SLIDER_3_DESC) +Sets the gamma correction. +May not work on all hardware. + #(BUTTONS) Quit Setup Menu Return to Main Menu diff --git a/sc2/content/menu.key b/sc2/content/menu.key index 98126cafd..bdff422b4 100644 --- a/sc2/content/menu.key +++ b/sc2/content/menu.key @@ -48,6 +48,7 @@ delete.2 = STRING:key Keypad-. backspace.1 = STRING:key Backspace editcancel.1 = STRING:key Escape search.1 = STRING:key / +search.2 = STRING:key F6 next.1 = STRING:key Tab pause.1 = STRING:key Pause pause.2 = STRING:key F1 diff --git a/sc2/doc/devel/checklist b/sc2/doc/devel/checklist index cc6235da3..23eed02c1 100644 --- a/sc2/doc/devel/checklist +++ b/sc2/doc/devel/checklist @@ -42,6 +42,7 @@ Announcing the release: - send a mail to sc2-announce - set the forum 'news' - set the #sc2 irc channel topic +- update the version number in http://uqm.stack.nl/wiki/Template:Uqmversion Moving on to the next version: diff --git a/sc2/doc/devel/generate b/sc2/doc/devel/generate index 1adf15263..a7108bb39 100644 --- a/sc2/doc/devel/generate +++ b/sc2/doc/devel/generate @@ -142,7 +142,7 @@ so that it will be shown appropriately in melee if combat follows. There is no generate function for the names of moons. The few moons that are named (those in the Sol system), are handled as a special case of the routines that prints these names (PrintCoarseScan3DO and -PrintCoraseScanPC). +PrintCoarseScanPC). INIT_NPCS REINIT_NPCS diff --git a/sc2/doc/devel/graphicslock b/sc2/doc/devel/graphicslock deleted file mode 100644 index fbd0573ee..000000000 --- a/sc2/doc/devel/graphicslock +++ /dev/null @@ -1,104 +0,0 @@ -HOW TO NOT GET HOSED BY DOUBLE-LOCK/UNLOCKS WITH GraphicsLock - -For the kinds of modifications you're likely to be doing, there only a -few functions that you must take care to ensure that you hold -GraphicsLock before calling. There are also some general guidelines. - -GENERAL GUIDELINES - -- Don't hold the GraphicsLock in Generate* functions. - -- Always hold it while doing ship operations - they're all only called - by RedrawQueue. (preprocess, postprocess, etc.) - -- On ConcludeTask, you must not be holding *anything* or you could - cause a deadlock if the thread you're waiting to conclude needs - whatever lock you hold before it can safely exit. It is - acceptable to hold the GraphicsLock when merely calling - Task_SetState. - -Specific Guidelines: - -Always hold the GraphicsLock when calling... - -- SetFlashRect in sis.c; this changes which part of the screen is - flashing. Very common. - -- RedrawQueue in process.c; this is for updating all the the graphics - for ship animations. - -- GetMeleeStarShip in pickmele.c. That this is extern at all is - probably a sign of lousy code organization. - -- DoMenuOptions in hyper.c; this is a consequence of being called from - a ship operation when in hyperspace, which means that it must assume - that it's called with the GraphicsLock held. - -- DoDiscoveryReport in planets/report.c; this is called by the - Generate* functions, which always start out not holding the Lock. - -- ClearSISRect and DeltaSISGauges in sis.c; you might call these if - working on code that modifies fuel or crew somehow. - -THE GORY DETAILS - -[functionname] means that the function is static and demands lockedness. - means that the function is static and demands unlockedness. -*functionname* means that the function is extern and demands lockedness -(functionname) means that the function is extern and demands unlockedness. - -This information is incomplete, and the result of a fairly informal -hand-analysis of the code. In the case of extern-requires-lock, -context and calling sites have been tracked so that all such functions -are reached. - -battle.c: (Battle) -border.c: (DrawSISFrame) -build.c: (ActivateStarShip) -clock.c: (clock_task_func) -comm.c: (ambient_anim_task) [SpewPhrases] (AlienTalkSegue) - [HailAlien] (InitCommunication) -confirm.c: (DoConfirmExit) -credits.c: (Credits) (OutTakes) -encount.c: (InitEncounter) [DrawFadeText] - (UninitEncounter) (EncounterBattle) -fmv.c: (Introduction) -gameopt.c: - [ShowSummary] - -hyper.c: *LoadHyperspace* *FreeHyperspace* *DoMenuOptions* -init.c: *InitShips* *UninitShips* -melee.c: [DrawPickFrame] (flash_selection_func) - - -menu.c: (DrawMenuStateStrings) -outfit.c: (ChangeFuelQuantity) (DoOutfit) -pickmele.c: *GetMeleeStarShip* -pickship.c: [GetArmadaStarShip] -process.c: *RedrawQueue* -restart.c: (StartGame) -save.c: (SaveProblem) -ship.c: *ship_preprocess* -shipyard.c: (hangar_anim_func) - [CrewTransaction] - (DoShipyard) -sis.c: *ClearSISRect* *DeltaSISGauges* (flash_rect_func) - *SetFlashRect* -starbase.c: (rotate_starbase) (DoStarBase) -starcon.c: (arilou_gate_task) (Starcon2Main) -utils.c: (PauseGame) -cargo.c: (DrawCargoStrings) (Cargo) -devices.c: (Devices) -lander.c: [AnimateLaunch] - (PlanetSide) (InitLander) -planets.c: (LoadPlanet) (FreePlanet) -plangen.c: (rotate_planet_task) -pstarmap.c: (flash_cursor_func) (DrawStarMap) [EraseCursor] - [DoStarMap] (DoFlagshipCommands) -report.c: [MakeReport] *DoDiscoveryReport* -roster.c: (flash_ship_task) -scan.c: - (flash_planet_loc_func) - (ScanSystem) -solarsys.c: (IPtask_func) - (ChangeSolarSys) diff --git a/sc2/doc/devel/netplay/todo b/sc2/doc/devel/netplay/todo index 844128b61..33102c7ae 100644 --- a/sc2/doc/devel/netplay/todo +++ b/sc2/doc/devel/netplay/todo @@ -14,6 +14,9 @@ Medium-priority: - Closing and destroying of NetConnections is a terrible mess. - Checks allConnected() shouldn't be needed if CHECK_ABORT is set on disconnect. +- Shorten or lengthen the time between frames depending on how full the input + buffer is, to prevent one side constantly stalling when the connection in + one direction is slower than in the other direction. Low-priority: @@ -75,6 +78,7 @@ Future improvements/optimisations: - Per state data (in NetConnection.stateData) is unnecessarilly complicated. Putting all fields directly in NetConnection simplifies things a lot. It's not as generic, but this code won't be used elsewhere anyhow. +- Send captain names to the other side Bugs: diff --git a/sc2/doc/devel/queues b/sc2/doc/devel/queues index 9c5d674aa..274828ed5 100644 --- a/sc2/doc/devel/queues +++ b/sc2/doc/devel/queues @@ -7,7 +7,7 @@ GlobData.Game_state.avail_race_q: except for, technically, SAMATRA_SHIP. URQUAN_PROBE_SHIP is a very incomplete 'race'. Elements are of type FLEET_INFO. - Filled in InitSIS(). + Filled in InitGameStructures(). Partially included in savegames. GlobData.Game_state.built_ship_q: @@ -19,7 +19,7 @@ GlobData.Game_state.built_ship_q: master_q: List of templates for all the ships that are available in SuperMelee. Elements are of type MASTER_SHIP_INFO. - Sorted on the (abbreviated) race name (see doc/racestrings). + Sorted on the (abbreviated) race name (see doc/devel/racestrings). Filled in LoadMasterShipList(). GlobData.Game_state.npc_built_ship_q: diff --git a/sc2/doc/devel/racestrings b/sc2/doc/devel/racestrings index fdbc27573..2993a65a9 100644 --- a/sc2/doc/devel/racestrings +++ b/sc2/doc/devel/racestrings @@ -1,4 +1,5 @@ -This file describes the use for each entry of the content//*.txt files +This file describes the use for each entry of the +content/base/ships//.txt files. Entry #0: diff --git a/sc2/doc/devel/statefiles b/sc2/doc/devel/statefiles new file mode 100644 index 000000000..3007bdf91 --- /dev/null +++ b/sc2/doc/devel/statefiles @@ -0,0 +1,123 @@ + Ur-Quan Masters State Files + --------------------------- + +Statefiles are a legacy component of the UQM runtime and savegame +format. They represent largish (10-64KB) chunks of semi-structured +data that the engine used to keep on disk during gameplay, checking +and updating it as needed. These files were then dumped into and +restored from save files in a compressed form. + +In UQM as it exists now (0.7), these files exist as expandable memory +arrays that are consulted as if they were files. UQM 0.8 will change +the savegame format to remove the compression (64K just isn't much +anymore) and put more structure to the data within. The statefile +abstraction itself is not guaranteed to be retained, and indeed core +team considers it kind of horrible and would like to destroy it. + +There are three state files. + + STARINFO_FILE aka "starinfo.dat" + -------------------------------- + +This is probably the most reasonable of the three. It keeps track of +which star systems you have visited, and which mineral deposits and +interesting life forms and gadgets you have harvested from the worlds +therein. + +The file begins with one DWORD for every star system in the +game. (There are 502 star systems, defined in a gigantic array in +starmap_array in plandata.c). The DWORD is 0 if the star system is +unvisited. It is otherwise an absolute offset within the state file. + +Generally speaking, UQM star systems are procedurally generated with a +PRNG and various properties of the star including its type and +location. Thus, the information in starmap.c is sufficient to provide +an accounting of the number and quality of worlds in any given +system. Each world can have up to 32 each of mineral deposits, energy +signatures, or life forms. Thus, each world, in order, in the system +will be listed at its offset with three DWORDS, representing mineral, +energy, and biological entities respectively. Captured entities have a +1 bit set. + +With a little over 3,800 visitable celestial bodies, this state file +is capped at a little under 50 KB. + + RANDGRPINFO_FILE aka "randgrp.dat" + ---------------------------------- + +This is a "battle group file" - it tracks the information regarding +groups of ships that you can encounter in interplanetary space. This +file gives the location information for all ships in the last solar +system you visited, and it tracks the fleet composition, health, &c +for ships randomly generated due to visiting a solar system in some +species's sphere of influence. Random battle groups are reset after a +week in HyperSpace or upon arrival in some other star system. + +The data structures, and the reader/writer functions for them, are +primarily defined in grpinfo.c. + +The RANDGRPINFO file starts with a GROUP_HEADER struct, specifying +which star this information is for, when the data expires, and then 65 +offsets into the file. This is a *one-indexed array* for +randomly-generated groups. + +This is because the offset for group zero points to an entirely +different data structure: the "Group List". This gives the starmap +depiction and location on the Interplanetary map of every battle group +in the system, whether it is randomly generated or pre-defined. This +comprises two bytes (the ID of the most recently encountered group, +and then the number of groups), followed by a series of 17-byte chunks +representing battle groups. These are a byte indicating the race +identifier of the fleet (battle groups can be mixed-composition, but +only one ship appears on the map at a time; this specifies that) +followed by 16 bytes that represent an IP_GROUP structure. See the +Read/WriteIpGroup functions in gengrp.c for the exact layout in the +virtual file. There's a lot of wasted space there, a legacy of the +time when these files were actually structure dumps on 32-bit machines +with very specific memory layouts. + +The offsets that are not Group Zero have a similar layout, interpreted +differently. Each of these represents a single battle group. It +retains the two-byte prologue, the second of which specifies the +number of 17-byte chunks to follow. The first byte here is the +displayed race identifier, again, and then each 17-byte chunk is that +ship's particular race ID followed by a 16-byte representation of a +SHIP_FRAGMENT. + +There are no requirements about order of layout or total size of this +file; the only requirement is that there is a GROUP_HEADER at offset +zero and that the extents described in the valid offsets do not +overlap. + + DEFGRPINFO_FILE aka "defgrp.dat" + -------------------------------- + +This is a random-access scratch space for battle groups that are +deliberately placed by the plot. There's one GROUP_HEADER in this +file, somewhere, for each star system that has ever had predefined +ships and that the player has visited. There is *no guarantee of any +kind* as to where they are, a priori. + +This information instead lives within the game state array, a +155-byte-long bitfield that is mostly used for storing plot events and +event flags. 32-bit values within this array store the relevant +offsets for their fleets, or a 0 if they have not yet been +encountered. In vanilla UQM, there are 14 of these values, +corresponding to the Ur-Quan Probe, the Zoq-Fot-Pik scout, the +Shofixti Survivor, the Unzervalt Guardian, the Sa-Matra, and the nine +Melnorme traders in TrueSpace. Each of these has a corresponding entry +in the game state array that ends in _OFFS0. (Due to the +implementation of GET_GAME_STATE, these values actually are stored as +four eight-bit values each, but this can be ignored pretty much +everywhere but the definition of the states themselves). + +If one of these offsets is non-zero, then that offset in the +DEFGRPINFO_FILE will have a SHIP_FRAGMENT-based group definition in +the same format as the ones in RANDGRPINFO_FILE. + +The Game State array uses 0 as a special value to mean "this +predefined battle group has not yet been spawned." Because of that, 0 +is not a legal offset to place a GROUP_HEADER. To ensure that no +GROUP_HEADER is placed there, a zero is written to the first byte of +the file. That way, the first defined group (which, for vanilla UQM, +will always be the Ur-Quan Probe) thus begins at offset 1. diff --git a/sc2/doc/devel/threads b/sc2/doc/devel/threads index 65147a3ce..5d1d65b33 100644 --- a/sc2/doc/devel/threads +++ b/sc2/doc/devel/threads @@ -97,10 +97,7 @@ The simplest form of lock. If a thread tries to lock a mutex, it will sleep if the mutex is already locked, and awaken once the mutex becomes available. A Mutex must be unlocked by the same thread that locked it, and a thread must never lock a mutex it has already locked -(without unlocking it first). The most important Mutex in the program -the GraphicsLock. Code in UQM that does things like change the -screen's clipping rectangle always grabs the GraphicsLock first, to -ensure that the screen doesn't go crazy. +(without unlocking it first). API: Mutex CreateMutex (const char *name, DWORD syncClass); diff --git a/sc2/doc/devel/versions b/sc2/doc/devel/versions index bcab2412a..4b3d36a33 100644 --- a/sc2/doc/devel/versions +++ b/sc2/doc/devel/versions @@ -39,4 +39,4 @@ Version 0.6.6: Revision 3143 Version 0.6.7: Revision 3276 Version 0.6.8: Revision 3334 Version 0.6.9: Revision 3537 -Version 0.7.0-rc2: Revision 3622 +Version 0.7.0: Revision 3631 diff --git a/sc2/doc/users/manual.txt b/sc2/doc/users/manual.txt index e60a8ada3..330d78577 100644 --- a/sc2/doc/users/manual.txt +++ b/sc2/doc/users/manual.txt @@ -1,6 +1,6 @@ THE UR-QUAN MASTERS v0.7 -- homepage: http://sc2.sf.net/ -Welcome to the sixth release of the Ur-Quan Masters port. This +Welcome to this beta release of the Ur-Quan Masters port. This document will tell you everything you need to play, even if you've never played the original. @@ -791,7 +791,7 @@ inside the directory content/addons/ will be included in the game. '--addon' may be specified more than once to enable multiple add-ons. -Formerly standard packages, 3domusic and 3dovoice are now standard add-ons, +Unlike previous releases, 3domusic and 3dovoice are now standard add-ons, and can be turned on and off from the in-game setup menu. The Precursors UQM Remix project is intended to be used as an add-on. If you install UQM 0.7 from the Windows installer, the remix packs diff --git a/sc2/src/Makeinfo b/sc2/src/Makeinfo index f1ea1d56e..80a2dd23a 100644 --- a/sc2/src/Makeinfo +++ b/sc2/src/Makeinfo @@ -1,4 +1,6 @@ uqm_SUBDIRS="libs res uqm" +uqm_CFILES="options.c port.c uqm.c" +uqm_HFILES="config.h endian_uqm.h options.h port.h types.h uqmversion.h" if [ "$uqm_HAVE_GETOPT_LONG" = 0 ]; then uqm_SUBDIRS="$uqm_SUBDIRS getopt" @@ -8,11 +10,12 @@ case "$HOST_SYSTEM" in Darwin) uqm_SUBDIRS="$uqm_SUBDIRS darwin" ;; + MSVC) + uqm_HFILES="$uqm_HFILES config_vc6.h" + ;; esac if [ "$uqm_HAVE_REGEX" = 0 ]; then uqm_SUBDIRS="$uqm_SUBDIRS regex" fi -uqm_CFILES="options.c port.c uqm.c" - diff --git a/sc2/src/darwin/Makeinfo b/sc2/src/darwin/Makeinfo index 836275fdc..6b019b29b 100644 --- a/sc2/src/darwin/Makeinfo +++ b/sc2/src/darwin/Makeinfo @@ -1,2 +1,2 @@ uqm_MFILES="SDLMain.m" - +uqm_HFILES="SDLMain.h" diff --git a/sc2/src/darwin/SDLMain.h b/sc2/src/darwin/SDLMain.h index 206cd7062..c56d90cbe 100644 --- a/sc2/src/darwin/SDLMain.h +++ b/sc2/src/darwin/SDLMain.h @@ -1,19 +1,16 @@ -/* SDLMain.m - main entry point for our Cocoa-ized SDL app - Initial Version: Darrell Walisser - Non-NIB-Code & other changes: Max Horn +/* SDLMain.m - main entry point for our Cocoa-ized SDL app + Initial Version: Darrell Walisser + Non-NIB-Code & other changes: Max Horn - Feel free to customize this file to suit your needs + Feel free to customize this file to suit your needs */ -#import +#ifndef _SDLMain_h_ +#define _SDLMain_h_ -/* An internal Apple class used to setup Apple menus */ -@interface NSAppleMenuController:NSObject {} -- (void)controlMenu:(NSMenu *)aMenu; -@end +#import @interface SDLMain : NSObject @end -@interface SDLApplication : NSApplication -@end +#endif /* _SDLMain_h_ */ diff --git a/sc2/src/darwin/SDLMain.m b/sc2/src/darwin/SDLMain.m index d664b2794..4bb038e3d 100644 --- a/sc2/src/darwin/SDLMain.m +++ b/sc2/src/darwin/SDLMain.m @@ -1,11 +1,8 @@ -/* SDLMain.m - main entry point for our Cocoa-ized SDL app - Initial Version: Darrell Walisser - Non-NIB-Code & other changes: Max Horn +/* SDLMain.m - main entry point for our Cocoa-ized SDL app + Initial Version: Darrell Walisser + Non-NIB-Code & other changes: Max Horn - Feel free to customize this file to suit your needs - - Modified for use with The Ur-Quan Masters by Nicolas Simonds - + Feel free to customize this file to suit your needs */ #import "port.h" @@ -35,254 +32,373 @@ static BOOL gFinderLaunch; (void) sender; /* Get rid of unused variable warning */ } -/* override NSApplication:sendEvent, to keep Cocoa from beeping on - non-command keystrokes */ -- (void)sendEvent:(NSEvent *)anEvent { - if (NSKeyDown == [anEvent type] || NSKeyUp == [anEvent type]) { - if ([anEvent modifierFlags] & NSCommandKeyMask) - [super sendEvent: anEvent]; - } else - [super sendEvent: anEvent]; +/* For some reaon, Apple removed setAppleMenu from the headers in 10.4, + but the method still is there and works. To avoid warnings, we declare + it ourselves here. */ +@interface NSApplication(SDL_Missing_Methods) +- (void)setAppleMenu:(NSMenu *)menu; +@end + +/* Use this flag to determine whether we use SDLMain.nib or not */ +#define SDL_USE_NIB_FILE 0 + +/* Use this flag to determine whether we use CPS (docking) or not */ +#define SDL_USE_CPS 1 +#ifdef SDL_USE_CPS +/* Portions of CPS.h */ +typedef struct CPSProcessSerNum +{ + UInt32 lo; + UInt32 hi; +} CPSProcessSerNum; + +extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn); +extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5); +extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn); + +#endif /* SDL_USE_CPS */ + +static int gArgc; +static char **gArgv; +static BOOL gFinderLaunch; +static BOOL gCalledAppMainline = FALSE; + +static NSString *getApplicationName(void) +{ + const NSDictionary *dict; + NSString *appName = 0; + + /* Determine the application name */ + dict = (const NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle()); + if (dict) + appName = [dict objectForKey: @"CFBundleName"]; + + if (![appName length]) + appName = [[NSProcessInfo processInfo] processName]; + + return appName; +} + +#if SDL_USE_NIB_FILE +/* A helper category for NSString */ +@interface NSString (ReplaceSubString) +- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString; +@end +#endif + +@interface NSApplication (SDLApplication) +@end + +@implementation NSApplication (SDLApplication) +/* Invoked from the Quit menu item */ +- (void)terminate:(id)sender +{ + /* Post a SDL_QUIT event */ + SDL_Event event; + event.type = SDL_QUIT; + SDL_PushEvent(&event); } @end /* The main class of the application, the application's delegate */ @implementation SDLMain -static char * -basename (char *path) -{ - char *base; - - base = strrchr (path, '/'); - if (base == NULL) - return path; - - return (base + 1); -} - /* Set the working directory to the .app's parent directory */ - (void) setupWorkingDirectory:(BOOL)shouldChdir { - char origindir[PATH_MAX]; - char *c; - - if (!shouldChdir) - return; - - strncpy (origindir, gArgv[0], sizeof origindir); - origindir[sizeof origindir - 1] = '\0'; - - c = basename (origindir); - if (c == origindir) - strcpy (origindir, "."); - else - *c = '\0'; - - /* chdir to the binary app's point of origin */ - if (chdir (origindir) != 0) - abort (); - /* then chdir to the .app's parent */ - if ( chdir ("../Resources/") != 0 ) - abort(); + if (shouldChdir) + { + char parentdir[MAXPATHLEN]; + CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle()); + CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url); + if (CFURLGetFileSystemRepresentation(url2, 1, (UInt8 *)parentdir, MAXPATHLEN)) { + chdir(parentdir); /* chdir to the binary app's parent */ + } + CFRelease(url); + CFRelease(url2); + } } -void -setupAppleMenu (void) +#if SDL_USE_NIB_FILE + +/* Fix menu to contain the real app name instead of "SDL App" */ +- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName { - NSMenu *appleMenu; + NSRange aRange; + NSEnumerator *enumerator; + NSMenuItem *menuItem; - NSMenuItem *menuItem; - NSString *title; - NSString *appName; + aRange = [[aMenu title] rangeOfString:@"SDL App"]; + if (aRange.length != 0) + [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]]; - appName = [NSString stringWithUTF8String:basename (gArgv[0])]; - appleMenu = [[NSMenu alloc] initWithTitle:appName]; + enumerator = [[aMenu itemArray] objectEnumerator]; + while ((menuItem = [enumerator nextObject])) + { + aRange = [[menuItem title] rangeOfString:@"SDL App"]; + if (aRange.length != 0) + [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]]; + if ([menuItem hasSubmenu]) + [self fixMenu:[menuItem submenu] withAppName:appName]; + } +} - /* Add menu items */ - title = [@"Hide " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(hide:) - keyEquivalent:@"h"]; +#else - menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" - action:@selector(hideOtherApplications:) - keyEquivalent:@"h"]; - [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)]; +static void setApplicationMenu(void) +{ + /* warning: this code is very odd */ + NSMenu *appleMenu; + NSMenuItem *menuItem; + NSString *title; + NSString *appName; + + appName = getApplicationName(); + appleMenu = [[NSMenu alloc] initWithTitle:@""]; + + /* Add menu items */ + title = [@"About " stringByAppendingString:appName]; + [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""]; - [appleMenu addItemWithTitle:@"Show All" - action:@selector(unhideAllApplications:) - keyEquivalent:@""]; + [appleMenu addItem:[NSMenuItem separatorItem]]; - [appleMenu addItem:[NSMenuItem separatorItem]]; + title = [@"Hide " stringByAppendingString:appName]; + [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"]; - title = [@"Quit " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(terminate:) - keyEquivalent:@"q"]; + menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; + [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)]; - /* Put menu into the menubar */ - menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil - keyEquivalent:@""]; - [menuItem setSubmenu:appleMenu]; - [[NSApp mainMenu] addItem:menuItem]; + [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; - /* Tell the application object that this is now the application menu */ - [NSApp setAppleMenu:appleMenu]; + [appleMenu addItem:[NSMenuItem separatorItem]]; - /* Finally give up our references to the objects */ - [appleMenu release]; - [menuItem release]; + title = [@"Quit " stringByAppendingString:appName]; + [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"]; + + + /* Put menu into the menubar */ + menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; + [menuItem setSubmenu:appleMenu]; + [[NSApp mainMenu] addItem:menuItem]; + + /* Tell the application object that this is now the application menu */ + [NSApp setAppleMenu:appleMenu]; + + /* Finally give up our references to the objects */ + [appleMenu release]; + [menuItem release]; } /* Create a window menu */ -void -setupWindowMenu (void) +static void setupWindowMenu(void) { - NSMenu *windowMenu; - NSMenuItem *windowMenuItem; - NSMenuItem *menuItem; + NSMenu *windowMenu; + NSMenuItem *windowMenuItem; + NSMenuItem *menuItem; - windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; + windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; + + /* "Minimize" item */ + menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"]; + [windowMenu addItem:menuItem]; + [menuItem release]; + + /* Put menu into the menubar */ + windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""]; + [windowMenuItem setSubmenu:windowMenu]; + [[NSApp mainMenu] addItem:windowMenuItem]; + + /* Tell the application object that this is now the window menu */ + [NSApp setWindowsMenu:windowMenu]; - /* "Minimize" item */ - menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" - action:@selector(performMiniaturize:) - keyEquivalent:@"m"]; - [windowMenu addItem:menuItem]; - [menuItem release]; - - /* Put menu into the menubar */ - windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" - action:nil keyEquivalent:@""]; - [windowMenuItem setSubmenu:windowMenu]; - [[NSApp mainMenu] addItem:windowMenuItem]; - - /* Tell the application object that this is now the window menu */ - [NSApp setWindowsMenu:windowMenu]; - - /* Finally give up our references to the objects */ - [windowMenu release]; - [windowMenuItem release]; + /* Finally give up our references to the objects */ + [windowMenu release]; + [windowMenuItem release]; } /* Replacement for NSApplicationMain */ -void -CustomApplicationMain (int argc, char **argv) +static void CustomApplicationMain (int argc, char **argv) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - SDLMain *sdlMain; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + SDLMain *sdlMain; - /* Ensure the application object is initialised */ - [SDLApplication sharedApplication]; + /* Ensure the application object is initialised */ + [NSApplication sharedApplication]; + +#ifdef SDL_USE_CPS + { + CPSProcessSerNum PSN; + /* Tell the dock about us */ + if (!CPSGetCurrentProcess(&PSN)) + if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103)) + if (!CPSSetFrontProcess(&PSN)) + [NSApplication sharedApplication]; + } +#endif /* SDL_USE_CPS */ - /* Set up the menubar */ - [NSApp setMainMenu:[[NSMenu alloc] init]]; - setupAppleMenu (); - setupWindowMenu (); + /* Set up the menubar */ + [NSApp setMainMenu:[[NSMenu alloc] init]]; + setApplicationMenu(); + setupWindowMenu(); - /* Create SDLMain and make it the app delegate */ - sdlMain = [[SDLMain alloc] init]; - [NSApp setDelegate:sdlMain]; - - /* Start the main event loop */ - [NSApp run]; - - [sdlMain release]; - [pool release]; - - (void) argc; /* Get rid of unused variable warning */ - (void) argv; /* Get rid of unused variable warning */ + /* Create SDLMain and make it the app delegate */ + sdlMain = [[SDLMain alloc] init]; + [NSApp setDelegate:sdlMain]; + + /* Start the main event loop */ + [NSApp run]; + + [sdlMain release]; + [pool release]; } +#endif + + +/* + * Catch document open requests...this lets us notice files when the app + * was launched by double-clicking a document, or when a document was + * dragged/dropped on the app's icon. You need to have a + * CFBundleDocumentsType section in your Info.plist to get this message, + * apparently. + * + * Files are added to gArgv, so to the app, they'll look like command line + * arguments. Previously, apps launched from the finder had nothing but + * an argv[0]. + * + * This message may be received multiple times to open several docs on launch. + * + * This message is ignored once the app's mainline has been called. + */ +- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename +{ + const char *temparg; + size_t arglen; + char *arg; + char **newargv; + + if (!gFinderLaunch) /* MacOS is passing command line args. */ + return FALSE; + + if (gCalledAppMainline) /* app has started, ignore this document. */ + return FALSE; + + temparg = [filename UTF8String]; + arglen = SDL_strlen(temparg) + 1; + arg = (char *) SDL_malloc(arglen); + if (arg == NULL) + return FALSE; + + newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2)); + if (newargv == NULL) + { + SDL_free(arg); + return FALSE; + } + gArgv = newargv; + + SDL_strlcpy(arg, temparg, arglen); + gArgv[gArgc++] = arg; + gArgv[gArgc] = NULL; + return TRUE; +} + + /* Called when the internal event loop has just started running */ - (void) applicationDidFinishLaunching: (NSNotification *) note { - int status; + int status; - /* Set the working directory to the .app's parent directory */ - [self setupWorkingDirectory:gFinderLaunch]; + /* Set the working directory to the .app's parent directory */ + [self setupWorkingDirectory:gFinderLaunch]; - /* allow Cocoa to hear keystrokes like Command-Q, etc. */ - setenv ("SDL_ENABLEAPPEVENTS", "1", 1); +#if SDL_USE_NIB_FILE + /* Set the main menu to contain the real app name instead of "SDL App" */ + [self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()]; +#endif - /* Hand off to main application code */ - status = SDL_main (gArgc, gArgv); + /* Hand off to main application code */ + gCalledAppMainline = TRUE; + status = SDL_main (gArgc, gArgv); - /* We're done, thank you for playing */ - exit (status); - - (void) note; /* Get rid of unused variable warning */ + /* We're done, thank you for playing */ + exit(status); } @end + @implementation NSString (ReplaceSubString) -- (NSString *) stringByReplacingRange:(NSRange)aRange with:(NSString *)aString +- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString { - unsigned int bufferSize; - unsigned int selfLen = [self length]; - unsigned int aStringLen = [aString length]; - unichar *buffer; - NSRange localRange; - NSString *result; + unsigned int bufferSize; + unsigned int selfLen = [self length]; + unsigned int aStringLen = [aString length]; + unichar *buffer; + NSRange localRange; + NSString *result; - bufferSize = selfLen + aStringLen - aRange.length; - buffer = NSAllocateMemoryPages (bufferSize * sizeof (unichar)); - - /* Get first part into buffer */ - localRange.location = 0; - localRange.length = aRange.location; - [self getCharacters:buffer range:localRange]; - - /* Get middle part into buffer */ - localRange.location = 0; - localRange.length = aStringLen; - [aString getCharacters:(buffer + aRange.location) range:localRange]; - - /* Get last part into buffer */ - localRange.location = aRange.location + aRange.length; - localRange.length = selfLen - localRange.location; - [self getCharacters:(buffer + aRange.location+aStringLen) - range:localRange]; - - /* Build output string */ - result = [NSString stringWithCharacters:buffer length:bufferSize]; - - NSDeallocateMemoryPages (buffer, bufferSize); - - return result; + bufferSize = selfLen + aStringLen - aRange.length; + buffer = (unichar *)NSAllocateMemoryPages(bufferSize*sizeof(unichar)); + + /* Get first part into buffer */ + localRange.location = 0; + localRange.length = aRange.location; + [self getCharacters:buffer range:localRange]; + + /* Get middle part into buffer */ + localRange.location = 0; + localRange.length = aStringLen; + [aString getCharacters:(buffer+aRange.location) range:localRange]; + + /* Get last part into buffer */ + localRange.location = aRange.location + aRange.length; + localRange.length = selfLen - localRange.location; + [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange]; + + /* Build output string */ + result = [NSString stringWithCharacters:buffer length:bufferSize]; + + NSDeallocateMemoryPages(buffer, bufferSize); + + return result; } @end + + #ifdef main # undef main #endif + /* Main entry point to executable - should *not* be SDL_main! */ -int -main (int argc, char **argv) +int main (int argc, char **argv) { - /* Copy the arguments into a global variable */ - int i; + /* Copy the arguments into a global variable */ + /* This is passed if we are launched by double-clicking */ + if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) { + gArgv = (char **) SDL_malloc(sizeof (char *) * 2); + gArgv[0] = argv[0]; + gArgv[1] = NULL; + gArgc = 1; + gFinderLaunch = YES; + } else { + int i; + gArgc = argc; + gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1)); + for (i = 0; i <= argc; i++) + gArgv[i] = argv[i]; + gFinderLaunch = NO; + } - /* If we are launched by double-clicking, argv[1] is "-psn_ */ - if ( argc >= 2 && strncmp (argv[1], "-psn_", 5) == 0 ) { - gArgc = 1; - gFinderLaunch = YES; - } else { - gArgc = argc; - gFinderLaunch = NO; - } - gArgv = (char **) malloc (sizeof *gArgv * (gArgc + 1)); - if (gArgv == NULL) - abort (); - for (i = 0; i < gArgc; i++) - gArgv[i] = argv[i]; - gArgv[i] = NULL; - - CustomApplicationMain (argc, argv); - free (gArgv); - return 0; +#if SDL_USE_NIB_FILE + NSApplicationMain (argc, argv); +#else + CustomApplicationMain (argc, argv); +#endif + return 0; } #endif diff --git a/sc2/src/endian_uqm.h b/sc2/src/endian_uqm.h index 373849787..057da4cdb 100644 --- a/sc2/src/endian_uqm.h +++ b/sc2/src/endian_uqm.h @@ -61,6 +61,11 @@ #define UQM_Swap32 __arch__swab32 #endif #endif /* linux */ + +#if defined(__cplusplus) +extern "C" { +#endif + /* Use inline functions for compilers that support them, and static functions for those that do not. Because these functions become static for compilers that do not support inline functions, this @@ -124,4 +129,8 @@ static __inline__ uint64 UQM_Swap64(uint64 val) #define UQM_SwapBE64(X) (X) #endif +#if defined(__cplusplus) +} +#endif + #endif /* _ENDIAN_H */ diff --git a/sc2/src/getopt/Makeinfo b/sc2/src/getopt/Makeinfo index 60e91d9f8..281a7f291 100644 --- a/sc2/src/getopt/Makeinfo +++ b/sc2/src/getopt/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="getopt.c getopt1.c" +uqm_HFILES="getopt.h" diff --git a/sc2/src/libs/Makeinfo b/sc2/src/libs/Makeinfo index dadf4841a..dbaa7d455 100644 --- a/sc2/src/libs/Makeinfo +++ b/sc2/src/libs/Makeinfo @@ -12,3 +12,8 @@ fi # uqm_SUBDIRS="$UQM_SUBDIRS debug" #fi +uqm_HFILES="alarm.h async.h callback.h cdplib.h compiler.h declib.h file.h + gfxlib.h heap.h inplib.h list.h log.h mathlib.h md5.h memlib.h + misc.h net.h platform.h reslib.h sndlib.h strlib.h tasklib.h + threadlib.h timelib.h uio.h uioutils.h unicode.h vidlib.h" + diff --git a/sc2/src/libs/alarm.h b/sc2/src/libs/alarm.h index 7cd33d2ca..b4a72cacb 100644 --- a/sc2/src/libs/alarm.h +++ b/sc2/src/libs/alarm.h @@ -1,2 +1,9 @@ +#if defined(__cplusplus) +extern "C" { +#endif + #include "callback/alarm.h" +#if defined(__cplusplus) +} +#endif diff --git a/sc2/src/libs/async.h b/sc2/src/libs/async.h new file mode 100644 index 000000000..25b71af6e --- /dev/null +++ b/sc2/src/libs/async.h @@ -0,0 +1,10 @@ +#if defined(__cplusplus) +extern "C" { +#endif + +#include "callback/async.h" + +#if defined(__cplusplus) +} +#endif + diff --git a/sc2/src/libs/callback.h b/sc2/src/libs/callback.h index d2d959b95..025160a5b 100644 --- a/sc2/src/libs/callback.h +++ b/sc2/src/libs/callback.h @@ -1,2 +1,10 @@ +#if defined(__cplusplus) +extern "C" { +#endif + #include "callback/callback.h" +#if defined(__cplusplus) +} +#endif + diff --git a/sc2/src/libs/callback/Makeinfo b/sc2/src/libs/callback/Makeinfo index a09ceaae6..8842cba48 100644 --- a/sc2/src/libs/callback/Makeinfo +++ b/sc2/src/libs/callback/Makeinfo @@ -1,2 +1,2 @@ -uqm_CFILES="alarm.c callback.c" - +uqm_CFILES="alarm.c async.c callback.c" +uqm_HFILES="alarm.h async.h callback.h" diff --git a/sc2/src/libs/callback/alarm.c b/sc2/src/libs/callback/alarm.c index d92ce23ec..6e31e0a2e 100644 --- a/sc2/src/libs/callback/alarm.c +++ b/sc2/src/libs/callback/alarm.c @@ -18,6 +18,7 @@ #include "alarm.h" +#include SDL_INCLUDE(SDL.h) #include "libs/heap.h" #include @@ -71,19 +72,36 @@ Alarm_uninit(void) { } static inline AlarmTime -AlarmTime_nowMS(void) { +AlarmTime_nowMs(void) { return SDL_GetTicks(); } Alarm * -Alarm_addRelativeMs(Uint32 ms, AlarmCallback callback, +Alarm_addAbsoluteMs(uint32 ms, AlarmCallback callback, AlarmCallbackArg arg) { Alarm *alarm; assert(alarmHeap != NULL); alarm = Alarm_alloc(); - alarm->time = AlarmTime_nowMS() + ms; + alarm->time = ms; + alarm->callback = callback; + alarm->arg = arg; + + Heap_add(alarmHeap, (HeapValue *) alarm); + + return alarm; +} + +Alarm * +Alarm_addRelativeMs(uint32 ms, AlarmCallback callback, + AlarmCallbackArg arg) { + Alarm *alarm; + + assert(alarmHeap != NULL); + + alarm = Alarm_alloc(); + alarm->time = AlarmTime_nowMs() + ms; alarm->callback = callback; alarm->arg = arg; @@ -99,15 +117,40 @@ Alarm_remove(Alarm *alarm) { Alarm_free(alarm); } +// Process at most one alarm, if its time has come. +// It is safe to call this function again from inside a callback function +// that it called. It should not be called from multiple threads at once. +bool +Alarm_processOne(void) +{ + AlarmTime now; + Alarm *alarm; + + assert(alarmHeap != NULL); + if (!Heap_hasMore(alarmHeap)) + return false; + + now = AlarmTime_nowMs(); + alarm = (Alarm *) Heap_first(alarmHeap); + if (now < alarm->time) + return false; + + Heap_pop(alarmHeap); + alarm->callback(alarm->arg); + Alarm_free(alarm); + return true; +} + +#if 0 // It is safe to call this function again from inside a callback function // that it called. It should not be called from multiple threads at once. void -Alarm_process(void) { +Alarm_processAll(void) { AlarmTime now; assert(alarmHeap != NULL); - now = AlarmTime_nowMS(); + now = AlarmTime_nowMs(); while (Heap_hasMore(alarmHeap)) { Alarm *alarm = (Alarm *) Heap_first(alarmHeap); @@ -119,8 +162,9 @@ Alarm_process(void) { Alarm_free(alarm); } } +#endif -Uint32 +uint32 Alarm_timeBeforeNextMs(void) { Alarm *alarm; @@ -131,4 +175,3 @@ Alarm_timeBeforeNextMs(void) { return alarmTimeToMsUint32(alarm->time); } - diff --git a/sc2/src/libs/callback/alarm.h b/sc2/src/libs/callback/alarm.h index efb46b60d..9f612639d 100644 --- a/sc2/src/libs/callback/alarm.h +++ b/sc2/src/libs/callback/alarm.h @@ -22,11 +22,10 @@ #include "port.h" #include "types.h" -#include SDL_INCLUDE(SDL.h) -typedef Uint32 AlarmTime; -static inline Uint32 +typedef uint32 AlarmTime; +static inline uint32 alarmTimeToMsUint32(AlarmTime time) { - return (Uint32) time; + return (uint32) time; } typedef struct Alarm Alarm; @@ -44,11 +43,14 @@ struct Alarm { void Alarm_init(void); void Alarm_uninit(void); -Alarm *Alarm_addRelativeMs(Uint32 ms, AlarmCallback callback, +Alarm *Alarm_addAbsoluteMs(uint32 ms, AlarmCallback callback, + AlarmCallbackArg arg); +Alarm *Alarm_addRelativeMs(uint32 ms, AlarmCallback callback, AlarmCallbackArg arg); void Alarm_remove(Alarm *alarm); -void Alarm_process(void); -Uint32 Alarm_timeBeforeNextMs(void); +bool Alarm_processOne(void); +void Alarm_processAll(void); +uint32 Alarm_timeBeforeNextMs(void); #endif /* LIBS_CALLBACK_ALARM_H_ */ diff --git a/sc2/src/libs/callback/async.c b/sc2/src/libs/callback/async.c new file mode 100644 index 000000000..d901158d3 --- /dev/null +++ b/sc2/src/libs/callback/async.c @@ -0,0 +1,56 @@ +/* + * Copyright 2012 Serge van den Boom + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "async.h" + +#include "libs/alarm.h" +#include "libs/callback.h" + + +// Process all alarms and callbacks. +// First, all scheduled callbacks are called. +// Then each alarm due is called, and after each of these alarms, the +// callbacks scheduled by this alarm are called. +void +Async_process(void) +{ + // Call pending callbacks. + Callback_process(); + + for (;;) { + if (!Alarm_processOne()) + return; + + // Call callbacks scheduled from the last alarm. + Callback_process(); + } +} + +// Returns the next time that some asynchronous callback is +// to be called. Note that all values lower than the current time +// should be considered as 'somewhere in the past'. +uint32 +Async_timeBeforeNextMs(void) { + if (Callback_haveMore()) { + // Any time before the current time is ok, though we reserve 0 so + // that the caller may use it as a special value in its own code. + return 1; + } + return Alarm_timeBeforeNextMs(); +} + diff --git a/sc2/src/libs/callback/async.h b/sc2/src/libs/callback/async.h new file mode 100644 index 000000000..8cfae39df --- /dev/null +++ b/sc2/src/libs/callback/async.h @@ -0,0 +1,28 @@ +/* + * Copyright 2012 Serge van den Boom + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _ASYNC_H +#define _ASYNC_H + +#include "types.h" + +void Async_process(void); +uint32 Async_timeBeforeNextMs(void); + +#endif /* _ASYNC_H */ + diff --git a/sc2/src/libs/callback/callback.c b/sc2/src/libs/callback/callback.c index dfcd5cef0..e8ae8e9f0 100644 --- a/sc2/src/libs/callback/callback.c +++ b/sc2/src/libs/callback/callback.c @@ -23,6 +23,8 @@ #include #include +#include "libs/threadlib.h" + typedef struct CallbackLink CallbackLink; #define CALLBACK_INTERNAL @@ -38,16 +40,16 @@ static CallbackLink *callbacks; static CallbackLink **callbacksEnd; static CallbackLink *const *callbacksProcessEnd; +static Mutex callbackListLock; + static inline void CallbackList_lock(void) { - // TODO - // Necessary for reentrant operation + LockMutex(callbackListLock); } static inline void CallbackList_unlock(void) { - // TODO - // Necessary for reentrant operation + UnlockMutex(callbackListLock); } #if 0 @@ -62,6 +64,14 @@ Callback_init(void) { callbacks = NULL; callbacksEnd = &callbacks; callbacksProcessEnd = &callbacks; + callbackListLock = CreateMutex("Callback List Lock", SYNC_CLASS_TOPLEVEL); +} + +void +Callback_uninit(void) { + // TODO: cleanup the queue? + DestroyMutex (callbackListLock); + callbackListLock = 0; } // Callbacks are guaranteed to be called in the order that they are queued. @@ -170,4 +180,14 @@ Callback_process(void) { } } +bool +Callback_haveMore(void) { + bool result; + + CallbackList_lock(); + result = (callbacks != NULL); + CallbackList_unlock(); + + return result; +} diff --git a/sc2/src/libs/callback/callback.h b/sc2/src/libs/callback/callback.h index f7f0d0b3e..e04ebe82b 100644 --- a/sc2/src/libs/callback/callback.h +++ b/sc2/src/libs/callback/callback.h @@ -33,9 +33,11 @@ typedef void *CallbackArg; typedef void (*CallbackFunction)(CallbackArg arg); void Callback_init(void); +void Callback_uninit(void); CallbackID Callback_add(CallbackFunction callback, CallbackArg arg); bool Callback_remove(CallbackID id); void Callback_process(void); +bool Callback_haveMore(void); #endif /* LIBS_CALLBACK_CALLBACK_H_ */ diff --git a/sc2/src/libs/cdp/Makeinfo b/sc2/src/libs/cdp/Makeinfo index 9ab9039a2..b2a83b5ec 100644 --- a/sc2/src/libs/cdp/Makeinfo +++ b/sc2/src/libs/cdp/Makeinfo @@ -1 +1,3 @@ uqm_CFILES="cdp.c cdpapi.c" +uqm_HFILES="cdp_alli.h cdpapi.h cdp.h cdp_iio.h cdp_imem.h cdpint.h + cdp_isnd.h cdp_ivid.h cdpmod.h windl.h" diff --git a/sc2/src/libs/cdplib.h b/sc2/src/libs/cdplib.h index 524d6e6be..83d6a6955 100644 --- a/sc2/src/libs/cdplib.h +++ b/sc2/src/libs/cdplib.h @@ -19,6 +19,14 @@ #ifndef LIBS_CDPLIB_H_ #define LIBS_CDPLIB_H_ +#if defined(__cplusplus) +extern "C" { +#endif + #include "cdp/cdp.h" +#if defined(__cplusplus) +} +#endif + #endif /* LIBS_CDPLIB_H_ */ diff --git a/sc2/src/libs/compiler.h b/sc2/src/libs/compiler.h index 954a2d997..a53f77914 100644 --- a/sc2/src/libs/compiler.h +++ b/sc2/src/libs/compiler.h @@ -21,6 +21,10 @@ #include "types.h" +#if defined(__cplusplus) +extern "C" { +#endif + typedef uint8 BYTE; typedef uint8 UBYTE; typedef sint8 SBYTE; @@ -85,5 +89,8 @@ typedef DWORD (*PDWORDFUNC) (void); # define _ALIGNED_ON(bytes) #endif -#endif /* LIBS_COMPILER_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* LIBS_COMPILER_H_ */ diff --git a/sc2/src/libs/declib.h b/sc2/src/libs/declib.h index 62fc3ec02..80d767cfd 100644 --- a/sc2/src/libs/declib.h +++ b/sc2/src/libs/declib.h @@ -20,6 +20,11 @@ #define LIBS_DECLIB_H_ #include "libs/compiler.h" + +#if defined(__cplusplus) +extern "C" { +#endif + typedef struct _LZHCODE_DESC* DECODE_REF; enum @@ -45,4 +50,8 @@ extern COUNT cread (void *pStr, COUNT size, COUNT count, extern COUNT cwrite (const void *pStr, COUNT size, COUNT count, DECODE_REF DecodeRef); +#if defined(__cplusplus) +} +#endif + #endif /* LIBS_DECLIB_H_ */ diff --git a/sc2/src/libs/decomp/Makeinfo b/sc2/src/libs/decomp/Makeinfo index 4a61647e3..699a24e13 100644 --- a/sc2/src/libs/decomp/Makeinfo +++ b/sc2/src/libs/decomp/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="lzdecode.c lzencode.c update.c" +uqm_HFILES="lzh.h" diff --git a/sc2/src/libs/file.h b/sc2/src/libs/file.h index 225b0ca9a..df8de5e57 100644 --- a/sc2/src/libs/file.h +++ b/sc2/src/libs/file.h @@ -25,6 +25,10 @@ // for bool #include "types.h" +#if defined(__cplusplus) +extern "C" { +#endif + #if 0 // from temp.h void initTempDir (void); @@ -83,5 +87,9 @@ static inline int isDriveLetter(int c) } #endif /* HAVE_DRIVE_LETTERS */ +#if defined(__cplusplus) +} +#endif + #endif /* LIBS_FILE_H_ */ diff --git a/sc2/src/libs/file/Makeinfo b/sc2/src/libs/file/Makeinfo index 858a90daa..b4ea11daa 100644 --- a/sc2/src/libs/file/Makeinfo +++ b/sc2/src/libs/file/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="dirs.c files.c" +uqm_HFILES="filintrn.h" diff --git a/sc2/src/libs/file/dirs.c b/sc2/src/libs/file/dirs.c index 2663edf70..39a44f5e5 100644 --- a/sc2/src/libs/file/dirs.c +++ b/sc2/src/libs/file/dirs.c @@ -142,7 +142,7 @@ mkdirhier (const char *path) if (*pathstart == '\0') { // path exists completely, nothing more to do - return 0; + goto success; } // walk through the path as long as the components exist @@ -177,7 +177,7 @@ mkdirhier (const char *path) } if (*pathend == '\0') - return 0; + goto success; *ptr = '/'; ptr++; @@ -187,7 +187,7 @@ mkdirhier (const char *path) // pathstart is the next non-slash character if (*pathstart == '\0') - return 0; + goto success; } // create all components left @@ -221,6 +221,9 @@ mkdirhier (const char *path) ptr += pathend - pathstart; *ptr = '\0'; } + +success: + HFree (buf); return 0; err: @@ -641,6 +644,7 @@ expandPath (char *dest, size_t len, const char *src, int what) *destptr = '\0'; } + HFree (buf); return 0; err: @@ -656,7 +660,7 @@ err: // This code is only needed if we have a current working directory // per drive. // letter is 0 based: 0 = A, 1 = B, ... -bool +static bool driveLetterExists(int letter) { unsigned long drives; diff --git a/sc2/src/libs/file/files.c b/sc2/src/libs/file/files.c index 1a45b9482..5ce7dacaa 100644 --- a/sc2/src/libs/file/files.c +++ b/sc2/src/libs/file/files.c @@ -94,7 +94,7 @@ copyFile (uio_DirHandle *srcDir, const char *srcName, buf = HMalloc(BUFSIZE); // This was originally a statically allocated buffer, // but as this function might be run from a thread with - // a small Stack, this is better. + // a small stack, this is better. while (1) { numInBuf = uio_read (src, buf, BUFSIZE); diff --git a/sc2/src/libs/gfxlib.h b/sc2/src/libs/gfxlib.h index c109d66d0..9a16a69e3 100644 --- a/sc2/src/libs/gfxlib.h +++ b/sc2/src/libs/gfxlib.h @@ -32,6 +32,10 @@ struct Color { #include "libs/reslib.h" +#if defined(__cplusplus) +extern "C" { +#endif + typedef struct context_desc CONTEXT_DESC; typedef struct frame_desc FRAME_DESC; typedef struct font_desc FONT_DESC; @@ -227,8 +231,16 @@ typedef struct text COUNT CharCount; } TEXT; +#if defined(__cplusplus) +} +#endif + #include "libs/strlib.h" +#if defined(__cplusplus) +extern "C" { +#endif + typedef STRING_TABLE COLORMAP_REF; typedef STRING COLORMAP; // COLORMAPPTR is really a pointer to colortable entry structure @@ -237,6 +249,7 @@ typedef void *COLORMAPPTR; #include "graphics/prim.h" + typedef BYTE BATCH_FLAGS; // This flag is currently unused but it might make sense to restore it #define BATCH_BUILD_PAGE (BATCH_FLAGS)(1 << 0) @@ -454,4 +467,8 @@ extern COLORMAPPTR GetColorMapAddress (COLORMAP); void SetSystemRect (const RECT *pRect); void ClearSystemRect (void); +#if defined(__cplusplus) +} +#endif + #endif /* LIBS_GFXLIB_H_ */ diff --git a/sc2/src/libs/graphics/Makeinfo b/sc2/src/libs/graphics/Makeinfo index 2417ea1ab..1a9f7ee39 100644 --- a/sc2/src/libs/graphics/Makeinfo +++ b/sc2/src/libs/graphics/Makeinfo @@ -7,3 +7,6 @@ uqm_CFILES="boxint.c clipline.c cmap.c context.c drawable.c filegfx.c font.c frame.c gfx_common.c intersec.c loaddisp.c pixmap.c resgfx.c tfb_draw.c tfb_prim.c widgets.c" +uqm_HFILES="bbox.h cmap.h context.h dcqueue.h drawable.h drawcmd.h font.h + gfx_common.h gfxintrn.h prim.h tfb_draw.h tfb_prim.h widgets.h" + diff --git a/sc2/src/libs/graphics/cmap.c b/sc2/src/libs/graphics/cmap.c index a99809aea..53cd13fbe 100644 --- a/sc2/src/libs/graphics/cmap.c +++ b/sc2/src/libs/graphics/cmap.c @@ -64,6 +64,10 @@ static int mapcount; static Mutex maplock; +static void release_colormap (TFB_ColorMap *map); +static void delete_colormap (TFB_ColorMap *map); + + void InitColorMaps (void) { @@ -84,13 +88,23 @@ InitColorMaps (void) void UninitColorMaps (void) { + int i; TFB_ColorMap *next; + for (i = 0; i < MAX_COLORMAPS; ++i) + { + TFB_ColorMap *map = colormaps[i]; + if (!map) + continue; + release_colormap (map); + colormaps[i] = 0; + } + // free spares - for ( ; poolhead; poolhead = next) + for ( ; poolhead; poolhead = next, --poolcount) { next = poolhead->next; - HFree (poolhead); + delete_colormap (poolhead); } DestroyMutex (fadeLock); @@ -155,6 +169,13 @@ clone_colormap (TFB_ColorMap *from, int index) return map; } +static void +delete_colormap (TFB_ColorMap *map) +{ + FreeNativePalette (map->palette); + HFree (map); +} + static inline void free_colormap (TFB_ColorMap *map) { @@ -172,8 +193,7 @@ free_colormap (TFB_ColorMap *map) } else { // don't need any more spares - FreeNativePalette (map->palette); - HFree (map); + delete_colormap (map); } } @@ -193,7 +213,7 @@ get_colormap (int index) return map; } -static inline void +static void release_colormap (TFB_ColorMap *map) { if (!map) diff --git a/sc2/src/libs/graphics/context.c b/sc2/src/libs/graphics/context.c index 009fe121b..d609deda8 100644 --- a/sc2/src/libs/graphics/context.c +++ b/sc2/src/libs/graphics/context.c @@ -123,6 +123,8 @@ FindContextPtr (CONTEXT context) { BOOLEAN DestroyContext (CONTEXT ContextRef) { + TFB_Image *img; + if (ContextRef == 0) return (FALSE); @@ -139,6 +141,10 @@ DestroyContext (CONTEXT ContextRef) } #endif /* DEBUG */ + img = ContextRef->FontBacking; + if (img) + TFB_DrawImage_Delete (img); + FreeContext (ContextRef); return TRUE; } diff --git a/sc2/src/libs/graphics/dcqueue.c b/sc2/src/libs/graphics/dcqueue.c index 2f33cb35c..70c066274 100644 --- a/sc2/src/libs/graphics/dcqueue.c +++ b/sc2/src/libs/graphics/dcqueue.c @@ -156,8 +156,17 @@ Init_DrawCommandQueue (void) void Uninit_DrawCommandQueue (void) { - DestroyCondVar (RenderingCond); - DestroyRecursiveMutex (DCQ_Mutex); + if (RenderingCond) + { + DestroyCondVar (RenderingCond); + RenderingCond = 0; + } + + if (DCQ_Mutex) + { + DestroyRecursiveMutex (DCQ_Mutex); + DCQ_Mutex = 0; + } } void @@ -216,6 +225,30 @@ TFB_DrawCommandQueue_Clear () UnlockRecursiveMutex (DCQ_Mutex); } +static void +checkExclusiveThread (TFB_DrawCommand* DrawCommand) +{ +#ifdef DEBUG_DCQ_THREADS + static uint32 exclusiveThreadId; + extern uint32 SDL_ThreadID(void); + + // Only one thread is currently allowed to enqueue commands + // This is not a technical limitation but rather a semantical one atm. + if (DrawCommand->Type == TFB_DRAWCOMMANDTYPE_REINITVIDEO) + { // TFB_DRAWCOMMANDTYPE_REINITVIDEO is an exception + // It is queued from the main() thread, which is safe to do + return; + } + + if (!exclusiveThreadId) + exclusiveThreadId = SDL_ThreadID(); + else + assert (SDL_ThreadID() == exclusiveThreadId); +#else + (void) DrawCommand; // suppress unused warning +#endif +} + void TFB_EnqueueDrawCommand (TFB_DrawCommand* DrawCommand) { @@ -224,6 +257,8 @@ TFB_EnqueueDrawCommand (TFB_DrawCommand* DrawCommand) return; } + checkExclusiveThread (DrawCommand); + if (DrawCommand->Type <= TFB_DRAWCOMMANDTYPE_COPYTOIMAGE && _CurFramePtr->Type == SCREEN_DRAWABLE) { @@ -587,3 +622,49 @@ TFB_FlushGraphics (void) RenderedFrames++; BroadcastCondVar (RenderingCond); } + +void +TFB_PurgeDanglingGraphics (void) +{ + Lock_DCQ (-1); + + for (;;) + { + TFB_DrawCommand DC; + + if (!TFB_DrawCommandQueue_Pop (&DC)) + { + // the Queue is now empty. + break; + } + + switch (DC.Type) + { + case TFB_DRAWCOMMANDTYPE_DELETEIMAGE: + { + TFB_Image *DC_image = DC.data.deleteimage.image; + TFB_DrawImage_Delete (DC_image); + break; + } + case TFB_DRAWCOMMANDTYPE_DELETEDATA: + { + void *data = DC.data.deletedata.data; + HFree (data); + break; + } + case TFB_DRAWCOMMANDTYPE_IMAGE: + { + TFB_ColorMap *cmap = DC.data.image.colormap; + if (cmap) + TFB_ReturnColorMap (cmap); + break; + } + case TFB_DRAWCOMMANDTYPE_SENDSIGNAL: + { + ClearSemaphore (DC.data.sendsignal.sem); + break; + } + } + } + Unlock_DCQ (); +} diff --git a/sc2/src/libs/graphics/gfx_common.c b/sc2/src/libs/graphics/gfx_common.c index e357d18c6..405f61447 100644 --- a/sc2/src/libs/graphics/gfx_common.c +++ b/sc2/src/libs/graphics/gfx_common.c @@ -99,7 +99,7 @@ UnbatchGraphics (void) been processed. */ void -FlushGraphics () +FlushGraphics (void) { TFB_DrawScreen_WaitForSignal (); } diff --git a/sc2/src/libs/graphics/gfx_common.h b/sc2/src/libs/graphics/gfx_common.h index 2690e9ae9..c4db5cd48 100644 --- a/sc2/src/libs/graphics/gfx_common.h +++ b/sc2/src/libs/graphics/gfx_common.h @@ -67,7 +67,7 @@ int TFB_InitGraphics (int driver, int flags, int width, int height); int TFB_ReInitGraphics (int driver, int flags, int width, int height); void TFB_UninitGraphics (void); void TFB_ProcessEvents (void); -void TFB_SetGamma (float gamma); +bool TFB_SetGamma (float gamma); void TFB_UploadTransitionScreen (void); int TFB_SupportsHardwareScaling (void); // This function should not be called directly @@ -99,6 +99,7 @@ extern float FrameRate; extern int FrameRateTickBase; void TFB_FlushGraphics (void); // Only call from main thread!! +void TFB_PurgeDanglingGraphics (void); // Only call from main thread as part of shutdown. extern int ScreenWidth; extern int ScreenHeight; diff --git a/sc2/src/libs/graphics/gfxload.c b/sc2/src/libs/graphics/gfxload.c index a18b09697..969a9102d 100644 --- a/sc2/src/libs/graphics/gfxload.c +++ b/sc2/src/libs/graphics/gfxload.c @@ -321,15 +321,7 @@ _ReleaseCelData (void *handle) return (FALSE); cel_ct = DrawablePtr->MaxIndex + 1; - - if (DrawablePtr->Frame) - { - FramePtr = DrawablePtr->Frame; - if (FramePtr->Type == SCREEN_DRAWABLE) - { - FramePtr = NULL; - } - } + FramePtr = DrawablePtr->Frame; HFree (handle); if (FramePtr) diff --git a/sc2/src/libs/graphics/sdl/Makeinfo b/sc2/src/libs/graphics/sdl/Makeinfo index c4ab927df..f940b763e 100644 --- a/sc2/src/libs/graphics/sdl/Makeinfo +++ b/sc2/src/libs/graphics/sdl/Makeinfo @@ -1,6 +1,9 @@ -uqm_CFILES="opengl.c palette.c primitives.c pure.c sdl2_pure.c +uqm_CFILES="opengl.c palette.c primitives.c pure.c sdl2_pure.c sdl_common.c sdl1_common.c sdl2_common.c scalers.c 2xscalers.c 2xscalers_mmx.c 2xscalers_sse.c 2xscalers_3dnow.c nearest2x.c bilinear2x.c biadv2x.c triscan2x.c hq2x.c canvas.c png2sdl.c sdluio.c rotozoom.c" +uqm_HFILES="2xscalers.h 2xscalers_mmx.h opengl.h palette.h png2sdl.h + primitives.h pure.h rotozoom.h scaleint.h scalemmx.h + scalers.h sdl_common.h sdluio.h" diff --git a/sc2/src/libs/graphics/sdl/opengl.c b/sc2/src/libs/graphics/sdl/opengl.c index f1c100aee..3dc4d9e96 100644 --- a/sc2/src/libs/graphics/sdl/opengl.c +++ b/sc2/src/libs/graphics/sdl/opengl.c @@ -74,30 +74,6 @@ static TFB_GRAPHICS_BACKEND opengl_unscaled_backend = { TFB_GL_ColorLayer }; -static SDL_Surface * -Create_Screen (SDL_Surface *template, int w, int h) -{ - SDL_Surface *newsurf = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, - template->format->BitsPerPixel, - template->format->Rmask, template->format->Gmask, - template->format->Bmask, 0); - if (newsurf == 0) { - log_add (log_Error, "Couldn't create screen buffers: %s", - SDL_GetError()); - } - return newsurf; -} - -static int -ReInit_Screen (SDL_Surface **screen, SDL_Surface *template, int w, int h) -{ - if (*screen) - SDL_FreeSurface (*screen); - *screen = Create_Screen (template, w, h); - - return *screen == 0 ? -1 : 0; -} - static int AttemptColorDepth (int flags, int width, int height, int bpp) { diff --git a/sc2/src/libs/graphics/sdl/opengl.h b/sc2/src/libs/graphics/sdl/opengl.h index 917055c45..6550bcaa8 100644 --- a/sc2/src/libs/graphics/sdl/opengl.h +++ b/sc2/src/libs/graphics/sdl/opengl.h @@ -23,6 +23,7 @@ #if SDL_MAJOR_VERSION == 1 int TFB_GL_InitGraphics (int driver, int flags, int width, int height); +void TFB_GL_UninitGraphics (void); int TFB_GL_ConfigureVideo (int driver, int flags, int width, int height, int togglefullscreen); #ifdef HAVE_OPENGL diff --git a/sc2/src/libs/graphics/sdl/pure.c b/sc2/src/libs/graphics/sdl/pure.c index 9a050347a..4e4426acc 100644 --- a/sc2/src/libs/graphics/sdl/pure.c +++ b/sc2/src/libs/graphics/sdl/pure.c @@ -53,30 +53,6 @@ static TFB_GRAPHICS_BACKEND pure_unscaled_backend = { TFB_Pure_ScreenLayer, TFB_Pure_ColorLayer }; -static SDL_Surface * -Create_Screen (SDL_Surface *template, int w, int h) -{ - SDL_Surface *newsurf = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, - template->format->BitsPerPixel, - template->format->Rmask, template->format->Gmask, - template->format->Bmask, 0); - if (newsurf == 0) { - log_add (log_Error, "Couldn't create screen buffers: %s", - SDL_GetError()); - } - return newsurf; -} - -static int -ReInit_Screen (SDL_Surface **screen, SDL_Surface *template, int w, int h) -{ - if (*screen) - SDL_FreeSurface (*screen); - *screen = Create_Screen (template, w, h); - - return *screen == 0 ? -1 : 0; -} - // We cannot rely on SDL_DisplayFormatAlpha() anymore. It can return // formats that we do not expect (SDL v1.2.14 on Mac OSX). Mac likes // ARGB surfaces, but SDL_DisplayFormatAlpha thinks that only RGBA are fast. @@ -293,6 +269,14 @@ TFB_Pure_InitGraphics (int driver, int flags, int width, int height) return 0; } +void +TFB_Pure_UninitGraphics (void) +{ + UnInit_Screen (&scaled_display); + UnInit_Screen (&fade_color_surface); + UnInit_Screen (&fade_temp); +} + static void ScanLines (SDL_Surface *dst, SDL_Rect *r) { diff --git a/sc2/src/libs/graphics/sdl/pure.h b/sc2/src/libs/graphics/sdl/pure.h index 2538c3f0d..8e2632a0a 100644 --- a/sc2/src/libs/graphics/sdl/pure.h +++ b/sc2/src/libs/graphics/sdl/pure.h @@ -22,6 +22,7 @@ #include "libs/graphics/sdl/sdl_common.h" int TFB_Pure_InitGraphics (int driver, int flags, int width, int height); +void TFB_Pure_UninitGraphics (void); int TFB_Pure_ConfigureVideo (int driver, int flags, int width, int height, int togglefullscreen); void Scale_PerfTest (void); diff --git a/sc2/src/libs/graphics/sdl/rotozoom.c b/sc2/src/libs/graphics/sdl/rotozoom.c index 4cc04a2a2..9f2276908 100644 --- a/sc2/src/libs/graphics/sdl/rotozoom.c +++ b/sc2/src/libs/graphics/sdl/rotozoom.c @@ -223,6 +223,7 @@ int zoomSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int smooth) */ +static int zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst) { Uint32 sx, sy, *sax, *say, *csax, *csay, csx, csy; @@ -343,6 +344,7 @@ int zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst) */ +static void transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int smooth) { int x, y, t1, t2, dx, dy, xd, yd, sdx, sdy, ax, ay, ex, ey, sw, sh; @@ -498,6 +500,7 @@ void transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, */ +static void transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos) { int x, y, dx, dy, xd, yd, sdx, sdy, ax, ay, sw, sh; @@ -560,6 +563,7 @@ void transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int /* Local rotozoom-size function with trig result return */ +static void rotozoomSurfaceSizeTrig(int width, int height, double angle, double zoom, int *dstwidth, int *dstheight, double *canglezoom, double *sanglezoom) { @@ -581,8 +585,8 @@ void rotozoomSurfaceSizeTrig(int width, int height, double angle, double zoom, i cy = *canglezoom * y; sx = *sanglezoom * x; sy = *sanglezoom * y; - dstwidthhalf = MAX((int) ceil(fabs(cx) + fabs(sy)), 1); - dstheighthalf = MAX((int) ceil(fabs(sx) + fabs(cy)), 1); + dstwidthhalf = MAX(ceil(fabs(cx) + fabs(sy)), 1); + dstheighthalf = MAX(ceil(fabs(sx) + fabs(cy)), 1); *dstwidth = 2 * dstwidthhalf; *dstheight = 2 * dstheighthalf; } diff --git a/sc2/src/libs/graphics/sdl/scalers.c b/sc2/src/libs/graphics/sdl/scalers.c index 0f3cab387..2acb21ee2 100644 --- a/sc2/src/libs/graphics/sdl/scalers.c +++ b/sc2/src/libs/graphics/sdl/scalers.c @@ -213,8 +213,8 @@ Scale_PrepPlatform (int flags, const SDL_PixelFormat* fmt) // first match wins // add better platform techs to the top #ifdef MMX_ASM - if ( (!force_platform && (SDL_HasSSE () || SDL_HasMMX ())) - || force_platform == SCALEPLAT_SSE) + if ( (!force_platform && (SDL_HasSSE () || SDL_HasMMXExt ())) + || force_platform == PLATFORM_SSE) { log_add (log_Info, "Screen scalers are using SSE/MMX-Ext/MMX code"); Scale_Platform = SCALEPLAT_SSE; @@ -223,7 +223,7 @@ Scale_PrepPlatform (int flags, const SDL_PixelFormat* fmt) } else if ( (!force_platform && SDL_HasAltiVec ()) - || force_platform == SCALEPLAT_ALTIVEC) + || force_platform == PLATFORM_ALTIVEC) { log_add (log_Info, "Screen scalers would use AltiVec code " "if someone actually wrote it"); @@ -231,7 +231,7 @@ Scale_PrepPlatform (int flags, const SDL_PixelFormat* fmt) } else if ( (!force_platform && SDL_Has3DNow ()) - || force_platform == SCALEPLAT_3DNOW) + || force_platform == PLATFORM_3DNOW) { log_add (log_Info, "Screen scalers are using 3DNow/MMX code"); Scale_Platform = SCALEPLAT_3DNOW; @@ -240,7 +240,7 @@ Scale_PrepPlatform (int flags, const SDL_PixelFormat* fmt) } else if ( (!force_platform && SDL_HasMMX ()) - || force_platform == SCALEPLAT_MMX) + || force_platform == PLATFORM_MMX) { log_add (log_Info, "Screen scalers are using MMX code"); Scale_Platform = SCALEPLAT_MMX; diff --git a/sc2/src/libs/graphics/sdl/sdl_common.c b/sc2/src/libs/graphics/sdl/sdl_common.c index 2257d9f72..6dbcb67d6 100644 --- a/sc2/src/libs/graphics/sdl/sdl_common.c +++ b/sc2/src/libs/graphics/sdl/sdl_common.c @@ -50,18 +50,96 @@ TFB_GRAPHICS_BACKEND *graphics_backend = NULL; volatile int QuitPosted = 0; volatile int GameActive = 1; // Track the SDL_ACTIVEEVENT state SDL_APPACTIVE +static void TFB_PreQuit (void); + +void +TFB_PreInit (void) +{ + log_add (log_Info, "Initializing base SDL functionality."); + log_add (log_Info, "Using SDL version %d.%d.%d (compiled with " + "%d.%d.%d)", SDL_Linked_Version ()->major, + SDL_Linked_Version ()->minor, SDL_Linked_Version ()->patch, + SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL); +#if 0 + if (SDL_Linked_Version ()->major != SDL_MAJOR_VERSION || + SDL_Linked_Version ()->minor != SDL_MINOR_VERSION || + SDL_Linked_Version ()->patch != SDL_PATCHLEVEL) { + log_add (log_Warning, "The used SDL library is not the same version " + "as the one used to compile The Ur-Quan Masters with! " + "If you experience any crashes, this would be an excellent " + "suspect."); + } +#endif + + if ((SDL_Init (SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) == -1)) + { + log_add (log_Fatal, "Could not initialize SDL: %s.", SDL_GetError ()); + exit (EXIT_FAILURE); + } + + atexit (TFB_PreQuit); +} + +static void +TFB_PreQuit (void) +{ + SDL_Quit (); +} + +int +TFB_ReInitGraphics (int driver, int flags, int width, int height) +{ + int result; + int togglefullscreen = 0; + char caption[200]; + + if (GfxFlags == (flags ^ TFB_GFXFLAGS_FULLSCREEN) && + driver == GraphicsDriver && + width == ScreenWidthActual && height == ScreenHeightActual) + { + togglefullscreen = 1; + } + + GfxFlags = flags; + + if (driver == TFB_GFXDRIVER_SDL_OPENGL) + { +#ifdef HAVE_OPENGL + result = TFB_GL_ConfigureVideo (driver, flags, width, height, + togglefullscreen); +#else + driver = TFB_GFXDRIVER_SDL_PURE; + log_add (log_Warning, "OpenGL support not compiled in," + " so using pure SDL driver"); + result = TFB_Pure_ConfigureVideo (driver, flags, width, height, + togglefullscreen); +#endif + } + else + { + result = TFB_Pure_ConfigureVideo (driver, flags, width, height, + togglefullscreen); + } + + sprintf (caption, "The Ur-Quan Masters v%d.%d.%d%s", + UQM_MAJOR_VERSION, UQM_MINOR_VERSION, + UQM_PATCH_VERSION, UQM_EXTRA_VERSION); + SDL_WM_SetCaption (caption, NULL); + + if (flags & TFB_GFXFLAGS_FULLSCREEN) + SDL_ShowCursor (SDL_DISABLE); + else + SDL_ShowCursor (SDL_ENABLE); + + return result; +} + int TFB_InitGraphics (int driver, int flags, int width, int height) { - int result, i; + int result; char caption[200]; - /* Null out screen pointers the first time */ - for (i = 0; i < TFB_GFX_NUMSCREENS; i++) - { - SDL_Screens[i] = NULL; - } - GfxFlags = flags; if (driver == TFB_GFXDRIVER_SDL_OPENGL) @@ -95,17 +173,25 @@ TFB_InitGraphics (int driver, int flags, int width, int height) TFB_DrawCanvas_Initialize (); - atexit (TFB_UninitGraphics); - return 0; } void TFB_UninitGraphics (void) { + int i; + Uninit_DrawCommandQueue (); - // TODO: Uninit whatever the drivers have set up for us - SDL_Quit (); + + for (i = 0; i < TFB_GFX_NUMSCREENS; i++) + UnInit_Screen (&SDL_Screens[i]); + + TFB_Pure_UninitGraphics (); +#ifdef HAVE_OPENGL + TFB_GL_UninitGraphics (); +#endif + + UnInit_Screen (&format_conv_surf); } void @@ -113,7 +199,7 @@ TFB_ProcessEvents () { SDL_Event Event; - while (SDL_PollEvent (&Event)) + while (SDL_PollEvent (&Event) > 0) { /* Run through the InputEvent filter. */ ProcessInputEvent (&Event); diff --git a/sc2/src/libs/graphics/sdl/sdl_common.h b/sc2/src/libs/graphics/sdl/sdl_common.h index b914eafbd..63e09d306 100644 --- a/sc2/src/libs/graphics/sdl/sdl_common.h +++ b/sc2/src/libs/graphics/sdl/sdl_common.h @@ -55,4 +55,8 @@ int TFB_SetColorKey (SDL_Surface *surface, Uint32 key, int rleaccel); int TFB_DisableColorKey (SDL_Surface *surface); int TFB_SetColors (SDL_Surface *surface, SDL_Color *colors, int firstcolor, int ncolors); +SDL_Surface* Create_Screen (SDL_Surface *templat, int w, int h); +int ReInit_Screen (SDL_Surface **screen, SDL_Surface *templat, int w, int h); +void UnInit_Screen (SDL_Surface **screen); + #endif diff --git a/sc2/src/libs/graphics/tfb_draw.c b/sc2/src/libs/graphics/tfb_draw.c index fc752ec50..1ac3c341e 100644 --- a/sc2/src/libs/graphics/tfb_draw.c +++ b/sc2/src/libs/graphics/tfb_draw.c @@ -301,6 +301,7 @@ TFB_DrawImage_New (TFB_Canvas canvas) img->last_scale_hs = NullHs; img->last_scale_type = -1; img->last_scale = 0; + img->dirty = FALSE; TFB_DrawCanvas_GetExtent (canvas, &img->extent); if (TFB_DrawCanvas_IsPaletted (canvas)) @@ -414,8 +415,16 @@ TFB_DrawImage_Delete (TFB_Image *image) TFB_DrawCanvas_Delete (image->NormalImg); - if (image->ScaledImg) { + if (image->ScaledImg) + { TFB_DrawCanvas_Delete (image->ScaledImg); + image->ScaledImg = 0; + } + + if (image->FilledImg) + { + TFB_DrawCanvas_Delete (image->FilledImg); + image->FilledImg = 0; } UnlockMutex (image->mutex); diff --git a/sc2/src/libs/graphics/tfb_prim.c b/sc2/src/libs/graphics/tfb_prim.c index d4d4c07c4..f8a2df4d7 100644 --- a/sc2/src/libs/graphics/tfb_prim.c +++ b/sc2/src/libs/graphics/tfb_prim.c @@ -131,7 +131,7 @@ TFB_Prim_Stamp (STAMP *stmp, DrawMode mode, POINT ctxOrigin) if (!SrcFramePtr) { log_add (log_Warning, "TFB_Prim_Stamp: Tried to draw a NULL frame" - " (Stamp address = %p)", stmp); + " (Stamp address = %p)", (void *) stmp); return; } img = SrcFramePtr->image; @@ -180,7 +180,7 @@ TFB_Prim_StampFill (STAMP *stmp, Color color, DrawMode mode, POINT ctxOrigin) if (!SrcFramePtr) { log_add (log_Warning, "TFB_Prim_StampFill: Tried to draw a NULL frame" - " (Stamp address = %p)", stmp); + " (Stamp address = %p)", (void *) stmp); return; } img = SrcFramePtr->image; diff --git a/sc2/src/libs/heap.h b/sc2/src/libs/heap.h index a6cce5838..674649bab 100644 --- a/sc2/src/libs/heap.h +++ b/sc2/src/libs/heap.h @@ -1,2 +1,9 @@ +#if defined(__cplusplus) +extern "C" { +#endif + #include "heap/heap.h" +#if defined(__cplusplus) +} +#endif diff --git a/sc2/src/libs/heap/Makeinfo b/sc2/src/libs/heap/Makeinfo index 8d58a7aa8..1622e1c36 100644 --- a/sc2/src/libs/heap/Makeinfo +++ b/sc2/src/libs/heap/Makeinfo @@ -1,2 +1,2 @@ uqm_CFILES="heap.c" - +uqm_HFILES="heap.h" diff --git a/sc2/src/libs/heap/heap.c b/sc2/src/libs/heap/heap.c index 515fc37a3..1f4c0f71b 100644 --- a/sc2/src/libs/heap/heap.c +++ b/sc2/src/libs/heap/heap.c @@ -49,7 +49,7 @@ Heap_new(HeapValue_Comparator comparator, size_t initialSize, size_t minSize, heap->minSize = minSize; heap->minFillQuotient = minFillQuotient; heap->size = nextPower2(initialSize); - heap->minFill = (size_t) ceil(((double) (heap->size >> 1)) + heap->minFill = ceil(((double) (heap->size >> 1)) * heap->minFillQuotient); heap->entries = malloc(heap->size * sizeof (HeapValue *)); heap->numEntries = 0; diff --git a/sc2/src/libs/inplib.h b/sc2/src/libs/inplib.h index c7fe2e172..2df1f79be 100644 --- a/sc2/src/libs/inplib.h +++ b/sc2/src/libs/inplib.h @@ -24,6 +24,10 @@ #include "libs/uio.h" #include "libs/unicode.h" +#if defined(__cplusplus) +extern "C" { +#endif + extern BOOLEAN AnyButtonPress (BOOLEAN DetectSpecial); @@ -49,9 +53,9 @@ UniChar GetLastCharacter (void); /* Interrogating the current key configuration */ -void InterrogateInputState (int template, int control, int index, char *buffer, int maxlen); -void RemoveInputState (int template, int control, int index); -void RebindInputState (int template, int control, int index); +void InterrogateInputState (int templat, int control, int index, char *buffer, int maxlen); +void RemoveInputState (int templat, int control, int index); +void RebindInputState (int templat, int control, int index); void SaveKeyConfiguration (uio_DirHandle *path, const char *fname); @@ -59,5 +63,8 @@ void SaveKeyConfiguration (uio_DirHandle *path, const char *fname); void BeginInputFrame (void); -#endif /* LIBS_INPLIB_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* LIBS_INPLIB_H */ diff --git a/sc2/src/libs/input/Makeinfo b/sc2/src/libs/input/Makeinfo index a939003a1..b76604fc6 100644 --- a/sc2/src/libs/input/Makeinfo +++ b/sc2/src/libs/input/Makeinfo @@ -3,3 +3,4 @@ if [ "$uqm_GFXMODULE" = "sdl" ]; then fi uqm_CFILES="input_common.c" +uqm_HFILES="inpintrn.h input_common.h" diff --git a/sc2/src/libs/input/sdl/Makeinfo b/sc2/src/libs/input/sdl/Makeinfo index 86cd999e5..427da5380 100644 --- a/sc2/src/libs/input/sdl/Makeinfo +++ b/sc2/src/libs/input/sdl/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="input.c keynames.c vcontrol.c" +uqm_HFILES="input.h keynames.h vcontrol.h" diff --git a/sc2/src/libs/input/sdl/input.c b/sc2/src/libs/input/sdl/input.c index 1cbd6c14f..d2b78014e 100644 --- a/sc2/src/libs/input/sdl/input.c +++ b/sc2/src/libs/input/sdl/input.c @@ -18,8 +18,10 @@ #include #include +#include +#include "input.h" #include "../inpintrn.h" -#include "libs/graphics/sdl/sdl_common.h" +#include "libs/threadlib.h" #include "libs/input/sdl/vcontrol.h" #include "libs/input/sdl/keynames.h" #include "libs/memlib.h" @@ -218,13 +220,12 @@ TFB_SetInputVectors (volatile int menu[], int num_menu_, volatile int flight[], num_flight = num_flight_; } -int -TFB_InitInput (int driver, int flags) +#ifdef HAVE_JOYSTICK + +static void +initJoystick (void) { - int i; int nJoysticks; - (void)driver; - (void)flags; #if SDL_MAJOR_VERSION == 1 SDL_EnableUNICODE(1); @@ -246,6 +247,8 @@ TFB_InitInput (int driver, int flags) nJoysticks = SDL_NumJoysticks (); if (nJoysticks > 0) { + int i; + log_add (log_Info, "The names of the joysticks are:"); for (i = 0; i < nJoysticks; i++) { @@ -258,6 +261,23 @@ TFB_InitInput (int driver, int flags) } SDL_JoystickEventState (SDL_ENABLE); } +} + +#endif /* HAVE_JOYSTICK */ + +int +TFB_InitInput (int driver, int flags) +{ + (void)driver; + (void)flags; + + SDL_EnableUNICODE(1); + (void)SDL_GetKeyState (&num_keys); + kbdstate = (int *)HMalloc (sizeof (int) * (num_keys + 1)); + + +#ifdef HAVE_JOYSTICK + initJoystick (); #endif /* HAVE_JOYSTICK */ in_character_mode = FALSE; @@ -271,7 +291,6 @@ TFB_InitInput (int driver, int flags) VControl_ResetInput (); InputInitialized = TRUE; - atexit (TFB_UninitInput); return 0; } @@ -328,7 +347,7 @@ GetLastCharacter (void) volatile int MouseButtonDown = 0; -void +static void ProcessMouseEvent (const SDL_Event *e) { switch (e->type) @@ -372,10 +391,12 @@ ProcessInputEvent (const SDL_Event *Event) if (Event->type == SDL_KEYDOWN || Event->type == SDL_KEYUP) { // process character input event, if any - SDLKey k = Event->key.keysym.sym; + // keysym.sym is an SDLKey type which is an enum and can be signed + // or unsigned on different platforms; we'll use a guaranteed type + int k = Event->key.keysym.sym; UniChar map_key = Event->key.keysym.unicode; - if (k > num_keys) + if (k < 0 || k > num_keys) k = num_keys; // for unknown keys if (Event->type == SDL_KEYDOWN) @@ -494,11 +515,11 @@ TFB_ResetControls (void) } void -InterrogateInputState (int template, int control, int index, char *buffer, int maxlen) +InterrogateInputState (int templat, int control, int index, char *buffer, int maxlen) { - VCONTROL_GESTURE *g = CONTROL_PTR(template, control, index); + VCONTROL_GESTURE *g = CONTROL_PTR(templat, control, index); - if (template >= num_templ || control >= num_flight + if (templat >= num_templ || control >= num_flight || index >= MAX_FLIGHT_ALTERNATES) { log_add (log_Warning, "InterrogateInputState(): invalid control index"); @@ -531,13 +552,13 @@ InterrogateInputState (int template, int control, int index, char *buffer, int m } void -RemoveInputState (int template, int control, int index) +RemoveInputState (int templat, int control, int index) { - VCONTROL_GESTURE *g = CONTROL_PTR(template, control, index); + VCONTROL_GESTURE *g = CONTROL_PTR(templat, control, index); char keybuf[40]; keybuf[39] = '\0'; - if (template >= num_templ || control >= num_flight + if (templat >= num_templ || control >= num_flight || index >= MAX_FLIGHT_ALTERNATES) { log_add (log_Warning, "RemoveInputState(): invalid control index"); @@ -545,23 +566,23 @@ RemoveInputState (int template, int control, int index) } VControl_RemoveGestureBinding (g, - (int *)(flight_vec + template * num_flight + control)); + (int *)(flight_vec + templat * num_flight + control)); g->type = VCONTROL_NONE; - snprintf (keybuf, 39, "keys.%d.%s.%d", template+1, flight_res_names[control], index+1); + snprintf (keybuf, 39, "keys.%d.%s.%d", templat+1, flight_res_names[control], index+1); res_Remove (keybuf); return; } void -RebindInputState (int template, int control, int index) +RebindInputState (int templat, int control, int index) { VCONTROL_GESTURE g; char keybuf[40], valbuf[40]; keybuf[39] = valbuf[39] = '\0'; - if (template >= num_templ || control >= num_flight + if (templat >= num_templ || control >= num_flight || index >= MAX_FLIGHT_ALTERNATES) { log_add (log_Warning, "RebindInputState(): invalid control index"); @@ -569,7 +590,7 @@ RebindInputState (int template, int control, int index) } /* Remove the old binding on this spot */ - RemoveInputState (template, control, index); + RemoveInputState (templat, control, index); /* Wait for the next interesting bit of user input */ VControl_ClearGesture (); @@ -580,9 +601,9 @@ RebindInputState (int template, int control, int index) /* And now, add the new binding. */ VControl_AddGestureBinding (&g, - (int *)(flight_vec + template * num_flight + control)); - *CONTROL_PTR(template, control, index) = g; - snprintf (keybuf, 39, "keys.%d.%s.%d", template+1, flight_res_names[control], index+1); + (int *)(flight_vec + templat * num_flight + control)); + *CONTROL_PTR(templat, control, index) = g; + snprintf (keybuf, 39, "keys.%d.%s.%d", templat+1, flight_res_names[control], index+1); VControl_DumpGesture (valbuf, 39, &g); res_PutString (keybuf, valbuf); } diff --git a/sc2/src/libs/input/sdl/input.h b/sc2/src/libs/input/sdl/input.h index c2b8a2017..3c599aa93 100644 --- a/sc2/src/libs/input/sdl/input.h +++ b/sc2/src/libs/input/sdl/input.h @@ -19,6 +19,9 @@ #ifndef INPUT_H #define INPUT_H +#include "port.h" +#include SDL_INCLUDE(SDL.h) + extern void ProcessInputEvent (const SDL_Event *Event); #endif diff --git a/sc2/src/libs/input/sdl/keynames.c b/sc2/src/libs/input/sdl/keynames.c index b3d197bef..86c104a2d 100644 --- a/sc2/src/libs/input/sdl/keynames.c +++ b/sc2/src/libs/input/sdl/keynames.c @@ -33,7 +33,7 @@ * tragedy. */ typedef struct vcontrol_keyname { - /* const */ char *name; + const char *name; int code; } keyname; @@ -197,7 +197,7 @@ static keyname keynames[] = { {"Unknown", 0}}; /* Last element must have code zero */ -char * +const char * VControl_code2name (int code) { int i = 0; @@ -213,12 +213,12 @@ VControl_code2name (int code) } int -VControl_name2code (char *name) +VControl_name2code (const char *name) { int i = 0; while (1) { - char *test = keynames[i].name; + const char *test = keynames[i].name; int code = keynames[i].code; if (!strcasecmp(test, name) || !code) { diff --git a/sc2/src/libs/input/sdl/keynames.h b/sc2/src/libs/input/sdl/keynames.h index e9879101e..affd854e3 100644 --- a/sc2/src/libs/input/sdl/keynames.h +++ b/sc2/src/libs/input/sdl/keynames.h @@ -17,6 +17,6 @@ #ifndef LIBS_INPUT_SDL_KEYNAMES_H_ #define LIBS_INPUT_SDL_KEYNAMES_H_ -char *VControl_code2name (int code); -int VControl_name2code (char *code); +const char *VControl_code2name (int code); +int VControl_name2code (const char *code); #endif diff --git a/sc2/src/libs/input/sdl/vcontrol.c b/sc2/src/libs/input/sdl/vcontrol.c index 2d916b272..9c226ae21 100644 --- a/sc2/src/libs/input/sdl/vcontrol.c +++ b/sc2/src/libs/input/sdl/vcontrol.c @@ -195,6 +195,7 @@ static void key_init (void) { unsigned int i; + int num_keys; // Temp to match type of param for SDL_GetKeyState(). pool = allocate_key_chunk (); for (i = 0; i < KEYBOARD_INPUT_BUCKETS; i++) bindings[i] = NULL; @@ -1265,7 +1266,7 @@ VControl_ParseGesture (VCONTROL_GESTURE *g, const char *spec) parse_state ps; strncpy (ps.line, spec, LINE_SIZE); - ps.line[LINE_SIZE] = '\0'; + ps.line[LINE_SIZE - 1] = '\0'; ps.index = ps.error = 0; ps.linenum = -1; diff --git a/sc2/src/libs/list.h b/sc2/src/libs/list.h index a7a507b03..42a28d4a9 100644 --- a/sc2/src/libs/list.h +++ b/sc2/src/libs/list.h @@ -16,5 +16,14 @@ * */ +#if defined(__cplusplus) +extern "C" { +#endif + #include "list/list.h" +#if defined(__cplusplus) +} +#endif + + diff --git a/sc2/src/libs/list/Makeinfo b/sc2/src/libs/list/Makeinfo index e39821732..c2bc72bb4 100644 --- a/sc2/src/libs/list/Makeinfo +++ b/sc2/src/libs/list/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="list.c" +uqm_HFILES="list.h" diff --git a/sc2/src/libs/log.h b/sc2/src/libs/log.h index 79b1fd8d7..11537c734 100644 --- a/sc2/src/libs/log.h +++ b/sc2/src/libs/log.h @@ -14,4 +14,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#if defined(__cplusplus) +extern "C" { +#endif + #include "log/uqmlog.h" + +#if defined(__cplusplus) +} +#endif diff --git a/sc2/src/libs/log/Makeinfo b/sc2/src/libs/log/Makeinfo index f1195db7d..124260fe4 100644 --- a/sc2/src/libs/log/Makeinfo +++ b/sc2/src/libs/log/Makeinfo @@ -1,4 +1,5 @@ uqm_CFILES="uqmlog.c" +uqm_HFILES="loginternal.h msgbox.h uqmlog.h" case "$HOST_SYSTEM" in Darwin) @@ -11,3 +12,4 @@ case "$HOST_SYSTEM" in uqm_CFILES="$uqm_CFILES msgbox_stub.c" ;; esac + diff --git a/sc2/src/libs/log/uqmlog.c b/sc2/src/libs/log/uqmlog.c index 5e9cc3dd5..e054edb40 100644 --- a/sc2/src/libs/log/uqmlog.c +++ b/sc2/src/libs/log/uqmlog.c @@ -159,6 +159,7 @@ log_exit (int code) { qlock = 0; DestroyMutex (qmutex); + qmutex = 0; } return code; diff --git a/sc2/src/libs/math/Makeinfo b/sc2/src/libs/math/Makeinfo index ac0a85a91..da10867d9 100644 --- a/sc2/src/libs/math/Makeinfo +++ b/sc2/src/libs/math/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="random.c random2.c sqrt.c" +uqm_HFILES="mthintrn.h random.h" diff --git a/sc2/src/libs/math/random.h b/sc2/src/libs/math/random.h index f8b0b8c9e..0e8d6020e 100644 --- a/sc2/src/libs/math/random.h +++ b/sc2/src/libs/math/random.h @@ -29,13 +29,6 @@ #ifndef LIBS_MATH_RANDOM_H_ #define LIBS_MATH_RANDOM_H_ -/* ----------------------------DEFINES------------------------------------ */ - -#define RAND(n) ( (int) ( (unsigned int)TFB_Random() % (n) ) ) -#define SRAND(n) ( (int)TFB_Random() % (n) ) -#define AND_RAND(n) ( (int)TFB_Random() & (n) ) - - /* ----------------------------GLOBALS/EXTERNS---------------------------- */ DWORD TFB_SeedRandom (DWORD seed); @@ -55,6 +48,7 @@ void RandomContext_Delete (RandomContext *context); RandomContext *RandomContext_Copy (const RandomContext *source); DWORD RandomContext_Random (RandomContext *context); DWORD RandomContext_SeedRandom (RandomContext *context, DWORD new_seed); +DWORD RandomContext_GetSeed (RandomContext *context); #endif /* LIBS_MATH_RANDOM_H_ */ diff --git a/sc2/src/libs/math/random2.c b/sc2/src/libs/math/random2.c index f6d05db4a..9d354b43f 100644 --- a/sc2/src/libs/math/random2.c +++ b/sc2/src/libs/math/random2.c @@ -82,4 +82,8 @@ RandomContext_SeedRandom (RandomContext *context, DWORD new_seed) return old_seed; } - +DWORD +RandomContext_GetSeed (RandomContext *context) +{ + return context->seed; +} diff --git a/sc2/src/libs/mathlib.h b/sc2/src/libs/mathlib.h index f5654b986..a7b27d1b0 100644 --- a/sc2/src/libs/mathlib.h +++ b/sc2/src/libs/mathlib.h @@ -20,10 +20,17 @@ #define LIBS_MATHLIB_H_ #include "libs/compiler.h" + +#if defined(__cplusplus) +extern "C" { +#endif + #include "math/random.h" extern COUNT square_root (DWORD value); +#if defined(__cplusplus) +} +#endif + #endif /* LIBS_MATHLIB_H_ */ - - diff --git a/sc2/src/libs/md5.h b/sc2/src/libs/md5.h index 1526b9dcd..f7732dc4e 100644 --- a/sc2/src/libs/md5.h +++ b/sc2/src/libs/md5.h @@ -19,7 +19,14 @@ #ifndef LIBS_MD5_H_ #define LIBS_MD5_H_ +#if defined(__cplusplus) +extern "C" { +#endif + #include "md5/md5.h" -#endif /* LIBS_MD5_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* LIBS_MD5_H_ */ diff --git a/sc2/src/libs/md5/Makeinfo b/sc2/src/libs/md5/Makeinfo index 60ef65a20..7ba0a78e0 100644 --- a/sc2/src/libs/md5/Makeinfo +++ b/sc2/src/libs/md5/Makeinfo @@ -1,2 +1,2 @@ uqm_CFILES="md5.c" - +uqm_HFILES="md5.h" diff --git a/sc2/src/libs/memlib.h b/sc2/src/libs/memlib.h index f68fc0895..c4fa385ca 100644 --- a/sc2/src/libs/memlib.h +++ b/sc2/src/libs/memlib.h @@ -19,15 +19,25 @@ #ifndef LIBS_MEMLIB_H_ #define LIBS_MEMLIB_H_ +#include + #include "types.h" +#if defined(__cplusplus) +extern "C" { +#endif + extern bool mem_init (void); extern bool mem_uninit (void); -extern void *HMalloc (int size); +extern void *HMalloc (size_t size); extern void HFree (void *p); -extern void *HCalloc (int size); -extern void *HRealloc (void *p, int size); +extern void *HCalloc (size_t size); +extern void *HRealloc (void *p, size_t size); + +#if defined(__cplusplus) +} +#endif #endif /* LIBS_MEMLIB_H_ */ diff --git a/sc2/src/libs/memory/w_memlib.c b/sc2/src/libs/memory/w_memlib.c index a4c55639c..342e34ef3 100644 --- a/sc2/src/libs/memory/w_memlib.c +++ b/sc2/src/libs/memory/w_memlib.c @@ -38,68 +38,47 @@ mem_uninit (void) } void * -HMalloc (int size) +HMalloc (size_t size) { - void *p; - - if (size == 0) - return NULL; - - if (size < 0) - { - log_add (log_Fatal, "HMalloc() FATAL: " - "request for negative amount of memory %d!", size); - fflush (stderr); - explode (); - } - - p = malloc (size); - if (p == NULL) + void *p = malloc (size); + if (p == NULL && size > 0) { log_add (log_Fatal, "HMalloc() FATAL: out of memory."); fflush (stderr); explode (); } - return (p); + + return p; } void HFree (void *p) { - if (p) - { - free (p); - } + free (p); } void * -HCalloc (int size) +HCalloc (size_t size) { void *p; p = HMalloc (size); memset (p, 0, size); - return (p); + return p; } void * -HRealloc (void *p, int size) +HRealloc (void *p, size_t size) { - if (size < 0) - { - log_add (log_Fatal, "HRealloc() FATAL: " - "request for negative amount of memory %d!", size); - fflush (stderr); - explode (); - } - p = realloc (p, size); - if (!p && size > 0) + if (p == NULL && size > 0) { log_add (log_Fatal, "HRealloc() FATAL: out of memory."); fflush (stderr); explode (); } + return p; } + diff --git a/sc2/src/libs/mikmod/Makeinfo b/sc2/src/libs/mikmod/Makeinfo index 0f286c501..cd037f9fc 100644 --- a/sc2/src/libs/mikmod/Makeinfo +++ b/sc2/src/libs/mikmod/Makeinfo @@ -2,3 +2,4 @@ uqm_CFILES="drv_nos.c load_it.c load_mod.c load_s3m.c load_stm.c load_xm.c mdreg.c mdriver.c mloader.c mlreg.c mlutil.c mmalloc.c mmerror.c mmio.c mplayer.c munitrk.c mwav.c npertab.c sloader.c virtch.c virtch2.c virtch_common.c" +uqm_HFILES="mikmod_build.h mikmod.h mikmod_internals.h" diff --git a/sc2/src/libs/misc.h b/sc2/src/libs/misc.h index a080f064c..39333a220 100644 --- a/sc2/src/libs/misc.h +++ b/sc2/src/libs/misc.h @@ -26,6 +26,10 @@ #include #include "port.h" +#if defined(__cplusplus) +extern "C" { +#endif + extern int TFB_DEBUG_HALT; @@ -47,12 +51,16 @@ static inline void explode (void) static inline void * unconst(const void *arg) { union { - char *c; - const char *cc; + void *c; + const void *cc; } u; u.cc = arg; return u.c; } +#if defined(__cplusplus) +} +#endif + #endif diff --git a/sc2/src/libs/net.h b/sc2/src/libs/net.h index f41c5b93e..ca5931e3b 100644 --- a/sc2/src/libs/net.h +++ b/sc2/src/libs/net.h @@ -19,11 +19,18 @@ #ifndef LIBS_NET_H_ #define LIBS_NET_H_ +#if defined(__cplusplus) +extern "C" { +#endif + #include "network/network.h" #include "network/netmanager/netmanager.h" #include "network/connect/connect.h" #include "network/connect/listen.h" #include "network/connect/resolve.h" -#endif /* LIBS_NET_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* LIBS_NET_H_ */ diff --git a/sc2/src/libs/network/Makeinfo b/sc2/src/libs/network/Makeinfo index 3afab6fa1..40171fa3a 100644 --- a/sc2/src/libs/network/Makeinfo +++ b/sc2/src/libs/network/Makeinfo @@ -1,9 +1,12 @@ uqm_SUBDIRS="connect netmanager socket" uqm_CFILES="netport.c" +uqm_HFILES="bytesex.h netport.h network.h" + if [ -n "$uqm_USE_WINSOCK" ]; then uqm_CFILES="$uqm_CFILES network_win.c" if [ -n "$MACRO___MINGW32__" ]; then uqm_CFILES="$uqm_CFILES wspiapiwrap.c" + uqm_HFILES="$uqm_HFILES wspiapiwrap.h" fi else uqm_CFILES="$uqm_CFILES network_bsd.c" diff --git a/sc2/src/libs/network/connect/Makeinfo b/sc2/src/libs/network/connect/Makeinfo index 863983f58..559527022 100644 --- a/sc2/src/libs/network/connect/Makeinfo +++ b/sc2/src/libs/network/connect/Makeinfo @@ -1,2 +1,2 @@ uqm_CFILES="connect.c listen.c resolve.c" - +uqm_HFILES="connect.h listen.h resolve.h" diff --git a/sc2/src/libs/network/connect/connect.c b/sc2/src/libs/network/connect/connect.c index 3742850e9..4599b187f 100644 --- a/sc2/src/libs/network/connect/connect.c +++ b/sc2/src/libs/network/connect/connect.c @@ -57,7 +57,7 @@ static void doConnectErrorCallback(ConnectState *connectState, static ConnectState * ConnectState_alloc(void) { return (ConnectState *) malloc(sizeof (ConnectState)); -}; +} static void ConnectState_free(ConnectState *connectState) { diff --git a/sc2/src/libs/network/connect/listen.c b/sc2/src/libs/network/connect/listen.c index 0016fad31..4a7a65c30 100644 --- a/sc2/src/libs/network/connect/listen.c +++ b/sc2/src/libs/network/connect/listen.c @@ -56,7 +56,7 @@ static void doListenErrorCallback(ListenState *listenState, static ListenState * ListenState_alloc(void) { return (ListenState *) malloc(sizeof (ListenState)); -}; +} static void ListenState_free(ListenState *listenState) { diff --git a/sc2/src/libs/network/connect/resolve.c b/sc2/src/libs/network/connect/resolve.c index f9a5d4e30..646e43778 100644 --- a/sc2/src/libs/network/connect/resolve.c +++ b/sc2/src/libs/network/connect/resolve.c @@ -33,7 +33,7 @@ static ResolveState * ResolveState_new(void) { return (ResolveState *) malloc(sizeof (ResolveState)); -}; +} static void ResolveState_free(ResolveState *resolveState) { diff --git a/sc2/src/libs/network/netmanager/Makeinfo b/sc2/src/libs/network/netmanager/Makeinfo index 714914d95..ddf28b31d 100644 --- a/sc2/src/libs/network/netmanager/Makeinfo +++ b/sc2/src/libs/network/netmanager/Makeinfo @@ -1,8 +1,11 @@ uqm_CFILES="ndesc.c" +uqm_HFILES="ndesc.h netmanager.h" + if [ -n "$uqm_USE_WINSOCK" ]; then uqm_CFILES="$uqm_CFILES netmanager_win.c" + uqm_HFILES="$uqm_HFILES netmanager_win.h" else uqm_CFILES="$uqm_CFILES netmanager_bsd.c" + uqm_HFILES="$uqm_HFILES netmanager_bsd.h" fi - diff --git a/sc2/src/libs/network/socket/Makeinfo b/sc2/src/libs/network/socket/Makeinfo index 5c605f1f4..19e1637ea 100644 --- a/sc2/src/libs/network/socket/Makeinfo +++ b/sc2/src/libs/network/socket/Makeinfo @@ -1,7 +1,11 @@ uqm_CFILES="socket.c" +uqm_HFILES="socket.h" + if [ -n "$uqm_USE_WINSOCK" ]; then uqm_CFILES="$uqm_CFILES socket_win.c" + uqm_HFILES="$uqm_HFILES socket_win.h" else uqm_CFILES="$uqm_CFILES socket_bsd.c" + uqm_HFILES="$uqm_CFILES socket_bsd.h" fi diff --git a/sc2/src/libs/network/socket/socket.h b/sc2/src/libs/network/socket/socket.h index 45631858f..5c7546706 100644 --- a/sc2/src/libs/network/socket/socket.h +++ b/sc2/src/libs/network/socket/socket.h @@ -80,7 +80,11 @@ int Socket_bind(Socket *sock, const struct sockaddr *addr, int Socket_listen(Socket *sock, int backlog); Socket *Socket_accept(Socket *sock, struct sockaddr *addr, socklen_t *addrLen); ssize_t Socket_send(Socket *sock, const void *buf, size_t len, int flags); +ssize_t Socket_sendto(Socket *sock, const void *buf, size_t len, int flags, + const struct sockaddr *addr, socklen_t addrLen); ssize_t Socket_recv(Socket *sock, void *buf, size_t len, int flags); +ssize_t Socket_recvfrom(Socket *sock, void *buf, size_t len, int flags, + struct sockaddr *from, socklen_t *fromLen); int Socket_setNonBlocking(Socket *sock); int Socket_setReuseAddr(Socket *sock); diff --git a/sc2/src/libs/network/socket/socket_bsd.c b/sc2/src/libs/network/socket/socket_bsd.c index 54d5d58ba..2bf25b83e 100644 --- a/sc2/src/libs/network/socket/socket_bsd.c +++ b/sc2/src/libs/network/socket/socket_bsd.c @@ -129,11 +129,23 @@ Socket_send(Socket *sock, const void *buf, size_t len, int flags) { return send(sock->fd, buf, len, flags); } +ssize_t +Socket_sendto(Socket *sock, const void *buf, size_t len, int flags, + const struct sockaddr *addr, socklen_t addrLen) { + return sendto(sock->fd, buf, len, flags, addr, addrLen); +} + ssize_t Socket_recv(Socket *sock, void *buf, size_t len, int flags) { return recv(sock->fd, buf, len, flags); } +ssize_t +Socket_recvfrom(Socket *sock, void *buf, size_t len, int flags, + struct sockaddr *from, socklen_t *fromLen) { + return recvfrom(sock->fd, buf, len, flags, from, fromLen); +} + int Socket_setNonBlocking(Socket *sock) { int flags; diff --git a/sc2/src/libs/network/socket/socket_win.c b/sc2/src/libs/network/socket/socket_win.c index 7c8ee3b2d..e1ed002f8 100644 --- a/sc2/src/libs/network/socket/socket_win.c +++ b/sc2/src/libs/network/socket/socket_win.c @@ -159,6 +159,20 @@ Socket_send(Socket *sock, const void *buf, size_t len, int flags) { return sendResult; } +ssize_t +Socket_sendto(Socket *sock, const void *buf, size_t len, int flags, + const struct sockaddr *addr, socklen_t addrLen) { + int sendResult; + + sendResult = sendto(sock->sock, buf, len, flags, addr, addrLen); + if (sendResult == SOCKET_ERROR) { + errno = getWinsockErrno(); + return -1; + } + + return sendResult; +} + ssize_t Socket_recv(Socket *sock, void *buf, size_t len, int flags) { int recvResult; @@ -172,6 +186,20 @@ Socket_recv(Socket *sock, void *buf, size_t len, int flags) { return recvResult; } +ssize_t +Socket_recvfrom(Socket *sock, void *buf, size_t len, int flags, + struct sockaddr *from, socklen_t *fromLen) { + int recvResult; + + recvResult = recvfrom(sock->sock, buf, len, flags, from, fromLen); + if (recvResult == SOCKET_ERROR) { + errno = getWinsockErrno(); + return -1; + } + + return recvResult; +} + int Socket_setNonBlocking(Socket *sock) { unsigned long flag = 1; diff --git a/sc2/src/libs/platform.h b/sc2/src/libs/platform.h index 8ab6919cc..f17674d60 100644 --- a/sc2/src/libs/platform.h +++ b/sc2/src/libs/platform.h @@ -17,6 +17,10 @@ #ifndef PLATFORM_H_ #define PLATFORM_H_ +#if defined(__cplusplus) +extern "C" { +#endif + #if defined(USE_PLATFORM_ACCEL) # if defined(__GNUC__) && (defined(i386) || defined(__x86_64__)) # define MMX_ASM @@ -46,4 +50,8 @@ typedef enum extern PLATFORM_TYPE force_platform; +#if defined(__cplusplus) +} +#endif + #endif /* PLATFORM_H_ */ diff --git a/sc2/src/libs/reslib.h b/sc2/src/libs/reslib.h index 616248a9f..0b56262bd 100644 --- a/sc2/src/libs/reslib.h +++ b/sc2/src/libs/reslib.h @@ -25,6 +25,10 @@ #include "libs/memlib.h" #include "libs/uio.h" +#if defined(__cplusplus) +extern "C" { +#endif + typedef struct resource_index_desc RESOURCE_INDEX_DESC; typedef RESOURCE_INDEX_DESC *RESOURCE_INDEX; @@ -33,6 +37,7 @@ typedef const char *RESOURCE; typedef union { DWORD num; void *ptr; + const char *str; } RESOURCE_DATA; #define NULL_RESOURCE NULL @@ -78,8 +83,16 @@ void *GetResourceData (uio_Stream *fp, DWORD length); #define AllocResourceData HMalloc BOOLEAN FreeResourceData (void *); +#if defined(__cplusplus) +} +#endif + #include "libs/strlib.h" #include "libs/gfxlib.h" + +#if defined(__cplusplus) +extern "C" { +#endif // For Color typedef STRING_TABLE DIRENTRY_REF; @@ -120,4 +133,8 @@ void res_PutColor (const char *key, Color value); BOOLEAN res_Remove (const char *key); +#if defined(__cplusplus) +} +#endif + #endif /* LIBS_RESLIB_H_ */ diff --git a/sc2/src/libs/resource/Makeinfo b/sc2/src/libs/resource/Makeinfo index 9359322a6..ddac8e27f 100644 --- a/sc2/src/libs/resource/Makeinfo +++ b/sc2/src/libs/resource/Makeinfo @@ -1,2 +1,3 @@ uqm_CFILES="direct.c filecntl.c getres.c loadres.c stringbank.c propfile.c resinit.c" +uqm_HFILES="index.h propfile.h resintrn.h stringbank.h" diff --git a/sc2/src/libs/resource/index.h b/sc2/src/libs/resource/index.h index 72b6be0b5..bdbb162b4 100644 --- a/sc2/src/libs/resource/index.h +++ b/sc2/src/libs/resource/index.h @@ -19,19 +19,22 @@ #ifndef LIBS_RESOURCE_INDEX_H_ #define LIBS_RESOURCE_INDEX_H_ +typedef struct resource_handlers ResourceHandlers; +typedef struct resource_desc ResourceDesc; + #include #include "libs/reslib.h" #include "libs/uio/charhashtable.h" -typedef struct resource_handlers +struct resource_handlers { const char *resType; ResourceLoadFun *loadFun; ResourceFreeFun *freeFun; ResourceStringFun *toString; -} ResourceHandlers; +}; -typedef struct resource_desc +struct resource_desc { RESOURCE res_id; char *fname; @@ -39,7 +42,7 @@ typedef struct resource_desc RESOURCE_DATA resdata; // refcount is rudimentary as nothing really frees the descriptors unsigned refcount; -} ResourceDesc; +}; struct resource_index_desc { diff --git a/sc2/src/libs/resource/resinit.c b/sc2/src/libs/resource/resinit.c index e53433ba3..40ed19e5b 100644 --- a/sc2/src/libs/resource/resinit.c +++ b/sc2/src/libs/resource/resinit.c @@ -34,7 +34,8 @@ static RESOURCE_INDEX allocResourceIndex (void) { RESOURCE_INDEX ndx = HMalloc (sizeof (RESOURCE_INDEX_DESC)); - ndx->map = CharHashTable_newHashTable (NULL, NULL, NULL, NULL, 0, 0.85, 0.9); + ndx->map = CharHashTable_newHashTable (NULL, NULL, NULL, NULL, NULL, + 0, 0.85, 0.9); return ndx; } @@ -138,7 +139,7 @@ process_resource_desc (const char *key, const char *value) static void UseDescriptorAsRes (const char *descriptor, RESOURCE_DATA *resdata) { - resdata->ptr = (void *)descriptor; + resdata->str = descriptor; } static void @@ -285,7 +286,7 @@ fail: static void RawDescriptor (RESOURCE_DATA *resdata, char *buf, unsigned int size) { - snprintf (buf, size, "%s", (char *)resdata->ptr); + snprintf (buf, size, "%s", resdata->str); } static void @@ -474,12 +475,12 @@ res_GetString (const char *key) { RESOURCE_INDEX idx = _get_current_index_header (); ResourceDesc *desc = lookupResourceDesc (idx, key); - if (!desc || !desc->resdata.ptr || strcmp(desc->vtable->resType, "STRING")) + if (!desc || !desc->resdata.str || strcmp(desc->vtable->resType, "STRING")) return ""; /* TODO: Work out exact STRING semantics, specifically, the lifetime of * the returned value. If caller is allowed to reference the returned * value forever, STRING has to be ref-counted. */ - return (const char *)desc->resdata.ptr; + return desc->resdata.str; } void @@ -488,24 +489,24 @@ res_PutString (const char *key, const char *value) RESOURCE_INDEX idx = _get_current_index_header (); ResourceDesc *desc = lookupResourceDesc (idx, key); int srclen, dstlen; - if (!desc || !desc->resdata.ptr || strcmp(desc->vtable->resType, "STRING")) + if (!desc || !desc->resdata.str || strcmp(desc->vtable->resType, "STRING")) { /* TODO: This is kind of roundabout. We can do better by refactoring newResourceDesc */ process_resource_desc(key, "STRING:undefined"); desc = lookupResourceDesc (idx, key); } srclen = strlen (value); - dstlen = strlen (desc->resdata.ptr); + dstlen = strlen (desc->fname); if (srclen > dstlen) { char *newValue = HMalloc(srclen + 1); char *oldValue = desc->fname; log_add(log_Warning, "Reallocating string space for '%s'", key); strncpy (newValue, value, srclen + 1); - desc->resdata.ptr = newValue; + desc->resdata.str = newValue; desc->fname = newValue; HFree (oldValue); } else { - strncpy (desc->resdata.ptr, value, srclen + 1); + strncpy (desc->fname, value, srclen + 1); } } diff --git a/sc2/src/libs/sndlib.h b/sc2/src/libs/sndlib.h index e64b56103..e90070758 100644 --- a/sc2/src/libs/sndlib.h +++ b/sc2/src/libs/sndlib.h @@ -22,6 +22,10 @@ #include "port.h" #include "libs/strlib.h" +#if defined(__cplusplus) +extern "C" { +#endif + typedef STRING_TABLE SOUND_REF; typedef STRING SOUND; // SOUNDPTR is really a TFB_SoundSample** @@ -95,5 +99,9 @@ extern void WaitForSoundEnd (COUNT Channel); extern DWORD FadeMusic (BYTE end_vol, SIZE TimeInterval); +#if defined(__cplusplus) +} +#endif + #endif /* LIBS_SNDLIB_H_ */ diff --git a/sc2/src/libs/sound/Makeinfo b/sc2/src/libs/sound/Makeinfo index 2a25098fb..28ee5cca5 100644 --- a/sc2/src/libs/sound/Makeinfo +++ b/sc2/src/libs/sound/Makeinfo @@ -6,4 +6,4 @@ else fi uqm_CFILES="audiocore.c fileinst.c resinst.c sound.c sfx.c music.c stream.c trackplayer.c" - +uqm_HFILES="audiocore.h sndintrn.h sound.h stream.h trackint.h trackplayer.h" diff --git a/sc2/src/libs/sound/audiocore.c b/sc2/src/libs/sound/audiocore.c index a271045b9..440f63f2d 100644 --- a/sc2/src/libs/sound/audiocore.c +++ b/sc2/src/libs/sound/audiocore.c @@ -20,6 +20,7 @@ #include #include #include "audiocore.h" +#include "sound.h" #include "libs/log.h" static audio_Driver audiodrv; @@ -76,6 +77,10 @@ initAudio (sint32 driver, sint32 flags) "NOTICE: Try running UQM with '--sound=none' option"); exit (EXIT_FAILURE); } + + SetSFXVolume (sfxVolumeScale); + SetSpeechVolume (speechVolumeScale); + SetMusicVolume (musicVolume); audio_inited = true; diff --git a/sc2/src/libs/sound/decoders/Makeinfo b/sc2/src/libs/sound/decoders/Makeinfo index 9b8f53469..e1735a1de 100644 --- a/sc2/src/libs/sound/decoders/Makeinfo +++ b/sc2/src/libs/sound/decoders/Makeinfo @@ -1,6 +1,8 @@ uqm_CFILES="decoder.c aiffaud.c wav.c dukaud.c modaud.c" +uqm_HFILES="aiffaud.h decoder.h dukaud.h modaud.h wav.h" if [ "$uqm_OGGVORBIS" '!=' "none" ]; then uqm_CFILES="$uqm_CFILES oggaud.c" + uqm_HFILES="$uqm_HFILES oggaud.h" fi diff --git a/sc2/src/libs/sound/decoders/aiffaud.c b/sc2/src/libs/sound/decoders/aiffaud.c index cd6b7364f..102a78e98 100644 --- a/sc2/src/libs/sound/decoders/aiffaud.c +++ b/sc2/src/libs/sound/decoders/aiffaud.c @@ -307,7 +307,7 @@ aifa_readCommonChunk (TFB_AiffSoundDecoder* aifa, uint32 size, { int bytes; - memset(fmt, sizeof(*fmt), 0); + memset(fmt, 0, sizeof(*fmt)); if (size < AIFF_COMM_SIZE) { aifa->last_error = aifae_BadFile; @@ -369,7 +369,7 @@ aifa_Open (THIS_PTR, uio_DirHandle *dir, const char *filename) aifa->max_pcm = 0; aifa->data_ofs = 0; memset(&aifa->fmtHdr, 0, sizeof(aifa->fmtHdr)); - memset(aifa->prev_val, sizeof(aifa->prev_val), 0); + memset(aifa->prev_val, 0, sizeof(aifa->prev_val)); // read wave header if (!aifa_readFileHeader (aifa, &fileHdr)) @@ -635,7 +635,7 @@ aifa_Seek (THIS_PTR, uint32 pcm_pos) // reset previous values for SDX2 on seek ops // the delta will recover faster with reset - memset(aifa->prev_val, sizeof(aifa->prev_val), 0); + memset(aifa->prev_val, 0, sizeof(aifa->prev_val)); return pcm_pos; } diff --git a/sc2/src/libs/sound/decoders/dukaud.c b/sc2/src/libs/sound/decoders/dukaud.c index 9e7a6ed65..aeff3733b 100644 --- a/sc2/src/libs/sound/decoders/dukaud.c +++ b/sc2/src/libs/sound/decoders/dukaud.c @@ -105,7 +105,7 @@ typedef struct static const TFB_DecoderFormats* duka_formats = NULL; -sint32 +static sint32 duka_readAudFrameHeader (TFB_DuckSoundDecoder* duka, uint32 iframe, DukAud_AudSubframe* aud) { @@ -246,7 +246,7 @@ decode_nibbles (sint16 *output, sint32 output_size, sint32 channels, } // *** END part copied from MPlayer *** -sint32 +static sint32 duka_decodeFrame (TFB_DuckSoundDecoder* duka, DukAud_AudSubframe* header, uint8* input) { @@ -273,7 +273,7 @@ duka_decodeFrame (TFB_DuckSoundDecoder* duka, DukAud_AudSubframe* header, } -sint32 +static sint32 duka_readNextFrame (TFB_DuckSoundDecoder* duka) { DukAud_FrameHeader hdr; diff --git a/sc2/src/libs/sound/decoders/modaud.c b/sc2/src/libs/sound/decoders/modaud.c index e7ef831dd..18c29a2e8 100644 --- a/sc2/src/libs/sound/decoders/modaud.c +++ b/sc2/src/libs/sound/decoders/modaud.c @@ -88,7 +88,7 @@ static void* buffer; static ULONG bufsize; static ULONG written; -ULONG* +static ULONG* moda_mmout_SetOutputBuffer (void* buf, ULONG size) { buffer = buf; @@ -132,12 +132,18 @@ moda_mmout_Reset (void) return 0; } +static char MDRIVER_name[] = "Mem Buffer"; +static char MDRIVER_version[] = "Mem Buffer driver v1.1"; +static char MDRIVER_alias[] = "membuf"; + static MDRIVER moda_mmout_drv = -{ NULL, - "Mem Buffer", // Name - "Mem Buffer driver v1.1", // Version - 0, 255, // Voice limits - "membuf", // Alias +{ + NULL, + //xxx libmikmod does not declare these fields const; it probably should. + MDRIVER_name, // Name + MDRIVER_version, // Version + 0, 255, // Voice limits + MDRIVER_alias, // Alias // The minimum mikmod version we support is 3.1.8 #if (LIBMIKMOD_VERSION_MAJOR > 3) || \ @@ -215,7 +221,7 @@ moda_uioReader_Tell (MREADER* reader) return uio_ftell (((MUIOREADER*)reader)->file); } -MREADER* +static MREADER* moda_new_uioReader (uio_Stream* fp) { MUIOREADER* reader = (MUIOREADER*) HMalloc (sizeof(MUIOREADER)); @@ -231,7 +237,7 @@ moda_new_uioReader (uio_Stream* fp) return (MREADER*)reader; } -void +static void moda_delete_uioReader (MREADER* reader) { if (reader) @@ -276,7 +282,7 @@ moda_InitModule (int flags, const TFB_DecoderFormats* fmts) md_pansep = 64; - if (MikMod_Init ("")) + if (MikMod_Init (NULL)) { log_add (log_Error, "MikMod_Init() failed, %s", MikMod_strerror (MikMod_errno)); diff --git a/sc2/src/libs/sound/mixer/Makeinfo b/sc2/src/libs/sound/mixer/Makeinfo index 8f06188f7..66f960d59 100644 --- a/sc2/src/libs/sound/mixer/Makeinfo +++ b/sc2/src/libs/sound/mixer/Makeinfo @@ -1,2 +1,3 @@ uqm_SUBDIRS="sdl nosound" uqm_CFILES="mixer.c" +uqm_HFILES="mixer.h mixerint.h" diff --git a/sc2/src/libs/sound/mixer/mixer.c b/sc2/src/libs/sound/mixer/mixer.c index c59d92ddb..3e14ddd7b 100644 --- a/sc2/src/libs/sound/mixer/mixer.c +++ b/sc2/src/libs/sound/mixer/mixer.c @@ -1569,7 +1569,7 @@ mixer_ResampleNone (mixer_Source *src, bool left) uint8 *d0 = src->nextqueued->data + src->pos; src->pos += mixer_chansize; (void) left; // satisfying compiler - unused arg - return (float)mixer_GetSampleInt (d0, mixer_chansize); + return mixer_GetSampleInt (d0, mixer_chansize); } /* get a resampled (up/down) sample from source (nearest neighbor) */ @@ -1578,7 +1578,7 @@ mixer_ResampleNearest (mixer_Source *src, bool left) { uint8 *d0 = src->nextqueued->data + src->pos; d0 += mixer_SourceAdvance (src, left); - return (float)mixer_GetSampleInt (d0, mixer_chansize); + return mixer_GetSampleInt (d0, mixer_chansize); } /* get an upsampled sample from source (linear interpolation) */ @@ -1608,8 +1608,8 @@ mixer_UpsampleLinear (mixer_Source *src, bool left) else d1 = d0 + curr->sampsize; - s0 = (float)mixer_GetSampleInt (d0, mixer_chansize); - s1 = (float)mixer_GetSampleInt (d1, mixer_chansize); + s0 = mixer_GetSampleInt (d0, mixer_chansize); + s1 = mixer_GetSampleInt (d1, mixer_chansize); return s0 + t * (s1 - s0); } @@ -1672,10 +1672,10 @@ mixer_UpsampleCubic (mixer_Source *src, bool left) d3 = d2 + curr->sampsize; } - s0 = (float)mixer_GetSampleInt (d0, mixer_chansize); - s1 = (float)mixer_GetSampleInt (d1, mixer_chansize); - s2 = (float)mixer_GetSampleInt (d2, mixer_chansize); - s3 = (float)mixer_GetSampleInt (d3, mixer_chansize); + s0 = mixer_GetSampleInt (d0, mixer_chansize); + s1 = mixer_GetSampleInt (d1, mixer_chansize); + s2 = mixer_GetSampleInt (d2, mixer_chansize); + s3 = mixer_GetSampleInt (d3, mixer_chansize); a = (3.0f * (s1 - s2) - s0 + s3) * 0.5f; b = 2.0f * s2 + s0 - ((5.0f * s1 + s3) * 0.5f); diff --git a/sc2/src/libs/sound/mixer/nosound/Makeinfo b/sc2/src/libs/sound/mixer/nosound/Makeinfo index 62d795c0a..17f0c34b5 100644 --- a/sc2/src/libs/sound/mixer/nosound/Makeinfo +++ b/sc2/src/libs/sound/mixer/nosound/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="audiodrv_nosound.c" +uqm_HFILES="audiodrv_nosound.h" diff --git a/sc2/src/libs/sound/mixer/nosound/audiodrv_nosound.c b/sc2/src/libs/sound/mixer/nosound/audiodrv_nosound.c index 3182f4e84..005bb4466 100644 --- a/sc2/src/libs/sound/mixer/nosound/audiodrv_nosound.c +++ b/sc2/src/libs/sound/mixer/nosound/audiodrv_nosound.c @@ -146,12 +146,6 @@ noSound_Init (audio_Driver *driver, sint32 flags) return -1; } - atexit (unInitAudio); - - SetSFXVolume (sfxVolumeScale); - SetSpeechVolume (speechVolumeScale); - SetMusicVolume ((COUNT)musicVolume); - PlaybackTask = AssignTask (PlaybackTaskFunc, 1024, "nosound audio playback"); @@ -215,7 +209,7 @@ PlaybackTaskFunc (void *data) mixer_MixFake (NULL, stream, len); delay = period - (GetTimeCounter () - entryTime); if (delay > 0) - SleepThread (delay); + HibernateThread (delay); } HFree (stream); diff --git a/sc2/src/libs/sound/mixer/sdl/Makeinfo b/sc2/src/libs/sound/mixer/sdl/Makeinfo index 5ff5a5cc2..64c22c039 100644 --- a/sc2/src/libs/sound/mixer/sdl/Makeinfo +++ b/sc2/src/libs/sound/mixer/sdl/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="audiodrv_sdl.c" +uqm_HFILES="audiodrv_sdl.h" diff --git a/sc2/src/libs/sound/mixer/sdl/audiodrv_sdl.c b/sc2/src/libs/sound/mixer/sdl/audiodrv_sdl.c index fa1b06c86..7ef522ed0 100644 --- a/sc2/src/libs/sound/mixer/sdl/audiodrv_sdl.c +++ b/sc2/src/libs/sound/mixer/sdl/audiodrv_sdl.c @@ -98,6 +98,8 @@ static const audio_Driver mixSDL_Driver = }; +static void audioCallback (void *userdata, Uint8 *stream, int len); + /* * Initialization */ @@ -150,7 +152,7 @@ mixSDL_Init (audio_Driver *driver, sint32 flags) desired.format = AUDIO_S16SYS; desired.channels = 2; - desired.callback = mixer_MixChannels; + desired.callback = audioCallback; log_add (log_Info, "Opening SDL audio device."); #if SDL_MAJOR_VERSION > 1 @@ -278,6 +280,7 @@ mixSDL_Uninit (void) HFree (sbuffer); } DestroyMutex (soundSource[i].stream_mutex); + soundSource[i].stream_mutex = 0; mixSDL_DeleteSources (1, &soundSource[i].handle); } @@ -288,6 +291,11 @@ mixSDL_Uninit (void) SDL_QuitSubSystem (SDL_INIT_AUDIO); } +static void +audioCallback (void *userdata, Uint8 *stream, int len) +{ + mixer_MixChannels (userdata, stream, len); +} /* * General diff --git a/sc2/src/libs/sound/openal/Makeinfo b/sc2/src/libs/sound/openal/Makeinfo index a099c70aa..146946166 100644 --- a/sc2/src/libs/sound/openal/Makeinfo +++ b/sc2/src/libs/sound/openal/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="audiodrv_openal.c" +uqm_HFILES="audiodrv_openal.h" diff --git a/sc2/src/libs/sound/openal/audiodrv_openal.c b/sc2/src/libs/sound/openal/audiodrv_openal.c index 857a8bb9b..eee1cd1d8 100644 --- a/sc2/src/libs/sound/openal/audiodrv_openal.c +++ b/sc2/src/libs/sound/openal/audiodrv_openal.c @@ -126,7 +126,6 @@ openAL_Init (audio_Driver *driver, sint32 flags) } *driver = openAL_Driver; - atexit (unInitAudio); alcContext = alcCreateContext (alcDevice, NULL); if (!alcContext) @@ -193,14 +192,7 @@ openAL_Init (audio_Driver *driver, sint32 flags) return -1; } - SetSFXVolume (sfxVolumeScale); - SetSpeechVolume (speechVolumeScale); - SetMusicVolume ((COUNT) musicVolume); - - if (optStereoSFX) - alDistanceModel (AL_INVERSE_DISTANCE); - else - alDistanceModel (AL_NONE); + alDistanceModel (AL_INVERSE_DISTANCE); (void) driver; // eat compiler warning diff --git a/sc2/src/libs/sound/openal/audiodrv_openal.h b/sc2/src/libs/sound/openal/audiodrv_openal.h index df359f1e6..c1a3eff54 100644 --- a/sc2/src/libs/sound/openal/audiodrv_openal.h +++ b/sc2/src/libs/sound/openal/audiodrv_openal.h @@ -22,7 +22,6 @@ #include "config.h" #include "libs/sound/sound.h" -#include "options.h" #include "endian_uqm.h" #if defined (__APPLE__) diff --git a/sc2/src/libs/sound/sfx.c b/sc2/src/libs/sound/sfx.c index e8af8b808..3060434b5 100644 --- a/sc2/src/libs/sound/sfx.c +++ b/sc2/src/libs/sound/sfx.c @@ -29,6 +29,7 @@ static void CheckFinishedChannels (void); +static const SoundPosition notPositional = {FALSE, 0, 0}; void PlayChannel (COUNT channel, SOUND snd, SoundPosition pos, @@ -50,8 +51,7 @@ PlayChannel (COUNT channel, SOUND snd, SoundPosition pos, soundSource[channel].sample = sample; soundSource[channel].positional_object = positional_object; - if (optStereoSFX) - UpdateSoundPosition (channel, pos); + UpdateSoundPosition (channel, optStereoSFX ? pos : notPositional); audio_Sourcei (soundSource[channel].handle, audio_BUFFER, sample->buffer[0]); diff --git a/sc2/src/libs/sound/sndintrn.h b/sc2/src/libs/sound/sndintrn.h index 2340c4d24..179028c6a 100644 --- a/sc2/src/libs/sound/sndintrn.h +++ b/sc2/src/libs/sound/sndintrn.h @@ -46,7 +46,7 @@ struct tfb_soundsample uint32 num_buffers; TFB_SoundTag *buffer_tag; sint32 offset; // initial offset - intptr_t data; // user-defined data + void* data; // user-defined data TFB_SoundCallbacks callbacks; // user-defined callbacks }; diff --git a/sc2/src/libs/sound/sound.h b/sc2/src/libs/sound/sound.h index 5e55fe309..2a4f447bf 100644 --- a/sc2/src/libs/sound/sound.h +++ b/sc2/src/libs/sound/sound.h @@ -66,8 +66,8 @@ void SetSpeechVolume (float volume); TFB_SoundSample *TFB_CreateSoundSample (TFB_SoundDecoder*, uint32 num_buffers, const TFB_SoundCallbacks* /* can be NULL */); void TFB_DestroySoundSample (TFB_SoundSample*); -void TFB_SetSoundSampleData (TFB_SoundSample*, intptr_t data); -intptr_t TFB_GetSoundSampleData (TFB_SoundSample*); +void TFB_SetSoundSampleData (TFB_SoundSample*, void* data); +void* TFB_GetSoundSampleData (TFB_SoundSample*); void TFB_SetSoundSampleCallbacks (TFB_SoundSample*, const TFB_SoundCallbacks* /* can be NULL */); TFB_SoundDecoder* TFB_GetSoundSampleDecoder (TFB_SoundSample*); diff --git a/sc2/src/libs/sound/stream.c b/sc2/src/libs/sound/stream.c index c9f7e800a..b7d271819 100644 --- a/sc2/src/libs/sound/stream.c +++ b/sc2/src/libs/sound/stream.c @@ -225,12 +225,12 @@ TFB_DestroySoundSample (TFB_SoundSample *sample) } void -TFB_SetSoundSampleData (TFB_SoundSample *sample, intptr_t data) +TFB_SetSoundSampleData (TFB_SoundSample *sample, void* data) { sample->data = data; } -intptr_t +void* TFB_GetSoundSampleData (TFB_SoundSample *sample) { return sample->data; @@ -568,7 +568,7 @@ StreamDecoderTaskFunc (void *data) if (active_streams == 0) { // Throttle down the thread when there are no active streams - SleepThread (ONE_SECOND / 10); + HibernateThread (ONE_SECOND / 10); } else TaskSwitch (); @@ -593,7 +593,8 @@ readSoundSample (void *ptr, int sample_size) // We use AGC because different pieces of music and speech can easily be // at very different gain levels, because the game is moddable. int -GraphForegroundStream (uint8 *data, sint32 width, sint32 height) +GraphForegroundStream (uint8 *data, sint32 width, sint32 height, + bool wantSpeech) { int source_num; TFB_SoundSource *source; @@ -634,7 +635,7 @@ GraphForegroundStream (uint8 *data, sint32 width, sint32 height) source_num = SPEECH_SOURCE; source = &soundSource[source_num]; LockMutex (source->stream_mutex); - if (speechVolumeScale != 0.0f && (!source->sample || + if (wantSpeech && (!source->sample || !source->sample->decoder || !source->sample->decoder->is_null)) { // Use speech waveform, since it's available // Step is picked experimentally. Using step of 1 sample at 11025Hz, @@ -642,9 +643,10 @@ GraphForegroundStream (uint8 *data, sint32 width, sint32 height) // better this way. step = 1; } - else if (musicVolumeScale != 0.0f) + else { // We do not have speech -- use music waveform UnlockMutex (source->stream_mutex); + source_num = MUSIC_SOURCE; source = &soundSource[source_num]; LockMutex (source->stream_mutex); @@ -653,11 +655,6 @@ GraphForegroundStream (uint8 *data, sint32 width, sint32 height) // It looks better this way. step = 4; } - else - { // We do not have anything usable - UnlockMutex (source->stream_mutex); - return 0; - } if (!PlayingStream (source_num) || !source->sample || !source->sample->decoder || !source->sbuffer diff --git a/sc2/src/libs/sound/stream.h b/sc2/src/libs/sound/stream.h index e71ae4b97..57661325a 100644 --- a/sc2/src/libs/sound/stream.h +++ b/sc2/src/libs/sound/stream.h @@ -28,7 +28,8 @@ void ResumeStream (uint32 source); void SeekStream (uint32 source, uint32 pos); BOOLEAN PlayingStream (uint32 source); -int GraphForegroundStream (uint8 *data, sint32 width, sint32 height); +int GraphForegroundStream (uint8 *data, sint32 width, sint32 height, + bool wantSpeech); // returns TRUE if the fade was accepted by stream decoder bool SetMusicStreamFade (sint32 howLong, int endVolume); diff --git a/sc2/src/libs/sound/trackint.h b/sc2/src/libs/sound/trackint.h index 9754f612e..fe3974097 100644 --- a/sc2/src/libs/sound/trackint.h +++ b/sc2/src/libs/sound/trackint.h @@ -17,6 +17,8 @@ #ifndef TRACKINT_H #define TRACKINT_H +#include "libs/callback.h" + struct tfb_soundchunk { TFB_SoundDecoder *decoder; // decoder for this chunk @@ -24,7 +26,7 @@ struct tfb_soundchunk int tag_me; // set for chunks with subtitles uint32 track_num; // logical track #, comm code needs this UNICODE *text; // subtitle text - TFB_TrackCB callback; // comm callback, executed on chunk start + CallbackFunction callback; // comm callback, executed on chunk start struct tfb_soundchunk *next; }; diff --git a/sc2/src/libs/sound/trackplayer.c b/sc2/src/libs/sound/trackplayer.c index 3006cc5fe..edff1943b 100644 --- a/sc2/src/libs/sound/trackplayer.c +++ b/sc2/src/libs/sound/trackplayer.c @@ -199,7 +199,8 @@ static void DoTrackTag (TFB_SoundChunk *chunk) { if (chunk->callback) - chunk->callback (); + Callback_add(chunk->callback, 0); + cur_sub_chunk = chunk; } @@ -421,7 +422,7 @@ SpliceMultiTrack (UNICODE *TrackNames[], UNICODE *TrackText) // XXX: This code and the entire trackplayer are begging to be overhauled void -SpliceTrack (UNICODE *TrackName, UNICODE *TrackText, UNICODE *TimeStamp, TFB_TrackCB cb) +SpliceTrack (UNICODE *TrackName, UNICODE *TrackText, UNICODE *TimeStamp, CallbackFunction cb) { static UNICODE last_track_name[128] = ""; static unsigned long dec_offset = 0; diff --git a/sc2/src/libs/sound/trackplayer.h b/sc2/src/libs/sound/trackplayer.h index 0ca14b4b3..5964e652a 100644 --- a/sc2/src/libs/sound/trackplayer.h +++ b/sc2/src/libs/sound/trackplayer.h @@ -20,8 +20,7 @@ #define TRACKPLAYER_H #include "libs/compiler.h" - -typedef void (*TFB_TrackCB) (void); +#include "libs/callback.h" #define ACCEL_SCROLL_SPEED 300 @@ -37,7 +36,7 @@ extern void FastForward_Smooth (void); extern void FastReverse_Page (void); extern void FastForward_Page (void); -extern void SpliceTrack (UNICODE *filespec, UNICODE *textspec, UNICODE *TimeStamp, TFB_TrackCB cb); +extern void SpliceTrack (UNICODE *filespec, UNICODE *textspec, UNICODE *TimeStamp, CallbackFunction cb); extern void SpliceMultiTrack (UNICODE *TrackNames[], UNICODE *TrackText); extern int GetTrackPosition (int in_units); diff --git a/sc2/src/libs/strings/Makeinfo b/sc2/src/libs/strings/Makeinfo index 4daaa3ed6..f1e4a9e4e 100644 --- a/sc2/src/libs/strings/Makeinfo +++ b/sc2/src/libs/strings/Makeinfo @@ -1 +1,2 @@ -uqm_CFILES="getstr.c sfileins.c sresins.c strings.c unicode.c" +uqm_CFILES="getstr.c sfileins.c sresins.c stringhashtable.c strings.c unicode.c" +uqm_HFILES="stringhashtable.c strintrn.h" diff --git a/sc2/src/libs/strings/getstr.c b/sc2/src/libs/strings/getstr.c index c6865cc45..ba428cf0f 100644 --- a/sc2/src/libs/strings/getstr.c +++ b/sc2/src/libs/strings/getstr.c @@ -42,8 +42,9 @@ dword_convert (DWORD *dword_array, COUNT num_dwords) } while (--num_dwords); } -static void -set_strtab_entry (STRING_TABLE_DESC *strtab, int index, const char *value, int len) +static STRING +set_strtab_entry (STRING_TABLE_DESC *strtab, int index, const char *value, + int len) { STRING str = &strtab->strings[index]; @@ -59,23 +60,107 @@ set_strtab_entry (STRING_TABLE_DESC *strtab, int index, const char *value, int l str->length = len; memcpy (str->data, value, len); } + return str; +} + +static void +copy_strings_to_strtab (STRING_TABLE_DESC *strtab, size_t firstIndex, + size_t count, const char *data, const DWORD *lens) +{ + size_t stringI; + const char *off = data; + + for (stringI = 0; stringI < count; stringI++) + { + set_strtab_entry(strtab, firstIndex + stringI, + off, lens[stringI]); + off += lens[stringI]; + } +} + +// Check whether a buffer has a certain minimum size, and enlarge it +// if necessary. +// buf: pointer to the pointer to the buffer. May be NULL. +// curSize: pointer to the current size (multiple of 'increment') +// minSize: required minimum size +// increment: size to increment the buffer with if necessary +// On success, *buf and *curSize are updated. On failure, they are +// unchanged. +// returns FALSE if and only if the buffer needs to be enlarged but +// memory allocation failed. +static BOOLEAN +ensureBufSize (char **buf, size_t *curSize, size_t minSize, size_t increment) +{ + char *newBuf; + size_t newSize; + + if (minSize <= *curSize) + { + // Buffer is large enough as it is. + return TRUE; + } + + newSize = ((minSize + (increment - 1)) / increment) * increment; + // Smallest multiple of 'increment' larger or equal to minSize. + newBuf = HRealloc (*buf, newSize); + if (newBuf == NULL) + return FALSE; + + // Success + *buf = newBuf; + *curSize = newSize; + return TRUE; } void _GetConversationData (const char *path, RESOURCE_DATA *resdata) { - uio_Stream *fp; unsigned long dataLen; void *result; - int n, path_len, num_data_sets; - DWORD opos, - slen[MAX_STRINGS], StringOffs, tot_string_size, - clen[MAX_STRINGS], ClipOffs, tot_clip_size, - tslen[MAX_STRINGS], TSOffs; - DWORD tot_ts_size = 0; - char CurrentLine[1024], paths[1024], *clip_path, *ts_path, - *strdata, *clipdata, *ts_data; + int stringI; + int path_len; + int num_data_sets; + DWORD opos; + + char *namedata = NULL; + // Contains the names (indexes) of the dialogs. + DWORD nlen[MAX_STRINGS]; + // Length of each of the names. + DWORD NameOffs; + size_t tot_name_size; + + char *strdata = NULL; + // Contains the dialog strings. + DWORD slen[MAX_STRINGS]; + // Length of each of the dialog strings. + DWORD StringOffs; + size_t tot_string_size; + + char *clipdata = NULL; + // Contains the file names of the speech files. + DWORD clen[MAX_STRINGS]; + // Length of each of the speech file names. + DWORD ClipOffs; + size_t tot_clip_size; + + char *ts_data = NULL; + // Contains the timestamp data for synching the text with the + // speech. + DWORD tslen[MAX_STRINGS]; + // Length of each of the timestamp strings. + DWORD TSOffs; + size_t tot_ts_size = 0; + + char CurrentLine[1024]; + char paths[1024]; + char *clip_path; + char *ts_path; + + uio_Stream *fp = NULL; uio_Stream *timestamp_fp = NULL; + StringHashTable_HashTable *nameHashTable = NULL; + // Hash table of string names (such as "GLAD_WHEN_YOU_COME_BACK") + // to a STRING. /* Parse out the conversation components. */ strncpy (paths, path, 1023); @@ -107,7 +192,8 @@ _GetConversationData (const char *path, RESOURCE_DATA *resdata) } dataLen = LengthResFile (fp); - log_add (log_Info, "\t'%s' -- conversation phrases -- %lu bytes", paths, dataLen); + log_add (log_Info, "\t'%s' -- conversation phrases -- %lu bytes", paths, + dataLen); if (clip_path) log_add (log_Info, "\t'%s' -- voice clip directory", clip_path); else @@ -117,90 +203,135 @@ _GetConversationData (const char *path, RESOURCE_DATA *resdata) else log_add (log_Info, "\tNo associated timestamp file"); - if (dataLen == 0) { - log_add (log_Warning, "Warning: Trying to load empty file '%s'.", path); + log_add (log_Warning, "Warning: Trying to load empty file '%s'.", + path); goto err; } - if ((strdata = HMalloc (tot_string_size = POOL_SIZE)) == 0) + tot_string_size = POOL_SIZE; + strdata = HMalloc (tot_string_size); + if (strdata == 0) goto err; - if ((clipdata = HMalloc (tot_clip_size = POOL_SIZE)) == 0) - { - HFree (strdata); + tot_name_size = POOL_SIZE; + namedata = HMalloc (tot_name_size); + if (namedata == 0) + goto err; + + tot_clip_size = POOL_SIZE; + clipdata = HMalloc (tot_clip_size); + if (clipdata == 0) goto err; - } ts_data = NULL; + + nameHashTable = StringHashTable_newHashTable( + NULL, NULL, NULL, NULL, NULL, 0, 0.85, 0.9); + if (nameHashTable == NULL) + goto err; path_len = clip_path ? strlen (clip_path) : 0; - if (ts_path && (timestamp_fp = uio_fopen (contentDir, ts_path, - "rb"))) + if (ts_path) { - if ((ts_data = HMalloc (tot_ts_size = POOL_SIZE)) == 0) - goto err; + timestamp_fp = uio_fopen (contentDir, ts_path, "rb"); + if (timestamp_fp != NULL) + { + tot_ts_size = POOL_SIZE; + ts_data = HMalloc (tot_ts_size); + if (ts_data == 0) + goto err; + } } opos = uio_ftell (fp); - n = -1; - StringOffs = ClipOffs = TSOffs = 0; - while (uio_fgets (CurrentLine, sizeof (CurrentLine), fp) && n < MAX_STRINGS - 1) + stringI = -1; + NameOffs = 0; + StringOffs = 0; + ClipOffs = 0; + TSOffs = 0; + for (;;) { int l; + if (uio_fgets (CurrentLine, sizeof (CurrentLine), fp) == NULL) + { + // EOF or read error. + break; + } + + if (stringI >= MAX_STRINGS - 1) + { + // Too many strings. + break; + } + if (CurrentLine[0] == '#') { + // String header, of the following form: + // #(GLAD_WHEN_YOU_COME_BACK) commander-000.ogg char CopyLine[1024]; - char *s; + char *name; + char *ts; strcpy (CopyLine, CurrentLine); - s = strtok (&CopyLine[1], "()"); - if (s) + name = strtok (&CopyLine[1], "()"); + if (name) { - if (n >= 0) + if (stringI >= 0) { - while (slen[n] > 1 && + while (slen[stringI] > 1 && (strdata[StringOffs - 2] == '\n' || strdata[StringOffs - 2] == '\r')) { - --slen[n]; + --slen[stringI]; --StringOffs; strdata[StringOffs - 1] = '\0'; } } - slen[++n] = 0; + slen[++stringI] = 0; + + // Store the string name. + l = strlen (name) + 1; + if (!ensureBufSize (&namedata, &tot_name_size, + NameOffs + l, POOL_SIZE)) + goto err; + strcpy (&namedata[NameOffs], name); + NameOffs += l; + nlen[stringI] = l; + // now lets check for timestamp data if (timestamp_fp) { - char TimeStampLine[1024], *tsptr; + // We have a time stamp file. + char TimeStampLine[1024]; + char *tsptr; BOOLEAN ts_ok = FALSE; uio_fgets (TimeStampLine, sizeof (TimeStampLine), timestamp_fp); if (TimeStampLine[0] == '#') { - tslen[n] = 0; - if ((tsptr = strstr (TimeStampLine,s)) - && (tsptr += strlen(s)) - && (++tsptr)) + // Line is of the following form: + // #(GIVE_FUEL_AGAIN) 3304,3255 + tslen[stringI] = 0; + tsptr = strstr (TimeStampLine, name); + if (tsptr) { + tsptr += strlen(name) + 1; ts_ok = TRUE; while (! strcspn(tsptr," \t\r\n") && *tsptr) tsptr++; if (*tsptr) { - l = strlen (tsptr) + 1; - if (TSOffs + l > tot_ts_size - && (ts_data = HRealloc (ts_data, - tot_ts_size += POOL_SIZE)) == 0) - { - HFree (strdata); + l = strlen (tsptr) + 1; + if (!ensureBufSize (&ts_data, &tot_ts_size, TSOffs + l, + POOL_SIZE)) goto err; - } + strcpy (&ts_data[TSOffs], tsptr); TSOffs += l; - tslen[n] = l; + tslen[stringI] = l; } } } @@ -208,7 +339,7 @@ _GetConversationData (const char *path, RESOURCE_DATA *resdata) { // timestamp data is invalid, remove all of it log_add (log_Warning, "Invalid timestamp data " - "for '%s'. Disabling timestamps", s); + "for '%s'. Disabling timestamps", name); HFree (ts_data); ts_data = NULL; uio_fclose (timestamp_fp); @@ -216,46 +347,39 @@ _GetConversationData (const char *path, RESOURCE_DATA *resdata) TSOffs = 0; } } - clen[n] = 0; - s = strtok (NULL, " \t\r\n)"); - if (s) + clen[stringI] = 0; + ts = strtok (NULL, " \t\r\n)"); + if (ts) { - l = path_len + strlen (s) + 1; - if (ClipOffs + l > tot_clip_size - && (clipdata = HRealloc (clipdata, - tot_clip_size += POOL_SIZE)) == 0) - { - HFree (strdata); + l = path_len + strlen (ts) + 1; + if (!ensureBufSize (&clipdata, &tot_clip_size, + ClipOffs + l, POOL_SIZE)) goto err; - } if (clip_path) strcpy (&clipdata[ClipOffs], clip_path); - strcpy (&clipdata[ClipOffs + path_len], s); + strcpy (&clipdata[ClipOffs + path_len], ts); ClipOffs += l; - clen[n] = l; + clen[stringI] = l; } } } - else if (n >= 0) + else if (stringI >= 0) { char *s; l = strlen (CurrentLine) + 1; - if (StringOffs + l > tot_string_size - && (strdata = HRealloc (strdata, - tot_string_size += POOL_SIZE)) == 0) - { - HFree (clipdata); - goto err; - } - if (slen[n]) + if (!ensureBufSize (&strdata, &tot_string_size, StringOffs + l, + POOL_SIZE)) + goto err; + + if (slen[stringI]) { - --slen[n]; + --slen[stringI]; --StringOffs; } s = &strdata[StringOffs]; - slen[n] += l; + slen[stringI] += l; StringOffs += l; strcpy (s, CurrentLine); @@ -264,12 +388,12 @@ _GetConversationData (const char *path, RESOURCE_DATA *resdata) if ((int)uio_ftell (fp) - (int)opos >= (int)dataLen) break; } - if (n >= 0) + if (stringI >= 0) { - while (slen[n] > 1 && (strdata[StringOffs - 2] == '\n' + while (slen[stringI] > 1 && (strdata[StringOffs - 2] == '\n' || strdata[StringOffs - 2] == '\r')) { - --slen[n]; + --slen[stringI]; --StringOffs; strdata[StringOffs - 1] = '\0'; } @@ -280,57 +404,83 @@ _GetConversationData (const char *path, RESOURCE_DATA *resdata) result = NULL; num_data_sets = (ClipOffs ? 1 : 0) + (TSOffs ? 1 : 0) + 1; - if (++n) + if (++stringI) { int flags = 0; + int stringCount = stringI; + if (ClipOffs) flags |= HAS_SOUND_CLIPS; if (TSOffs) flags |= HAS_TIMESTAMP; - result = AllocStringTable (n, flags); + flags |= HAS_NAMEINDEX; + + result = AllocStringTable (stringCount, flags); if (result) { - int StringIndex, ClipIndex, TSIndex; - STRING_TABLE_DESC *lpST; + // Copy all the gatherered data in a STRING_TABLE + STRING_TABLE_DESC *lpST = (STRING_TABLE) result; + STRING str; + stringI = 0; - lpST = (STRING_TABLE) result; - - StringIndex = 0; - ClipIndex = n; - TSIndex = n * ((flags & HAS_SOUND_CLIPS) ? 2 : 1); - - StringOffs = ClipOffs = TSOffs = 0; - - for (n = 0; n < (int)lpST->size; - ++n, ++StringIndex, ++ClipIndex, ++TSIndex) + // Store the dialog string. + copy_strings_to_strtab ( + lpST, stringI, stringCount, strdata, slen); + stringI += stringCount; + + // Store the dialog names. + copy_strings_to_strtab ( + lpST, stringI, stringCount, namedata, nlen); + stringI += stringCount; + + // Store sound clip file names. + if (lpST->flags & HAS_SOUND_CLIPS) { - set_strtab_entry(lpST, StringIndex, strdata + StringOffs, slen[n]); - StringOffs += slen[n]; - if (lpST->flags & HAS_SOUND_CLIPS) - { - set_strtab_entry(lpST, ClipIndex, clipdata + ClipOffs, clen[n]); - ClipOffs += clen[n]; - } - if (lpST->flags & HAS_TIMESTAMP) - { - set_strtab_entry(lpST, TSIndex, ts_data + TSOffs, tslen[n]); - TSOffs += tslen[n]; - } + copy_strings_to_strtab ( + lpST, stringI, stringCount, clipdata, clen); + stringI += stringCount; } + + // Store time stamp data. + if (lpST->flags & HAS_TIMESTAMP) + { + copy_strings_to_strtab ( + lpST, stringI, stringCount, ts_data, tslen); + //stringI += stringCount; + } + + // Store the STRING in the hash table indexed by the dialog + // name. + str = &lpST->strings[stringCount]; + for (stringI = 0; stringI < stringCount; stringI++) + { + StringHashTable_add (nameHashTable, str[stringI].data, + &str[stringI]); + } + + lpST->nameIndex = nameHashTable; } } HFree (strdata); - HFree (clipdata); - if (ts_data) + if (clipdata != NULL) + HFree (clipdata); + if (ts_data != NULL) HFree (ts_data); resdata->ptr = result; return; err: + if (nameHashTable != NULL) + StringHashTable_deleteHashTable (nameHashTable); + if (ts_data != NULL) + HFree (ts_data); + if (clipdata != NULL) + HFree (clipdata); + if (strdata != NULL) + HFree (strdata); res_CloseResFile (fp); resdata->ptr = NULL; - } void * @@ -338,20 +488,38 @@ _GetStringData (uio_Stream *fp, DWORD length) { void *result; - int n; - DWORD opos, slen[MAX_STRINGS], StringOffs, tot_string_size; - char CurrentLine[1024], *strdata; + int stringI; + DWORD opos; + DWORD slen[MAX_STRINGS]; + DWORD StringOffs; + size_t tot_string_size; + char CurrentLine[1024]; + char *strdata = NULL; - if ((strdata = HMalloc (tot_string_size = POOL_SIZE)) == 0) - return (0); + tot_string_size = POOL_SIZE; + strdata = HMalloc (tot_string_size); + if (strdata == 0) + goto err; opos = uio_ftell (fp); - n = -1; + stringI = -1; StringOffs = 0; - while (uio_fgets (CurrentLine, sizeof (CurrentLine), fp) && n < MAX_STRINGS - 1) + for (;;) { int l; + if (uio_fgets (CurrentLine, sizeof (CurrentLine), fp) == NULL) + { + // EOF or read error. + break; + } + + if (stringI >= MAX_STRINGS - 1) + { + // Too many strings. + break; + } + if (CurrentLine[0] == '#') { char CopyLine[1024]; @@ -361,39 +529,37 @@ _GetStringData (uio_Stream *fp, DWORD length) s = strtok (&CopyLine[1], "()"); if (s) { - if (n >= 0) + if (stringI >= 0) { - while (slen[n] > 1 && + while (slen[stringI] > 1 && (strdata[StringOffs - 2] == '\n' || strdata[StringOffs - 2] == '\r')) { - --slen[n]; + --slen[stringI]; --StringOffs; strdata[StringOffs - 1] = '\0'; } } - slen[++n] = 0; + slen[++stringI] = 0; } } - else if (n >= 0) + else if (stringI >= 0) { char *s; l = strlen (CurrentLine) + 1; - if (StringOffs + l > tot_string_size - && (strdata = HRealloc (strdata, - tot_string_size += POOL_SIZE)) == 0) - { - return (0); - } - if (slen[n]) + if (!ensureBufSize (&strdata, &tot_string_size, StringOffs + l, + POOL_SIZE)) + goto err; + + if (slen[stringI]) { - --slen[n]; + --slen[stringI]; --StringOffs; } s = &strdata[StringOffs]; - slen[n] += l; + slen[stringI] += l; StringOffs += l; strcpy (s, CurrentLine); @@ -402,44 +568,38 @@ _GetStringData (uio_Stream *fp, DWORD length) if ((int)uio_ftell (fp) - (int)opos >= (int)length) break; } - if (n >= 0) + if (stringI >= 0) { - while (slen[n] > 1 && (strdata[StringOffs - 2] == '\n' + while (slen[stringI] > 1 && (strdata[StringOffs - 2] == '\n' || strdata[StringOffs - 2] == '\r')) { - --slen[n]; + --slen[stringI]; --StringOffs; strdata[StringOffs - 1] = '\0'; } } result = NULL; - if (++n) + if (++stringI) { int flags = 0; - result = AllocStringTable (n, flags); + int stringCount = stringI; + + result = AllocStringTable (stringI, flags); if (result) { - int StringIndex; - STRING_TABLE_DESC *lpST; - - lpST = (STRING_TABLE) result; - - StringIndex = 0; - - StringOffs = 0; - - for (n = 0; n < (int)lpST->size; - ++n, ++StringIndex) - { - set_strtab_entry(lpST, StringIndex, strdata + StringOffs, slen[n]); - StringOffs += slen[n]; - } + STRING_TABLE_DESC *lpST = (STRING_TABLE) result; + copy_strings_to_strtab (lpST, 0, stringCount, strdata, slen); } } HFree (strdata); - return (result); + return result; + +err: + if (strdata != NULL) + HFree (strdata); + return 0; } @@ -478,6 +638,6 @@ _GetBinaryTableData (uio_Stream *fp, DWORD length) result = lpST; } - return (result); + return result; } diff --git a/sc2/src/libs/strings/stringhashtable.c b/sc2/src/libs/strings/stringhashtable.c new file mode 100644 index 000000000..ac4b4f467 --- /dev/null +++ b/sc2/src/libs/strings/stringhashtable.c @@ -0,0 +1,67 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * Nota bene: later versions of the GNU General Public License do not apply + * to this program. + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#define HASHTABLE_INTERNAL +#include "stringhashtable.h" +#include "types.h" +#include "libs/misc.h" + // For unconst() +#include "libs/uio/uioport.h" + +static inline uio_uint32 StringHashTable_hash( + StringHashTable_HashTable *hashTable, const char *string); +static inline uio_bool StringHashTable_equal( + StringHashTable_HashTable *hashTable, + const char *key1, const char *key2); +static inline char *StringHashTable_copy( + StringHashTable_HashTable *hashTable, const char *key); + +#include "libs/uio/hashtable.c" + + +static inline uio_uint32 +StringHashTable_hash(StringHashTable_HashTable *hashTable, const char *key) { + uio_uint32 hash; + + (void) hashTable; + // Rotating hash, variation of something on the web which + // wasn't original itself. + hash = 0; + // Hash was on that web page initialised as the length, + // but that isn't known at this time. + while (*key != '\0') { + hash = (hash << 4) ^ (hash >> 28) ^ *key; + key++; + } + return hash ^ (hash >> 10) ^ (hash >> 20); +} + +static inline uio_bool +StringHashTable_equal(StringHashTable_HashTable *hashTable, + const char *key1, const char *key2) { + (void) hashTable; + return strcmp(key1, key2) == 0; +} + +static inline char * +StringHashTable_copy(StringHashTable_HashTable *hashTable, + const char *key) { + (void) hashTable; + return unconst(key); +} + diff --git a/sc2/src/libs/strings/stringhashtable.h b/sc2/src/libs/strings/stringhashtable.h new file mode 100644 index 000000000..36f9e47ec --- /dev/null +++ b/sc2/src/libs/strings/stringhashtable.h @@ -0,0 +1,43 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * Nota bene: later versions of the GNU General Public License do not apply + * to this program. + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef _STRINGHASHTABLE_H +#define _STRINGHASHTABLE_H + +// HashTable from 'char *' to STRING. +// We don't actually copy the index, which means that the caller is +// responsible for keeping them unchanged during the time that it is used in +// the hash table. + +#include "libs/strlib.h" + +#define HASHTABLE_(identifier) StringHashTable ## _ ## identifier +typedef char HASHTABLE_(Key); +typedef STRING_TABLE_ENTRY_DESC HASHTABLE_(Value); +#define StringHashTable_HASH StringHashTable_hash +#define StringHashTable_EQUAL StringHashTable_equal +#define StringHashTable_COPY StringHashTable_copy +#define StringHashTable_FREEKEY(hashTable, key) \ + ((void) (hashTable), (void) (key)) +#define StringHashTable_FREEVALUE(hashTable, value) \ + ((void) (hashTable), (void) (value)) + +#include "libs/uio/hashtable.h" + + +#endif /* _STRINGHASHTABLE_H */ diff --git a/sc2/src/libs/strings/strings.c b/sc2/src/libs/strings/strings.c index 02e93a2a2..7f8d5e4db 100644 --- a/sc2/src/libs/strings/strings.c +++ b/sc2/src/libs/strings/strings.c @@ -25,6 +25,10 @@ AllocStringTable (int num_entries, int flags) STRING_TABLE strtab = HMalloc (sizeof (STRING_TABLE_DESC)); int i, multiplier = 1; + if (flags & HAS_NAMEINDEX) + { + multiplier++; + } if (flags & HAS_SOUND_CLIPS) { multiplier++; @@ -44,6 +48,7 @@ AllocStringTable (int num_entries, int flags) strtab->strings[i].parent = strtab; strtab->strings[i].index = i; } + strtab->nameIndex = NULL; return strtab; } @@ -208,6 +213,40 @@ GetStringLengthBin (STRING String) return String->length; } +STRINGPTR +GetStringName (STRING String) +{ + STRING_TABLE StringTablePtr; + COUNT StringIndex; + + if (String == NULL) + { + return NULL; + } + + StringTablePtr = String->parent; + if (StringTablePtr == NULL) + { + return NULL; + } + + StringIndex = String->index; + + if (!(StringTablePtr->flags & HAS_NAMEINDEX)) + { + return NULL; + } + StringIndex += StringTablePtr->size; + + String = &StringTablePtr->strings[StringIndex]; + if (String->length == 0) + { + return NULL; + } + + return String->data; +} + STRINGPTR GetStringSoundClip (STRING String) { @@ -230,8 +269,13 @@ GetStringSoundClip (STRING String) { return NULL; } - StringIndex += StringTablePtr->size; + + if (StringTablePtr->flags & HAS_NAMEINDEX) + { + StringIndex += StringTablePtr->size; + } + String = &StringTablePtr->strings[StringIndex]; if (String->length == 0) { @@ -246,7 +290,6 @@ GetStringTimeStamp (STRING String) { STRING_TABLE StringTablePtr; COUNT StringIndex; - int offset; if (String == NULL) { @@ -264,9 +307,18 @@ GetStringTimeStamp (STRING String) { return NULL; } + StringIndex += StringTablePtr->size; + + if (StringTablePtr->flags & HAS_NAMEINDEX) + { + StringIndex += StringTablePtr->size; + } + + if (StringTablePtr->flags & HAS_SOUND_CLIPS) + { + StringIndex += StringTablePtr->size; + } - offset = (StringTablePtr->flags & HAS_SOUND_CLIPS) ? 1 : 0; - StringIndex += StringTablePtr->size << offset; String = &StringTablePtr->strings[StringIndex]; if (String->length == 0) { @@ -285,3 +337,11 @@ GetStringAddress (STRING String) } return String->data; } + +STRING +GetStringByName (STRING_TABLE StringTable, const char *index) +{ + return (STRING) StringHashTable_find (StringTable->nameIndex, index); +} + + diff --git a/sc2/src/libs/strings/strintrn.h b/sc2/src/libs/strings/strintrn.h index 24484f0e8..0c41fb07d 100644 --- a/sc2/src/libs/strings/strintrn.h +++ b/sc2/src/libs/strings/strintrn.h @@ -23,6 +23,7 @@ #include #include "libs/strlib.h" #include "libs/reslib.h" +#include "stringhashtable.h" struct string_table_entry { @@ -37,10 +38,12 @@ struct string_table unsigned short flags; int size; STRING_TABLE_ENTRY_DESC *strings; + StringHashTable_HashTable *nameIndex; }; -#define HAS_SOUND_CLIPS (1 << 0) -#define HAS_TIMESTAMP (1 << 1) +#define HAS_SOUND_CLIPS (1 << 0) +#define HAS_TIMESTAMP (1 << 1) +#define HAS_NAMEINDEX (1 << 2) STRING_TABLE AllocStringTable (int num_entries, int flags); void FreeStringTable (STRING_TABLE strtab); diff --git a/sc2/src/libs/strlib.h b/sc2/src/libs/strlib.h index 59a290f32..c313f7f33 100644 --- a/sc2/src/libs/strlib.h +++ b/sc2/src/libs/strlib.h @@ -36,6 +36,10 @@ typedef char *STRINGPTR; /* This has to go here because reslib requires the above typedefs. */ #include "libs/reslib.h" +#if defined(__cplusplus) +extern "C" { +#endif + extern BOOLEAN InstallStringTableResType (void); extern STRING_TABLE LoadStringTableInstance (RESOURCE res); extern STRING_TABLE LoadStringTableFile (uio_DirHandle *dir, @@ -53,8 +57,10 @@ extern STRING SetRelStringTableIndex (STRING String, SIZE extern COUNT GetStringLength (STRING String); extern COUNT GetStringLengthBin (STRING String); extern STRINGPTR GetStringAddress (STRING String); +extern STRINGPTR GetStringName (STRING String); extern STRINGPTR GetStringSoundClip (STRING String); extern STRINGPTR GetStringTimeStamp (STRING String); +extern STRING GetStringByName (STRING_TABLE StringTable, const char *index); #define UNICHAR_DEGREE_SIGN 0x00b0 #define STR_DEGREE_SIGN "\xC2\xB0" @@ -67,5 +73,8 @@ extern STRINGPTR GetStringTimeStamp (STRING String); #define UNICHAR_BULLET 0x2022 #define STR_BULLET "\xE2\x80\xA2" -#endif /* LIBS_STRLIB_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* LIBS_STRLIB_H_ */ diff --git a/sc2/src/libs/task/tasklib.c b/sc2/src/libs/task/tasklib.c index f88b48afe..81f77aff1 100644 --- a/sc2/src/libs/task/tasklib.c +++ b/sc2/src/libs/task/tasklib.c @@ -124,7 +124,6 @@ InitTaskSystem (void) { task_array[i].state_mutex = CreateMutex ("task manager lock", SYNC_CLASS_TOPLEVEL | SYNC_CLASS_RESOURCE); } - atexit (CleanupTaskSystem); } void @@ -134,6 +133,7 @@ CleanupTaskSystem (void) for (i = 0; i < TASK_MAX; ++i) { DestroyMutex (task_array[i].state_mutex); + task_array[i].state_mutex = 0; } } diff --git a/sc2/src/libs/tasklib.h b/sc2/src/libs/tasklib.h index b086b05ac..41544db67 100644 --- a/sc2/src/libs/tasklib.h +++ b/sc2/src/libs/tasklib.h @@ -26,6 +26,10 @@ #include "libs/threadlib.h" +#if defined(__cplusplus) +extern "C" { +#endif + /* Bitmasks for setting task state. */ #define TASK_INUSE 1 #define TASK_EXIT 2 @@ -50,5 +54,9 @@ extern DWORD Task_ReadState (Task task, DWORD state_mask); extern void FinishTask (Task task); extern void ConcludeTask (Task task); +#if defined(__cplusplus) +} +#endif + #endif diff --git a/sc2/src/libs/threadlib.h b/sc2/src/libs/threadlib.h index a5cf9f31e..6586d7f27 100644 --- a/sc2/src/libs/threadlib.h +++ b/sc2/src/libs/threadlib.h @@ -45,6 +45,10 @@ #include #include "libs/timelib.h" +#if defined(__cplusplus) +extern "C" { +#endif + #if defined (PROFILE_THREADS) || defined (DEBUG_THREADS) #define THREAD_NAMES #endif @@ -141,6 +145,8 @@ ThreadLocal *CreateThreadLocal (void); void DestroyThreadLocal (ThreadLocal *tl); ThreadLocal *GetMyThreadLocal (void); +void HibernateThread (TimePeriod timePeriod); +void HibernateThreadUntil (TimeCount wakeTime); void SleepThread (TimePeriod timePeriod); void SleepThreadUntil (TimeCount wakeTime); void DestroyThread (Thread); @@ -173,5 +179,8 @@ void WaitCondVar (CondVar); void SignalCondVar (CondVar); void BroadcastCondVar (CondVar); -#endif /* LIBS_THREADLIB_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* LIBS_THREADLIB_H_ */ diff --git a/sc2/src/libs/threads/Makeinfo b/sc2/src/libs/threads/Makeinfo index c9bcc9267..57f56a8b1 100644 --- a/sc2/src/libs/threads/Makeinfo +++ b/sc2/src/libs/threads/Makeinfo @@ -6,4 +6,6 @@ case "$uqm_THREADLIB" in uqm_SUBDIRS="pthread" ;; esac + uqm_CFILES="thrcommon.c" +uqm_HFILES="thrcommon.h" diff --git a/sc2/src/libs/threads/pthread/Makeinfo b/sc2/src/libs/threads/pthread/Makeinfo index a410f056f..251db7b1c 100644 --- a/sc2/src/libs/threads/pthread/Makeinfo +++ b/sc2/src/libs/threads/pthread/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="posixthreads.c" +uqm_HFILES="posixthreads.h" diff --git a/sc2/src/libs/threads/sdl/Makeinfo b/sc2/src/libs/threads/sdl/Makeinfo index 5527cb9f6..7a7ad765f 100644 --- a/sc2/src/libs/threads/sdl/Makeinfo +++ b/sc2/src/libs/threads/sdl/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="sdlthreads.c" +uqm_HFILES="sdlthreads.h" diff --git a/sc2/src/libs/threads/thrcommon.c b/sc2/src/libs/threads/thrcommon.c index 041712cf1..bc5475137 100644 --- a/sc2/src/libs/threads/thrcommon.c +++ b/sc2/src/libs/threads/thrcommon.c @@ -19,6 +19,7 @@ #include "libs/threadlib.h" #include "libs/timelib.h" #include "libs/log.h" +#include "libs/async.h" #include "libs/memlib.h" #include "thrcommon.h" @@ -284,16 +285,79 @@ WaitThread (Thread thread, int *status) NativeWaitThread (thread, status); } +#ifdef DEBUG_SLEEP +extern uint32 mainThreadId; +extern uint32 SDL_ThreadID(void); +#endif /* DEBUG_SLEEP */ + void -SleepThread (TimePeriod timePeriod) +HibernateThread (TimePeriod timePeriod) { +#ifdef DEBUG_SLEEP + if (SDL_ThreadID() == mainThreadId) + log_add (log_Debug, "HibernateThread called from main thread.\n"); +#endif /* DEBUG_SLEEP */ + NativeSleepThread (timePeriod); } +void +HibernateThreadUntil (TimeCount wakeTime) +{ +#ifdef DEBUG_SLEEP + if (SDL_ThreadID() == mainThreadId) + log_add (log_Debug, "HibernateThreadUntil called from main " + "thread.\n"); +#endif /* DEBUG_SLEEP */ + + NativeSleepThreadUntil (wakeTime); +} + +void +SleepThread (TimePeriod timePeriod) +{ + TimeCount now; + +#ifdef DEBUG_SLEEP + if (SDL_ThreadID() != mainThreadId) + log_add (log_Debug, "SleepThread called from non-main " + "thread.\n"); +#endif /* DEBUG_SLEEP */ + + now = GetTimeCounter (); + SleepThreadUntil (now + timePeriod); +} + +// Sleep until wakeTime, but call asynchrounous operations until then. void SleepThreadUntil (TimeCount wakeTime) { - NativeSleepThreadUntil (wakeTime); +#ifdef DEBUG_SLEEP + if (SDL_ThreadID() != mainThreadId) + log_add (log_Debug, "SleepThreadUntil called from non-main " + "thread.\n"); +#endif /* DEBUG_SLEEP */ + + for (;;) { + uint32 nextTimeMs; + TimeCount nextTime; + TimeCount now; + + Async_process (); + + now = GetTimeCounter (); + if (wakeTime <= now) + return; + + nextTimeMs = Async_timeBeforeNextMs (); + nextTime = (nextTimeMs / 1000) * ONE_SECOND + + ((nextTimeMs % 1000) * ONE_SECOND / 1000); + // Overflow-safe conversion. + if (wakeTime < nextTime) + nextTime = wakeTime; + + NativeSleepThreadUntil (nextTime); + } } void diff --git a/sc2/src/libs/time/Makeinfo b/sc2/src/libs/time/Makeinfo index 9c5712cda..14a7ca8a6 100644 --- a/sc2/src/libs/time/Makeinfo +++ b/sc2/src/libs/time/Makeinfo @@ -1,2 +1,3 @@ uqm_SUBDIRS="sdl" uqm_CFILES="timecommon.c" +uqm_HFILES="timecommon.h" diff --git a/sc2/src/libs/time/sdl/Makeinfo b/sc2/src/libs/time/sdl/Makeinfo index 07bb3a8da..47180adf9 100644 --- a/sc2/src/libs/time/sdl/Makeinfo +++ b/sc2/src/libs/time/sdl/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="sdltime.c" +uqm_HFILES="sdltime.h" diff --git a/sc2/src/libs/timelib.h b/sc2/src/libs/timelib.h index b069c8d36..8fc652246 100644 --- a/sc2/src/libs/timelib.h +++ b/sc2/src/libs/timelib.h @@ -21,6 +21,10 @@ #include "libs/compiler.h" +#if defined(__cplusplus) +extern "C" { +#endif + /* ONE_SECOND is the LCM of all the fractions of a second the game uses. * Battle is 24 FPS, Landers are 35 FPS, most UI-level things are 15 FPS, * The Interplanetary flight is 30 FPS, Comm ambient animation is 40 FPS, @@ -38,5 +42,8 @@ extern void InitTimeSystem (void); extern void UnInitTimeSystem (void); extern TimeCount GetTimeCounter (void); -#endif /* LIBS_TIMELIB_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* LIBS_TIMLIB_H_ */ diff --git a/sc2/src/libs/uio.h b/sc2/src/libs/uio.h index 16ad7a929..f455049f2 100644 --- a/sc2/src/libs/uio.h +++ b/sc2/src/libs/uio.h @@ -21,7 +21,14 @@ #ifndef LIBS_UIO_H_ #define LIBS_UIO_H_ +#if defined(__cplusplus) +extern "C" { +#endif + #include "uio/io.h" -#endif /* LIBS_UIO_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* LIBS_UIO_H_ */ diff --git a/sc2/src/libs/uio/Makeinfo b/sc2/src/libs/uio/Makeinfo index b6147387a..9d127fc24 100644 --- a/sc2/src/libs/uio/Makeinfo +++ b/sc2/src/libs/uio/Makeinfo @@ -1,8 +1,10 @@ uqm_SUBDIRS="stdio" -uqm_CFILES="charhashtable.c defaultfs.c fileblock.c fstypes.c - gphys.c io.c ioaux.c match.c mount.c - mounttree.c paths.c physical.c uiostream.c uioutils.c - utils.c" +uqm_CFILES="charhashtable.c defaultfs.c fileblock.c fstypes.c gphys.c io.c + ioaux.c match.c mount.c mounttree.c paths.c physical.c uiostream.c + uioutils.c utils.c" +uqm_HFILES="charhashtable.h defaultfs.h fileblock.h fstypes.h getint.h + gphys.h ioaux.h io.h iointrn.h match.h mem.h mount.h mounttree.h + paths.h physical.h types.h uioport.h uiostream.h uioutils.h utils.h" if [ -n "$uqm_USE_ZIP_IO" ]; then uqm_SUBDIRS="$uqm_SUBDIRS zip" @@ -10,9 +12,11 @@ fi #if [ -n "$DEBUG" -o -n "$uqm_UIO_DEBUG" ]; then uqm_CFILES="$uqm_CFILES debug.c" + uqm_HFILES="$uqm_HFILES debug.h" #fi if [ -n "$MEMDEBUG" ]; then uqm_CFILES="$uqm_CFILES hashtable.c memdebug.c" + uqm_HFILES="$uqm_HFILES hashtable.h memdebug.h" fi diff --git a/sc2/src/libs/uio/charhashtable.c b/sc2/src/libs/uio/charhashtable.c index ba5b09032..df10b2a02 100644 --- a/sc2/src/libs/uio/charhashtable.c +++ b/sc2/src/libs/uio/charhashtable.c @@ -30,7 +30,7 @@ static inline uio_bool CharHashTable_equal(CharHashTable_HashTable *hashTable, const char *key1, const char *key2); static inline char *CharHashTable_copy(CharHashTable_HashTable *hashTable, const char *key); -static inline void CharHashTable_free(CharHashTable_HashTable *hashTable, +static inline void CharHashTable_freeKey(CharHashTable_HashTable *hashTable, char *key); #include "hashtable.c" @@ -56,21 +56,21 @@ CharHashTable_hash(CharHashTable_HashTable *hashTable, const char *key) { static inline uio_bool CharHashTable_equal(CharHashTable_HashTable *hashTable, const char *key1, const char *key2) { - (void) *hashTable; + (void) hashTable; return strcmp(key1, key2) == 0; } static inline char * CharHashTable_copy(CharHashTable_HashTable *hashTable, const char *key) { - (void) *hashTable; + (void) hashTable; return uio_strdup(key); } static inline void -CharHashTable_free(CharHashTable_HashTable *hashTable, +CharHashTable_freeKey(CharHashTable_HashTable *hashTable, char *key) { - (void) *hashTable; + (void) hashTable; uio_free(key); } diff --git a/sc2/src/libs/uio/charhashtable.h b/sc2/src/libs/uio/charhashtable.h index 6c387c105..3cd0add85 100644 --- a/sc2/src/libs/uio/charhashtable.h +++ b/sc2/src/libs/uio/charhashtable.h @@ -28,10 +28,12 @@ typedef void HASHTABLE_(Value); #define CharHashTable_HASH CharHashTable_hash #define CharHashTable_EQUAL CharHashTable_equal #define CharHashTable_COPY CharHashTable_copy -#define CharHashTable_FREE CharHashTable_free +#define CharHashTable_FREEKEY CharHashTable_freeKey +#define CharHashTable_FREEVALUE(hashTable, value) \ + ((void) (hashTable), (void) (value)) #include "hashtable.h" -#endif /* _HASHTABLE_H */ +#endif /* _CHARHASHTABLE_H */ diff --git a/sc2/src/libs/uio/debug.c b/sc2/src/libs/uio/debug.c index 4485602a1..66bab47b5 100644 --- a/sc2/src/libs/uio/debug.c +++ b/sc2/src/libs/uio/debug.c @@ -473,7 +473,7 @@ debugCmdExec(DebugContext *debugContext, int argc, char *argv[]) { O_RDONLY, tempDir); if (handles[i - 1] == NULL) { if (errno == ENOENT) { - // No match; we keep what's typed litterally. + // No match; we keep what's typed literally. newArgs[i - 1] = argv[i]; continue; } @@ -703,7 +703,7 @@ listOneDir(DebugContext *debugContext, const char *arg) { match_MATCH_PREFIX); } else { dirList = uio_getDirList(debugContext->cwd, cpath, pattern, - match_MATCH_LITTERAL); + match_MATCH_LITERAL); } #endif if (dirList == NULL) { diff --git a/sc2/src/libs/uio/doc/basics b/sc2/src/libs/uio/doc/basics index 69f06a18f..e04afd8c6 100644 --- a/sc2/src/libs/uio/doc/basics +++ b/sc2/src/libs/uio/doc/basics @@ -123,18 +123,56 @@ no problem, as long as the repositories don't overlap. -= Internals =- Types: -uio_MountTree - A node in a data structure describing the mounted directories. -uio_PRoot - A struct describing the a physical file system. -uio_PRootExtra - Filesystem-dependant extra data for a PRoot. -uio_GPRoot - Generic filesystem-dependant data for a PRoot, used as - uio_PRootExtra. -uio_GPRootExtra - Extra filesystem-dependant data for a PRoot, when using - uio_GPRoot for generic filesystem-dependant data. -uio_GPDir - Generic structure representing a node in a physical directory - structure describing one directory. -uio_GPFile - Generic structure describing a file in a physical file system. + +uio_MountTree + A node in a data structure describing the mounted directories. + +uio_PRoot + A struct describing the a physical file system. + +uio_PRootExtra + Filesystem-dependant extra data for a PRoot. + +uio_GPRoot + Generic filesystem-dependant data for a PRoot, used as uio_PRootExtra. + +uio_GPRootExtra + Extra filesystem-dependant data for a PRoot, when using uio_GPRoot for + generic filesystem-dependant data. + +uio_GPDir + Generic structure representing a node in a physical directory structure + describing one directory. + +uio_GPFile + Generic structure describing a file in a physical file system. -TODO: functions +Helper functions (defined in ioaux.c): + +uio_copyFilePhysical + Copy a file from one physical directory to another. + +uio_getPathPhysicalDirs + Get handles to the (existing) physical dirs that are effective in a + path 'path' relative from 'dirHandle' + +uio_getPhysicalAccess + Find PDirHandle and MountInfo structures for reading and writing for a path + from a DirHandle. + +uio_makePath + Create a directory inside a physical directory. All non-existant + parent directories will be created as well. + +uio_resolvePath + Determine the absolute path given a path relative to a given directory. + +uio_verifyPath + Test whether a path is valid and exists. + +uio_walkPhysicalPath + Follow a path starting from a specified physical dir for as long as + possible. diff --git a/sc2/src/libs/uio/gphys.h b/sc2/src/libs/uio/gphys.h index 627f71b0c..7a9d6bea4 100644 --- a/sc2/src/libs/uio/gphys.h +++ b/sc2/src/libs/uio/gphys.h @@ -33,7 +33,7 @@ typedef struct CharHashTable_HashTable uio_GPDirEntries; #define uio_GPDirEntries_new() \ ((uio_GPDirEntries *) CharHashTable_newHashTable(NULL, NULL, NULL, \ - NULL, 0, 0.85, 0.9)) + NULL, NULL, 0, 0.85, 0.9)) #define uio_GPDirEntries_add(hashTable, name, item) \ CharHashTable_add((CharHashTable_HashTable *) hashTable, name, \ (void *) item) diff --git a/sc2/src/libs/uio/hashtable.c b/sc2/src/libs/uio/hashtable.c index b9e6b088c..1f376e154 100644 --- a/sc2/src/libs/uio/hashtable.c +++ b/sc2/src/libs/uio/hashtable.c @@ -46,12 +46,14 @@ static inline HASHTABLE_(HashEntry) *HASHTABLE_(allocHashEntry)(void); static inline void HASHTABLE_(freeHashEntry)( HASHTABLE_(HashEntry) *entry); +// Create a new HashTable. HASHTABLE_(HashTable) * HASHTABLE_(newHashTable)( HASHTABLE_(HashFunction) hashFunction, HASHTABLE_(EqualFunction) equalFunction, HASHTABLE_(CopyFunction) copyFunction, - HASHTABLE_(FreeFunction) freeFunction, + HASHTABLE_(FreeKeyFunction) freeKeyFunction, + HASHTABLE_(FreeValueFunction) freeValueFunction, uio_uint32 initialSize, double minFillQuotient, double maxFillQuotient) { @@ -63,7 +65,8 @@ HASHTABLE_(newHashTable)( hashTable->hashFunction = hashFunction; hashTable->equalFunction = equalFunction; hashTable->copyFunction = copyFunction; - hashTable->freeFunction = freeFunction; + hashTable->freeKeyFunction = freeKeyFunction; + hashTable->freeValueFunction = freeValueFunction; hashTable->minFillQuotient = minFillQuotient; hashTable->maxFillQuotient = maxFillQuotient; @@ -72,6 +75,7 @@ HASHTABLE_(newHashTable)( return hashTable; } +// Add an entry to the HashTable. uio_bool HASHTABLE_(add)(HASHTABLE_(HashTable) *hashTable, const HASHTABLE_(Key) *key, HASHTABLE_(Value) *value) { @@ -104,6 +108,7 @@ HASHTABLE_(add)(HASHTABLE_(HashTable) *hashTable, return true; } +// Remove an entry with a specified Key from the HashTable. uio_bool HASHTABLE_(remove)(HASHTABLE_(HashTable) *hashTable, const HASHTABLE_(Key) *key) { @@ -122,7 +127,8 @@ HASHTABLE_(remove)(HASHTABLE_(HashTable) *hashTable, entry = &(*entry)->next; } next = (*entry)->next; - HASHTABLE_(FREE)(hashTable, (*entry)->key); + HASHTABLE_(FREEKEY)(hashTable, (*entry)->key); + HASHTABLE_(FREEVALUE)(hashTable, (*entry)->value); HASHTABLE_(freeHashEntry)(*entry); *entry = next; @@ -133,6 +139,7 @@ HASHTABLE_(remove)(HASHTABLE_(HashTable) *hashTable, return true; } +// Find the Value stored for some Key. HASHTABLE_(Value) * HASHTABLE_(find)(HASHTABLE_(HashTable) *hashTable, const HASHTABLE_(Key) *key) { @@ -151,21 +158,23 @@ HASHTABLE_(find)(HASHTABLE_(HashTable) *hashTable, return NULL; } +// Returns the number of entries in the HashTable. uio_uint32 HASHTABLE_(count)(const HASHTABLE_(HashTable) *hashTable) { return hashTable->numEntries; } +// Auxiliary function to (re)initialise the buckets in the HashTable. static void HASHTABLE_(setup)(HASHTABLE_(HashTable) *hashTable, uio_uint32 initialSize) { if (initialSize < 4) initialSize = 4; - hashTable->size = nextPower2((uio_uint32) ceil( - ((double) initialSize) / hashTable->maxFillQuotient)); + hashTable->size = nextPower2(ceil(((double) initialSize) / + hashTable->maxFillQuotient)); hashTable->hashMask = hashTable->size - 1; - hashTable->minSize = (uio_uint32) ceil(((double) (hashTable->size >> 1)) + hashTable->minSize = ceil(((double) (hashTable->size >> 1)) * hashTable->minFillQuotient); - hashTable->maxSize = (uio_uint32) floor(((double) hashTable->size) + hashTable->maxSize = floor(((double) hashTable->size) * hashTable->maxFillQuotient); hashTable->entries = uio_calloc(hashTable->size, sizeof (HASHTABLE_(HashEntry) *)); @@ -175,6 +184,7 @@ HASHTABLE_(setup)(HASHTABLE_(HashTable) *hashTable, uio_uint32 initialSize) { #endif } +// Resize the buckets in the HashTable. static void HASHTABLE_(resize)(HASHTABLE_(HashTable) *hashTable) { HASHTABLE_(HashEntry) **oldEntries; @@ -224,6 +234,7 @@ nextPower2(uio_uint32 x) { return x + 1; } +// Get an iterator to iterate through all the entries in the HashTable. // NB: Iterator should be considered invalid if the HashTable is changed. // TODO: change this (make it thread-safe) // this can be done by only marking items as deleted when @@ -252,21 +263,26 @@ HASHTABLE_(getIterator)(const HASHTABLE_(HashTable) *hashTable) { return iterator; } +// Returns true if and only if there are no more entries in the hash table +// for the Iterator to find. int HASHTABLE_(iteratorDone)(const HASHTABLE_(Iterator) *iterator) { return iterator->bucketNr >= iterator->hashTable->size; } +// Get the Key of the entry pointed to by an Iterator. HASHTABLE_(Key) * HASHTABLE_(iteratorKey)(HASHTABLE_(Iterator) *iterator) { return iterator->entry->key; } +// Get the Value of the entry pointed to by an Iterator. HASHTABLE_(Value) * HASHTABLE_(iteratorValue)(HASHTABLE_(Iterator) *iterator) { return iterator->entry->value; } +// Move the Iterator to the next entry in the HashTable. // Should not be called if the iterator is already past the last entry. HASHTABLE_(Iterator) * HASHTABLE_(iteratorNext)(HASHTABLE_(Iterator) *iterator) { @@ -293,16 +309,19 @@ HASHTABLE_(iteratorNext)(HASHTABLE_(Iterator) *iterator) { return iterator; } +// Free the Iterator. void HASHTABLE_(freeIterator)(HASHTABLE_(Iterator) *iterator) { uio_free(iterator); } +// Auxiliary function to allocate a HashTable. static inline HASHTABLE_(HashTable) * HASHTABLE_(allocHashTable)(void) { return uio_malloc(sizeof (HASHTABLE_(HashTable))); } +// Auxiliary function to create a HashEntry. static inline HASHTABLE_(HashEntry) * HASHTABLE_(newHashEntry)(uio_uint32 hash, HASHTABLE_(Key) *key, HASHTABLE_(Value) *value, HASHTABLE_(HashEntry) *next) { @@ -316,11 +335,13 @@ HASHTABLE_(newHashEntry)(uio_uint32 hash, HASHTABLE_(Key) *key, return result; } +// Allocate a new HashEntry. static inline HASHTABLE_(HashEntry) * HASHTABLE_(allocHashEntry)(void) { return uio_malloc(sizeof (HASHTABLE_(HashEntry))); } +// Delete the HashTable. void HASHTABLE_(deleteHashTable)(HASHTABLE_(HashTable) *hashTable) { uio_uint32 i; @@ -333,7 +354,8 @@ HASHTABLE_(deleteHashTable)(HASHTABLE_(HashTable) *hashTable) { entry = *bucketPtr; while (entry != NULL) { next = entry->next; - HASHTABLE_(FREE)(hashTable, entry->key); + HASHTABLE_(FREEKEY)(hashTable, entry->key); + HASHTABLE_(FREEVALUE)(hashTable, entry->value); HASHTABLE_(freeHashEntry)(entry); entry = next; i--; @@ -344,6 +366,7 @@ HASHTABLE_(deleteHashTable)(HASHTABLE_(HashTable) *hashTable) { uio_free(hashTable); } +// Auxiliary function to deallocate a HashEntry. static inline void HASHTABLE_(freeHashEntry)(HASHTABLE_(HashEntry) *entry) { uio_free(entry); diff --git a/sc2/src/libs/uio/hashtable.h b/sc2/src/libs/uio/hashtable.h index 5b134629f..eb4437ffa 100644 --- a/sc2/src/libs/uio/hashtable.h +++ b/sc2/src/libs/uio/hashtable.h @@ -39,6 +39,8 @@ // (and typedefs) from the HASHTABLE_ block below. // In the .c file, #define HASHTABLE_INTERNAL, #include the .h file // and hashtable.c (in this order), and add the necessary functions. +// If you do not need to free the Value, you can define HashTable_FREEVALUE +// as a no-op. #ifndef HASHTABLE_ # define HASHTABLE_(identifier) HashTable ## _ ## identifier typedef void HashTable_Key; @@ -49,8 +51,10 @@ (hashTable)->equalFunction(hashKey1, hashKey2) # define HashTable_COPY(hashTable, hashKey) \ (hashTable)->copyFunction(hashKey) -# define HashTable_FREE(hashTable, hashKey) \ - (hashTable)->freeFunction(hashKey) +# define HashTable_FREEKEY(hashTable, hashKey) \ + (hashTable)->freeKeyFunction(hashKey) +# define HashTable_FREEVALUE(hashTable, hashValue) \ + (hashTable)->freeValueFunction(hashValue) #endif @@ -59,8 +63,9 @@ typedef uio_uint32 (*HASHTABLE_(HashFunction))(const HASHTABLE_(Key) *); typedef uio_bool (*HASHTABLE_(EqualFunction))(const HASHTABLE_(Key) *, const HASHTABLE_(Key) *); typedef HASHTABLE_(Value) *(*HASHTABLE_(CopyFunction))( - const HASHTABLE_(Value) *); -typedef void (*HASHTABLE_(FreeFunction))(HASHTABLE_(Value) *); + const HASHTABLE_(Key) *); +typedef void (*HASHTABLE_(FreeKeyFunction))(HASHTABLE_(Key) *); +typedef void (*HASHTABLE_(FreeValueFunction))(HASHTABLE_(Value) *); typedef struct HASHTABLE_(HashTable) HASHTABLE_(HashTable); typedef struct HASHTABLE_(HashEntry) HASHTABLE_(HashEntry); @@ -68,9 +73,17 @@ typedef struct HASHTABLE_(Iterator) HASHTABLE_(Iterator); struct HASHTABLE_(HashTable) { HASHTABLE_(HashFunction) hashFunction; + // Function creating a uio_uint32 hash of a key. HASHTABLE_(EqualFunction) equalFunction; + // Function used to compare two keys. HASHTABLE_(CopyFunction) copyFunction; - HASHTABLE_(FreeFunction) freeFunction; + // Function used to copy a key. + HASHTABLE_(FreeKeyFunction) freeKeyFunction; + // Function used to free a key. + HASHTABLE_(FreeValueFunction) freeValueFunction; + // Function used to free a value. Called when an entry is + // removed using the remove function, or for entries + // still in the HashTable when the HashTable is deleted. double minFillQuotient; // How much of half of the hashtable needs to be filled @@ -114,7 +127,9 @@ HASHTABLE_(HashTable) *HASHTABLE_(newHashTable)( HASHTABLE_(HashFunction) hashFunction, HASHTABLE_(EqualFunction) equalFunction, HASHTABLE_(CopyFunction) copyFunction, - HASHTABLE_(FreeFunction) freeFunction, uio_uint32 initialSize, + HASHTABLE_(FreeKeyFunction) freeKeyFunction, + HASHTABLE_(FreeValueFunction) freeValueFunction, + uio_uint32 initialSize, double minFillQuotient, double maxFillQuotient); uio_bool HASHTABLE_(add)(HASHTABLE_(HashTable) *hashTable, const HASHTABLE_(Key) *key, HASHTABLE_(Value) *value); diff --git a/sc2/src/libs/uio/io.c b/sc2/src/libs/uio/io.c index a7c721e67..247d1e24a 100644 --- a/sc2/src/libs/uio/io.c +++ b/sc2/src/libs/uio/io.c @@ -287,6 +287,103 @@ uio_mountDir(uio_Repository *destRep, const char *mountPoint, } } +// Mount a repository directory into same repository at a different location +// From fossil. +uio_MountHandle * +uio_transplantDir(const char *mountPoint, uio_DirHandle *sourceDir, int flags, + uio_MountHandle *relative) { + uio_MountInfo *relativeInfo; + int numPDirHandles; + uio_PDirHandle **pDirHandles; + uio_MountTreeItem **treeItems; + int i; + uio_MountHandle *handle = NULL; + + if ((flags & uio_MOUNT_RDONLY) != uio_MOUNT_RDONLY) { + // Only read-only transplants supported atm + errno = ENOSYS; + return NULL; + } + + switch (flags & uio_MOUNT_LOCATION_MASK) { + case uio_MOUNT_TOP: + case uio_MOUNT_BOTTOM: + if (relative != NULL) { + errno = EINVAL; + return NULL; + } + relativeInfo = NULL; + break; + case uio_MOUNT_BELOW: + case uio_MOUNT_ABOVE: + if (relative == NULL) { + errno = EINVAL; + return NULL; + } + relativeInfo = relative->mountInfo; + break; + default: + abort(); + } + + if (mountPoint[0] == '/') + mountPoint++; + if (!validPathName(mountPoint, strlen(mountPoint))) { + errno = EINVAL; + return NULL; + } + + if (uio_getPathPhysicalDirs(sourceDir, "", 0, + &pDirHandles, &numPDirHandles, &treeItems) == -1) { + // errno is set + return NULL; + } + if (numPDirHandles == 0) { + errno = ENOENT; + return NULL; + } + + // TODO: We only transplant the first read-only physical dir that we find + // Maybe transplant all of them? We would then have several + // uio_MountHandles to return. + for (i = 0; i < numPDirHandles; ++i) { + uio_PDirHandle *pDirHandle = pDirHandles[i]; + uio_MountInfo *oldMountInfo = treeItems[i]->mountInfo; + uio_Repository *rep = oldMountInfo->mountHandle->repository; + uio_MountInfo *mountInfo; + uio_MountTree *mountTree; + + // Only interested in read-only dirs in this incarnation + if (!uio_mountInfoIsReadOnly(oldMountInfo)) + continue; + + mountInfo = uio_MountInfo_new(oldMountInfo->fsID, NULL, pDirHandle, + uio_strdup(""), oldMountInfo->autoMount, NULL, flags); + // New mount references the same handles + uio_PDirHandle_ref(pDirHandle); + uio_PRoot_refMount(pDirHandle->pRoot); + + uio_repositoryAddMount(rep, mountInfo, + flags & uio_MOUNT_LOCATION_MASK, relativeInfo); + mountTree = uio_mountTreeAddMountInfo(rep, rep->mountTree, + mountInfo, mountPoint, flags & uio_MOUNT_LOCATION_MASK, + relativeInfo); + // mountTree is the node in rep->mountTree where mountInfo leads to + mountInfo->mountTree = mountTree; + mountInfo->mountHandle = uio_MountHandle_new(rep, mountInfo); + handle = mountInfo->mountHandle; + break; + } + + uio_PDirHandles_delete(pDirHandles, numPDirHandles); + uio_free(treeItems); + + if (handle == NULL) + errno = ENOENT; + + return handle; +} + int uio_unmountDir(uio_MountHandle *mountHandle) { uio_PRoot *pRoot; diff --git a/sc2/src/libs/uio/io.h b/sc2/src/libs/uio/io.h index e98baca35..813a2c32b 100644 --- a/sc2/src/libs/uio/io.h +++ b/sc2/src/libs/uio/io.h @@ -82,6 +82,12 @@ uio_MountHandle *uio_mountDir(uio_Repository *destRep, const char *mountPoint, const char *inPath, uio_AutoMount **autoMount, int flags, uio_MountHandle *relative); +// Mount a repository directory into same repository at a different +// location. +// From fossil. +uio_MountHandle *uio_transplantDir(const char *mountPoint, + uio_DirHandle *sourceDir, int flags, uio_MountHandle *relative); + // Unmount a previously mounted dir. int uio_unmountDir(uio_MountHandle *mountHandle); diff --git a/sc2/src/libs/uio/ioaux.c b/sc2/src/libs/uio/ioaux.c index 0ec975358..3dc088049 100644 --- a/sc2/src/libs/uio/ioaux.c +++ b/sc2/src/libs/uio/ioaux.c @@ -260,7 +260,7 @@ uio_copyFilePhysical(uio_PDirHandle *fromDir, const char *fromName, * Closes fromHandle if it's not -1. * Removes 'toName' from 'toDir' if it's not NULL. * Frees 'buf' if not NULL. - * Always returns -1. + * Always returns -1, setting errno to 'error'. */ static int copyError(int error, @@ -605,15 +605,26 @@ uio_getPhysicalAccess(uio_DirHandle *dirHandle, const char *path, return 0; } -// Get handles to the (existing) physical dirs that are effective in a -// path 'path' relative from 'dirHandle' -// returns the PDirHandles through '*pDirHandles'. It is NULL if none -// were found. -// If resItems != NULL, it returns the MountTreeItems belonging to those -// PDIrHandles through *resItems. It is NULL if none were found. -// numPDirHandles will contain the number of PDirHandles found. -// returns 0 if everything went ok. -// returns -1 in case of an error; errno is set. + +/** + * Get handles to the (existing) physical dirs that are effective in a + * path 'path' relative from 'dirHandle' + * + * @param[in] pDirHandle The physical directory to which 'path' is + * relative. + * @param[in] path The path to get the physical dirs for, relative to + * 'pDirHandle' + * @param[in] pathLen The string length of 'path'. + * @param[out] resPDirHandles *resPDirHandles is set to the handles to the + * (existing) physical dirs that are effective in 'path' (relative to + * pDirHandle), or NULL if there are none. + * @param[out] resNumPDirHandles The number of PDirHandles found. + * @param[out] resItems If 'resItems' != NULL, *resItems is set to the + * MountTreeItems belonging to $pDirHandles, or NULL if none were found. + * + * @retval 0 if everything went ok. + * @retval -1 if an error occurred; #errno is set. + */ int uio_getPathPhysicalDirs(uio_DirHandle *dirHandle, const char *path, size_t pathLen, uio_PDirHandle ***resPDirHandles, diff --git a/sc2/src/libs/uio/match.c b/sc2/src/libs/uio/match.c index 03ce1614c..68e6897b8 100644 --- a/sc2/src/libs/uio/match.c +++ b/sc2/src/libs/uio/match.c @@ -37,9 +37,9 @@ static inline match_MatchContext *match_allocMatchContext(void); static inline void match_freeMatchContext(match_MatchContext *context); -static inline match_LitteralContext *match_newLitteralContext(char *pattern); -static inline match_LitteralContext *match_allocLitteralContext(void); -static inline void match_freeLitteralContext(match_LitteralContext *context); +static inline match_LiteralContext *match_newLiteralContext(char *pattern); +static inline match_LiteralContext *match_allocLiteralContext(void); +static inline void match_freeLiteralContext(match_LiteralContext *context); static inline match_PrefixContext *match_newPrefixContext(char *pattern); static inline match_PrefixContext *match_allocPrefixContext(void); static inline void match_freePrefixContext(match_PrefixContext *context); @@ -85,9 +85,9 @@ match_prepareContext(const char *pattern, match_MatchContext **contextPtr, *contextPtr = match_allocMatchContext(); (*contextPtr)->type = type; switch (type) { - case match_MATCH_LITTERAL: - result = match_prepareLitteral(pattern, - &(*contextPtr)->u.litteral); + case match_MATCH_LITERAL: + result = match_prepareLiteral(pattern, + &(*contextPtr)->u.literal); break; case match_MATCH_PREFIX: result = match_preparePrefix(pattern, &(*contextPtr)->u.prefix); @@ -122,8 +122,8 @@ match_prepareContext(const char *pattern, match_MatchContext **contextPtr, match_Result match_matchPattern(match_MatchContext *context, const char *string) { switch (context->type) { - case match_MATCH_LITTERAL: - return match_matchLitteral(context->u.litteral, string); + case match_MATCH_LITERAL: + return match_matchLiteral(context->u.literal, string); case match_MATCH_PREFIX: return match_matchPrefix(context->u.prefix, string); case match_MATCH_SUFFIX: @@ -168,8 +168,8 @@ match_errorString(match_MatchContext *context, match_Result result) { switch (context->type) { #if 0 - case match_MATCH_LITTERAL: - return match_errorStringLitteral(context->u.litteral, result); + case match_MATCH_LITERAL: + return match_errorStringLiteral(context->u.literal, result); case match_MATCH_PREFIX: return match_errorStringPrefix(context->u.prefix, result); case match_MATCH_SUFFIX: @@ -193,8 +193,8 @@ match_errorString(match_MatchContext *context, match_Result result) { void match_freeContext(match_MatchContext *context) { switch (context->type) { - case match_MATCH_LITTERAL: - match_freeLitteral(context->u.litteral); + case match_MATCH_LITERAL: + match_freeLiteral(context->u.literal); break; case match_MATCH_PREFIX: match_freePrefix(context->u.prefix); @@ -239,43 +239,43 @@ out: } -// *** Litteral part *** +// *** Literal part *** match_Result -match_prepareLitteral(const char *pattern, - match_LitteralContext **contextPtr) { - *contextPtr = match_newLitteralContext(uio_strdup(pattern)); +match_prepareLiteral(const char *pattern, + match_LiteralContext **contextPtr) { + *contextPtr = match_newLiteralContext(uio_strdup(pattern)); return match_OK; } match_Result -match_matchLitteral(match_LitteralContext *context, const char *string) { +match_matchLiteral(match_LiteralContext *context, const char *string) { return (strcmp(context->pattern, string) == 0) ? match_MATCH : match_NOMATCH; } void -match_freeLitteral(match_LitteralContext *context) { +match_freeLiteral(match_LiteralContext *context) { uio_free(context->pattern); - match_freeLitteralContext(context); + match_freeLiteralContext(context); } -static inline match_LitteralContext * -match_newLitteralContext(char *pattern) { - match_LitteralContext *result; +static inline match_LiteralContext * +match_newLiteralContext(char *pattern) { + match_LiteralContext *result; - result = match_allocLitteralContext(); + result = match_allocLiteralContext(); result->pattern = pattern; return result; } -static inline match_LitteralContext * -match_allocLitteralContext(void) { - return uio_malloc(sizeof (match_LitteralContext)); +static inline match_LiteralContext * +match_allocLiteralContext(void) { + return uio_malloc(sizeof (match_LiteralContext)); } static inline void -match_freeLitteralContext(match_LitteralContext *context) { +match_freeLiteralContext(match_LiteralContext *context) { uio_free(context); } diff --git a/sc2/src/libs/uio/match.h b/sc2/src/libs/uio/match.h index 9faf5887f..0557e7d7c 100644 --- a/sc2/src/libs/uio/match.h +++ b/sc2/src/libs/uio/match.h @@ -31,7 +31,7 @@ typedef struct match_MatchContext match_MatchContext; typedef enum { - match_MATCH_LITTERAL = 0, + match_MATCH_LITERAL = 0, match_MATCH_PREFIX, match_MATCH_SUFFIX, match_MATCH_SUBSTRING, @@ -52,7 +52,7 @@ typedef int match_Result; #define match_ECUSTOM -3 #define match_ENOTINIT -4 -typedef struct match_LitteralContext match_LitteralContext; +typedef struct match_LiteralContext match_LiteralContext; typedef struct match_PrefixContext match_PrefixContext; typedef struct match_SuffixContext match_SuffixContext; typedef struct match_SubStringContext match_SubStringContext; @@ -87,7 +87,7 @@ match_Result match_matchPatternOnce(const char *pattern, match_MatchType type, struct match_MatchContext { match_MatchType type; union { - match_LitteralContext *litteral; + match_LiteralContext *literal; match_PrefixContext *prefix; match_SuffixContext *suffix; match_SubStringContext *subString; @@ -100,7 +100,7 @@ struct match_MatchContext { } u; }; -struct match_LitteralContext { +struct match_LiteralContext { char *pattern; }; @@ -134,11 +134,11 @@ struct match_RegexContext { }; #endif -match_Result match_prepareLitteral(const char *pattern, - match_LitteralContext **contextPtr); -match_Result match_matchLitteral(match_LitteralContext *context, +match_Result match_prepareLiteral(const char *pattern, + match_LiteralContext **contextPtr); +match_Result match_matchLiteral(match_LiteralContext *context, const char *string); -void match_freeLitteral(match_LitteralContext *context); +void match_freeLiteral(match_LiteralContext *context); match_Result match_preparePrefix(const char *pattern, match_PrefixContext **contextPtr); diff --git a/sc2/src/libs/uio/mount.c b/sc2/src/libs/uio/mount.c index 1bde4d7f4..f095d3f9b 100644 --- a/sc2/src/libs/uio/mount.c +++ b/sc2/src/libs/uio/mount.c @@ -61,7 +61,7 @@ uio_repositoryAddMount(uio_Repository *repository, repository->mounts[repository->numMounts] = mountInfo; repository->numMounts++; break; - case uio_MOUNT_BELOW: { + case uio_MOUNT_ABOVE: { int i; uio_MountInfo **newMounts; @@ -76,7 +76,7 @@ uio_repositoryAddMount(uio_Repository *repository, repository->numMounts++; break; } - case uio_MOUNT_ABOVE: { + case uio_MOUNT_BELOW: { int i; uio_MountInfo **newMounts; diff --git a/sc2/src/libs/uio/physical.c b/sc2/src/libs/uio/physical.c index d5fdec1d6..18f96d16c 100644 --- a/sc2/src/libs/uio/physical.c +++ b/sc2/src/libs/uio/physical.c @@ -157,7 +157,7 @@ uio_PRoot_refMount(uio_PRoot *pRoot) { #ifdef uio_MEM_DEBUG uio_MemDebug_debugRef(uio_PRoot, (void *) pRoot); #endif - pRoot->handleRef++; + pRoot->mountRef++; } void diff --git a/sc2/src/libs/uio/stdio/Makeinfo b/sc2/src/libs/uio/stdio/Makeinfo index a41976f9b..2d99c66c1 100644 --- a/sc2/src/libs/uio/stdio/Makeinfo +++ b/sc2/src/libs/uio/stdio/Makeinfo @@ -1,3 +1,2 @@ uqm_CFILES="stdio.c" - - +uqm_HFILES="stdio.h" diff --git a/sc2/src/libs/uio/uioutils.h b/sc2/src/libs/uio/uioutils.h index 68258c3c2..6e0484365 100644 --- a/sc2/src/libs/uio/uioutils.h +++ b/sc2/src/libs/uio/uioutils.h @@ -44,8 +44,8 @@ char *dosToUnixPath(const char *path); static inline void * unconst(const void *arg) { union { - char *c; - const char *cc; + void *c; + const void *cc; } u; u.cc = arg; return u.c; diff --git a/sc2/src/libs/uio/zip/Makeinfo b/sc2/src/libs/uio/zip/Makeinfo index ab1778015..64ae8d544 100644 --- a/sc2/src/libs/uio/zip/Makeinfo +++ b/sc2/src/libs/uio/zip/Makeinfo @@ -1,3 +1,2 @@ uqm_CFILES="zip.c" - - +uqm_HFILES="zip.h" diff --git a/sc2/src/libs/uioutils.h b/sc2/src/libs/uioutils.h index 7cff44bb4..ec8a5a53d 100644 --- a/sc2/src/libs/uioutils.h +++ b/sc2/src/libs/uioutils.h @@ -21,7 +21,14 @@ #ifndef LIBS_UIOUTILS_H_ #define LIBS_UIOUTILS_H_ +#if defined(__cplusplus) +extern "C" { +#endif + #include "uio/utils.h" -#endif /* LIBS_UIOUTILS_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* LIBS_UIOUTILS_H_ */ diff --git a/sc2/src/libs/unicode.h b/sc2/src/libs/unicode.h index 428de6f5c..922a3cc4e 100644 --- a/sc2/src/libs/unicode.h +++ b/sc2/src/libs/unicode.h @@ -23,6 +23,10 @@ #include // For size_t +#if defined(__cplusplus) +extern "C" { +#endif + typedef uint32 UniChar; #ifdef UNICODE_INTERNAL @@ -60,5 +64,9 @@ UniChar UniChar_toLower(UniChar ch); #undef UNICODE_CHAR +#if defined(__cplusplus) +} +#endif + #endif /* UNICODE_H */ diff --git a/sc2/src/libs/video/Makeinfo b/sc2/src/libs/video/Makeinfo index 5c460ff6d..1282e496b 100644 --- a/sc2/src/libs/video/Makeinfo +++ b/sc2/src/libs/video/Makeinfo @@ -1,2 +1,3 @@ uqm_CFILES="vfileins.c vresins.c video.c videodec.c vidplayer.c dukvid.c \ legacyplayer.c" +uqm_HFILES="dukvid.h videodec.h video.h vidintrn.h vidplayer.h" diff --git a/sc2/src/libs/video/dukvid.c b/sc2/src/libs/video/dukvid.c index 7d727d0c8..d9cb8fa2c 100644 --- a/sc2/src/libs/video/dukvid.c +++ b/sc2/src/libs/video/dukvid.c @@ -727,7 +727,8 @@ dukv_SeekTime (THIS_PTR, float time) //TFB_DuckVideoDecoder* dukv = (TFB_DuckVideoDecoder*) This; uint32 frame = (uint32) (time * DUCK_GENERAL_FPS); - return (float) dukv_SeekFrame (This, frame) / DUCK_GENERAL_FPS; + // Note that DUCK_GENERAL_FPS is a float constant + return dukv_SeekFrame (This, frame) / DUCK_GENERAL_FPS; } static uint32 diff --git a/sc2/src/libs/video/video.c b/sc2/src/libs/video/video.c index 8080592ae..dd4cd468d 100644 --- a/sc2/src/libs/video/video.c +++ b/sc2/src/libs/video/video.c @@ -127,7 +127,6 @@ VidPlayEx (VIDEO_REF vid, MUSIC_REF AudRef, MUSIC_REF SpeechRef, _cur_speech = 0; _cur_video = NULL_VIDEO_REF; - LockMutex (GraphicsLock); // play video in the center of the screen if (TFB_PlayVideo (vid, (ScreenWidth - vid->w) / 2, (ScreenHeight - vid->h) / 2)) @@ -144,7 +143,6 @@ VidPlayEx (VIDEO_REF vid, MUSIC_REF AudRef, MUSIC_REF SpeechRef, { ret = NO_FMV; } - UnlockMutex (GraphicsLock); return ret; } diff --git a/sc2/src/libs/video/vidintrn.h b/sc2/src/libs/video/vidintrn.h index 2d5819017..40a19e44d 100644 --- a/sc2/src/libs/video/vidintrn.h +++ b/sc2/src/libs/video/vidintrn.h @@ -38,10 +38,4 @@ struct legacy_video_ref MUSIC_REF speechref; }; -// XXX: There has to be a better way to synchronize gfx calls with the rest -// of the game. The only thing we need to sync is the current context, and -// even there only the cliprect. Perhaps a DCQ command that takes an -// explicit cliprect would be better. -extern Mutex GraphicsLock; - #endif diff --git a/sc2/src/libs/video/vidplayer.c b/sc2/src/libs/video/vidplayer.c index 0770592b6..09a506d23 100644 --- a/sc2/src/libs/video/vidplayer.c +++ b/sc2/src/libs/video/vidplayer.c @@ -143,14 +143,12 @@ processAudioSyncedFrame (VIDEO_REF vid) vid->cur_frame = vid->decoder->cur_frame; // draw the frame - LockMutex (GraphicsLock); // We have the cliprect precalculated and don't need the rest oldContext = SetContext (NULL); TFB_DrawScreen_Image (vid->frame, vid->dst_rect.corner.x, vid->dst_rect.corner.y, 0, 0, NULL, DRAW_REPLACE_MODE, TFB_SCREEN_MAIN); SetContext (oldContext); - UnlockMutex (GraphicsLock); FlushGraphics (); // needed to prevent half-frame updates // increase interframe with positive lag-count to allow audio to catch up @@ -195,14 +193,12 @@ processMuteFrame (VIDEO_REF vid) vid->cur_frame = vid->decoder->cur_frame; - LockMutex (GraphicsLock); // We have the cliprect precalculated and don't need the rest oldContext = SetContext (NULL); TFB_DrawScreen_Image (vid->frame, vid->dst_rect.corner.x, vid->dst_rect.corner.y, 0, 0, NULL, DRAW_REPLACE_MODE, TFB_SCREEN_MAIN); SetContext (oldContext); - UnlockMutex (GraphicsLock); FlushGraphics (); // needed to prevent half-frame updates if (vid->cur_frame == vid->loop_frame) @@ -273,7 +269,7 @@ TFB_PlayVideo (VIDEO_REF vid, uint32 x, uint32 y) } TFB_SetSoundSampleCallbacks (*vid->hAudio, &vp_AudioCBs); - TFB_SetSoundSampleData (*vid->hAudio, (intptr_t)vid); + TFB_SetSoundSampleData (*vid->hAudio, vid); } // get the first frame @@ -432,7 +428,7 @@ vp_SetTimer (TFB_VideoDecoder* decoder, uint32 msecs) static bool vp_AudioStart (TFB_SoundSample* sample) { - TFB_VideoClip* vid = (TFB_VideoClip*) TFB_GetSoundSampleData (sample); + TFB_VideoClip* vid = TFB_GetSoundSampleData (sample); TFB_SoundDecoder *decoder; assert (sizeof (intptr_t) >= sizeof (vid)); @@ -450,7 +446,7 @@ vp_AudioStart (TFB_SoundSample* sample) static void vp_AudioEnd (TFB_SoundSample* sample) { - TFB_VideoClip* vid = (TFB_VideoClip*) TFB_GetSoundSampleData (sample); + TFB_VideoClip* vid = TFB_GetSoundSampleData (sample); assert (vid != NULL); @@ -462,7 +458,7 @@ vp_AudioEnd (TFB_SoundSample* sample) static void vp_BufferTag (TFB_SoundSample* sample, TFB_SoundTag* tag) { - TFB_VideoClip* vid = (TFB_VideoClip*) TFB_GetSoundSampleData (sample); + TFB_VideoClip* vid = TFB_GetSoundSampleData (sample); uint32 frame = (uint32) tag->data; assert (sizeof (tag->data) >= sizeof (frame)); diff --git a/sc2/src/libs/vidlib.h b/sc2/src/libs/vidlib.h index cef74156a..9c32d7ccf 100644 --- a/sc2/src/libs/vidlib.h +++ b/sc2/src/libs/vidlib.h @@ -23,6 +23,10 @@ #include "libs/sndlib.h" #include "libs/reslib.h" +#if defined(__cplusplus) +extern "C" { +#endif + typedef enum { NO_FMV = 0, @@ -57,4 +61,8 @@ extern LEGACY_VIDEO_REF PlayLegacyVideo (LEGACY_VIDEO vid); extern void StopLegacyVideo (LEGACY_VIDEO_REF ref); extern BOOLEAN PlayingLegacyVideo (LEGACY_VIDEO_REF ref); +#if defined(__cplusplus) +} +#endif + #endif /* LIBS_VIDLIB_H_ */ diff --git a/sc2/src/options.c b/sc2/src/options.c index d8306dfa1..46c7c30c1 100644 --- a/sc2/src/options.c +++ b/sc2/src/options.c @@ -54,9 +54,13 @@ const char **optAddons; BOOLEAN opt3doMusic; BOOLEAN optRemixMusic; +BOOLEAN optSpeech; BOOLEAN optSubtitles; BOOLEAN optStereoSFX; BOOLEAN optKeepAspectRatio; + +float optGamma; + uio_DirHandle *contentDir; uio_DirHandle *configDir; uio_DirHandle *saveDir; @@ -416,7 +420,7 @@ mountAddonDir (uio_Repository *repository, uio_MountHandle *contentMountHandle, count = 0; for (i = 0; i < availableAddons->numNames; ++i) { - static char mountname[128]; + char mountname[128]; uio_DirHandle *addonDir; const char *addon = availableAddons->names[i]; @@ -426,8 +430,7 @@ mountAddonDir (uio_Repository *repository, uio_MountHandle *contentMountHandle, ++count; log_add (log_Info, " %d. %s", count, addon); - snprintf(mountname, 128, "addons/%s", addon); - mountname[127]=0; + snprintf (mountname, sizeof mountname, "addons/%s", addon); addonDir = uio_openDirRelative (addonsDir, addon, 0); if (addonDir == NULL) @@ -528,6 +531,11 @@ loadAddon (const char *addon) } numLoaded = loadIndices (addonDir); + if (!numLoaded) + { + log_add (log_Error, "No RMP index files were loaded for addon '%s'", + addon); + } uio_closeDir (addonDir); uio_closeDir (addonsDir); @@ -563,6 +571,14 @@ prepareShadowAddons (const char **addons) { log_add (log_Debug, "Mounting shadow content of '%s' addon", addon); mountDirZips (shadowDir, "/", uio_MOUNT_ABOVE, contentMountHandle); + // Mount non-zipped shadow content + if (uio_transplantDir ("/", shadowDir, uio_MOUNT_RDONLY | + uio_MOUNT_ABOVE, contentMountHandle) == NULL) + { + log_add (log_Warning, "Warning: Could not mount shadow content" + " of '%s': %s.", addon, strerror (errno)); + } + uio_closeDir (shadowDir); } uio_closeDir (addonDir); @@ -579,7 +595,46 @@ prepareAddons (const char **addons) log_add (log_Info, "Loading addon '%s'", *addons); if (!loadAddon (*addons)) { + // TODO: Should we do something like inform the user? + // Why simply refuse to load other addons? + // Maybe exit() to inform the user of the failure? break; } } } + +void +unprepareAllDirs (void) +{ + if (saveDir) + { + uio_closeDir (saveDir); + saveDir = 0; + } + if (meleeDir) + { + uio_closeDir (meleeDir); + meleeDir = 0; + } + if (contentDir) + { + uio_closeDir (contentDir); + contentDir = 0; + } + if (configDir) + { + uio_closeDir (configDir); + configDir = 0; + } +} + +bool +setGammaCorrection (float gamma) +{ + bool set = TFB_SetGamma (gamma); + if (set) + log_add (log_Info, "Gamma correction set to %.4f.", gamma); + else + log_add (log_Warning, "Unable to set gamma correction."); + return set; +} diff --git a/sc2/src/options.h b/sc2/src/options.h index c675aec02..67480a4d9 100644 --- a/sc2/src/options.h +++ b/sc2/src/options.h @@ -26,6 +26,10 @@ #include "libs/compiler.h" #include "libs/uio.h" +#if defined(__cplusplus) +extern "C" { +#endif + #define OPT_3DO 0x01 #define OPT_PC 0x02 #define OPT_ALL 0xFF @@ -40,10 +44,14 @@ extern int optMeleeScale; extern BOOLEAN opt3doMusic; extern BOOLEAN optRemixMusic; +extern BOOLEAN optSpeech; extern BOOLEAN optSubtitles; extern BOOLEAN optStereoSFX; extern BOOLEAN optKeepAspectRatio; +#define GAMMA_SCALE 1000 +extern float optGamma; + extern uio_DirHandle *contentDir; extern uio_DirHandle *configDir; extern uio_DirHandle *saveDir; @@ -71,9 +79,16 @@ void prepareMeleeDir (void); void prepareSaveDir (void); void prepareAddons (const char **addons); void prepareShadowAddons (const char **addons); +void unprepareAllDirs (void); BOOLEAN loadAddon (const char *addon); int loadIndices (uio_DirHandle *baseDir); +bool setGammaCorrection (float gamma); + +#if defined(__cplusplus) +} +#endif + #endif diff --git a/sc2/src/port.h b/sc2/src/port.h index 61ffd41e3..4dc56ee29 100644 --- a/sc2/src/port.h +++ b/sc2/src/port.h @@ -79,12 +79,24 @@ #ifndef HAVE_STRUPR +#if defined(__cplusplus) +extern "C" { +#endif char *strupr (char *str); +#if defined(__cplusplus) +} +#endif #endif #if !defined (_MSC_VER) && !defined (HAVE_READDIR_R) # include +#if defined(__cplusplus) +extern "C" { +#endif int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result); +#if defined(__cplusplus) +} +#endif #endif // Directories @@ -161,10 +173,21 @@ typedef unsigned short mode_t; #ifdef _MSC_VER # include // Defined in port.c +#if defined(__cplusplus) +extern "C" { +#endif int snprintf(char *str, size_t size, const char *format, ...); int vsnprintf(char *str, size_t size, const char *format, va_list args); +#if defined(__cplusplus) +} +#endif + #endif /* _MSC_VER */ +#if defined(__cplusplus) +extern "C" { +#endif + // setenv() #ifndef HAVE_SETENV int setenv (const char *name, const char *value, int overwrite); @@ -178,6 +201,10 @@ typedef unsigned short wchar_t; typedef unsigned int wint_t; #endif +#if defined(__cplusplus) +} +#endif + #if defined (_MSC_VER) || defined(__MINGW32__) # define USE_WINSOCK #endif diff --git a/sc2/src/regex/Makeinfo b/sc2/src/regex/Makeinfo index cb4435624..71026835d 100644 --- a/sc2/src/regex/Makeinfo +++ b/sc2/src/regex/Makeinfo @@ -1,2 +1,2 @@ uqm_CFILES="regex.c" - +uqm_HFILES="regex.h regex_internal.h" diff --git a/sc2/src/types.h b/sc2/src/types.h index e979aca2a..db58630b6 100644 --- a/sc2/src/types.h +++ b/sc2/src/types.h @@ -50,6 +50,10 @@ # endif /* defined(PRIxPTR) */ #endif +#if defined(__cplusplus) +extern "C" { +#endif + #if defined(__arch64__) || defined(__alpha) || defined(__x86_64) \ || defined(_M_IA64) || defined(_M_AMD64) /* 64-bit platforms */ @@ -177,4 +181,8 @@ UQM_COMPILE_TIME_ASSERT(uint64, sizeof(uint64) == 8); #define UINT16_MAX 0xffff /* 65535U */ #define UINT32_MAX 0xffffffff /* 4294967295U */ +#if defined(__cplusplus) +} +#endif + #endif /* TYPES_H_ */ diff --git a/sc2/src/uqm.c b/sc2/src/uqm.c index e0929886e..4924f931c 100644 --- a/sc2/src/uqm.c +++ b/sc2/src/uqm.c @@ -27,6 +27,7 @@ #endif #include +#include #include "libs/graphics/gfx_common.h" #include "libs/graphics/cmap.h" #include "libs/sound/sound.h" @@ -114,6 +115,7 @@ struct options_struct DECL_CONFIG_OPTION(int, soundQuality); DECL_CONFIG_OPTION(bool, use3doMusic); DECL_CONFIG_OPTION(bool, useRemixMusic); + DECL_CONFIG_OPTION(bool, useSpeech); DECL_CONFIG_OPTION(int, whichCoarseScan); DECL_CONFIG_OPTION(int, whichMenu); DECL_CONFIG_OPTION(int, whichFonts); @@ -242,11 +244,12 @@ main (int argc, char *argv[]) INIT_CONFIG_OPTION( scaler, 0 ), INIT_CONFIG_OPTION( showFps, false ), INIT_CONFIG_OPTION( keepAspectRatio, false ), - INIT_CONFIG_OPTION( gamma, 0.0f ), + INIT_CONFIG_OPTION( gamma, 1.0f ), INIT_CONFIG_OPTION( soundDriver, audio_DRIVER_MIXSDL ), INIT_CONFIG_OPTION( soundQuality, audio_QUALITY_MEDIUM ), INIT_CONFIG_OPTION( use3doMusic, true ), INIT_CONFIG_OPTION( useRemixMusic, false ), + INIT_CONFIG_OPTION( useSpeech, true ), INIT_CONFIG_OPTION( whichCoarseScan, OPT_PC ), INIT_CONFIG_OPTION( whichMenu, OPT_PC ), INIT_CONFIG_OPTION( whichFonts, OPT_PC ), @@ -277,7 +280,11 @@ main (int argc, char *argv[]) if (options.logFile != NULL) { int i; - freopen (options.logFile, "w", stderr); + if (!freopen (options.logFile, "w", stderr)) + { + printf ("Error %d calling freopen() on stderr\n", errno); + return EXIT_FAILURE; + } #ifdef UNBUFFERED_LOGFILE setbuf (stderr, NULL); #endif @@ -368,6 +375,7 @@ main (int argc, char *argv[]) // Fill in global variables: opt3doMusic = options.use3doMusic.value; optRemixMusic = options.useRemixMusic.value; + optSpeech = options.useSpeech.value; optWhichCoarseScan = options.whichCoarseScan.value; optWhichMenu = options.whichMenu.value; optWhichFonts = options.whichFonts.value; @@ -394,16 +402,14 @@ main (int argc, char *argv[]) InitTimeSystem (); InitTaskSystem (); -#ifdef NETPLAY - Network_init (); Alarm_init (); Callback_init (); + +#ifdef NETPLAY + Network_init (); NetManager_init (); #endif - GraphicsLock = CreateMutex ("Graphics", - SYNC_CLASS_TOPLEVEL | SYNC_CLASS_VIDEO); - gfxDriver = options.opengl.value ? TFB_GFXDRIVER_SDL_OPENGL : TFB_GFXDRIVER_SDL_PURE; gfxFlags = options.scaler.value; @@ -415,8 +421,11 @@ main (int argc, char *argv[]) gfxFlags |= TFB_GFXFLAGS_SHOWFPS; TFB_InitGraphics (gfxDriver, gfxFlags, options.resolution.width, options.resolution.height); - if (options.gamma.set) - TFB_SetGamma (options.gamma.value); + if (options.gamma.set && setGammaCorrection (options.gamma.value)) + optGamma = options.gamma.value; + else + optGamma = 1.0f; // failed or default + InitColorMaps (); init_communication (); /* TODO: Once threading is gone, restore initAudio here. @@ -441,7 +450,7 @@ main (int argc, char *argv[]) } else if (!GameActive) { // Throttle down the main loop when game is inactive - SleepThread (ONE_SECOND / 4); + HibernateThread (ONE_SECOND / 4); } TFB_ProcessEvents (); @@ -455,27 +464,35 @@ main (int argc, char *argv[]) * tasks might still be using it */ if (MainExited) { - // Not yet: TFB_UninitInput (); + TFB_UninitInput (); unInitAudio (); uninit_communication (); + + TFB_PurgeDanglingGraphics (); + // Purge above refers to colormaps which have to be still up UninitColorMaps (); - // Not yet: TFB_UninitGraphics (); + TFB_UninitGraphics (); #ifdef NETPLAY NetManager_uninit (); - Alarm_uninit (); Network_uninit (); #endif - // Not yet: CleanupTaskSystem (); + Callback_uninit (); + Alarm_uninit (); + + CleanupTaskSystem (); UnInitTimeSystem (); #if 0 unInitTempDir (); #endif + unprepareAllDirs (); uninitIO (); UnInitThreadSystem (); mem_uninit (); } + + HFree (options.addons); return EXIT_SUCCESS; } @@ -554,6 +571,25 @@ getVolumeConfigValue (struct float_option *option, const char *config_val) option->set = true; } +static void +getGammaConfigValue (struct float_option *option, const char *config_val) +{ + int val; + + if (option->set || !res_IsInteger (config_val)) + return; + + val = res_GetInteger (config_val); + // gamma config option is a fixed-point number + // ignore ridiculously out-of-range values + if (val < (int)(0.03 * GAMMA_SCALE) || val > (int)(9.9 * GAMMA_SCALE)) + return; + option->value = val / (float)GAMMA_SCALE; + // avoid setting gamma when not necessary + if (option->value != 1.0f) + option->set = true; +} + static bool getListConfigValue (struct int_option *option, const char *config_val, const struct option_list_value *list) @@ -602,6 +638,7 @@ getUserConfigOptions (struct options_struct *options) getBoolConfigValue (&options->scanlines, "config.scanlines"); getBoolConfigValue (&options->showFps, "config.showfps"); getBoolConfigValue (&options->keepAspectRatio, "config.keepaspectratio"); + getGammaConfigValue (&options->gamma, "config.gamma"); getBoolConfigValue (&options->subtitles, "config.subtitles"); @@ -620,19 +657,13 @@ getUserConfigOptions (struct options_struct *options) getBoolConfigValue (&options->use3doMusic, "config.3domusic"); getBoolConfigValue (&options->useRemixMusic, "config.remixmusic"); + getBoolConfigValue (&options->useSpeech, "config.speech"); getBoolConfigValueXlat (&options->meleeScale, "config.smoothmelee", TFB_SCALE_TRILINEAR, TFB_SCALE_STEP); - if (getListConfigValue (&options->soundDriver, "config.audiodriver", - audioDriverList)) - { - // XXX: I don't know if we should turn speech off in this case. - // This affects which version of the alien script will be used. - if (options->soundDriver.value == audio_DRIVER_NOSOUND) - options->speechVolumeScale.value = 0.0f; - } - + getListConfigValue (&options->soundDriver, "config.audiodriver", + audioDriverList); getListConfigValue (&options->soundQuality, "config.audioquality", audioQualityList); getBoolConfigValue (&options->stereoSFX, "config.positionalsfx"); @@ -687,7 +718,7 @@ enum #endif }; -static const char *optString = "+r:foc:b:spC:n:?hM:S:T:m:q:ug:l:i:vwxk"; +static const char *optString = "+r:foc:b:spC:n:?hM:S:T:q:ug:l:i:vwxk"; static struct option longOptions[] = { {"res", 1, NULL, 'r'}, @@ -982,16 +1013,8 @@ parseOptions (int argc, char *argv[], struct options_struct *options) } break; case SOUND_OPT: - if (setListOption (&options->soundDriver, optarg, + if (!setListOption (&options->soundDriver, optarg, audioDriverList)) - { - // XXX: I don't know if we should turn speech off in - // this case. This affects which version of the alien - // script will be used. - if (options->soundDriver.value == audio_DRIVER_NOSOUND) - options->speechVolumeScale.value = 0.0f; - } - else { InvalidArgument (optarg, "--sound"); badArg = true; @@ -1024,7 +1047,7 @@ parseOptions (int argc, char *argv[], struct options_struct *options) } break; } - case SAFEMODE_OPT: + case SAFEMODE_OPT: setBoolOption (&options->safeMode, true); break; #ifdef NETPLAY diff --git a/sc2/src/uqm/Makeinfo b/sc2/src/uqm/Makeinfo index 9e3baebd3..5f0145617 100644 --- a/sc2/src/uqm/Makeinfo +++ b/sc2/src/uqm/Makeinfo @@ -9,4 +9,15 @@ uqm_CFILES="battle.c battlecontrols.c border.c build.c cleanup.c clock.c ship.c shipstat.c shipyard.c sis.c sounds.c starbase.c starcon.c starmap.c state.c status.c tactrans.c trans.c uqmdebug.c util.c velocity.c weapon.c" +uqm_HFILES="battlecontrols.h battle.h build.h clock.h cnctdlg.h coderes.h + collide.h colors.h commanim.h commglue.h comm.h cons_res.h controls.h + corecode.h credits.h demo.h displist.h dummy.h element.h encount.h + flash.h fmv.h gameev.h gameopt.h gamestr.h gendef.h globdata.h + grpinfo.h hyper.h ifontres.h igfxres.h ikey_con.h imusicre.h init.h + intel.h ipdisp.h isndres.h istrtab.h load.h master.h menustat.h + nameref.h oscill.h pickship.h process.h races.h resinst.h respkg.h + restart.h save.h settings.h setup.h setupmenu.h shipcont.h ship.h + sis.h sounds.h starbase.h starcon.h state.h status.h tactrans.h + starmap.h + units.h uqmdebug.h util.h velocity.h weapon.h" diff --git a/sc2/src/uqm/battle.c b/sc2/src/uqm/battle.c index 7774aaab0..f33e66dbc 100644 --- a/sc2/src/uqm/battle.c +++ b/sc2/src/uqm/battle.c @@ -40,6 +40,7 @@ #include "setup.h" #include "settings.h" #include "sounds.h" +#include "libs/async.h" #include "libs/graphics/gfx_common.h" #include "libs/log.h" #include "libs/mathlib.h" @@ -235,12 +236,12 @@ BattleSong (BOOLEAN DoPlay) { if (BattleRef == 0) { - if (LOBYTE (GLOBAL (CurrentActivity)) != IN_HYPERSPACE) - BattleRef = LoadMusic (BATTLE_MUSIC); - else if (GET_GAME_STATE (ARILOU_SPACE_SIDE) <= 1) + if (inHyperSpace ()) BattleRef = LoadMusic (HYPERSPACE_MUSIC); - else + else if (inQuasiSpace ()) BattleRef = LoadMusic (QUASISPACE_MUSIC); + else + BattleRef = LoadMusic (BATTLE_MUSIC); } if (DoPlay) @@ -301,7 +302,6 @@ DoBattle (BATTLE_STATE *bs) } #endif - LockMutex (GraphicsLock); if (bs->first_time) { r.corner.x = SIS_ORG_X; @@ -324,7 +324,6 @@ DoBattle (BATTLE_STATE *bs) ScreenTransition (3, &r); } UnbatchGraphics (); - UnlockMutex (GraphicsLock); if ((!(GLOBAL (CurrentActivity) & IN_BATTLE)) || (GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD))) { @@ -334,6 +333,7 @@ DoBattle (BATTLE_STATE *bs) battle_speed = HIBYTE (nth_frame); if (battle_speed == (BYTE)~0) { // maximum speed, nothing rendered at all + Async_process (); TaskSwitch (); } else @@ -397,7 +397,6 @@ Battle (BattleFrameCallback *callback) { SIZE num_ships; - LockMutex (GraphicsLock); #if !(DEMO_MODE || CREATE_JOURNAL) if (LOBYTE (GLOBAL (CurrentActivity)) != SUPER_MELEE) { @@ -464,12 +463,9 @@ Battle (BattleFrameCallback *callback) #endif /* NETPLAY */ bs.InputFunc = DoBattle; bs.frame_cb = callback; - bs.first_time = (BOOLEAN)(LOBYTE (GLOBAL (CurrentActivity)) == - IN_HYPERSPACE); + bs.first_time = inHQSpace (); - UnlockMutex (GraphicsLock); DoInput (&bs, FALSE); - LockMutex (GraphicsLock); AbortBattle: if (LOBYTE (GLOBAL (CurrentActivity)) == SUPER_MELEE) @@ -479,12 +475,10 @@ AbortBattle: // Do not return to the main menu when a game is aborted, // (just to the supermelee menu). #ifdef NETPLAY - UnlockMutex (GraphicsLock); waitResetConnections(NetState_inSetup); // A connection may already be in inSetup (set from // GetMeleeStarship). This is not a problem, although // it will generate a warning in debug mode. - LockMutex (GraphicsLock); #endif GLOBAL (CurrentActivity) &= ~CHECK_ABORT; @@ -512,7 +506,6 @@ AbortBattle: UninitShips (); FreeBattleSong (); - UnlockMutex (GraphicsLock); return (BOOLEAN) (num_ships < 0); } diff --git a/sc2/src/uqm/battle.h b/sc2/src/uqm/battle.h index 8e93e36ca..2b1d912b8 100644 --- a/sc2/src/uqm/battle.h +++ b/sc2/src/uqm/battle.h @@ -26,9 +26,12 @@ typedef DWORD BattleFrameCounter; #include "init.h" // For NUM_SIDES +#if defined(__cplusplus) +extern "C" { +#endif + // The callback function is called on every battle frame -// with GraphicsLock held, just before the display queue -// is drawn +// just before the display queue is drawn typedef void (BattleFrameCallback) (void); typedef struct battlestate_struct { @@ -56,4 +59,8 @@ BOOLEAN Battle (BattleFrameCallback *); extern void BattleSong (BOOLEAN DoPlay); extern void FreeBattleSong (void); +#if defined(__cplusplus) +} +#endif + #endif /* UQM_BATTLE_H_ */ diff --git a/sc2/src/uqm/battlecontrols.h b/sc2/src/uqm/battlecontrols.h index f12738ce9..4d424b7f9 100644 --- a/sc2/src/uqm/battlecontrols.h +++ b/sc2/src/uqm/battlecontrols.h @@ -30,6 +30,10 @@ typedef struct NetworkInputContext NetworkInputContext; #include "races.h" #include "libs/compiler.h" +#if defined(__cplusplus) +extern "C" { +#endif + typedef BATTLE_INPUT_STATE (*BattleFrameInputFunction) ( InputContext *context, STARSHIP *StarShipPtr); typedef BOOLEAN (*SelectShipFunction) (InputContext *context, @@ -88,6 +92,8 @@ void InputContext_delete (InputContext *context); // Call InputContext->handlers->freeContext() to release an // InputContext. +#if defined(__cplusplus) +} +#endif + #endif /* UQM_BATTLECONTROLS_H_ */ - - diff --git a/sc2/src/uqm/build.c b/sc2/src/uqm/build.c index 5d327379f..070453a78 100644 --- a/sc2/src/uqm/build.c +++ b/sc2/src/uqm/build.c @@ -68,235 +68,340 @@ GetStarShipFromIndex (QUEUE *pShipQ, COUNT Index) return (hStarShip); } +HSHIPFRAG +GetEscortByStarShipIndex (COUNT index) +{ + HSHIPFRAG hStarShip; + HSHIPFRAG hNextShip; + SHIP_FRAGMENT *StarShipPtr; + + for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q)); + hStarShip; hStarShip = hNextShip) + { + StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip); + + if (StarShipPtr->index == index) + { + UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); + break; + } + + hNextShip = _GetSuccLink (StarShipPtr); + UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); + } + + return hStarShip; +} + /* - * What this function does depends on the value of the 'state' argument: - * SPHERE_TRACKING: - * The sphere of influence for the race for 'which_ship' will be shown - * on the starmap in the future. - * The value returned is 'which_ship', unless the type of ship is only - * available in SuperMelee, in which case 0 is returned. - * SPHERE_KNOWN: - * The size of the fleet of the race of 'which_ship' when the starmap was - * last checked is returned. - * ESCORT_WORTH: - * The total value of all the ships escorting the SIS is returned. - * 'which_ship' is ignored. - * ESCORTING_FLAGSHIP: - * Test if a ship of type 'which_ship' is among the escorts of the SIS - * 0 is returned if false, 1 if true. - * FEASIBILITY_STUDY: - * Test if the SIS can have an escort of type 'which_ship'. - * 0 is returned if 'which_ship' is not available. - * Otherwise, the number of ships that can be added is returned. - * CHECK_ALLIANCE: - * Test the alliance status of the race of 'which_ship'. - * Either GOOD_GUY (allied) or BAD_GUY (not allied) is returned. - * SET_ALLIED (0): - * Ally with the race of 'which_ship'. This makes their ship available - * for building in the shipyard. - * SET_NOT_ALLIED: - * End an alliance with the race of 'which_ship'. This ends the possibility - * of building their ships in the shipyard. - * REMOVE_BUILT: - * Make the already built escorts of the race of 'which_ship' disappear. - * (as for the Orz when the alliance with them ends) - * any other positive number: - * Give the player this many ships of type 'which_ship'. + * Give the player 'count' ships of the specified race, + * limited by the number of free slots. + * Returns the number of ships added. */ COUNT -ActivateStarShip (COUNT which_ship, SIZE state) +AddEscortShips (COUNT race, SIZE count) { HFLEETINFO hFleet; + BYTE which_window; + COUNT i; - hFleet = GetStarShipFromIndex (&GLOBAL (avail_race_q), which_ship); + hFleet = GetStarShipFromIndex (&GLOBAL (avail_race_q), race); if (!hFleet) return 0; - switch (state) + assert (count > 0); + + which_window = 0; + for (i = 0; i < (COUNT) count; i++) { - case SPHERE_TRACKING: - case SPHERE_KNOWN: + HSHIPFRAG hStarShip; + HSHIPFRAG hOldShip; + SHIP_FRAGMENT *StarShipPtr; + + hStarShip = CloneShipFragment (race, &GLOBAL (built_ship_q), 0); + if (!hStarShip) + break; + + RemoveQueue (&GLOBAL (built_ship_q), hStarShip); + + /* Find first available escort window */ + while ((hOldShip = GetStarShipFromIndex ( + &GLOBAL (built_ship_q), which_window++))) { - FLEET_INFO *FleetPtr; + BYTE win_loc; - FleetPtr = LockFleetInfo (&GLOBAL (avail_race_q), hFleet); - if (state == SPHERE_KNOWN) - which_ship = FleetPtr->known_strength; - else if (FleetPtr->actual_strength == 0) - { - if (FleetPtr->allied_state == DEAD_GUY) - which_ship = 0; - } - else if (FleetPtr->known_strength == 0 - && FleetPtr->actual_strength != INFINITE_RADIUS) - { - FleetPtr->known_strength = 1; - FleetPtr->known_loc = FleetPtr->loc; - } - UnlockFleetInfo (&GLOBAL (avail_race_q), hFleet); - return (which_ship); - } - case ESCORT_WORTH: - { - COUNT ShipCost[] = - { - RACE_SHIP_COST - }; - COUNT total = 0; - HSHIPFRAG hStarShip, hNextShip; - - for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q)); - hStarShip; hStarShip = hNextShip) - { - SHIP_FRAGMENT *StarShipPtr; - - StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip); - hNextShip = _GetSuccLink (StarShipPtr); - total += ShipCost[StarShipPtr->race_id]; - UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); - } - return total; - } - case ESCORTING_FLAGSHIP: - { - HSHIPFRAG hStarShip, hNextShip; - - for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q)); - hStarShip; hStarShip = hNextShip) - { - BYTE ship_type; - SHIP_FRAGMENT *StarShipPtr; - - StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip); - hNextShip = _GetSuccLink (StarShipPtr); - ship_type = StarShipPtr->race_id; - UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); - - if (ship_type == which_ship) - return 1; - } - return 0; - } - case FEASIBILITY_STUDY: - { - return (MAX_BUILT_SHIPS - CountLinks (&GLOBAL (built_ship_q))); - } - case CHECK_ALLIANCE: - { - UWORD flags; - FLEET_INFO *FleetPtr = LockFleetInfo (&GLOBAL (avail_race_q), - hFleet); - flags = FleetPtr->allied_state; - UnlockFleetInfo (&GLOBAL (avail_race_q), hFleet); - return flags; - } - case SET_ALLIED: - case SET_NOT_ALLIED: - { - FLEET_INFO *FleetPtr = LockFleetInfo (&GLOBAL (avail_race_q), - hFleet); - - if (FleetPtr->allied_state == DEAD_GUY) - { /* Strange request, silently ignore it */ - UnlockFleetInfo (&GLOBAL (avail_race_q), hFleet); + StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hOldShip); + win_loc = StarShipPtr->index; + UnlockShipFrag (&GLOBAL (built_ship_q), hOldShip); + if (which_window <= win_loc) break; - } - - if (state == SET_ALLIED) - FleetPtr->allied_state = GOOD_GUY; - else - FleetPtr->allied_state = BAD_GUY; - - UnlockFleetInfo (&GLOBAL (avail_race_q), hFleet); - break; } - case REMOVE_BUILT: - { - HSHIPFRAG hStarShip, hNextShip; - BOOLEAN ShipRemoved = FALSE; - for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q)); - hStarShip; hStarShip = hNextShip) - { - BOOLEAN RemoveShip; - SHIP_FRAGMENT *StarShipPtr; + StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip); + StarShipPtr->index = which_window - 1; + UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); - StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip); - hNextShip = _GetSuccLink (StarShipPtr); - RemoveShip = (StarShipPtr->race_id == which_ship); - UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); - - if (RemoveShip) - { - ShipRemoved = TRUE; - - RemoveQueue (&GLOBAL (built_ship_q), hStarShip); - FreeShipFrag (&GLOBAL (built_ship_q), hStarShip); - } - } - - if (ShipRemoved) - { - LockMutex (GraphicsLock); - DeltaSISGauges (UNDEFINED_DELTA, UNDEFINED_DELTA, - UNDEFINED_DELTA); - UnlockMutex (GraphicsLock); - } - break; - } - default: - { - BYTE which_window; - COUNT i; - - assert (state > 0); - /* Add ships to the escorts */ - which_window = 0; - for (i = 0; i < (COUNT)state; i++) - { - HSHIPFRAG hStarShip; - HSHIPFRAG hOldShip; - SHIP_FRAGMENT *StarShipPtr; - - hStarShip = CloneShipFragment (which_ship, - &GLOBAL (built_ship_q), 0); - if (!hStarShip) - break; - - RemoveQueue (&GLOBAL (built_ship_q), hStarShip); - - /* Find first available escort window */ - while ((hOldShip = GetStarShipFromIndex ( - &GLOBAL (built_ship_q), which_window++))) - { - BYTE win_loc; - - StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), - hOldShip); - win_loc = StarShipPtr->index; - UnlockShipFrag (&GLOBAL (built_ship_q), hOldShip); - if (which_window <= win_loc) - break; - } - - StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip); - StarShipPtr->index = which_window - 1; - UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); - - InsertQueue (&GLOBAL (built_ship_q), hStarShip, hOldShip); - } - - LockMutex (GraphicsLock); - DeltaSISGauges (UNDEFINED_DELTA, - UNDEFINED_DELTA, UNDEFINED_DELTA); - UnlockMutex (GraphicsLock); - return i; - } + InsertQueue (&GLOBAL (built_ship_q), hStarShip, hOldShip); } + DeltaSISGauges (UNDEFINED_DELTA, UNDEFINED_DELTA, UNDEFINED_DELTA); + return i; +} + +/* + * Returns the total value of all the ships escorting the SIS. + */ +COUNT +CalculateEscortsWorth (void) +{ + COUNT ShipCost[] = + { + RACE_SHIP_COST + }; + COUNT total = 0; + HSHIPFRAG hStarShip, hNextShip; + + for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q)); + hStarShip; hStarShip = hNextShip) + { + SHIP_FRAGMENT *StarShipPtr; + + StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip); + hNextShip = _GetSuccLink (StarShipPtr); + total += ShipCost[StarShipPtr->race_id]; + UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); + } + return total; +} + +#if 0 +/* + * Returns the size of the fleet of the specified race when the starmap was + * last checked. If the race has no SoI, 0 is returned. + */ +COUNT +GetRaceKnownSize (COUNT race) +{ + HFLEETINFO hFleet; + FLEET_INFO *FleetPtr; + COUNT result; + + hFleet = GetStarShipFromIndex (&GLOBAL (avail_race_q), race); + if (!hFleet) + return 0; + + FleetPtr = LockFleetInfo (&GLOBAL (avail_race_q), hFleet); + + result = FleetPtr->known_strength; + + UnlockFleetInfo (&GLOBAL (avail_race_q), hFleet); + return result; +} +#endif + +/* + * Start or end an alliance with the specified race. + * Being in an alliance with a race makes their ships available for building + * in the shipyard. + * flag == TRUE: start an alliance + * flag == TRUE: end an alliance + */ +COUNT +SetRaceAllied (COUNT race, BOOLEAN flag) { + HFLEETINFO hFleet; + FLEET_INFO *FleetPtr; + + hFleet = GetStarShipFromIndex (&GLOBAL (avail_race_q), race); + if (!hFleet) + return 0; + + FleetPtr = LockFleetInfo (&GLOBAL (avail_race_q), hFleet); + + if (FleetPtr->allied_state == DEAD_GUY) + { + /* Strange request, silently ignore it */ + } + else + { + FleetPtr->allied_state = (flag ? GOOD_GUY : BAD_GUY); + } + + UnlockFleetInfo (&GLOBAL (avail_race_q), hFleet); return 1; } +/* + * Make the sphere of influence for the specified race shown on the starmap + * in the future. + * The value returned is 'race', unless the type of ship is only available + * in SuperMelee, in which case 0 is returned. + */ +COUNT +StartSphereTracking (COUNT race) +{ + HFLEETINFO hFleet; + FLEET_INFO *FleetPtr; + + hFleet = GetStarShipFromIndex (&GLOBAL (avail_race_q), race); + if (!hFleet) + return 0; + + FleetPtr = LockFleetInfo (&GLOBAL (avail_race_q), hFleet); + + if (FleetPtr->actual_strength == 0) + { + if (FleetPtr->allied_state == DEAD_GUY) + { + // Race is extinct. + UnlockFleetInfo (&GLOBAL (avail_race_q), hFleet); + return 0; + } + } + else if (FleetPtr->known_strength == 0 + && FleetPtr->actual_strength != INFINITE_RADIUS) + { + FleetPtr->known_strength = 1; + FleetPtr->known_loc = FleetPtr->loc; + } + + UnlockFleetInfo (&GLOBAL (avail_race_q), hFleet); + return race; +} + +/* + * Returns the number of ships of the specified race among the + * escort ships. + */ +COUNT +CountEscortShips (COUNT race) +{ + HFLEETINFO hFleet; + HSHIPFRAG hStarShip, hNextShip; + COUNT result = 0; + + hFleet = GetStarShipFromIndex (&GLOBAL (avail_race_q), race); + if (!hFleet) + return 0; + + for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q)); hStarShip; + hStarShip = hNextShip) + { + BYTE ship_type; + SHIP_FRAGMENT *StarShipPtr; + + StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip); + hNextShip = _GetSuccLink (StarShipPtr); + ship_type = StarShipPtr->race_id; + UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); + + if (ship_type == race) + result++; + } + return result; +} + +/* + * Returns true if and only if a ship of the specified race is among the + * escort ships. + */ +BOOLEAN +HaveEscortShip (COUNT race) +{ + return (CountEscortShips (race) > 0); +} + +/* + * Test if the SIS can have an escort of the specified race. + * Returns 0 if 'race' is not available. + * Otherwise, returns the number of ships that can be added. + */ +COUNT +EscortFeasibilityStudy (COUNT race) +{ + HFLEETINFO hFleet; + + hFleet = GetStarShipFromIndex (&GLOBAL (avail_race_q), race); + if (!hFleet) + return 0; + + return (MAX_BUILT_SHIPS - CountLinks (&GLOBAL (built_ship_q))); +} + +/* + * Test the alliance status of the specified race. + * Either DEAD_GUY (extinct), GOOD_GUY (allied), or BAD_GUY (not allied) is + * returned. + */ +COUNT +CheckAlliance (COUNT race) +{ + HFLEETINFO hFleet; + UWORD flags; + FLEET_INFO *FleetPtr; + + hFleet = GetStarShipFromIndex (&GLOBAL (avail_race_q), race); + if (!hFleet) + return 0; + + FleetPtr = LockFleetInfo (&GLOBAL (avail_race_q), hFleet); + flags = FleetPtr->allied_state; + UnlockFleetInfo (&GLOBAL (avail_race_q), hFleet); + + return flags; +} + +/* + * Remove a number of escort ships of the specified race (if present). + * Returns the number of escort ships removed. + */ +COUNT +RemoveSomeEscortShips (COUNT race, COUNT count) +{ + HSHIPFRAG hStarShip; + HSHIPFRAG hNextShip; + + if (count == 0) + return 0; + + for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q)); hStarShip; + hStarShip = hNextShip) + { + BOOLEAN RemoveShip; + SHIP_FRAGMENT *StarShipPtr; + + StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip); + hNextShip = _GetSuccLink (StarShipPtr); + RemoveShip = (StarShipPtr->race_id == race); + UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); + + if (RemoveShip) + { + RemoveQueue (&GLOBAL (built_ship_q), hStarShip); + FreeShipFrag (&GLOBAL (built_ship_q), hStarShip); + count--; + if (count == 0) + break; + } + } + + if (count > 0) + { + // Update the display. + DeltaSISGauges (UNDEFINED_DELTA, UNDEFINED_DELTA, UNDEFINED_DELTA); + } + + return count; +} + +/* + * Remove all escort ships of the specified race. + */ +void +RemoveEscortShips (COUNT race) +{ + RemoveSomeEscortShips (race, (COUNT) -1); +} + COUNT GetIndexFromStarShip (QUEUE *pShipQ, HLINK hStarShip) { diff --git a/sc2/src/uqm/build.h b/sc2/src/uqm/build.h index 55e0f2055..4bf21cccc 100644 --- a/sc2/src/uqm/build.h +++ b/sc2/src/uqm/build.h @@ -23,6 +23,10 @@ #include "displist.h" #include "libs/compiler.h" +#if defined(__cplusplus) +extern "C" { +#endif + #define NAME_OFFSET 5 #define NUM_CAPTAINS_NAMES 16 @@ -34,31 +38,32 @@ extern HLINK Build (QUEUE *pQueue, SPECIES_ID SpeciesID); extern HSHIPFRAG CloneShipFragment (COUNT shipIndex, QUEUE *pDstQueue, COUNT crew_level); extern HLINK GetStarShipFromIndex (QUEUE *pShipQ, COUNT Index); +extern HSHIPFRAG GetEscortByStarShipIndex (COUNT index); extern BYTE NameCaptain (QUEUE *pQueue, SPECIES_ID SpeciesID); -/* Possible values for the 'state' argument of - * COUNT ActivateStarShip (COUNT which_ship, SIZE state) - * See that function for more information. - */ -#define SET_ALLIED 0 -#define SET_NOT_ALLIED -1 -#define CHECK_ALLIANCE -2 -#define REMOVE_BUILT -3 -#define ESCORT_WORTH -4 -#define SPHERE_KNOWN -5 -#define SPHERE_TRACKING -6 -#define ESCORTING_FLAGSHIP -7 -#define FEASIBILITY_STUDY -8 - /* Check for how many escort ships there's still space */ - extern COUNT ActivateStarShip (COUNT which_ship, SIZE state); extern COUNT GetIndexFromStarShip (QUEUE *pShipQ, HLINK hStarShip); extern int SetEscortCrewComplement (COUNT which_ship, COUNT crew_level, BYTE captain); +extern COUNT AddEscortShips (COUNT race, SIZE count); +extern COUNT CalculateEscortsWorth (void); +//extern COUNT GetRaceKnownSize (COUNT race); +extern COUNT SetRaceAllied (COUNT race, BOOLEAN flag); +extern COUNT StartSphereTracking (COUNT race); +extern COUNT CountEscortShips (COUNT race); +extern BOOLEAN HaveEscortShip (COUNT race); +extern COUNT EscortFeasibilityStudy (COUNT race); +extern COUNT CheckAlliance (COUNT race); +extern COUNT RemoveSomeEscortShips (COUNT race, COUNT count); +extern void RemoveEscortShips (COUNT race); + extern RACE_DESC *load_ship (SPECIES_ID SpeciesID, BOOLEAN LoadBattleData); extern void free_ship (RACE_DESC *RaceDescPtr, BOOLEAN FreeIconData, BOOLEAN FreeBattleData); -#endif /* UQM_BUILD_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_BUILD_H_ */ diff --git a/sc2/src/uqm/cleanup.c b/sc2/src/uqm/cleanup.c index 1e09da618..a6e437728 100644 --- a/sc2/src/uqm/cleanup.c +++ b/sc2/src/uqm/cleanup.c @@ -25,14 +25,11 @@ #include "planets/lander.h" #include "starcon.h" #include "setup.h" +#include "planets/solarsys.h" #include "sounds.h" #include "libs/sndlib.h" #include "libs/vidlib.h" -// XXX: we do not current have a header for this prototype to live in -// should be something like solarsys.h -extern void FreeIPData (void); - void FreeKernel (void) @@ -42,7 +39,9 @@ FreeKernel (void) UninitResourceSystem (); DestroyDrawable (ReleaseDrawable (Screen)); + Screen = 0; DestroyContext (ScreenContext); + ScreenContext = 0; UninitVideoPlayer (); UninitSound (); diff --git a/sc2/src/uqm/clock.c b/sc2/src/uqm/clock.c index c45deffb8..6660226a4 100644 --- a/sc2/src/uqm/clock.c +++ b/sc2/src/uqm/clock.c @@ -157,22 +157,16 @@ UnlockGameClock (void) BOOLEAN GameClockRunning (void) { - SIZE prev_tick, cur_tick; + SIZE day_in_ticks; if (!clock_mutex) return FALSE; LockMutex (clock_mutex); - prev_tick = GLOBAL (GameClock.tick_count); + day_in_ticks = GLOBAL (GameClock.day_in_ticks); UnlockMutex (clock_mutex); - SleepThread (ONE_SECOND / 5); - - LockMutex (clock_mutex); - cur_tick = GLOBAL (GameClock.tick_count); - UnlockMutex (clock_mutex); - - return cur_tick != prev_tick; + return day_in_ticks != 0; } void @@ -282,7 +276,6 @@ AddEvent (EVENT_TYPE type, COUNT month_index, COUNT day_index, COUNT return (0); } -// This function must be called with GraphicsLock held. void GameClockTick (void) { @@ -305,7 +298,6 @@ GameClockTick (void) UnlockMutex (clock_mutex); } -// This function must be called with GraphicsLock held. void MoveGameClockDays (COUNT days) { diff --git a/sc2/src/uqm/clock.h b/sc2/src/uqm/clock.h index b16898f1d..5bd428c1b 100644 --- a/sc2/src/uqm/clock.h +++ b/sc2/src/uqm/clock.h @@ -22,6 +22,10 @@ #include "libs/tasklib.h" #include "displist.h" +#if defined(__cplusplus) +extern "C" { +#endif + #define START_YEAR 2155 @@ -100,5 +104,8 @@ extern void UnlockGameClock (void); // but not much else extern BOOLEAN GameClockRunning (void); -#endif /* UQM_CLOCK_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_CLOCK_H_ */ diff --git a/sc2/src/uqm/cnctdlg.c b/sc2/src/uqm/cnctdlg.c index 5ff1cc3e9..47824eb9e 100644 --- a/sc2/src/uqm/cnctdlg.c +++ b/sc2/src/uqm/cnctdlg.c @@ -531,14 +531,12 @@ DrawConnectDialog (void) r.corner.x = (SCREEN_WIDTH - r.extent.width) >> 1; r.corner.y = (SCREEN_HEIGHT - r.extent.height) >> 1; - LockMutex (GraphicsLock); DrawShadowedBox (&r, SHADOWBOX_BACKGROUND_COLOR, SHADOWBOX_DARK_COLOR, SHADOWBOX_MEDIUM_COLOR); menu.draw ((WIDGET *)&menu, r.corner.x + 10, r.corner.y + 10); - UnlockMutex (GraphicsLock); } static BOOLEAN diff --git a/sc2/src/uqm/cnctdlg.h b/sc2/src/uqm/cnctdlg.h index acfc8c605..019535545 100644 --- a/sc2/src/uqm/cnctdlg.h +++ b/sc2/src/uqm/cnctdlg.h @@ -21,11 +21,20 @@ #ifndef UQM_CNCTDLG_H_ #define UQM_CNCTDLG_H_ +#ifdef NETPLAY + #include "libs/compiler.h" +#if defined(__cplusplus) +extern "C" { +#endif + BOOLEAN MeleeConnectDialog (int side); +#if defined(__cplusplus) +} +#endif + #endif /* UQM_CNCTDLG_H_ */ #endif /* NETPLAY */ - diff --git a/sc2/src/uqm/coderes.h b/sc2/src/uqm/coderes.h index 63e7836b7..add0970e4 100644 --- a/sc2/src/uqm/coderes.h +++ b/sc2/src/uqm/coderes.h @@ -21,6 +21,10 @@ #include "libs/reslib.h" +#if defined(__cplusplus) +extern "C" { +#endif + extern BOOLEAN InstallCodeResType (void); extern void *LoadCodeResInstance (RESOURCE res); extern void *CaptureCodeRes (void *hCode, void *pData, void **ppLocData); @@ -32,5 +36,8 @@ typedef struct UWORD size; } CODE_REF; -#endif /* UQM_CODERES_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_CODERES_H_ */ diff --git a/sc2/src/uqm/collide.h b/sc2/src/uqm/collide.h index dfa9c702b..50cc5f105 100644 --- a/sc2/src/uqm/collide.h +++ b/sc2/src/uqm/collide.h @@ -21,6 +21,10 @@ #include "element.h" +#if defined(__cplusplus) +extern "C" { +#endif + #define COLLISION_TURN_WAIT 1 #define COLLISION_THRUST_WAIT 3 @@ -59,5 +63,8 @@ extern void collide (ELEMENT *ElementPtr0, ELEMENT *ElementPtr1); -#endif /* UQM_COLLIDE_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_COLLIDE_H_ */ diff --git a/sc2/src/uqm/comm.c b/sc2/src/uqm/comm.c index 13a5a7e1b..55c07df11 100644 --- a/sc2/src/uqm/comm.c +++ b/sc2/src/uqm/comm.c @@ -27,6 +27,7 @@ #include "sis.h" #include "units.h" #include "encount.h" +#include "starmap.h" #include "endian_uqm.h" #include "gamestr.h" #include "options.h" @@ -46,8 +47,7 @@ #include #define MAX_RESPONSES 8 -#define BACKGROUND_VOL \ - (speechVolumeScale == 0.0f ? NORMAL_VOLUME : (NORMAL_VOLUME >> 1)) +#define BACKGROUND_VOL (usingSpeech ? (NORMAL_VOLUME / 2) : NORMAL_VOLUME) #define FOREGROUND_VOL NORMAL_VOLUME // Oscilloscope frame rate @@ -632,13 +632,11 @@ DoTalkSegue (TALKING_STATE *pTS) CheckSubtitles (); } - LockMutex (GraphicsLock); // XXX: When seeking, all animations (talking and ambient) stop // progressing. This is an original 3DO behavior, and I see no // reason why the animations cannot continue while seeking. UpdateAnimations (pTS->seeking); UpdateSpeechGraphics (); - UnlockMutex (GraphicsLock); curTrack = PlayingTrack (); pTS->ended = !pTS->seeking && !curTrack; @@ -653,9 +651,7 @@ DoTalkSegue (TALKING_STATE *pTS) static void runCommAnimFrame (void) { - LockMutex (GraphicsLock); UpdateCommGraphics (); - UnlockMutex (GraphicsLock); SleepThread (COMM_ANIM_RATE); } @@ -764,13 +760,11 @@ AlienTalkSegue (COUNT wait_track) if (!pCurInputState->Initialized) { InitSpeechGraphics (); - LockMutex (GraphicsLock); SetColorMap (GetColorMapAddress (CommData.AlienColorMap)); SetContext (AnimContext); DrawAlienFrame (NULL, 0, TRUE); UpdateSpeechGraphics (); CommIntroTransition (); - UnlockMutex (GraphicsLock); pCurInputState->Initialized = TRUE; @@ -845,7 +839,6 @@ DoConvSummary (SUMMARY_STATE *pSS) r.extent.width = SIS_SCREEN_WIDTH; r.extent.height = SIS_SCREEN_HEIGHT - SLIDER_Y - SLIDER_HEIGHT + 2; - LockMutex (GraphicsLock); SetContext (AnimContext); SetContextForeGroundColor (COMM_HISTORY_BACKGROUND_COLOR); DrawFilledRectangle (&r); @@ -914,7 +907,6 @@ DoConvSummary (SUMMARY_STATE *pSS) font_DrawText (&mt); } - UnlockMutex (GraphicsLock); pSS->PrintNext = FALSE; } @@ -934,9 +926,7 @@ SelectResponse (ENCOUNTER_STATE *pES) &pES->response_list[pES->cur_response].response_text; utf8StringCopy (pES->phrase_buf, sizeof pES->phrase_buf, response_text->pStr); - LockMutex (GraphicsLock); FeedbackPlayerPhrase (pES->phrase_buf); - UnlockMutex (GraphicsLock); StopTrack (); ClearSubtitles (); SetSliderImage (SetAbsFrameIndex (ActivityFrame, 2)); @@ -955,29 +945,23 @@ SelectConversationSummary (ENCOUNTER_STATE *pES) { SUMMARY_STATE SummaryState; - LockMutex (GraphicsLock); if (pES) FeedbackPlayerPhrase (pES->phrase_buf); - UnlockMutex (GraphicsLock); SummaryState.Initialized = FALSE; DoConvSummary (&SummaryState); - LockMutex (GraphicsLock); if (pES) RefreshResponses (pES); clear_subtitles = TRUE; - UnlockMutex (GraphicsLock); } static void SelectReplay (ENCOUNTER_STATE *pES) { FadeMusic (BACKGROUND_VOL, ONE_SECOND); - LockMutex (GraphicsLock); if (pES) FeedbackPlayerPhrase (pES->phrase_buf); - UnlockMutex (GraphicsLock); TalkSegue (0); } @@ -990,9 +974,7 @@ PlayerResponseInput (ENCOUNTER_STATE *pES) if (pES->top_response == (BYTE)~0) { pES->top_response = 0; - LockMutex (GraphicsLock); RefreshResponses (pES); - UnlockMutex (GraphicsLock); } if (PulsedInputState.menu[KEY_MENU_SELECT]) @@ -1013,9 +995,7 @@ PlayerResponseInput (ENCOUNTER_STATE *pES) if (!(GLOBAL (CurrentActivity) & CHECK_ABORT)) { - LockMutex (GraphicsLock); RefreshResponses (pES); - UnlockMutex (GraphicsLock); FadeMusic (FOREGROUND_VOL, ONE_SECOND); } } @@ -1029,7 +1009,6 @@ PlayerResponseInput (ENCOUNTER_STATE *pES) { COORD y; - LockMutex (GraphicsLock); BatchGraphics (); add_text (-2, &pES->response_list[pES->cur_response].response_text); @@ -1049,12 +1028,9 @@ PlayerResponseInput (ENCOUNTER_STATE *pES) RefreshResponses (pES); } UnbatchGraphics (); - UnlockMutex (GraphicsLock); } - LockMutex (GraphicsLock); UpdateCommGraphics (); - UnlockMutex (GraphicsLock); SleepThreadUntil (pES->NextTime); pES->NextTime = GetTimeCounter () + COMM_ANIM_RATE; @@ -1094,9 +1070,7 @@ DoLastReplay (LAST_REPLAY_STATE *pLRS) pLRS->TimeOut = FadeMusic (0, ONE_SECOND * 2) + ONE_SECOND / 60; } - LockMutex (GraphicsLock); UpdateCommGraphics (); - UnlockMutex (GraphicsLock); SleepThreadUntil (pLRS->NextTime); pLRS->NextTime = GetTimeCounter () + COMM_ANIM_RATE; @@ -1135,11 +1109,9 @@ DoCommunication (ENCOUNTER_STATE *pES) return TRUE; } - LockMutex (GraphicsLock); SetContext (SpaceContext); DestroyContext (AnimContext); AnimContext = NULL; - UnlockMutex (GraphicsLock); FlushColorXForms (); ClearSubtitles (); @@ -1228,7 +1200,6 @@ HailAlien (void) SubtitleText.baseline = CommData.AlienTextBaseline; SubtitleText.align = CommData.AlienTextAlign; - LockMutex (GraphicsLock); // init subtitle cache context TextCacheContext = CreateContext ("TextCacheContext"); @@ -1293,7 +1264,6 @@ HailAlien (void) DrawSISComWindow (); } - UnlockMutex (GraphicsLock); LastActivity |= CHECK_LOAD; /* prevent spurious input */ (*CommData.init_encounter_func) (); @@ -1302,10 +1272,8 @@ HailAlien (void) (*CommData.post_encounter_func) (); (*CommData.uninit_encounter_func) (); - LockMutex (GraphicsLock); SetContext (SpaceContext); SetContextFont (OldFont); - UnlockMutex (GraphicsLock); DestroyStringTable (ReleaseStringTable (CommData.ConversationPhrases)); DestroyMusic (CommData.AlienSong); @@ -1343,7 +1311,6 @@ InitCommunication (CONVERSATION which_comm) return 0; #endif - LockMutex (GraphicsLock); if (LastActivity & CHECK_LOAD) { @@ -1360,7 +1327,7 @@ InitCommunication (CONVERSATION which_comm) RepairSISBorder (); } DrawSISMessage (NULL); - if (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE) + if (inHQSpace ()) DrawHyperCoords (GLOBAL (ShipStamp.origin)); else if (GLOBAL (ip_planet) == 0) DrawHyperCoords (CurStarDescPtr->star_pt); @@ -1369,7 +1336,6 @@ InitCommunication (CONVERSATION which_comm) } } - UnlockMutex (GraphicsLock); if (which_comm == URQUAN_DRONE_CONVERSATION) { @@ -1394,7 +1360,7 @@ InitCommunication (CONVERSATION which_comm) status = HUMAN_SHIP; } } - ActivateStarShip (status, SPHERE_TRACKING); + StartSphereTracking (status); if (which_comm == ORZ_CONVERSATION || (which_comm == TALKING_PET_CONVERSATION @@ -1402,7 +1368,7 @@ InitCommunication (CONVERSATION which_comm) || LOBYTE (GLOBAL (CurrentActivity)) == IN_LAST_BATTLE)) || (which_comm != CHMMR_CONVERSATION && which_comm != SYREEN_CONVERSATION - ))//&& ActivateStarShip (status, CHECK_ALLIANCE) == BAD_GUY)) + ))//&& CheckAlliance (status) == BAD_GUY)) BuildBattle (NPC_PLAYER_NUM); } @@ -1526,7 +1492,7 @@ RaceCommunication (void) SET_GAME_STATE (ESCAPE_COUNTER, ec); return; } - else if (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE) + else if (inHQSpace ()) { ReinitQueue (&GLOBAL (npc_built_ship_q)); if (GET_GAME_STATE (ARILOU_SPACE_SIDE) >= 2) @@ -1537,7 +1503,6 @@ RaceCommunication (void) else { /* Encounter with a black globe in HS, prepare enemy ship list */ - COUNT NumShips; ENCOUNTER *EncounterPtr; // The encounter globe that the flagship collided with is moved @@ -1545,10 +1510,9 @@ RaceCommunication (void) hEncounter = GetHeadEncounter (); LockEncounter (hEncounter, &EncounterPtr); - NumShips = LONIBBLE (EncounterPtr->SD.Index); - for (i = 0; i < NumShips; ++i) + for (i = 0; i < EncounterPtr->num_ships; ++i) { - CloneShipFragment (EncounterPtr->SD.Type, + CloneShipFragment (EncounterPtr->race_id, &GLOBAL (npc_built_ship_q), EncounterPtr->ShipList[i].crew_level); } @@ -1589,12 +1553,11 @@ RaceCommunication (void) LockEncounter (hEncounter, &EncounterPtr); - NumShips = (BYTE)CountLinks (&GLOBAL (npc_built_ship_q)); - EncounterPtr->SD.Index = MAKE_BYTE (NumShips, - HINIBBLE (EncounterPtr->SD.Index)); - EncounterPtr->SD.Index |= ENCOUNTER_REFORMING; + NumShips = CountLinks (&GLOBAL (npc_built_ship_q)); + EncounterPtr->num_ships = NumShips; + EncounterPtr->flags |= ENCOUNTER_REFORMING; if (status == 0) - EncounterPtr->SD.Index |= ONE_SHOT_ENCOUNTER; + EncounterPtr->flags |= ONE_SHOT_ENCOUNTER; for (i = 0; i < NumShips; ++i) { diff --git a/sc2/src/uqm/comm.h b/sc2/src/uqm/comm.h index feabde905..e8f01822e 100644 --- a/sc2/src/uqm/comm.h +++ b/sc2/src/uqm/comm.h @@ -31,6 +31,10 @@ #include "commanim.h" +#if defined(__cplusplus) +extern "C" { +#endif + extern LOCDATA CommData; static inline BOOLEAN @@ -131,6 +135,8 @@ extern void SetCommIntroMode (CommIntroMode, TimeCount howLong); extern void EnableTalkingAnim (BOOLEAN enable); +#if defined(__cplusplus) +} +#endif + #endif /* UQM_COMM_H_ */ - - diff --git a/sc2/src/uqm/comm/Makeinfo b/sc2/src/uqm/comm/Makeinfo index 7686c5ff7..3f87e5bd0 100644 --- a/sc2/src/uqm/comm/Makeinfo +++ b/sc2/src/uqm/comm/Makeinfo @@ -1,3 +1,4 @@ uqm_SUBDIRS="arilou blackur chmmr comandr druuge ilwrath melnorm mycon orz pkunk rebel shofixt slyhome slyland spahome spathi starbas supox syreen talkpet thradd umgah urquan utwig vux yehat zoqfot" +uqm_HFILES="commall.h" diff --git a/sc2/src/uqm/comm/arilou/Makeinfo b/sc2/src/uqm/comm/arilou/Makeinfo index 29ea7522f..27cb0537d 100644 --- a/sc2/src/uqm/comm/arilou/Makeinfo +++ b/sc2/src/uqm/comm/arilou/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="arilouc.c" +uqm_HFILES="resinst.h strings.h" diff --git a/sc2/src/uqm/comm/arilou/arilouc.c b/sc2/src/uqm/comm/arilou/arilouc.c index 0bb043429..13f2d728a 100644 --- a/sc2/src/uqm/comm/arilou/arilouc.c +++ b/sc2/src/uqm/comm/arilou/arilouc.c @@ -230,7 +230,7 @@ static LOCDATA arilou_desc = static void ExitConversation (RESPONSE_REF R) { - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); if (PLAYER_SAID (R, bye_angry_space)) NPCPhrase (GOODBYE_ANGRY_SPACE); @@ -644,7 +644,7 @@ Intro (void) { NPCPhrase (OUT_TAKES); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); return; } else if (!GET_GAME_STATE (MET_ARILOU)) @@ -691,7 +691,7 @@ Intro (void) } SET_GAME_STATE (ARILOU_VISITS, NumVisits); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else if (Manner == 1) { @@ -801,7 +801,7 @@ post_arilou_enc (void) { BYTE Manner; - if (GET_GAME_STATE (BATTLE_SEGUE) == 1 + if (getSegue () == Segue_hostile && (Manner = GET_GAME_STATE (ARILOU_MANNER)) != 2) { SET_GAME_STATE (ARILOU_MANNER, 1); @@ -843,11 +843,11 @@ init_arilou_comm (void) || GET_GAME_STATE (ARILOU_MANNER) == 3 || LOBYTE (GLOBAL (CurrentActivity)) == WON_LAST_BATTLE) { - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else { - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } retval = &arilou_desc; diff --git a/sc2/src/uqm/comm/arilou/resinst.h b/sc2/src/uqm/comm/arilou/resinst.h index ac251f0e2..991ea377a 100644 --- a/sc2/src/uqm/comm/arilou/resinst.h +++ b/sc2/src/uqm/comm/arilou/resinst.h @@ -1,5 +1,9 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define ARILOU_COLOR_MAP "comm.arilou.colortable" -#define ARILOU_PMAP_ANIM "comm.arilou.graphics" -#define ARILOU_FONT "comm.arilou.font" #define ARILOU_CONVERSATION_PHRASES "comm.arilou.dialogue" +#define ARILOU_FONT "comm.arilou.font" #define ARILOU_MUSIC "comm.arilou.music" +#define ARILOU_PMAP_ANIM "comm.arilou.graphics" diff --git a/sc2/src/uqm/comm/blackur/Makeinfo b/sc2/src/uqm/comm/blackur/Makeinfo index 9e526508c..1927a56e2 100644 --- a/sc2/src/uqm/comm/blackur/Makeinfo +++ b/sc2/src/uqm/comm/blackur/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="blackurc.c" +uqm_HFILES="resinst.h strings.h" diff --git a/sc2/src/uqm/comm/blackur/blackurc.c b/sc2/src/uqm/comm/blackur/blackurc.c index 7070a9365..1b47a7b64 100644 --- a/sc2/src/uqm/comm/blackur/blackurc.c +++ b/sc2/src/uqm/comm/blackur/blackurc.c @@ -134,7 +134,7 @@ CombatIsInevitable (RESPONSE_REF R) { BYTE NumVisits; - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); if (PLAYER_SAID (R, bye)) { @@ -447,7 +447,7 @@ Intro (void) { NPCPhrase (OUT_TAKES); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); return; } @@ -455,7 +455,7 @@ Intro (void) { NPCPhrase (GAME_OVER_DUDE); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); return; } @@ -474,7 +474,7 @@ Intro (void) NPCPhrase (HELLO_SAMATRA); SET_GAME_STATE (AWARE_OF_SAMATRA, 1); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else { @@ -555,11 +555,11 @@ init_blackurq_comm (void) if (!GET_GAME_STATE (KOHR_AH_KILLED_ALL) && LOBYTE (GLOBAL (CurrentActivity)) != WON_LAST_BATTLE) { - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else { - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } retval = &blackurq_desc; diff --git a/sc2/src/uqm/comm/blackur/resinst.h b/sc2/src/uqm/comm/blackur/resinst.h index d3465b6eb..d0c23132b 100644 --- a/sc2/src/uqm/comm/blackur/resinst.h +++ b/sc2/src/uqm/comm/blackur/resinst.h @@ -1,5 +1,9 @@ -#define BLACKURQ_PMAP_ANIM "comm.kohrah.graphics" -#define BLACKURQ_FONT "comm.kohrah.font" +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define BLACKURQ_COLOR_MAP "comm.kohrah.colortable" #define BLACKURQ_CONVERSATION_PHRASES "comm.kohrah.dialogue" +#define BLACKURQ_FONT "comm.kohrah.font" #define BLACKURQ_MUSIC "comm.kohrah.music" +#define BLACKURQ_PMAP_ANIM "comm.kohrah.graphics" diff --git a/sc2/src/uqm/comm/chmmr/Makeinfo b/sc2/src/uqm/comm/chmmr/Makeinfo index e42794f7e..f01e2b8dc 100644 --- a/sc2/src/uqm/comm/chmmr/Makeinfo +++ b/sc2/src/uqm/comm/chmmr/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="chmmrc.c" +uqm_HFILES="resinst.h strings.h" diff --git a/sc2/src/uqm/comm/chmmr/chmmrc.c b/sc2/src/uqm/comm/chmmr/chmmrc.c index 80b5c61de..1b35fc0d3 100644 --- a/sc2/src/uqm/comm/chmmr/chmmrc.c +++ b/sc2/src/uqm/comm/chmmr/chmmrc.c @@ -120,7 +120,7 @@ static LOCDATA chmmr_desc = static void ExitConversation (RESPONSE_REF R) { - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); if (PLAYER_SAID (R, bye)) NPCPhrase (GOODBYE); @@ -134,7 +134,7 @@ ExitConversation (RESPONSE_REF R) NPCPhrase (TAKE_2_WEEKS); - ActivateStarShip (CHMMR_SHIP, SET_ALLIED); + SetRaceAllied (CHMMR_SHIP, TRUE); SET_GAME_STATE (CHMMR_HOME_VISITS, 0); SET_GAME_STATE (CHMMR_STACK, 0); @@ -248,7 +248,7 @@ NotReady (RESPONSE_REF R) { NPCPhrase (USE_OUR_SHIPS_BEFORE); - ActivateStarShip (CHMMR_SHIP, SET_ALLIED); + SetRaceAllied (CHMMR_SHIP, TRUE); } else if (PLAYER_SAID (R, where_weapon)) { @@ -263,7 +263,7 @@ NotReady (RESPONSE_REF R) DISABLE_PHRASE (where_distraction); } - if (ActivateStarShip (CHMMR_SHIP, CHECK_ALLIANCE) != GOOD_GUY) + if (CheckAlliance (CHMMR_SHIP) != GOOD_GUY) Response (tech_help, NotReady); else if (PHRASE_ENABLED (further_assistance)) Response (further_assistance, NotReady); @@ -301,7 +301,7 @@ ImproveBomb (RESPONSE_REF R) { NPCPhrase (USE_OUR_SHIPS_AFTER); - ActivateStarShip (CHMMR_SHIP, SET_ALLIED); + SetRaceAllied (CHMMR_SHIP, TRUE); } if (PHRASE_ENABLED (what_now)) @@ -310,7 +310,7 @@ ImproveBomb (RESPONSE_REF R) Response (wont_hurt_my_ship, ImproveBomb); else if (PHRASE_ENABLED (bummer_about_my_ship)) Response (bummer_about_my_ship, ImproveBomb); - if (ActivateStarShip (CHMMR_SHIP, CHECK_ALLIANCE) != GOOD_GUY) + if (CheckAlliance (CHMMR_SHIP) != GOOD_GUY) Response (other_assistance, ImproveBomb); Response (proceed, ExitConversation); } @@ -634,7 +634,7 @@ init_chmmr_comm (void) chmmr_desc.AlienTextBaseline.y = 0; chmmr_desc.AlienTextWidth = SIS_TEXT_WIDTH - 16; - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); retval = &chmmr_desc; return (retval); diff --git a/sc2/src/uqm/comm/chmmr/resinst.h b/sc2/src/uqm/comm/chmmr/resinst.h index 166bb3bd7..3365c9790 100644 --- a/sc2/src/uqm/comm/chmmr/resinst.h +++ b/sc2/src/uqm/comm/chmmr/resinst.h @@ -1,5 +1,9 @@ -#define CHMMR_PMAP_ANIM "comm.chmmr.graphics" -#define CHMMR_FONT "comm.chmmr.font" +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define CHMMR_COLOR_MAP "comm.chmmr.colortable" #define CHMMR_CONVERSATION_PHRASES "comm.chmmr.dialogue" +#define CHMMR_FONT "comm.chmmr.font" #define CHMMR_MUSIC "comm.chmmr.music" +#define CHMMR_PMAP_ANIM "comm.chmmr.graphics" diff --git a/sc2/src/uqm/comm/comandr/Makeinfo b/sc2/src/uqm/comm/comandr/Makeinfo index c7efd1e77..36b63edac 100644 --- a/sc2/src/uqm/comm/comandr/Makeinfo +++ b/sc2/src/uqm/comm/comandr/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="comandr.c" +uqm_HFILES="resinst.h strings.h" diff --git a/sc2/src/uqm/comm/comandr/comandr.c b/sc2/src/uqm/comm/comandr/comandr.c index 39c14f95c..57df233be 100644 --- a/sc2/src/uqm/comm/comandr/comandr.c +++ b/sc2/src/uqm/comm/comandr/comandr.c @@ -227,10 +227,8 @@ NoRadioactives (RESPONSE_REF R) { NPCPhrase (HERE_IS_A_NEW_LANDER); ++GLOBAL_SIS (NumLanders); - LockMutex (GraphicsLock); DrawLanders (); DeltaSISGauges (4, 0, 0); - UnlockMutex (GraphicsLock); SET_GAME_STATE (LANDERS_LOST, 1); } @@ -238,27 +236,21 @@ NoRadioactives (RESPONSE_REF R) { NPCPhrase (HERE_IS_ANOTHER_LANDER); ++GLOBAL_SIS (NumLanders); - LockMutex (GraphicsLock); DrawLanders (); DeltaSISGauges (4, 0, 0); - UnlockMutex (GraphicsLock); } else if (PLAYER_SAID (R, need_fuel_mercury) || PLAYER_SAID (R, need_fuel_luna)) { NPCPhrase (GIVE_FUEL); - LockMutex (GraphicsLock); DeltaSISGauges (0, 5 * FUEL_TANK_SCALE, 0); - UnlockMutex (GraphicsLock); SET_GAME_STATE (GIVEN_FUEL_BEFORE, 1); } else if (PLAYER_SAID (R, need_fuel_again)) { NPCPhrase (GIVE_FUEL_AGAIN); - LockMutex (GraphicsLock); DeltaSISGauges (0, 5 * FUEL_TANK_SCALE, 0); - UnlockMutex (GraphicsLock); } if (GLOBAL_SIS (ElementAmounts[RADIOACTIVE])) @@ -297,10 +289,8 @@ AskAfterRadios (RESPONSE_REF R) { NPCPhrase (HERE_IS_A_NEW_LANDER); ++GLOBAL_SIS (NumLanders); - LockMutex (GraphicsLock); DrawLanders (); DeltaSISGauges (4, 0, 0); - UnlockMutex (GraphicsLock); SET_GAME_STATE (LANDERS_LOST, 1); } @@ -308,27 +298,21 @@ AskAfterRadios (RESPONSE_REF R) { NPCPhrase (HERE_IS_ANOTHER_LANDER); ++GLOBAL_SIS (NumLanders); - LockMutex (GraphicsLock); DrawLanders (); DeltaSISGauges (4, 0, 0); - UnlockMutex (GraphicsLock); } else if (PLAYER_SAID (R, need_fuel_mercury) || PLAYER_SAID (R, need_fuel_luna)) { NPCPhrase (GIVE_FUEL); - LockMutex (GraphicsLock); DeltaSISGauges (0, 5 * FUEL_TANK_SCALE, 0); - UnlockMutex (GraphicsLock); SET_GAME_STATE (GIVEN_FUEL_BEFORE, 1); } else if (PLAYER_SAID (R, need_fuel_again)) { NPCPhrase (GIVE_FUEL_AGAIN); - LockMutex (GraphicsLock); DeltaSISGauges (0, 5 * FUEL_TANK_SCALE, 0); - UnlockMutex (GraphicsLock); } else if (PLAYER_SAID (R, where_get_radios)) { @@ -399,10 +383,8 @@ TellMoonBase (RESPONSE_REF R) { NPCPhrase (HERE_IS_A_NEW_LANDER); ++GLOBAL_SIS (NumLanders); - LockMutex (GraphicsLock); DrawLanders (); DeltaSISGauges (4, 0, 0); - UnlockMutex (GraphicsLock); SET_GAME_STATE (LANDERS_LOST, 1); } @@ -410,27 +392,21 @@ TellMoonBase (RESPONSE_REF R) { NPCPhrase (HERE_IS_ANOTHER_LANDER); ++GLOBAL_SIS (NumLanders); - LockMutex (GraphicsLock); DrawLanders (); DeltaSISGauges (4, 0, 0); - UnlockMutex (GraphicsLock); } else if (PLAYER_SAID (R, need_fuel_mercury) || PLAYER_SAID (R, need_fuel_luna)) { NPCPhrase (GIVE_FUEL); - LockMutex (GraphicsLock); DeltaSISGauges (0, 5 * FUEL_TANK_SCALE, 0); - UnlockMutex (GraphicsLock); SET_GAME_STATE (GIVEN_FUEL_BEFORE, 1); } else if (PLAYER_SAID (R, need_fuel_again)) { NPCPhrase (GIVE_FUEL_AGAIN); - LockMutex (GraphicsLock); DeltaSISGauges (0, 5 * FUEL_TANK_SCALE, 0); - UnlockMutex (GraphicsLock); } else if (PLAYER_SAID (R, we_are_here_to_help)) { @@ -593,9 +569,7 @@ GiveRadios (RESPONSE_REF R) NPCPhrase (FUEL_UP1); AlienTalkSegue (1); - LockMutex (GraphicsLock); CommData.AlienAmbientArray[2].AnimFlags |= ANIM_DISABLED; - UnlockMutex (GraphicsLock); XFormColorMap (GetColorMapAddress ( SetAbsColorMapIndex (CommData.AlienColorMap, 0) @@ -713,7 +687,7 @@ init_commander_comm () commander_desc.AlienTextBaseline.x = 164; commander_desc.AlienTextBaseline.y = 20; - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); retval = &commander_desc; return (retval); diff --git a/sc2/src/uqm/comm/comandr/resinst.h b/sc2/src/uqm/comm/comandr/resinst.h index e88d71c1c..7798214bf 100644 --- a/sc2/src/uqm/comm/comandr/resinst.h +++ b/sc2/src/uqm/comm/comandr/resinst.h @@ -1,8 +1,12 @@ -#define COMMANDER_PMAP_ANIM "comm.commander.graphics" -#define COMMANDER_FONT "comm.commander.font" +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define COMMANDER_COLOR_MAP "comm.commander.colortable" #define COMMANDER_CONVERSATION_PHRASES "comm.commander.dialogue" -#define STARBASE_CONVERSATION_PHRASES "comm.starbase.dialogue" +#define COMMANDER_FONT "comm.commander.font" #define COMMANDER_LOWPOW_MUSIC "comm.commander.lowpower.music" #define COMMANDER_MUSIC "comm.commander.music" +#define COMMANDER_PMAP_ANIM "comm.commander.graphics" #define STARBASE_ALT_MUSIC "comm.starbase.music" +#define STARBASE_CONVERSATION_PHRASES "comm.starbase.dialogue" diff --git a/sc2/src/uqm/comm/druuge/Makeinfo b/sc2/src/uqm/comm/druuge/Makeinfo index fc37716e6..733ed6c38 100644 --- a/sc2/src/uqm/comm/druuge/Makeinfo +++ b/sc2/src/uqm/comm/druuge/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="druugec.c" +uqm_HFILES="resinst.h strings.h" diff --git a/sc2/src/uqm/comm/druuge/druugec.c b/sc2/src/uqm/comm/druuge/druugec.c index d90b7a25f..9a082c115 100644 --- a/sc2/src/uqm/comm/druuge/druugec.c +++ b/sc2/src/uqm/comm/druuge/druugec.c @@ -166,7 +166,7 @@ ExitConversation (RESPONSE_REF R) { if (PLAYER_SAID (R, bye)) { - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); if (GET_GAME_STATE (GLOBAL_FLAGS_AND_DATA) & (1 << 7)) { @@ -210,7 +210,7 @@ ExitConversation (RESPONSE_REF R) } else /* if (R == then_we_take_bomb) */ { - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); NPCPhrase (FIGHT_FOR_BOMB); } @@ -240,15 +240,13 @@ Buy (RESPONSE_REF R) #define SHIP_CREW_COST 100 if (GLOBAL_SIS (CrewEnlisted) < SHIP_CREW_COST) NPCPhrase (NOT_ENOUGH_CREW); - else if (ActivateStarShip (DRUUGE_SHIP, FEASIBILITY_STUDY) == 0) + else if (EscortFeasibilityStudy (DRUUGE_SHIP) == 0) NPCPhrase (NOT_ENOUGH_ROOM); else { - LockMutex (GraphicsLock); DeltaSISGauges (-SHIP_CREW_COST, 0, 0); - UnlockMutex (GraphicsLock); SlaveryCount += SHIP_CREW_COST; - ActivateStarShip (DRUUGE_SHIP, 1); + AddEscortShips (DRUUGE_SHIP, 1); NPCPhrase (BOUGHT_SHIP); } @@ -260,9 +258,7 @@ Buy (RESPONSE_REF R) NPCPhrase (NOT_ENOUGH_CREW); else { - LockMutex (GraphicsLock); DeltaSISGauges (-ARTIFACT_CREW_COST, 0, 0); - UnlockMutex (GraphicsLock); SlaveryCount += ARTIFACT_CREW_COST; SET_GAME_STATE (ROSY_SPHERE_ON_SHIP, 1); SET_GAME_STATE (ROSY_SPHERE, 1); @@ -276,9 +272,7 @@ Buy (RESPONSE_REF R) NPCPhrase (NOT_ENOUGH_CREW); else { - LockMutex (GraphicsLock); DeltaSISGauges (-ARTIFACT_CREW_COST, 0, 0); - UnlockMutex (GraphicsLock); SlaveryCount += ARTIFACT_CREW_COST; SET_GAME_STATE (ARTIFACT_2_ON_SHIP, 1); @@ -291,9 +285,7 @@ Buy (RESPONSE_REF R) NPCPhrase (NOT_ENOUGH_CREW); else { - LockMutex (GraphicsLock); DeltaSISGauges (-ARTIFACT_CREW_COST, 0, 0); - UnlockMutex (GraphicsLock); SlaveryCount += ARTIFACT_CREW_COST; SET_GAME_STATE (ARTIFACT_3_ON_SHIP, 1); @@ -307,10 +299,8 @@ Buy (RESPONSE_REF R) NPCPhrase (NOT_ENOUGH_CREW); else { - LockMutex (GraphicsLock); DeltaSISGauges (-FUEL_CREW_COST, FUEL_CREW_COST * FUEL_TANK_SCALE, 0); - UnlockMutex (GraphicsLock); SlaveryCount += FUEL_CREW_COST; NPCPhrase (BOUGHT_FUEL); @@ -403,7 +393,7 @@ DoTransaction (RESPONSE_REF R) trade_gas = 0; ships_to_trade = 0; - ship_slots = ActivateStarShip (DRUUGE_SHIP, FEASIBILITY_STUDY); + ship_slots = EscortFeasibilityStudy (DRUUGE_SHIP); if (PLAYER_SAID (R, sell_maidens)) { NPCPhrase (BOUGHT_MAIDENS); @@ -430,7 +420,7 @@ DoTransaction (RESPONSE_REF R) NPCPhrase (YOU_GET); if (ships_to_trade) { - ActivateStarShip (DRUUGE_SHIP, ships_to_trade); + AddEscortShips (DRUUGE_SHIP, ships_to_trade); if (ship_slots >= ships_to_trade) NPCPhrase (DEAL_FOR_STATED_SHIPS); @@ -466,14 +456,12 @@ DoTransaction (RESPONSE_REF R) capacity -= GLOBAL_SIS (FuelOnBoard); f = (COUNT)((capacity + (FUEL_TANK_SCALE >> 1)) / FUEL_TANK_SCALE); - LockMutex (GraphicsLock); while (capacity > 0x3FFFL) { DeltaSISGauges (0, 0x3FFF, 0); capacity -= 0x3FFF; } DeltaSISGauges (0, (SIZE)capacity, 0); - UnlockMutex (GraphicsLock); NPCPhrase (FUEL0); NPCNumber (f, NULL); @@ -695,7 +683,7 @@ Intro (void) { NPCPhrase (OUT_TAKES); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); return; } @@ -732,7 +720,7 @@ Intro (void) SET_GAME_STATE (DRUUGE_VISITS, NumVisits); } - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else if (GET_GAME_STATE (GLOBAL_FLAGS_AND_DATA) & (1 << 7)) { @@ -826,7 +814,7 @@ Intro (void) } SET_GAME_STATE (DRUUGE_VISITS, NumVisits); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else { @@ -862,7 +850,7 @@ Intro (void) } SET_GAME_STATE (DRUUGE_SALVAGE, NumVisits); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); AttemptedSalvage = TRUE; } else @@ -894,7 +882,7 @@ uninit_druuge (void) static void post_druuge_enc (void) { - if (GET_GAME_STATE (BATTLE_SEGUE) == 1 + if (getSegue () == Segue_hostile && !AttemptedSalvage && !GET_GAME_STATE (DRUUGE_MANNER)) { @@ -926,11 +914,11 @@ init_druuge_comm (void) && (GET_GAME_STATE (GLOBAL_FLAGS_AND_DATA) & (1 << 7))) || LOBYTE (GLOBAL (CurrentActivity)) == WON_LAST_BATTLE) { - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else { - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } retval = &druuge_desc; diff --git a/sc2/src/uqm/comm/druuge/resinst.h b/sc2/src/uqm/comm/druuge/resinst.h index 1db46237c..ca82a22d2 100644 --- a/sc2/src/uqm/comm/druuge/resinst.h +++ b/sc2/src/uqm/comm/druuge/resinst.h @@ -1,5 +1,9 @@ -#define DRUUGE_PMAP_ANIM "comm.druuge.graphics" -#define DRUUGE_FONT "comm.druuge.font" +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define DRUUGE_COLOR_MAP "comm.druuge.colortable" #define DRUUGE_CONVERSATION_PHRASES "comm.druuge.dialogue" +#define DRUUGE_FONT "comm.druuge.font" #define DRUUGE_MUSIC "comm.druuge.music" +#define DRUUGE_PMAP_ANIM "comm.druuge.graphics" diff --git a/sc2/src/uqm/comm/ilwrath/Makeinfo b/sc2/src/uqm/comm/ilwrath/Makeinfo index 645715ef1..3f40e7951 100644 --- a/sc2/src/uqm/comm/ilwrath/Makeinfo +++ b/sc2/src/uqm/comm/ilwrath/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="ilwrathc.c" +uqm_HFILES="resinst.h strings.h" diff --git a/sc2/src/uqm/comm/ilwrath/ilwrathc.c b/sc2/src/uqm/comm/ilwrath/ilwrathc.c index 6e9f3909e..1afd81257 100644 --- a/sc2/src/uqm/comm/ilwrath/ilwrathc.c +++ b/sc2/src/uqm/comm/ilwrath/ilwrathc.c @@ -102,7 +102,7 @@ static LOCDATA ilwrath_desc = static void CombatIsInevitable (RESPONSE_REF R) { - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); if (PLAYER_SAID (R, you_are_weak)) NPCPhrase (STRENGTH_NOT_ALL); @@ -124,7 +124,7 @@ CombatIsInevitable (RESPONSE_REF R) { NPCPhrase (GOODBYE_GODS); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } if (PLAYER_SAID (R, whats_up)) { @@ -586,7 +586,7 @@ Intro (void) else NPCPhrase (JUST_GRUNTS); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else if (GET_GAME_STATE (GLOBAL_FLAGS_AND_DATA) & (1 << 4)) { @@ -596,7 +596,7 @@ Intro (void) } else { - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); if (GET_GAME_STATE (ILWRATH_FIGHT_THRADDASH)) NPCPhrase (HAPPY_FIGHTING_THRADDASH); @@ -637,11 +637,11 @@ init_ilwrath_comm (void) & ((1 << 4) | (1 << 5))) || LOBYTE (GLOBAL (CurrentActivity)) == WON_LAST_BATTLE) { - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else { - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } retval = &ilwrath_desc; diff --git a/sc2/src/uqm/comm/ilwrath/resinst.h b/sc2/src/uqm/comm/ilwrath/resinst.h index 2c90b03cd..7063e399d 100644 --- a/sc2/src/uqm/comm/ilwrath/resinst.h +++ b/sc2/src/uqm/comm/ilwrath/resinst.h @@ -1,5 +1,9 @@ -#define ILWRATH_PMAP_ANIM "comm.ilwrath.graphics" -#define ILWRATH_FONT "comm.ilwrath.font" +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define ILWRATH_COLOR_MAP "comm.ilwrath.colortable" #define ILWRATH_CONVERSATION_PHRASES "comm.ilwrath.dialogue" +#define ILWRATH_FONT "comm.ilwrath.font" #define ILWRATH_MUSIC "comm.ilwrath.music" +#define ILWRATH_PMAP_ANIM "comm.ilwrath.graphics" diff --git a/sc2/src/uqm/comm/melnorm/Makeinfo b/sc2/src/uqm/comm/melnorm/Makeinfo index 64cbe71a1..5e3a21439 100644 --- a/sc2/src/uqm/comm/melnorm/Makeinfo +++ b/sc2/src/uqm/comm/melnorm/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="melnorm.c" +uqm_HFILES="resinst.h strings.h" diff --git a/sc2/src/uqm/comm/melnorm/melnorm.c b/sc2/src/uqm/comm/melnorm/melnorm.c index df7553ba8..00b6a0727 100644 --- a/sc2/src/uqm/comm/melnorm/melnorm.c +++ b/sc2/src/uqm/comm/melnorm/melnorm.c @@ -21,8 +21,6 @@ #include "strings.h" #include "uqm/gameev.h" -#include "uqm/setup.h" - // for GraphicsLock #include "uqm/shipcont.h" #include "libs/inplib.h" #include "libs/mathlib.h" @@ -34,11 +32,6 @@ #include "uqm/sis.h" -#define NUM_HISTORY_ITEMS 9 -#define NUM_EVENT_ITEMS 8 -#define NUM_ALIEN_RACE_ITEMS 16 -#define NUM_TECH_ITEMS 13 - static const NUMBER_SPEECH_DESC melnorme_numbers_english; static LOCDATA melnorme_desc = @@ -201,6 +194,294 @@ static const NUMBER_SPEECH_DESC melnorme_numbers_english = } }; +#define ARRAY_SIZE(array) (sizeof(array) / sizeof (*array)) + + +//////////////Technology System/////////////////////// +// This section deals with enabling and checking for +// various technologies. It should probably be +// migrated to its own file. + +// Identifiers for the various technologies +typedef enum +{ + TECH_MODULE_BLASTER, + TECH_LANDER_SPEED, + TECH_MODULE_ANTIMISSILE, + TECH_LANDER_SHIELD_BIO, + TECH_LANDER_CARGO, + TECH_MODULE_BIGFUELTANK, + TECH_LANDER_RAPIDFIRE, + TECH_LANDER_SHIELD_QUAKE, + TECH_MODULE_TRACKING, + TECH_LANDER_SHIELD_LIGHTNING, + TECH_LANDER_SHIELD_HEAT, + TECH_MODULE_CANNON, + TECH_MODULE_FURNACE, +} TechId_t; + +// Group the technologies into three subtypes +typedef enum +{ + TECH_TYPE_MODULE, // Flagship modules + // subtype = moduleId, info = cost + // Cost will be scaled by MODULE_COST_SCALE. + TECH_TYPE_LANDER_SHIELD, // Lander shield enhancements + // subtype = disaster type, info = unused + TECH_TYPE_STATE // Other game state changes + // subtype = stateId, info = state value +} TechType_t; + + +// Define the information specifying a particular technology +typedef struct +{ + TechId_t id; // ID of the technology + TechType_t type; // Type of the technology + int subtype; // Subtype of the technology + int info; // Supplemental information +} TechData; + + +// A table of the available technologies. +// This should really be an associative map of TechIds to tech data records, +// but implementing that would be excessive. +static const TechData tech_data_table[] = +{ + // Tech ID Tech Type, Supplemental info + { TECH_MODULE_BLASTER, TECH_TYPE_MODULE, BLASTER_WEAPON, 4000 }, + { TECH_LANDER_SPEED, TECH_TYPE_STATE, IMPROVED_LANDER_SPEED, 1 }, + { TECH_MODULE_ANTIMISSILE, TECH_TYPE_MODULE, ANTIMISSILE_DEFENSE, 4000 }, + { TECH_LANDER_SHIELD_BIO, TECH_TYPE_LANDER_SHIELD, BIOLOGICAL_DISASTER, -1 }, + { TECH_LANDER_CARGO, TECH_TYPE_STATE, IMPROVED_LANDER_CARGO, 1 }, + { TECH_MODULE_BIGFUELTANK, TECH_TYPE_MODULE, HIGHEFF_FUELSYS, 1000 }, + { TECH_LANDER_RAPIDFIRE, TECH_TYPE_STATE, IMPROVED_LANDER_SHOT, 1 }, + { TECH_LANDER_SHIELD_QUAKE, TECH_TYPE_LANDER_SHIELD, EARTHQUAKE_DISASTER, -1 }, + { TECH_MODULE_TRACKING, TECH_TYPE_MODULE, TRACKING_SYSTEM, 5000 }, + { TECH_LANDER_SHIELD_LIGHTNING, TECH_TYPE_LANDER_SHIELD, LIGHTNING_DISASTER, -1 }, + { TECH_LANDER_SHIELD_HEAT, TECH_TYPE_LANDER_SHIELD, LAVASPOT_DISASTER, -1 }, + { TECH_MODULE_CANNON, TECH_TYPE_MODULE, CANNON_WEAPON, 6000 }, + { TECH_MODULE_FURNACE, TECH_TYPE_MODULE, SHIVA_FURNACE, 4000 }, +}; +const size_t NUM_TECHNOLOGIES = ARRAY_SIZE (tech_data_table); + +// Lookup function to get the data for a particular tech +static const TechData* +GetTechData (TechId_t techId) +{ + size_t i = 0; + for (i = 0; i < NUM_TECHNOLOGIES; ++i) + { + if (tech_data_table[i].id == techId) + return &tech_data_table[i]; + } + return NULL; +} + + +// We have to explicitly switch on the state ID because the xxx_GAME_STATE +// macros use preprocessor stringizing. +static bool +HasStateTech (int stateId) +{ + switch (stateId) + { + case IMPROVED_LANDER_SPEED: + return GET_GAME_STATE (IMPROVED_LANDER_SPEED); + case IMPROVED_LANDER_CARGO: + return GET_GAME_STATE (IMPROVED_LANDER_CARGO); + case IMPROVED_LANDER_SHOT: + return GET_GAME_STATE (IMPROVED_LANDER_SHOT); + } + return false; +} + +static void +GrantStateTech (int stateId, BYTE value) +{ + switch (stateId) + { + case IMPROVED_LANDER_SPEED: + SET_GAME_STATE (IMPROVED_LANDER_SPEED, value); + return; + case IMPROVED_LANDER_CARGO: + SET_GAME_STATE (IMPROVED_LANDER_CARGO, value); + return; + case IMPROVED_LANDER_SHOT: + SET_GAME_STATE (IMPROVED_LANDER_SHOT, value); + return; + } +} + +static bool +HasTech (TechId_t techId) +{ + const TechData* techData = GetTechData (techId); + if (!techData) + return false; + + switch (techData->type) + { + case TECH_TYPE_MODULE: + return GLOBAL (ModuleCost[techData->subtype]) != 0; + case TECH_TYPE_LANDER_SHIELD: + return (GET_GAME_STATE (LANDER_SHIELDS) & (1 << techData->subtype)) != 0; + case TECH_TYPE_STATE: + return HasStateTech (techData->subtype); + } + return false; +} + +static void +GrantTech (TechId_t techId) +{ + const TechData* techData = GetTechData (techId); + if (!techData) + return; + + switch (techData->type) + { + case TECH_TYPE_MODULE: + GLOBAL (ModuleCost[techData->subtype]) = techData->info / MODULE_COST_SCALE; + return; + case TECH_TYPE_LANDER_SHIELD: + { + COUNT state = GET_GAME_STATE (LANDER_SHIELDS) | (1 << techData->subtype); + SET_GAME_STATE (LANDER_SHIELDS, state); + return; + } + case TECH_TYPE_STATE: + GrantStateTech (techData->subtype, techData->info); + return; + } +} + + +////////////Melnorme Sales System/////////// +// This section contains code related to Melnorme sales + +// Many of the conversation lines in strings.h fall into groups +// of sequential responses. These structures allow those +// responses to be interated through. +static const int ok_buy_event_lines[] = +{ + OK_BUY_EVENT_1, OK_BUY_EVENT_2, OK_BUY_EVENT_3, OK_BUY_EVENT_4, + OK_BUY_EVENT_5, OK_BUY_EVENT_6, OK_BUY_EVENT_7, OK_BUY_EVENT_8 +}; +const size_t NUM_EVENT_ITEMS = ARRAY_SIZE (ok_buy_event_lines); + +static const int ok_buy_alien_race_lines[] = +{ + OK_BUY_ALIEN_RACE_1, OK_BUY_ALIEN_RACE_2, OK_BUY_ALIEN_RACE_3, + OK_BUY_ALIEN_RACE_4, OK_BUY_ALIEN_RACE_5, OK_BUY_ALIEN_RACE_6, + OK_BUY_ALIEN_RACE_7, OK_BUY_ALIEN_RACE_8, OK_BUY_ALIEN_RACE_9, + OK_BUY_ALIEN_RACE_10, OK_BUY_ALIEN_RACE_11, OK_BUY_ALIEN_RACE_12, + OK_BUY_ALIEN_RACE_13, OK_BUY_ALIEN_RACE_14, OK_BUY_ALIEN_RACE_15, + OK_BUY_ALIEN_RACE_16 +}; +const size_t NUM_ALIEN_RACE_ITEMS = ARRAY_SIZE (ok_buy_alien_race_lines); + +static const int ok_buy_history_lines[] = +{ + OK_BUY_HISTORY_1, OK_BUY_HISTORY_2, OK_BUY_HISTORY_3, + OK_BUY_HISTORY_4, OK_BUY_HISTORY_5, OK_BUY_HISTORY_6, + OK_BUY_HISTORY_7, OK_BUY_HISTORY_8, OK_BUY_HISTORY_9 +}; +const size_t NUM_HISTORY_ITEMS = ARRAY_SIZE (ok_buy_history_lines); + +static const int hello_and_down_to_business_lines[] = +{ + HELLO_AND_DOWN_TO_BUSINESS_1, HELLO_AND_DOWN_TO_BUSINESS_2, + HELLO_AND_DOWN_TO_BUSINESS_3, HELLO_AND_DOWN_TO_BUSINESS_4, + HELLO_AND_DOWN_TO_BUSINESS_5, HELLO_AND_DOWN_TO_BUSINESS_6, + HELLO_AND_DOWN_TO_BUSINESS_7, HELLO_AND_DOWN_TO_BUSINESS_8, + HELLO_AND_DOWN_TO_BUSINESS_9, HELLO_AND_DOWN_TO_BUSINESS_10 +}; +const size_t NUM_HELLO_LINES = ARRAY_SIZE (hello_and_down_to_business_lines); + +static const int rescue_lines[] = +{ + RESCUE_EXPLANATION, RESCUE_AGAIN_1, RESCUE_AGAIN_2, + RESCUE_AGAIN_3, RESCUE_AGAIN_4, RESCUE_AGAIN_5 +}; +const size_t NUM_RESCUE_LINES = ARRAY_SIZE (rescue_lines); + +// How many lines are available in the given array? +static size_t +GetNumLines (const int array[]) +{ + if (array == ok_buy_event_lines) + return NUM_EVENT_ITEMS; + else if (array == ok_buy_alien_race_lines) + return NUM_ALIEN_RACE_ITEMS; + else if (array == ok_buy_history_lines) + return NUM_HISTORY_ITEMS; + else if (array == hello_and_down_to_business_lines) + return NUM_HELLO_LINES; + else if (array == rescue_lines) + return NUM_RESCUE_LINES; + return 0; +} + +// Get the line, with range checking. +// Returns the last line if the desired one is out of range. +static int +GetLineSafe (const int array[], size_t linenum) +{ + const size_t array_size = GetNumLines (array); + assert (array_size > 0); + if (linenum >= array_size) + linenum = array_size - 1; + return array[linenum]; +} + +// Data structure to hold the Melnorme's info on a technology +typedef struct +{ + TechId_t techId; // ID of technology + int price; // Melnorme's price to sell + int sale_line; // Sales pitch line ID + int sold_line; // Post-sale line ID +} TechSaleData; + +// Right now, all techs have the same price. +#define TECHPRICE (75 * BIO_CREDIT_VALUE) + +static const TechSaleData tech_sale_catalog[] = +{ + { TECH_MODULE_BLASTER, TECHPRICE, NEW_TECH_1, OK_BUY_NEW_TECH_1 }, + { TECH_LANDER_SPEED, TECHPRICE, NEW_TECH_2, OK_BUY_NEW_TECH_2 }, + { TECH_MODULE_ANTIMISSILE, TECHPRICE, NEW_TECH_3, OK_BUY_NEW_TECH_3 }, + { TECH_LANDER_SHIELD_BIO, TECHPRICE, NEW_TECH_4, OK_BUY_NEW_TECH_4 }, + { TECH_LANDER_CARGO, TECHPRICE, NEW_TECH_5, OK_BUY_NEW_TECH_5 }, + { TECH_MODULE_BIGFUELTANK, TECHPRICE, NEW_TECH_6, OK_BUY_NEW_TECH_6 }, + { TECH_LANDER_RAPIDFIRE, TECHPRICE, NEW_TECH_7, OK_BUY_NEW_TECH_7 }, + { TECH_LANDER_SHIELD_QUAKE, TECHPRICE, NEW_TECH_8, OK_BUY_NEW_TECH_8 }, + { TECH_MODULE_TRACKING, TECHPRICE, NEW_TECH_9, OK_BUY_NEW_TECH_9 }, + { TECH_LANDER_SHIELD_LIGHTNING, TECHPRICE, NEW_TECH_10, OK_BUY_NEW_TECH_10 }, + { TECH_LANDER_SHIELD_HEAT, TECHPRICE, NEW_TECH_11, OK_BUY_NEW_TECH_11 }, + { TECH_MODULE_CANNON, TECHPRICE, NEW_TECH_12, OK_BUY_NEW_TECH_12 }, + { TECH_MODULE_FURNACE, TECHPRICE, NEW_TECH_13, OK_BUY_NEW_TECH_13 }, +}; +const size_t NUM_TECH_ITEMS = ARRAY_SIZE (tech_sale_catalog); + +// Return the next tech for sale that the player doesn't already have. +// Returns NULL if the player has all the techs. +static const TechSaleData* +GetNextTechForSale (void) +{ + size_t i = 0; + for (i = 0; i < NUM_TECH_ITEMS; ++i) + { + if (!HasTech (tech_sale_catalog[i].techId)) + return &tech_sale_catalog[i]; + } + + return NULL; +} + +///////////End Melnorme Sales Section////////////////// + static StatMsgMode prevMsgMode; static void DoFirstMeeting (RESPONSE_REF R); @@ -247,6 +528,51 @@ ShipWorth (void) static COUNT rescue_fuel; static SIS_STATE SIS_copy; +// Extract method to return the response string index +// for stripping a given module. +static int +GetStripModuleRef (int moduleID) +{ + switch (moduleID) + { + case PLANET_LANDER: return LANDERS; + case FUSION_THRUSTER: return THRUSTERS; + case TURNING_JETS: return JETS; + case CREW_POD: return PODS; + case STORAGE_BAY: return BAYS; + case DYNAMO_UNIT: return DYNAMOS; + case SHIVA_FURNACE: return FURNACES; + case GUN_WEAPON: return GUNS; + case BLASTER_WEAPON: return BLASTERS; + case CANNON_WEAPON: return CANNONS; + case TRACKING_SYSTEM: return TRACKERS; + case ANTIMISSILE_DEFENSE: return DEFENSES; + // If a modder has added new modules, should it really + // be a fatal error if the Melnorme don't know about + // them? + default: + assert (0 && "Unknown module"); + } + return 0; +} + +static DWORD +getStripRandomSeed (void) +{ + DWORD x, y; + // We truncate the location because encounters move the ship slightly in + // HSpace, and throw some other relatively immutable values in the mix to + // vary the deal when stuck at the same general location again. + // It is still possible but unlikely for encounters to move the ship into + // another truncation sector so the player could choose from 2 deals. + x = LOGX_TO_UNIVERSE (GLOBAL_SIS (log_x)) / 100; + y = LOGY_TO_UNIVERSE (GLOBAL_SIS (log_y)) / 100; + // prime numbers help randomness + return y * 1013 + x + GLOBAL_SIS (NumLanders) + + GLOBAL_SIS (ModuleSlots[1]) + GLOBAL_SIS (ModuleSlots[4]) + + GLOBAL_SIS (ModuleSlots[7]) + GLOBAL_SIS (ModuleSlots[10]); +} + static BOOLEAN StripShip (COUNT fuel_required) { @@ -262,9 +588,7 @@ StripShip (COUNT fuel_required) if (fuel_required == 0) { GlobData.SIS_state = SIS_copy; - LockMutex (GraphicsLock); DeltaSISGauges (UNDEFINED_DELTA, rescue_fuel, UNDEFINED_DELTA); - UnlockMutex (GraphicsLock); } else if (fuel_required == (COUNT)~0) { @@ -288,9 +612,7 @@ StripShip (COUNT fuel_required) GLOBAL_SIS (ModuleSlots[i]) = EMPTY_SLOT + 2; } - LockMutex (GraphicsLock); DeltaSISGauges (UNDEFINED_DELTA, UNDEFINED_DELTA, UNDEFINED_DELTA); - UnlockMutex (GraphicsLock); } else if (fuel_required) { @@ -300,6 +622,15 @@ StripShip (COUNT fuel_required) BYTE module_count[BOMB_MODULE_0]; BYTE slot; DWORD capacity; + RandomContext *rc; + + // Bug #567 + // In order to offer the same deal each time if it is refused, we seed + // the random number generator with our location, thus making the deal + // a repeatable pseudo-random function of where we got stuck and what, + // exactly, is on our ship. + rc = RandomContext_New(); + RandomContext_SeedRandom (rc, getStripRandomSeed ()); SIS_copy = GlobData.SIS_state; for (i = PLANET_LANDER; i < BOMB_MODULE_0; ++i) @@ -343,7 +674,7 @@ StripShip (COUNT fuel_required) { DWORD rand_val; - rand_val = TFB_Random (); + rand_val = RandomContext_Random (rc); switch (which_module = LOBYTE (LOWORD (rand_val)) % (CREW_POD + 1)) { case PLANET_LANDER: @@ -393,13 +724,12 @@ StripShip (COUNT fuel_required) ++module_count[which_module]; total += GLOBAL (ModuleCost[which_module]); } + RandomContext_Delete (rc); if (total == 0) { NPCPhrase (CHARITY); - LockMutex (GraphicsLock); DeltaSISGauges (0, fuel_required, 0); - UnlockMutex (GraphicsLock); return (FALSE); } else @@ -414,54 +744,10 @@ StripShip (COUNT fuel_required) { if (module_count[i]) { - RESPONSE_REF pStr = 0; - - switch (i) - { - case PLANET_LANDER: - pStr = LANDERS; - break; - case FUSION_THRUSTER: - pStr = THRUSTERS; - break; - case TURNING_JETS: - pStr = JETS; - break; - case CREW_POD: - pStr = PODS; - break; - case STORAGE_BAY: - pStr = BAYS; - break; - case DYNAMO_UNIT: - pStr = DYNAMOS; - break; - case SHIVA_FURNACE: - pStr = FURNACES; - break; - case GUN_WEAPON: - pStr = GUNS; - break; - case BLASTER_WEAPON: - pStr = BLASTERS; - break; - case CANNON_WEAPON: - pStr = CANNONS; - break; - case TRACKING_SYSTEM: - pStr = TRACKERS; - break; - case ANTIMISSILE_DEFENSE: - pStr = DEFENSES; - break; - default: - assert (0 && "Unknown module"); - } - if (i == end_mod && i != beg_mod) NPCPhrase (END_LIST_WITH_AND); NPCPhrase (ENUMERATE_ONE + (module_count[i] - 1)); - NPCPhrase (pStr); + NPCPhrase (GetStripModuleRef (i)); } } } @@ -480,14 +766,14 @@ ExitConversation (RESPONSE_REF R) NPCPhrase (YOU_GIVE_US_NO_CHOICE); SET_GAME_STATE (MELNORME_ANGER, 1); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else if (PLAYER_SAID (R, so_we_can_attack)) { NPCPhrase (DECEITFUL_HUMAN); SET_GAME_STATE (MELNORME_ANGER, 2); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else if (PLAYER_SAID (R, bye_melnorme_slightly_angry)) NPCPhrase (MELNORME_SLIGHTLY_ANGRY_GOODBYE); @@ -509,7 +795,7 @@ ExitConversation (RESPONSE_REF R) NPCPhrase (OK_FIGHT_SOME_MORE); SET_GAME_STATE (MELNORME_ANGER, 3); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else if (PLAYER_SAID (R, bye_melnorme_pissed_off)) NPCPhrase (MELNORME_PISSED_OFF_GOODBYE); @@ -517,7 +803,7 @@ ExitConversation (RESPONSE_REF R) { NPCPhrase (WE_FIGHT_AGAIN); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else if (PLAYER_SAID (R, you_hate_us_so_we_go_away)) NPCPhrase (HATE_YOU_GOODBYE); @@ -569,183 +855,108 @@ DoRescue (RESPONSE_REF R) } } -static COUNT +// Extract method for getting the player's current credits. +static COUNT +GetAvailableCredits (void) +{ + return MAKE_WORD (GET_GAME_STATE (MELNORME_CREDIT0), + GET_GAME_STATE (MELNORME_CREDIT1)); +} + +// Extract method for setting the player's current credits. +static void +SetAvailableCredits (COUNT credits) +{ + SET_GAME_STATE (MELNORME_CREDIT0, LOBYTE (credits)); + SET_GAME_STATE (MELNORME_CREDIT1, HIBYTE (credits)); +} + +// Now returns whether the purchase succeeded instead of the remaining +// credit balance. Use GetAvailableCredits() to get the latter. +static bool DeltaCredit (SIZE delta_credit) { - COUNT Credit; + COUNT Credit = GetAvailableCredits (); - Credit = MAKE_WORD ( - GET_GAME_STATE (MELNORME_CREDIT0), - GET_GAME_STATE (MELNORME_CREDIT1) - ); + // Can they afford it? if ((int)delta_credit >= 0 || ((int)(-delta_credit) <= (int)(Credit))) { Credit += delta_credit; - SET_GAME_STATE (MELNORME_CREDIT0, LOBYTE (Credit)); - SET_GAME_STATE (MELNORME_CREDIT1, HIBYTE (Credit)); - LockMutex (GraphicsLock); + SetAvailableCredits (Credit); DrawStatusMessage (NULL); - UnlockMutex (GraphicsLock); - } - else - { - NPCPhrase (NEED_MORE_CREDIT0); - NPCNumber (-delta_credit - Credit, NULL); - NPCPhrase (NEED_MORE_CREDIT1); + return true; } + + // Fail + NPCPhrase (NEED_MORE_CREDIT0); + NPCNumber (-delta_credit - Credit, NULL); + NPCPhrase (NEED_MORE_CREDIT1); - return (Credit); + return false; } + +// Extract methods to process the giving of various bits of information to the +// player. Ideally, we'd want to merge these three into a single parameterized +// function, but the nature of the XXX_GAME_STATE() code makes that tricky. static void CurrentEvents (void) { - BYTE stack; - - stack = GET_GAME_STATE (MELNORME_EVENTS_INFO_STACK); - switch (stack++) - { - case 0: - NPCPhrase (OK_BUY_EVENT_1); - break; - case 1: - NPCPhrase (OK_BUY_EVENT_2); - break; - case 2: - NPCPhrase (OK_BUY_EVENT_3); - break; - case 3: - NPCPhrase (OK_BUY_EVENT_4); - break; - case 4: - NPCPhrase (OK_BUY_EVENT_5); - break; - case 5: - NPCPhrase (OK_BUY_EVENT_6); - break; - case 6: - NPCPhrase (OK_BUY_EVENT_7); - break; - case 7: - NPCPhrase (OK_BUY_EVENT_8); - break; - } - SET_GAME_STATE (MELNORME_EVENTS_INFO_STACK, stack); + BYTE stack = GET_GAME_STATE (MELNORME_EVENTS_INFO_STACK); + const int phraseId = GetLineSafe (ok_buy_event_lines, stack); + NPCPhrase (phraseId); + SET_GAME_STATE (MELNORME_EVENTS_INFO_STACK, stack + 1); } static void AlienRaces (void) { - BYTE stack; - - stack = GET_GAME_STATE (MELNORME_ALIEN_INFO_STACK); - switch (stack++) + BYTE stack = GET_GAME_STATE (MELNORME_ALIEN_INFO_STACK); + const int phraseId = GetLineSafe (ok_buy_alien_race_lines, stack); + // Two pieces of alien knowledge trigger state changes. + switch (phraseId) { - case 0: - NPCPhrase (OK_BUY_ALIEN_RACE_1); - break; - case 1: - NPCPhrase (OK_BUY_ALIEN_RACE_2); - break; - case 2: - NPCPhrase (OK_BUY_ALIEN_RACE_3); - break; - case 3: - NPCPhrase (OK_BUY_ALIEN_RACE_4); - break; - case 4: - NPCPhrase (OK_BUY_ALIEN_RACE_5); - break; - case 5: - NPCPhrase (OK_BUY_ALIEN_RACE_6); - break; - case 6: - NPCPhrase (OK_BUY_ALIEN_RACE_7); - break; - case 7: - NPCPhrase (OK_BUY_ALIEN_RACE_8); - break; - case 8: - NPCPhrase (OK_BUY_ALIEN_RACE_9); - break; - case 9: - NPCPhrase (OK_BUY_ALIEN_RACE_10); - break; - case 10: - NPCPhrase (OK_BUY_ALIEN_RACE_11); - break; - case 11: - NPCPhrase (OK_BUY_ALIEN_RACE_12); - break; - case 12: - NPCPhrase (OK_BUY_ALIEN_RACE_13); - break; - case 13: - NPCPhrase (OK_BUY_ALIEN_RACE_14); + case OK_BUY_ALIEN_RACE_14: if (!GET_GAME_STATE (FOUND_PLUTO_SPATHI)) { SET_GAME_STATE (KNOW_SPATHI_PASSWORD, 1); SET_GAME_STATE (SPATHI_HOME_VISITS, 7); } break; - case 14: - NPCPhrase (OK_BUY_ALIEN_RACE_15); + case OK_BUY_ALIEN_RACE_15: if (GET_GAME_STATE (KNOW_ABOUT_SHATTERED) < 2) { SET_GAME_STATE (KNOW_ABOUT_SHATTERED, 2); } SET_GAME_STATE (KNOW_SYREEN_WORLD_SHATTERED, 1); break; - case 15: - NPCPhrase (OK_BUY_ALIEN_RACE_16); - break; } - SET_GAME_STATE (MELNORME_ALIEN_INFO_STACK, stack); + NPCPhrase (phraseId); + SET_GAME_STATE (MELNORME_ALIEN_INFO_STACK, stack + 1); } static void History (void) { - BYTE stack; + BYTE stack = GET_GAME_STATE (MELNORME_HISTORY_INFO_STACK); + const int phraseId = GetLineSafe (ok_buy_history_lines, stack); + NPCPhrase (phraseId); + SET_GAME_STATE (MELNORME_HISTORY_INFO_STACK, stack + 1); +} - stack = GET_GAME_STATE (MELNORME_HISTORY_INFO_STACK); - switch (stack++) - { - case 0: - NPCPhrase (OK_BUY_HISTORY_1); - break; - case 1: - NPCPhrase (OK_BUY_HISTORY_2); - break; - case 2: - NPCPhrase (OK_BUY_HISTORY_3); - break; - case 3: - NPCPhrase (OK_BUY_HISTORY_4); - break; - case 4: - NPCPhrase (OK_BUY_HISTORY_5); - break; - case 5: - NPCPhrase (OK_BUY_HISTORY_6); - break; - case 6: - NPCPhrase (OK_BUY_HISTORY_7); - break; - case 7: - NPCPhrase (OK_BUY_HISTORY_8); - break; - case 8: - NPCPhrase (OK_BUY_HISTORY_9); - break; - } - SET_GAME_STATE (MELNORME_HISTORY_INFO_STACK, stack); +// extract method to tell if we have any information left to sell to the player. +static bool AnyInfoLeftToSell (void) +{ + return GET_GAME_STATE (MELNORME_EVENTS_INFO_STACK) < NUM_EVENT_ITEMS + || GET_GAME_STATE (MELNORME_ALIEN_INFO_STACK) < NUM_ALIEN_RACE_ITEMS + || GET_GAME_STATE (MELNORME_HISTORY_INFO_STACK) < NUM_HISTORY_ITEMS; } static void NatureOfConversation (RESPONSE_REF R); static BYTE AskedToBuy; + static void DoBuy (RESPONSE_REF R) { @@ -754,10 +965,7 @@ DoBuy (RESPONSE_REF R) BYTE slot; DWORD capacity; - credit = MAKE_WORD ( - GET_GAME_STATE (MELNORME_CREDIT0), - GET_GAME_STATE (MELNORME_CREDIT1) - ); + credit = GetAvailableCredits (); capacity = FUEL_RESERVE; slot = NUM_MODULE_SLOTS - 1; @@ -774,6 +982,7 @@ DoBuy (RESPONSE_REF R) } } while (slot--); + // If they're out of credits, educate them on how commerce works. if (credit == 0) { AskedToBuy = TRUE; @@ -826,14 +1035,12 @@ DoBuy (RESPONSE_REF R) NPCPhrase (GOT_FUEL); f = (DWORD)needed_credit * FUEL_TANK_SCALE; - LockMutex (GraphicsLock); while (f > 0x3FFFL) { DeltaSISGauges (0, 0x3FFF, 0); f -= 0x3FFF; } DeltaSISGauges (0, (SIZE)f, 0); - UnlockMutex (GraphicsLock); } needed_credit *= (BIO_CREDIT_VALUE / 2); } @@ -856,223 +1063,43 @@ TryFuelAgain: else if (PLAYER_SAID (R, buy_technology) || PLAYER_SAID (R, buy_new_tech)) { - BYTE stack; + // Note that this code no longer uses the MELNORME_TECH_STACK state + // buts, as they're not needed; we can tell what technologies the + // player has by using the technology API above. This opens the + // possibility of the player acquiring tech from someplace other than + // the Melnorme. + const TechSaleData* nextTech; - needed_credit = 0; - if (PLAYER_SAID (R, buy_technology)) + // If it's our first time, give an introduction. + if (!GET_GAME_STATE (MELNORME_TECH_PROCEDURE)) { - if (!GET_GAME_STATE (MELNORME_TECH_PROCEDURE)) - { - NPCPhrase (BUY_NEW_TECH_INTRO); - SET_GAME_STATE (MELNORME_TECH_PROCEDURE, 1); - } - stack = 0; - } - else - { - RESPONSE_REF pStr = 0; - - stack = GET_GAME_STATE (MELNORME_TECH_STACK); - switch (stack) - { - case 0: - pStr = OK_BUY_NEW_TECH_1; - needed_credit = 75 * BIO_CREDIT_VALUE; - break; - case 1: - pStr = OK_BUY_NEW_TECH_2; - needed_credit = 75 * BIO_CREDIT_VALUE; - break; - case 2: - pStr = OK_BUY_NEW_TECH_3; - needed_credit = 75 * BIO_CREDIT_VALUE; - break; - case 3: - pStr = OK_BUY_NEW_TECH_4; - needed_credit = 75 * BIO_CREDIT_VALUE; - break; - case 4: - pStr = OK_BUY_NEW_TECH_5; - needed_credit = 75 * BIO_CREDIT_VALUE; - break; - case 5: - pStr = OK_BUY_NEW_TECH_6; - needed_credit = 75 * BIO_CREDIT_VALUE; - break; - case 6: - pStr = OK_BUY_NEW_TECH_7; - needed_credit = 75 * BIO_CREDIT_VALUE; - break; - case 7: - pStr = OK_BUY_NEW_TECH_8; - needed_credit = 75 * BIO_CREDIT_VALUE; - break; - case 8: - pStr = OK_BUY_NEW_TECH_9; - needed_credit = 75 * BIO_CREDIT_VALUE; - break; - case 9: - pStr = OK_BUY_NEW_TECH_10; - needed_credit = 75 * BIO_CREDIT_VALUE; - break; - case 10: - pStr = OK_BUY_NEW_TECH_11; - needed_credit = 75 * BIO_CREDIT_VALUE; - break; - case 11: - pStr = OK_BUY_NEW_TECH_12; - needed_credit = 75 * BIO_CREDIT_VALUE; - break; - case 12: - pStr = OK_BUY_NEW_TECH_13; - needed_credit = 75 * BIO_CREDIT_VALUE; - break; - default: - assert (0 && "Unknown tech"); - } - if ((int)needed_credit > (int)credit) - { - DeltaCredit (-needed_credit); - goto BuyBuyBuy; - } - else - { - ++stack; - NPCPhrase (pStr); - DeltaCredit (-needed_credit); - } + NPCPhrase (BUY_NEW_TECH_INTRO); + SET_GAME_STATE (MELNORME_TECH_PROCEDURE, 1); } - switch (stack) + // Did the player just attempt to buy a tech? + if (PLAYER_SAID (R, buy_new_tech)) { - case 0: - if (GLOBAL (ModuleCost[BLASTER_WEAPON]) == 0) - { - NPCPhrase (NEW_TECH_1); - break; - } - ++stack; - case 1: - GLOBAL (ModuleCost[BLASTER_WEAPON]) = - 4000 / MODULE_COST_SCALE; - if (!GET_GAME_STATE (IMPROVED_LANDER_SPEED)) - { - NPCPhrase (NEW_TECH_2); - break; - } - ++stack; - case 2: - SET_GAME_STATE (IMPROVED_LANDER_SPEED, 1); - if (GLOBAL (ModuleCost[ANTIMISSILE_DEFENSE]) == 0) - { - NPCPhrase (NEW_TECH_3); - break; - } - ++stack; - case 3: - GLOBAL (ModuleCost[ANTIMISSILE_DEFENSE]) = - 4000 / MODULE_COST_SCALE; - if (!(GET_GAME_STATE (LANDER_SHIELDS) - & (1 << BIOLOGICAL_DISASTER))) - { - NPCPhrase (NEW_TECH_4); - break; - } - ++stack; - case 4: - credit = GET_GAME_STATE (LANDER_SHIELDS) - | (1 << BIOLOGICAL_DISASTER); - SET_GAME_STATE (LANDER_SHIELDS, credit); - if (!GET_GAME_STATE (IMPROVED_LANDER_CARGO)) - { - NPCPhrase (NEW_TECH_5); - break; - } - ++stack; - case 5: - SET_GAME_STATE (IMPROVED_LANDER_CARGO, 1); - if (GLOBAL (ModuleCost[HIGHEFF_FUELSYS]) == 0) - { - NPCPhrase (NEW_TECH_6); - break; - } - ++stack; - case 6: - GLOBAL (ModuleCost[HIGHEFF_FUELSYS]) = - 1000 / MODULE_COST_SCALE; - if (!GET_GAME_STATE (IMPROVED_LANDER_SHOT)) - { - NPCPhrase (NEW_TECH_7); - break; - } - ++stack; - case 7: - SET_GAME_STATE (IMPROVED_LANDER_SHOT, 1); - if (!(GET_GAME_STATE (LANDER_SHIELDS) - & (1 << EARTHQUAKE_DISASTER))) - { - NPCPhrase (NEW_TECH_8); - break; - } - ++stack; - case 8: - credit = GET_GAME_STATE (LANDER_SHIELDS) - | (1 << EARTHQUAKE_DISASTER); - SET_GAME_STATE (LANDER_SHIELDS, credit); - if (GLOBAL (ModuleCost[TRACKING_SYSTEM]) == 0) - { - NPCPhrase (NEW_TECH_9); - break; - } - ++stack; - case 9: - GLOBAL (ModuleCost[TRACKING_SYSTEM]) = - 5000 / MODULE_COST_SCALE; - if (!(GET_GAME_STATE (LANDER_SHIELDS) - & (1 << LIGHTNING_DISASTER))) - { - NPCPhrase (NEW_TECH_10); - break; - } - ++stack; - case 10: - credit = GET_GAME_STATE (LANDER_SHIELDS) - | (1 << LIGHTNING_DISASTER); - SET_GAME_STATE (LANDER_SHIELDS, credit); - if (!(GET_GAME_STATE (LANDER_SHIELDS) - & (1 << LAVASPOT_DISASTER))) - { - NPCPhrase (NEW_TECH_11); - break; - } - ++stack; - case 11: - credit = GET_GAME_STATE (LANDER_SHIELDS) - | (1 << LAVASPOT_DISASTER); - SET_GAME_STATE (LANDER_SHIELDS, credit); - if (GLOBAL (ModuleCost[CANNON_WEAPON]) == 0) - { - NPCPhrase (NEW_TECH_12); - break; - } - ++stack; - case 12: - GLOBAL (ModuleCost[CANNON_WEAPON]) = - 6000 / MODULE_COST_SCALE; - if (GLOBAL (ModuleCost[SHIVA_FURNACE]) == 0) - { - NPCPhrase (NEW_TECH_13); - break; - } - ++stack; - case 13: - GLOBAL (ModuleCost[SHIVA_FURNACE]) = - 4000 / MODULE_COST_SCALE; - NPCPhrase (NEW_TECH_ALL_GONE); - SET_GAME_STATE (MELNORME_TECH_STACK, stack); - goto BuyBuyBuy; + nextTech = GetNextTechForSale (); + if (!nextTech) + goto BuyBuyBuy; // No tech left to buy + + if (!DeltaCredit (-nextTech->price)) + goto BuyBuyBuy; // Can't afford it + + // Make the sale + GrantTech (nextTech->techId); + NPCPhrase (nextTech->sold_line); } - SET_GAME_STATE (MELNORME_TECH_STACK, stack); + + nextTech = GetNextTechForSale (); + if (!nextTech) + { + NPCPhrase (NEW_TECH_ALL_GONE); + goto BuyBuyBuy; // No tech left to buy + } + + NPCPhrase (nextTech->sale_line); Response (buy_new_tech, DoBuy); Response (no_buy_new_tech, DoBuy); @@ -1082,42 +1109,33 @@ TryFuelAgain: || PLAYER_SAID (R, buy_alien_races) || PLAYER_SAID (R, buy_history)) { - needed_credit = 0; - if (PLAYER_SAID (R, buy_info)) + if (!GET_GAME_STATE (MELNORME_INFO_PROCEDURE)) { - if (GET_GAME_STATE (MELNORME_INFO_PROCEDURE)) - NPCPhrase (OK_BUY_INFO); - else - { - NPCPhrase (BUY_INFO_INTRO); - SET_GAME_STATE (MELNORME_INFO_PROCEDURE, 1); - } + NPCPhrase (BUY_INFO_INTRO); + SET_GAME_STATE (MELNORME_INFO_PROCEDURE, 1); + } + else if (PLAYER_SAID (R, buy_info)) + { + NPCPhrase (OK_BUY_INFO); } else { #define INFO_COST 75 - needed_credit = INFO_COST; - if ((int)credit >= (int)needed_credit) - { - if (PLAYER_SAID (R, buy_current_events)) - CurrentEvents (); - else if (PLAYER_SAID (R, buy_alien_races)) - AlienRaces (); - else /* if (R == buy_history) */ - History (); - } - - DeltaCredit (-needed_credit); - if (GET_GAME_STATE (MELNORME_EVENTS_INFO_STACK) < NUM_EVENT_ITEMS - || GET_GAME_STATE (MELNORME_ALIEN_INFO_STACK) < NUM_ALIEN_RACE_ITEMS - || GET_GAME_STATE (MELNORME_HISTORY_INFO_STACK) < NUM_HISTORY_ITEMS) - { - } - else - { - NPCPhrase (INFO_ALL_GONE); + if (!DeltaCredit (-INFO_COST)) goto BuyBuyBuy; - } + + if (PLAYER_SAID (R, buy_current_events)) + CurrentEvents (); + else if (PLAYER_SAID (R, buy_alien_races)) + AlienRaces (); + else if (PLAYER_SAID (R, buy_history)) + History (); + } + + if (!AnyInfoLeftToSell ()) + { + NPCPhrase (INFO_ALL_GONE); + goto BuyBuyBuy; } if (GET_GAME_STATE (MELNORME_EVENTS_INFO_STACK) < NUM_EVENT_ITEMS) @@ -1142,12 +1160,11 @@ TryFuelAgain: BuyBuyBuy: if (GLOBAL_SIS (FuelOnBoard) < capacity) Response (buy_fuel, DoBuy); - if (GET_GAME_STATE (MELNORME_TECH_STACK) < NUM_TECH_ITEMS) + if (GetNextTechForSale ()) Response (buy_technology, DoBuy); - if (GET_GAME_STATE (MELNORME_ALIEN_INFO_STACK) < NUM_ALIEN_RACE_ITEMS - || GET_GAME_STATE (MELNORME_HISTORY_INFO_STACK) < NUM_HISTORY_ITEMS - || GET_GAME_STATE (MELNORME_EVENTS_INFO_STACK) < NUM_EVENT_ITEMS) + if (AnyInfoLeftToSell ()) Response (buy_info, DoBuy); + Response (done_buying, NatureOfConversation); Response (be_leaving_now, ExitConversation); } @@ -1222,9 +1239,7 @@ DoSell (RESPONSE_REF R) } while (GLOBAL_SIS (TotalBioMass)); SleepThread (ONE_SECOND / 2); - LockMutex (GraphicsLock); ClearSISRect (DRAW_SIS_DISPLAY); - UnlockMutex (GraphicsLock); } else /* if (R == sell_rainbow_locations) */ { @@ -1267,6 +1282,7 @@ DoSell (RESPONSE_REF R) } } + static void NatureOfConversation (RESPONSE_REF R) { @@ -1280,46 +1296,15 @@ NatureOfConversation (RESPONSE_REF R) R = 0; } - Credit = DeltaCredit (0); + // Draw credits display + DeltaCredit (0); + Credit = GetAvailableCredits (); if (R == 0) { - BYTE stack; - - stack = (BYTE)(GET_GAME_STATE (MELNORME_YACK_STACK2) - 5); - switch (stack++) - { - case 0: - NPCPhrase (HELLO_AND_DOWN_TO_BUSINESS_1); - break; - case 1: - NPCPhrase (HELLO_AND_DOWN_TO_BUSINESS_2); - break; - case 2: - NPCPhrase (HELLO_AND_DOWN_TO_BUSINESS_3); - break; - case 3: - NPCPhrase (HELLO_AND_DOWN_TO_BUSINESS_4); - break; - case 4: - NPCPhrase (HELLO_AND_DOWN_TO_BUSINESS_5); - break; - case 5: - NPCPhrase (HELLO_AND_DOWN_TO_BUSINESS_6); - break; - case 6: - NPCPhrase (HELLO_AND_DOWN_TO_BUSINESS_7); - break; - case 7: - NPCPhrase (HELLO_AND_DOWN_TO_BUSINESS_8); - break; - case 8: - NPCPhrase (HELLO_AND_DOWN_TO_BUSINESS_9); - break; - default: - --stack; - NPCPhrase (HELLO_AND_DOWN_TO_BUSINESS_10); - break; - } + BYTE stack = GET_GAME_STATE (MELNORME_YACK_STACK2) - 5; + NPCPhrase (GetLineSafe (hello_and_down_to_business_lines, stack)); + if (stack < (NUM_HELLO_LINES - 1)) + ++stack; SET_GAME_STATE (MELNORME_YACK_STACK2, stack + 5); } @@ -1352,11 +1337,11 @@ NatureOfConversation (RESPONSE_REF R) { /* Melnorme reports any news and turns purple */ NPCPhrase (BUY_OR_SELL); - AlienTalkSegue(1); + AlienTalkSegue (1); XFormColorMap (GetColorMapAddress ( SetAbsColorMapIndex (CommData.AlienColorMap, 1) ), ONE_SECOND / 2); - AlienTalkSegue((COUNT)~0); + AlienTalkSegue ((COUNT)~0); } else if (PLAYER_SAID (R, why_turned_purple)) { @@ -1394,32 +1379,10 @@ NatureOfConversation (RESPONSE_REF R) } else { - BYTE num_rescues; + BYTE num_rescues = GET_GAME_STATE (MELNORME_RESCUE_COUNT); + NPCPhrase (GetLineSafe (rescue_lines, num_rescues)); - num_rescues = GET_GAME_STATE (MELNORME_RESCUE_COUNT); - switch (num_rescues) - { - case 0: - NPCPhrase (RESCUE_EXPLANATION); - break; - case 1: - NPCPhrase (RESCUE_AGAIN_1); - break; - case 2: - NPCPhrase (RESCUE_AGAIN_2); - break; - case 3: - NPCPhrase (RESCUE_AGAIN_3); - break; - case 4: - NPCPhrase (RESCUE_AGAIN_4); - break; - case 5: - NPCPhrase (RESCUE_AGAIN_5); - break; - } - - if (num_rescues < 5) + if (num_rescues < NUM_RESCUE_LINES - 1) { ++num_rescues; SET_GAME_STATE (MELNORME_RESCUE_COUNT, num_rescues); @@ -1861,11 +1824,9 @@ uninit_melnorme (void) static void post_melnorme_enc (void) { - LockMutex (GraphicsLock); if (prevMsgMode != SMM_UNDEFINED) SetStatusMessageMode (prevMsgMode); DrawStatusMessage (NULL); - UnlockMutex (GraphicsLock); } LOCDATA* @@ -1886,7 +1847,7 @@ init_melnorme_comm (void) prevMsgMode = SMM_UNDEFINED; - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); AskedToBuy = FALSE; retval = &melnorme_desc; diff --git a/sc2/src/uqm/comm/melnorm/resinst.h b/sc2/src/uqm/comm/melnorm/resinst.h index 8d0f00dec..cda8d5a22 100644 --- a/sc2/src/uqm/comm/melnorm/resinst.h +++ b/sc2/src/uqm/comm/melnorm/resinst.h @@ -1,5 +1,9 @@ -#define MELNORME_PMAP_ANIM "comm.melnorme.graphics" -#define MELNORME_FONT "comm.melnorme.font" +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define MELNORME_COLOR_MAP "comm.melnorme.colortable" #define MELNORME_CONVERSATION_PHRASES "comm.melnorme.dialogue" +#define MELNORME_FONT "comm.melnorme.font" #define MELNORME_MUSIC "comm.melnorme.music" +#define MELNORME_PMAP_ANIM "comm.melnorme.graphics" diff --git a/sc2/src/uqm/comm/mycon/Makeinfo b/sc2/src/uqm/comm/mycon/Makeinfo index 04f5f10f2..df0ef7237 100644 --- a/sc2/src/uqm/comm/mycon/Makeinfo +++ b/sc2/src/uqm/comm/mycon/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="myconc.c" +uqm_HFILES="resinst.h strings.h" diff --git a/sc2/src/uqm/comm/mycon/myconc.c b/sc2/src/uqm/comm/mycon/myconc.c index 326bb1253..6490904d7 100644 --- a/sc2/src/uqm/comm/mycon/myconc.c +++ b/sc2/src/uqm/comm/mycon/myconc.c @@ -245,7 +245,7 @@ DoRamble (RESPONSE_REF R) static void CombatIsInevitable (RESPONSE_REF R) { - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); if (PLAYER_SAID (R, bye_space)) NPCPhrase (BYE_AND_DIE_SPACE); @@ -257,7 +257,7 @@ CombatIsInevitable (RESPONSE_REF R) { NPCPhrase (GOODBYE_SUN_DEVICE); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else { @@ -340,7 +340,7 @@ TrickMycon (RESPONSE_REF R) { NPCPhrase (WE_GO_TO_IMPLANT); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); SET_GAME_STATE (MYCON_FELL_FOR_AMBUSH, 1); AddEvent (RELATIVE_EVENT, 0, 0, 0, ADVANCE_MYCON_MISSION); } @@ -371,7 +371,7 @@ NormalMycon (RESPONSE_REF R) DoRamble (R); NPCPhrase (RAMBLE_TAIL); - DISABLE_PHRASE (RESPONSE_TO_REF (R)); + DISABLE_PHRASE (R); } if ((BYTE)TFB_Random () < 256 * 30 / 100) @@ -505,13 +505,13 @@ Intro (void) } SET_GAME_STATE (MYCON_VISITS, NumVisits); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else if (GET_GAME_STATE (MYCON_KNOW_AMBUSH)) { NPCPhrase (DIE_LIAR); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else if (GET_GAME_STATE (GLOBAL_FLAGS_AND_DATA) & (1 << 6)) { @@ -631,11 +631,11 @@ init_mycon_comm (void) if (LOBYTE (GLOBAL (CurrentActivity)) != WON_LAST_BATTLE) { - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else { - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } retval = &mycon_desc; diff --git a/sc2/src/uqm/comm/mycon/resinst.h b/sc2/src/uqm/comm/mycon/resinst.h index db5591024..65a6a3381 100644 --- a/sc2/src/uqm/comm/mycon/resinst.h +++ b/sc2/src/uqm/comm/mycon/resinst.h @@ -1,5 +1,9 @@ -#define MYCON_PMAP_ANIM "comm.mycon.graphics" -#define MYCON_FONT "comm.mycon.font" +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define MYCON_COLOR_MAP "comm.mycon.colortable" #define MYCON_CONVERSATION_PHRASES "comm.mycon.dialogue" +#define MYCON_FONT "comm.mycon.font" #define MYCON_MUSIC "comm.mycon.music" +#define MYCON_PMAP_ANIM "comm.mycon.graphics" diff --git a/sc2/src/uqm/comm/orz/Makeinfo b/sc2/src/uqm/comm/orz/Makeinfo index 3da8e0242..b5c56d24c 100644 --- a/sc2/src/uqm/comm/orz/Makeinfo +++ b/sc2/src/uqm/comm/orz/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="orzc.c" +uqm_HFILES="resinst.h strings.h" diff --git a/sc2/src/uqm/comm/orz/orzc.c b/sc2/src/uqm/comm/orz/orzc.c index 9d1a313eb..72076a67a 100644 --- a/sc2/src/uqm/comm/orz/orzc.c +++ b/sc2/src/uqm/comm/orz/orzc.c @@ -174,7 +174,7 @@ static LOCDATA orz_desc = static void ExitConversation (RESPONSE_REF R) { - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); if (PLAYER_SAID (R, bye_ally)) NPCPhrase (GOODBYE_ALLY); @@ -193,7 +193,7 @@ ExitConversation (RESPONSE_REF R) { NPCPhrase (HOSTILITY_IS_BAD_2); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else if (PLAYER_SAID (R, may_we_land)) { @@ -213,13 +213,13 @@ ExitConversation (RESPONSE_REF R) SET_GAME_STATE (ORZ_GENERAL_INFO, 0); SET_GAME_STATE (ORZ_PERSONAL_INFO, 0); SET_GAME_STATE (ORZ_MANNER, 3); - ActivateStarShip (ORZ_SHIP, SET_ALLIED); + SetRaceAllied (ORZ_SHIP, TRUE); } else if (PLAYER_SAID (R, demand_to_land)) { NPCPhrase (NO_DEMAND); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else if (PLAYER_SAID (R, about_andro_3) || PLAYER_SAID (R, must_know_about_androsyn)) @@ -231,11 +231,11 @@ ExitConversation (RESPONSE_REF R) SET_GAME_STATE (ORZ_VISITS, 0); SET_GAME_STATE (ORZ_MANNER, 2); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); if (PLAYER_SAID (R, about_andro_3)) { - ActivateStarShip (ORZ_SHIP, SET_NOT_ALLIED); - ActivateStarShip (ORZ_SHIP, REMOVE_BUILT); + SetRaceAllied (ORZ_SHIP, FALSE); + RemoveEscortShips (ORZ_SHIP); } XFormColorMap (GetColorMapAddress ( @@ -257,13 +257,13 @@ ExitConversation (RESPONSE_REF R) break; case 2: NPCPhrase (INSULTED_3); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); break; case 7: --NumVisits; default: NPCPhrase (INSULTED_4); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); break; } SET_GAME_STATE (ORZ_PERSONAL_INFO, NumVisits); @@ -322,8 +322,7 @@ TaaloWorld (RESPONSE_REF R) if (PHRASE_ENABLED (may_we_land)) { - if (Manner == 3 && - ActivateStarShip (ORZ_SHIP, CHECK_ALLIANCE) == GOOD_GUY) + if (Manner == 3 && CheckAlliance (ORZ_SHIP) == GOOD_GUY) Response (may_we_land, ExitConversation); else Response (may_we_land, TaaloWorld); @@ -644,7 +643,7 @@ Intro (void) { NPCPhrase (OUT_TAKES); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); return; } @@ -670,7 +669,7 @@ Intro (void) } SET_GAME_STATE (ORZ_VISITS, NumVisits); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else if (GET_GAME_STATE (GLOBAL_FLAGS_AND_DATA) & (1 << 6)) { @@ -705,8 +704,7 @@ Intro (void) TaaloWorld ((RESPONSE_REF)0); } - else if (Manner == 3 && - ActivateStarShip (ORZ_SHIP, CHECK_ALLIANCE) == GOOD_GUY) + else if (Manner == 3 && CheckAlliance (ORZ_SHIP) == GOOD_GUY) { if (GET_GAME_STATE (GLOBAL_FLAGS_AND_DATA) & (1 << 7)) { @@ -859,7 +857,7 @@ post_orz_enc (void) { BYTE Manner; - if (GET_GAME_STATE (BATTLE_SEGUE) == 1 + if (getSegue () == Segue_hostile && (Manner = GET_GAME_STATE (ORZ_MANNER)) != 2) { SET_GAME_STATE (ORZ_MANNER, 1); @@ -888,11 +886,11 @@ init_orz_comm (void) if (GET_GAME_STATE (ORZ_MANNER) == 3 || LOBYTE (GLOBAL (CurrentActivity)) == WON_LAST_BATTLE) { - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else { - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } retval = &orz_desc; diff --git a/sc2/src/uqm/comm/orz/resinst.h b/sc2/src/uqm/comm/orz/resinst.h index da1890d16..a526cefaa 100644 --- a/sc2/src/uqm/comm/orz/resinst.h +++ b/sc2/src/uqm/comm/orz/resinst.h @@ -1,5 +1,9 @@ -#define ORZ_PMAP_ANIM "comm.orz.graphics" -#define ORZ_FONT "comm.orz.font" +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define ORZ_COLOR_MAP "comm.orz.colortable" #define ORZ_CONVERSATION_PHRASES "comm.orz.dialogue" +#define ORZ_FONT "comm.orz.font" #define ORZ_MUSIC "comm.orz.music" +#define ORZ_PMAP_ANIM "comm.orz.graphics" diff --git a/sc2/src/uqm/comm/pkunk/Makeinfo b/sc2/src/uqm/comm/pkunk/Makeinfo index fcc2b3ad7..67dc511a3 100644 --- a/sc2/src/uqm/comm/pkunk/Makeinfo +++ b/sc2/src/uqm/comm/pkunk/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="pkunkc.c" +uqm_HFILES="resinst.h strings.h" diff --git a/sc2/src/uqm/comm/pkunk/pkunkc.c b/sc2/src/uqm/comm/pkunk/pkunkc.c index 55c5e9f2a..5db575d4a 100644 --- a/sc2/src/uqm/comm/pkunk/pkunkc.c +++ b/sc2/src/uqm/comm/pkunk/pkunkc.c @@ -110,7 +110,7 @@ static void PrepareShip (void) { #define MAX_PKUNK_SHIPS 4 - if (ActivateStarShip (PKUNK_SHIP, MAX_PKUNK_SHIPS)) + if (AddEscortShips (PKUNK_SHIP, MAX_PKUNK_SHIPS)) { BYTE mi, di, yi; @@ -132,7 +132,7 @@ PrepareShip (void) static void ExitConversation (RESPONSE_REF R) { - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); if (PLAYER_SAID (R, friendly_bye_space)) NPCPhrase (FRIENDLY_GOODBYE_SPACE); @@ -157,7 +157,7 @@ ExitConversation (RESPONSE_REF R) SET_GAME_STATE (PKUNK_INFO, 0); AddEvent (RELATIVE_EVENT, 6, 0, 0, ADVANCE_PKUNK_MISSION); - if (ActivateStarShip (PKUNK_SHIP, FEASIBILITY_STUDY) == 0) + if (EscortFeasibilityStudy (PKUNK_SHIP) == 0) NPCPhrase (INIT_NO_ROOM); else { @@ -187,13 +187,13 @@ ExitConversation (RESPONSE_REF R) SET_GAME_STATE (PKUNK_MANNER, 2); } - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else if (PLAYER_SAID (R, die_idiot_fools)) { NPCPhrase (VERY_WELL); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else if (PLAYER_SAID (R, suit_yourself)) NPCPhrase (GOODBYE_MIGRATION); @@ -853,7 +853,7 @@ Intro (void) { NPCPhrase (OUT_TAKES); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); return; } @@ -880,7 +880,7 @@ Intro (void) } SET_GAME_STATE (PKUNK_VISITS, NumVisits); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else if (Manner == 1) { @@ -949,7 +949,7 @@ Intro (void) { if (NumVisits && ShipsReady ()) { - if (ActivateStarShip (PKUNK_SHIP, FEASIBILITY_STUDY) == 0) + if (EscortFeasibilityStudy (PKUNK_SHIP) == 0) NPCPhrase (NO_ROOM); else { @@ -1104,7 +1104,7 @@ post_pkunk_enc (void) { BYTE Manner; - if (GET_GAME_STATE (BATTLE_SEGUE) == 1 + if (getSegue () == Segue_hostile && (Manner = GET_GAME_STATE (PKUNK_MANNER)) != 2) { SET_GAME_STATE (PKUNK_MANNER, 1); @@ -1133,12 +1133,12 @@ init_pkunk_comm (void) || LOBYTE (GLOBAL (CurrentActivity)) == WON_LAST_BATTLE) { // Enter communications immediately. - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else { // Ask the player whether to attack or talk. - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } retval = &pkunk_desc; diff --git a/sc2/src/uqm/comm/pkunk/resinst.h b/sc2/src/uqm/comm/pkunk/resinst.h index 2a45b79b1..8f9ab7a5b 100644 --- a/sc2/src/uqm/comm/pkunk/resinst.h +++ b/sc2/src/uqm/comm/pkunk/resinst.h @@ -1,5 +1,9 @@ -#define PKUNK_PMAP_ANIM "comm.pkunk.graphics" -#define PKUNK_FONT "comm.pkunk.font" +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define PKUNK_COLOR_MAP "comm.pkunk.colortable" #define PKUNK_CONVERSATION_PHRASES "comm.pkunk.dialogue" +#define PKUNK_FONT "comm.pkunk.font" #define PKUNK_MUSIC "comm.pkunk.music" +#define PKUNK_PMAP_ANIM "comm.pkunk.graphics" diff --git a/sc2/src/uqm/comm/rebel/Makeinfo b/sc2/src/uqm/comm/rebel/Makeinfo index df7dbc339..4a174671d 100644 --- a/sc2/src/uqm/comm/rebel/Makeinfo +++ b/sc2/src/uqm/comm/rebel/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="rebel.c" +uqm_HFILES="strings.h" diff --git a/sc2/src/uqm/comm/rebel/rebel.c b/sc2/src/uqm/comm/rebel/rebel.c index a26a03260..6366f2092 100644 --- a/sc2/src/uqm/comm/rebel/rebel.c +++ b/sc2/src/uqm/comm/rebel/rebel.c @@ -324,7 +324,7 @@ Rebels (RESPONSE_REF R) || ((NumVisits == 0 && (NumVisits = GLOBAL (GameClock.month_index) - GET_GAME_STATE (YEHAT_SHIP_MONTH)) < 0) || (NumVisits == 0 && GLOBAL (GameClock.day_index) < GET_GAME_STATE (YEHAT_SHIP_DAY))))) NPCPhrase (NO_SHIPS_YET); - else if ((NumVisits = ActivateStarShip (YEHAT_SHIP, FEASIBILITY_STUDY)) == 0) + else if ((NumVisits = EscortFeasibilityStudy (YEHAT_SHIP)) == 0) NPCPhrase (NO_ROOM); else { @@ -338,7 +338,7 @@ Rebels (RESPONSE_REF R) } AlienTalkSegue ((COUNT)~0); - ActivateStarShip (YEHAT_SHIP, NumVisits); + AddEscortShips (YEHAT_SHIP, NumVisits); PrepareShip (); } @@ -376,18 +376,17 @@ Intro (void) { BYTE NumVisits; - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); if (LOBYTE (GLOBAL (CurrentActivity)) == IN_LAST_BATTLE) { NPCPhrase (YEHAT_CAVALRY); AlienTalkSegue ((COUNT)~0); - if ((NumVisits = (BYTE)ActivateStarShip ( - YEHAT_REBEL_SHIP, FEASIBILITY_STUDY - )) > 8) + NumVisits = (BYTE) EscortFeasibilityStudy (YEHAT_REBEL_SHIP); + if (NumVisits > 8) NumVisits = 8; - ActivateStarShip (YEHAT_REBEL_SHIP, NumVisits - (NumVisits >> 1)); - ActivateStarShip (PKUNK_SHIP, NumVisits >> 1); + AddEscortShips (YEHAT_REBEL_SHIP, NumVisits - (NumVisits >> 1)); + AddEscortShips (PKUNK_SHIP, NumVisits >> 1); } else { @@ -443,7 +442,7 @@ init_rebel_yehat_comm (void) yehat_desc.AlienAltSongRes = REBEL_MUSIC; yehat_desc.AlienSongFlags |= LDASF_USE_ALTERNATE; - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); retval = &yehat_desc; return (retval); diff --git a/sc2/src/uqm/comm/shofixt/Makeinfo b/sc2/src/uqm/comm/shofixt/Makeinfo index 9c8364e5b..3cad2ac14 100644 --- a/sc2/src/uqm/comm/shofixt/Makeinfo +++ b/sc2/src/uqm/comm/shofixt/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="shofixt.c" +uqm_HFILES="resinst.h strings.h" diff --git a/sc2/src/uqm/comm/shofixt/resinst.h b/sc2/src/uqm/comm/shofixt/resinst.h index 3fcd62a45..8fe9a871e 100644 --- a/sc2/src/uqm/comm/shofixt/resinst.h +++ b/sc2/src/uqm/comm/shofixt/resinst.h @@ -1,5 +1,9 @@ -#define SHOFIXTI_PMAP_ANIM "comm.shofixti.graphics" -#define SHOFIXTI_FONT "comm.shofixti.font" +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define SHOFIXTI_COLOR_MAP "comm.shofixti.colortable" #define SHOFIXTI_CONVERSATION_PHRASES "comm.shofixti.dialogue" +#define SHOFIXTI_FONT "comm.shofixti.font" #define SHOFIXTI_MUSIC "comm.shofixti.music" +#define SHOFIXTI_PMAP_ANIM "comm.shofixti.graphics" diff --git a/sc2/src/uqm/comm/shofixt/shofixt.c b/sc2/src/uqm/comm/shofixt/shofixt.c index 7b286f34c..e76d8d0a6 100644 --- a/sc2/src/uqm/comm/shofixt/shofixt.c +++ b/sc2/src/uqm/comm/shofixt/shofixt.c @@ -170,25 +170,25 @@ GetShofixtiName (void) static void ExitConversation (RESPONSE_REF R) { - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); if (PLAYER_SAID (R, bye0)) { NPCPhrase (GOODBYE); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else if (PLAYER_SAID (R, go_ahead)) { NPCPhrase (ON_SECOND_THOUGHT); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else if (PLAYER_SAID (R, need_you_for_duty)) { NPCPhrase (OK_WILL_BE_SENTRY); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else if (PLAYER_SAID (R, females) || PLAYER_SAID (R, nubiles) @@ -198,7 +198,7 @@ ExitConversation (RESPONSE_REF R) SET_GAME_STATE (SHOFIXTI_RECRUITED, 1); SET_GAME_STATE (MAIDENS_ON_SHIP, 0); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); AddEvent (RELATIVE_EVENT, 2, 0, 0, SHOFIXTI_RETURN_EVENT); } @@ -546,7 +546,7 @@ Intro (void) { NPCPhrase (OUT_TAKES); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); return; } @@ -644,7 +644,7 @@ init_shofixti_comm (void) shofixti_desc.AlienTextBaseline.y = 0; shofixti_desc.AlienTextWidth = SIS_TEXT_WIDTH; - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); retval = &shofixti_desc; diff --git a/sc2/src/uqm/comm/slyhome/Makeinfo b/sc2/src/uqm/comm/slyhome/Makeinfo index 9c3c19924..a09471e48 100644 --- a/sc2/src/uqm/comm/slyhome/Makeinfo +++ b/sc2/src/uqm/comm/slyhome/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="slyhome.c" +uqm_HFILES="resinst.h strings.h" diff --git a/sc2/src/uqm/comm/slyhome/resinst.h b/sc2/src/uqm/comm/slyhome/resinst.h index 2c12e53c0..1bbf16252 100644 --- a/sc2/src/uqm/comm/slyhome/resinst.h +++ b/sc2/src/uqm/comm/slyhome/resinst.h @@ -1,5 +1,9 @@ -#define SLYLANDRO_PMAP_ANIM "comm.slylandro.graphics" -#define SLYLANDRO_FONT "comm.slylandro.font" +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define SLYLANDRO_COLOR_MAP "comm.slylandro.colortable" #define SLYLANDRO_CONVERSATION_PHRASES "comm.slylandro.dialogue" +#define SLYLANDRO_FONT "comm.slylandro.font" #define SLYLANDRO_MUSIC "comm.slylandro.music" +#define SLYLANDRO_PMAP_ANIM "comm.slylandro.graphics" diff --git a/sc2/src/uqm/comm/slyhome/slyhome.c b/sc2/src/uqm/comm/slyhome/slyhome.c index 85954947b..80cb83979 100644 --- a/sc2/src/uqm/comm/slyhome/slyhome.c +++ b/sc2/src/uqm/comm/slyhome/slyhome.c @@ -175,7 +175,7 @@ static void ExitConversation (RESPONSE_REF R) { (void) R; // ignored - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); switch (GET_GAME_STATE (SLYLANDRO_HOME_VISITS)) { @@ -914,7 +914,7 @@ init_slylandro_comm (void) slylandro_desc.AlienTextBaseline.y = 0; slylandro_desc.AlienTextWidth = SIS_TEXT_WIDTH; - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); retval = &slylandro_desc; return (retval); diff --git a/sc2/src/uqm/comm/slyland/Makeinfo b/sc2/src/uqm/comm/slyland/Makeinfo index 5d503f80d..10d3a53c1 100644 --- a/sc2/src/uqm/comm/slyland/Makeinfo +++ b/sc2/src/uqm/comm/slyland/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="slyland.c" +uqm_HFILES="resinst.h strings.h" diff --git a/sc2/src/uqm/comm/slyland/resinst.h b/sc2/src/uqm/comm/slyland/resinst.h index 162a09eec..d0b9a3608 100644 --- a/sc2/src/uqm/comm/slyland/resinst.h +++ b/sc2/src/uqm/comm/slyland/resinst.h @@ -1,5 +1,9 @@ -#define SLYLAND_PMAP_ANIM "comm.probe.graphics" -#define SLYLAND_FONT "comm.probe.font" +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define SLYLAND_COLOR_MAP "comm.probe.colortable" #define SLYLAND_CONVERSATION_PHRASES "comm.probe.dialogue" +#define SLYLAND_FONT "comm.probe.font" #define SLYLAND_MUSIC "comm.probe.music" +#define SLYLAND_PMAP_ANIM "comm.probe.graphics" diff --git a/sc2/src/uqm/comm/slyland/slyland.c b/sc2/src/uqm/comm/slyland/slyland.c index 0566b4922..ae7cb44e9 100644 --- a/sc2/src/uqm/comm/slyland/slyland.c +++ b/sc2/src/uqm/comm/slyland/slyland.c @@ -314,8 +314,7 @@ CombatIsInevitable (RESPONSE_REF R) else if (PLAYER_SAID (R, destruct_code)) { NPCPhrase (DESTRUCT_SEQUENCE); - instantVictory = TRUE; - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_victory); } else { @@ -443,7 +442,7 @@ CombatIsInevitable (RESPONSE_REF R) NPCPhrase (HOSTILE); SET_GAME_STATE (PROBE_EXHIBITED_BUG, 1); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } } @@ -511,7 +510,7 @@ init_slyland_comm (void) slylandro_desc.AlienTextBaseline.y = 0; slylandro_desc.AlienTextWidth = SIS_TEXT_WIDTH - 16; - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); retval = &slylandro_desc; return (retval); diff --git a/sc2/src/uqm/comm/spahome/Makeinfo b/sc2/src/uqm/comm/spahome/Makeinfo index e3c358e57..69720139d 100644 --- a/sc2/src/uqm/comm/spahome/Makeinfo +++ b/sc2/src/uqm/comm/spahome/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="spahome.c" +uqm_HFILES="strings.h" diff --git a/sc2/src/uqm/comm/spahome/spahome.c b/sc2/src/uqm/comm/spahome/spahome.c index e503104da..190e3bb38 100644 --- a/sc2/src/uqm/comm/spahome/spahome.c +++ b/sc2/src/uqm/comm/spahome/spahome.c @@ -186,24 +186,24 @@ static LOCDATA spahome_desc = static void ExitConversation (RESPONSE_REF R) { - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); if (PLAYER_SAID (R, we_attack_again)) { NPCPhrase (WE_FIGHT_AGAIN); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else if (PLAYER_SAID (R, surrender_or_die)) { NPCPhrase (DEFEND_OURSELVES); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else if (PLAYER_SAID (R, we_are_vindicator0)) { NPCPhrase (NO_PASSWORD); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else if (PLAYER_SAID (R, gort_merenga) || PLAYER_SAID (R, guph_florp) @@ -212,13 +212,13 @@ ExitConversation (RESPONSE_REF R) { NPCPhrase (WRONG_PASSWORD); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else if (PLAYER_SAID (R, screw_password)) { NPCPhrase (NO_PASSWORD); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else if (PLAYER_SAID (R, bye_no_ally_offer)) NPCPhrase (GOODBYE_NO_ALLY_OFFER); @@ -251,7 +251,7 @@ ExitConversation (RESPONSE_REF R) { NPCPhrase (DEPART_FOR_EARTH); - ActivateStarShip (SPATHI_SHIP, SET_ALLIED); + SetRaceAllied (SPATHI_SHIP, TRUE); AddEvent (RELATIVE_EVENT, 6, 0, 0, SPATHI_SHIELD_EVENT); SET_GAME_STATE (SPATHI_HOME_VISITS, 0); SET_GAME_STATE (SPATHI_VISITS, 0); @@ -821,7 +821,7 @@ SpathiCouncil (RESPONSE_REF R) { if (PHRASE_ENABLED (spathi_on_pluto)) Response (spathi_on_pluto, SpathiCouncil); - else if (ActivateStarShip (SPATHI_SHIP, ESCORTING_FLAGSHIP)) + else if (HaveEscortShip (SPATHI_SHIP)) { if (PHRASE_ENABLED (hostage)) Response (hostage, SpathiCouncil); @@ -906,7 +906,7 @@ Intro (void) if (Manner == 2) { NPCPhrase (HATE_YOU_FOREVER); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else if (Manner == 1 && GET_GAME_STATE (KNOW_SPATHI_PASSWORD) @@ -915,7 +915,7 @@ Intro (void) { SpathiAngry ((RESPONSE_REF)0); } - else if (ActivateStarShip (SPATHI_SHIP, CHECK_ALLIANCE) == GOOD_GUY) + else if (CheckAlliance (SPATHI_SHIP) == GOOD_GUY) { CommData.AlienColorMap = SetAbsColorMapIndex (CommData.AlienColorMap, 1); @@ -940,7 +940,7 @@ Intro (void) NPCPhrase (YOU_LIED_2); SET_GAME_STATE (SPATHI_MANNER, 2); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } } else if (GET_GAME_STATE (KNOW_SPATHI_QUEST)) @@ -974,7 +974,7 @@ post_spahome_enc (void) { BYTE Manner; - if (GET_GAME_STATE (BATTLE_SEGUE) == 1 + if (getSegue () == Segue_hostile && (Manner = GET_GAME_STATE (SPATHI_MANNER)) != 2) { SET_GAME_STATE (SPATHI_MANNER, 1); @@ -1005,11 +1005,11 @@ init_spahome_comm () if (GET_GAME_STATE (SPATHI_MANNER) == 3) { - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else { - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } retval = &spahome_desc; diff --git a/sc2/src/uqm/comm/spathi/Makeinfo b/sc2/src/uqm/comm/spathi/Makeinfo index 49fb60564..09e88742e 100644 --- a/sc2/src/uqm/comm/spathi/Makeinfo +++ b/sc2/src/uqm/comm/spathi/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="spathic.c" +uqm_HFILES="resinst.h strings.h" diff --git a/sc2/src/uqm/comm/spathi/resinst.h b/sc2/src/uqm/comm/spathi/resinst.h index a94bb27b5..f83962b81 100644 --- a/sc2/src/uqm/comm/spathi/resinst.h +++ b/sc2/src/uqm/comm/spathi/resinst.h @@ -1,10 +1,14 @@ -#define SPATHI_HOME_PMAP_ANIM "comm.safeones.graphics" -#define SPATHI_PMAP_ANIM "comm.spathi.graphics" -#define SPATHI_FONT "comm.spathi.font" -#define SPATHI_COLOR_MAP "comm.spathi.colortable" -#define SPATHI_CONVERSATION_PHRASES "comm.spathi.dialogue" -#define SPATHI_HOME_COLOR_MAP "comm.safeones.colortable" -#define SPATHI_HOME_CONVERSATION_PHRASES "comm.safeones.dialogue" +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define FWIFFO_MUSIC "comm.fwiffo.music" #define SPAHOME_MUSIC "comm.safeones.music" +#define SPATHI_COLOR_MAP "comm.spathi.colortable" +#define SPATHI_CONVERSATION_PHRASES "comm.spathi.dialogue" +#define SPATHI_FONT "comm.spathi.font" +#define SPATHI_HOME_COLOR_MAP "comm.safeones.colortable" +#define SPATHI_HOME_CONVERSATION_PHRASES "comm.safeones.dialogue" +#define SPATHI_HOME_PMAP_ANIM "comm.safeones.graphics" #define SPATHI_MUSIC "comm.spathi.music" +#define SPATHI_PMAP_ANIM "comm.spathi.graphics" diff --git a/sc2/src/uqm/comm/spathi/spathic.c b/sc2/src/uqm/comm/spathi/spathic.c index c34605f2a..29288dc17 100644 --- a/sc2/src/uqm/comm/spathi/spathic.c +++ b/sc2/src/uqm/comm/spathi/spathic.c @@ -147,7 +147,7 @@ static LOCDATA spathi_desc = static void ExitConversation (RESPONSE_REF Response) { - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); if (PLAYER_SAID (Response, bye_ally_space)) NPCPhrase (GOODBYE_ALLY_SPACE); @@ -165,13 +165,13 @@ ExitConversation (RESPONSE_REF Response) { NPCPhrase (YIPES); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else if (PLAYER_SAID (Response, we_fight_again_space)) { NPCPhrase (OK_FIGHT_AGAIN_SPACE); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else if (PLAYER_SAID (Response, die_slugboy) || PLAYER_SAID (Response, we_fight_1) @@ -184,18 +184,18 @@ ExitConversation (RESPONSE_REF Response) NPCPhrase (FAKE_COORDINATES); NPCPhrase (OK_WE_FIGHT_AT_PLUTO); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else if (PLAYER_SAID (Response, join_us)) { - if (ActivateStarShip (SPATHI_SHIP, FEASIBILITY_STUDY) == 0) + if (EscortFeasibilityStudy (SPATHI_SHIP) == 0) NPCPhrase (TOO_SCARY); else { NPCPhrase (WILL_JOIN); AlienTalkSegue ((COUNT)~0); - ActivateStarShip (SPATHI_SHIP, 1); + AddEscortShips (SPATHI_SHIP, 1); /* Make the Eluder escort captained by Fwiffo alone */ SetEscortCrewComplement (SPATHI_SHIP, 1, NAME_OFFSET + NUM_CAPTAINS_NAMES); @@ -726,7 +726,7 @@ Intro (void) else if (Manner == 2) { NPCPhrase (HATE_YOU_FOREVER_SPACE); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else if (Manner == 1) { @@ -750,7 +750,7 @@ Intro (void) Response (we_fight_again_space, ExitConversation); Response (bye_angry_space, ExitConversation); } - else if (ActivateStarShip (SPATHI_SHIP, CHECK_ALLIANCE) == GOOD_GUY) + else if (CheckAlliance (SPATHI_SHIP) == GOOD_GUY) { SpathiAllies ((RESPONSE_REF)0); } @@ -779,7 +779,7 @@ post_spathi_enc (void) { SET_GAME_STATE (FOUND_PLUTO_SPATHI, 2); } - else if (GET_GAME_STATE (BATTLE_SEGUE) == 1 + else if (getSegue () == Segue_hostile && (Manner = GET_GAME_STATE (SPATHI_MANNER)) != 2) { SET_GAME_STATE (SPATHI_MANNER, 1); @@ -822,11 +822,11 @@ init_spathi_comm (void) || GET_GAME_STATE (SPATHI_MANNER) == 3 || LOBYTE (GLOBAL (CurrentActivity)) == WON_LAST_BATTLE) { - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else { - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } retval = &spathi_desc; diff --git a/sc2/src/uqm/comm/starbas/Makeinfo b/sc2/src/uqm/comm/starbas/Makeinfo index 93fcc7e9b..7f1eab870 100644 --- a/sc2/src/uqm/comm/starbas/Makeinfo +++ b/sc2/src/uqm/comm/starbas/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="starbas.c" +uqm_HFILES="strings.h" diff --git a/sc2/src/uqm/comm/starbas/starbas.c b/sc2/src/uqm/comm/starbas/starbas.c index 860896cc2..5f25a2dba 100644 --- a/sc2/src/uqm/comm/starbas/starbas.c +++ b/sc2/src/uqm/comm/starbas/starbas.c @@ -28,7 +28,6 @@ #include "libs/graphics/gfx_common.h" #include "libs/mathlib.h" #include "libs/inplib.h" -#include "libs/sound/sound.h" static void TellMission (RESPONSE_REF R); @@ -214,7 +213,7 @@ ByeBye (RESPONSE_REF R) } NPCPhrase (pStr0); - if (speechVolumeScale == 0.0f) + if (!usingSpeech) { NPCPhrase (SPACE); NPCPhrase (GLOBAL_PLAYER_NAME); @@ -303,6 +302,7 @@ HierarchyInfo (RESPONSE_REF R) #define HIERARCHY_ANDROSYNTH (1 << 3) #define HIERARCHY_ILWRATH (1 << 4) #define HIERARCHY_VUX (1 << 5) +#define HIERARCHY_URQUAN (1 << 6) static BYTE HierarchyMask = 0; if (PLAYER_SAID (R, what_about_hierarchy)) @@ -310,6 +310,11 @@ HierarchyInfo (RESPONSE_REF R) NPCPhrase (WHICH_HIERARCHY); HierarchyMask = 0; } + else if (PLAYER_SAID (R, urquan)) + { + NPCPhrase (ABOUT_URQUAN); + HierarchyMask |= HIERARCHY_URQUAN; + } else if (PLAYER_SAID (R, mycon)) { NPCPhrase (ABOUT_MYCON); @@ -341,6 +346,8 @@ HierarchyInfo (RESPONSE_REF R) HierarchyMask |= HIERARCHY_VUX; } + if (!(HierarchyMask & HIERARCHY_URQUAN)) + Response (urquan, HierarchyInfo); if (!(HierarchyMask & HIERARCHY_MYCON)) Response (mycon, HierarchyInfo); if (!(HierarchyMask & HIERARCHY_SPATHI)) @@ -678,7 +685,7 @@ AnalyzeCondition (void) if (num_bays < 1) NPCPhrase (NEED_STORAGE_1); if (GLOBAL_SIS (NumLanders) == 0) - NPCPhrase (NEED_LANDERS_1); + NPCPhrase (NEED_LANDERS_2); if (num_batts < 1) NPCPhrase (NEED_DYNAMOS_1); @@ -693,11 +700,10 @@ AnalyzeCondition (void) COUNT FleetStrength; BOOLEAN HasMaximum; - FleetStrength = ActivateStarShip (0, ESCORT_WORTH); + FleetStrength = CalculateEscortsWorth (); for (i = 0; i < NUM_AVAILABLE_RACES; ++i) { - if (i != HUMAN_SHIP - && ActivateStarShip (i, CHECK_ALLIANCE) == GOOD_GUY) + if (i != HUMAN_SHIP && CheckAlliance (i) == GOOD_GUY) ++num_aliens; } @@ -755,7 +761,7 @@ AnalyzeCondition (void) if (GLOBAL_SIS (FuelOnBoard) < FUEL_TANK_CAPACITY * 3) NPCPhrase (NEED_FUEL_2); if (GLOBAL_SIS (NumLanders) < 3) - NPCPhrase (NEED_LANDERS_2); + NPCPhrase (NEED_LANDERS_1); if (num_batts < 4) NPCPhrase (NEED_DYNAMOS_2); if (num_defense < 2) @@ -900,7 +906,7 @@ TellStarBase (RESPONSE_REF R) else if (PLAYER_SAID (R, tell_me_about_crew)) { NPCPhrase (ABOUT_CREW0); - if (speechVolumeScale > 0.0f) + if (usingSpeech) NPCPhrase (YOUR_FLAGSHIP_3DO2); else { NPCPhrase (YOUR_FLAGSHIP_PC); @@ -1370,36 +1376,31 @@ CheckBulletins (BOOLEAN Repeat) switch (b0) { case 0: - if (ActivateStarShip (SPATHI_SHIP, CHECK_ALLIANCE) - == GOOD_GUY) + if (CheckAlliance (SPATHI_SHIP) == GOOD_GUY) { pStr = STARBASE_BULLETIN_1; } break; case 1: - if (ActivateStarShip (ZOQFOTPIK_SHIP, CHECK_ALLIANCE) - == GOOD_GUY) + if (CheckAlliance (ZOQFOTPIK_SHIP) == GOOD_GUY) { pStr = STARBASE_BULLETIN_2; } break; case 2: - if (ActivateStarShip (SUPOX_SHIP, CHECK_ALLIANCE) - == GOOD_GUY) + if (CheckAlliance (SUPOX_SHIP) == GOOD_GUY) { pStr = STARBASE_BULLETIN_3; } break; case 3: - if (ActivateStarShip (UTWIG_SHIP, CHECK_ALLIANCE) - == GOOD_GUY) + if (CheckAlliance (UTWIG_SHIP) == GOOD_GUY) { pStr = STARBASE_BULLETIN_4; } break; case 4: - if (ActivateStarShip (ORZ_SHIP, CHECK_ALLIANCE) - == GOOD_GUY) + if (CheckAlliance (ORZ_SHIP) == GOOD_GUY) { pStr = STARBASE_BULLETIN_5; } @@ -1408,14 +1409,13 @@ CheckBulletins (BOOLEAN Repeat) if (GET_GAME_STATE (ARILOU_MANNER) == 2) BulletinMask |= 1L << b0; else if (GET_GAME_STATE (PORTAL_SPAWNER) - && (Repeat || ActivateStarShip ( - ARILOU_SHIP, FEASIBILITY_STUDY - ))) + && (Repeat || EscortFeasibilityStudy ( + ARILOU_SHIP))) { #define NUM_GIFT_ARILOUS 3 pStr = STARBASE_BULLETIN_6; if (!Repeat) - ActivateStarShip (ARILOU_SHIP, NUM_GIFT_ARILOUS); + AddEscortShips (ARILOU_SHIP, NUM_GIFT_ARILOUS); } break; case 6: @@ -1464,15 +1464,13 @@ CheckBulletins (BOOLEAN Repeat) } break; case 12: - if (ActivateStarShip (CHMMR_SHIP, CHECK_ALLIANCE) - == GOOD_GUY) + if (CheckAlliance (CHMMR_SHIP) == GOOD_GUY) { pStr = STARBASE_BULLETIN_13; } break; case 13: - if (ActivateStarShip (SHOFIXTI_SHIP, CHECK_ALLIANCE) - == GOOD_GUY) + if (CheckAlliance (SHOFIXTI_SHIP) == GOOD_GUY) { pStr = STARBASE_BULLETIN_14; } @@ -1646,21 +1644,19 @@ NormalStarbase (RESPONSE_REF R) if (GET_GAME_STATE (MOONBASE_ON_SHIP)) { NPCPhrase (STARBASE_IS_READY_A); - if (speechVolumeScale > 0.0f) + if (usingSpeech) NPCPhrase (YOUR_FLAGSHIP_3DO1); else { NPCPhrase (YOUR_FLAGSHIP_PC); NPCPhrase (GLOBAL_SHIP_NAME); } NPCPhrase (STARBASE_IS_READY_B); - if (speechVolumeScale > 0.0f) + if (usingSpeech) NPCPhrase (YOUR_FLAGSHIP_3DO0); else NPCPhrase (GLOBAL_SHIP_NAME); NPCPhrase (STARBASE_IS_READY_C); - LockMutex (GraphicsLock); DeltaSISGauges (0, 0, 2500); - UnlockMutex (GraphicsLock); SET_GAME_STATE (STARBASE_MONTH, GLOBAL (GameClock.month_index)); SET_GAME_STATE (STARBASE_DAY, @@ -1711,7 +1707,7 @@ NormalStarbase (RESPONSE_REF R) break; } NPCPhrase (pStr0); - if (speechVolumeScale == 0.0f) + if (!usingSpeech) { NPCPhrase (SPACE); NPCPhrase (GLOBAL_PLAYER_NAME); @@ -1772,9 +1768,7 @@ SellMinerals (RESPONSE_REF R) Sleepy = FALSE; GLOBAL_SIS (ElementAmounts[i]) = 0; GLOBAL_SIS (TotalElementMass) -= amount; - LockMutex (GraphicsLock); DeltaSISGauges (0, 0, amount * GLOBAL (ElementWorth[i])); - UnlockMutex (GraphicsLock); break; } @@ -1783,10 +1777,8 @@ SellMinerals (RESPONSE_REF R) TaskSwitch (); TimeIn = GetTimeCounter (); DrawCargoStrings ((BYTE)i, (BYTE)i); - LockMutex (GraphicsLock); ShowRemainingCapacity (); DeltaSISGauges (0, 0, GLOBAL (ElementWorth[i])); - UnlockMutex (GraphicsLock); } while (--amount); } if (Sleepy) { @@ -1796,9 +1788,7 @@ SellMinerals (RESPONSE_REF R) } SleepThread (ONE_SECOND / 2); - LockMutex (GraphicsLock); ClearSISRect (DRAW_SIS_DISPLAY); - UnlockMutex (GraphicsLock); // DrawStorageBays (FALSE); if (total < 1000) @@ -1914,7 +1904,7 @@ SellMinerals (RESPONSE_REF R) } NPCPhrase (pStr1); - if (speechVolumeScale == 0.0f) + if (!usingSpeech) { NPCPhrase (SPACE); NPCPhrase (GLOBAL_PLAYER_NAME); @@ -1964,7 +1954,7 @@ init_starbase_comm () commander_desc.AlienSongFlags |= LDASF_USE_ALTERNATE; CurBulletinMask = 0; - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); retval = &commander_desc; return (retval); diff --git a/sc2/src/uqm/comm/supox/Makeinfo b/sc2/src/uqm/comm/supox/Makeinfo index db7eaa5b6..8745013a0 100644 --- a/sc2/src/uqm/comm/supox/Makeinfo +++ b/sc2/src/uqm/comm/supox/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="supoxc.c" +uqm_HFILES="resinst.h strings.h" diff --git a/sc2/src/uqm/comm/supox/resinst.h b/sc2/src/uqm/comm/supox/resinst.h index e56472523..03459ea90 100644 --- a/sc2/src/uqm/comm/supox/resinst.h +++ b/sc2/src/uqm/comm/supox/resinst.h @@ -1,5 +1,9 @@ -#define SUPOX_PMAP_ANIM "comm.supox.graphics" -#define SUPOX_FONT "comm.supox.font" +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define SUPOX_COLOR_MAP "comm.supox.colortable" #define SUPOX_CONVERSATION_PHRASES "comm.supox.dialogue" +#define SUPOX_FONT "comm.supox.font" #define SUPOX_MUSIC "comm.supox.music" +#define SUPOX_PMAP_ANIM "comm.supox.graphics" diff --git a/sc2/src/uqm/comm/supox/supoxc.c b/sc2/src/uqm/comm/supox/supoxc.c index abad51c30..e169cbab7 100644 --- a/sc2/src/uqm/comm/supox/supoxc.c +++ b/sc2/src/uqm/comm/supox/supoxc.c @@ -103,7 +103,7 @@ static LOCDATA supox_desc = static void ExitConversation (RESPONSE_REF R) { - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); if (PLAYER_SAID (R, bye_neutral)) NPCPhrase (GOODBYE_NEUTRAL); @@ -126,14 +126,14 @@ ExitConversation (RESPONSE_REF R) else if (PLAYER_SAID (R, can_you_help)) { NPCPhrase (HOW_HELP); - if (ActivateStarShip (SUPOX_SHIP, FEASIBILITY_STUDY) == 0) + if (EscortFeasibilityStudy (SUPOX_SHIP) == 0) NPCPhrase (DONT_NEED); else { NPCPhrase (HAVE_4_SHIPS); AlienTalkSegue ((COUNT)~0); - ActivateStarShip (SUPOX_SHIP, 4); + AddEscortShips (SUPOX_SHIP, 4); } } } @@ -357,7 +357,7 @@ NeutralSupox (RESPONSE_REF R) LastStack = 2; SET_GAME_STATE (SUPOX_WAR_NEWS, 1); - ActivateStarShip (UTWIG_SHIP, SPHERE_TRACKING); + StartSphereTracking (UTWIG_SHIP); } else if (PLAYER_SAID (R, what_relation_to_utwig)) { @@ -531,7 +531,7 @@ Intro (void) { NPCPhrase (OUT_TAKES); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); return; } @@ -550,9 +550,9 @@ Intro (void) } SET_GAME_STATE (SUPOX_VISITS, NumVisits); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } - else if (ActivateStarShip (SUPOX_SHIP, CHECK_ALLIANCE) == GOOD_GUY) + else if (CheckAlliance (SUPOX_SHIP) == GOOD_GUY) { if (GET_GAME_STATE (GLOBAL_FLAGS_AND_DATA) & (1 << 7)) { @@ -696,11 +696,11 @@ init_supox_comm (void) if (!GET_GAME_STATE (SUPOX_HOSTILE) || LOBYTE (GLOBAL (CurrentActivity)) == WON_LAST_BATTLE) { - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else { - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } retval = &supox_desc; diff --git a/sc2/src/uqm/comm/syreen/Makeinfo b/sc2/src/uqm/comm/syreen/Makeinfo index af4e997e3..e2a265e2f 100644 --- a/sc2/src/uqm/comm/syreen/Makeinfo +++ b/sc2/src/uqm/comm/syreen/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="syreenc.c" +uqm_HFILES="resinst.h strings.h" diff --git a/sc2/src/uqm/comm/syreen/resinst.h b/sc2/src/uqm/comm/syreen/resinst.h index 675c0812e..16f7b0bfd 100644 --- a/sc2/src/uqm/comm/syreen/resinst.h +++ b/sc2/src/uqm/comm/syreen/resinst.h @@ -1,5 +1,9 @@ -#define SYREEN_PMAP_ANIM "comm.syreen.graphics" -#define SYREEN_FONT "comm.syreen.font" +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define SYREEN_COLOR_MAP "comm.syreen.colortable" #define SYREEN_CONVERSATION_PHRASES "comm.syreen.dialogue" +#define SYREEN_FONT "comm.syreen.font" #define SYREEN_MUSIC "comm.syreen.music" +#define SYREEN_PMAP_ANIM "comm.syreen.graphics" diff --git a/sc2/src/uqm/comm/syreen/syreenc.c b/sc2/src/uqm/comm/syreen/syreenc.c index 5224eca3c..8884ad6b0 100644 --- a/sc2/src/uqm/comm/syreen/syreenc.c +++ b/sc2/src/uqm/comm/syreen/syreenc.c @@ -20,8 +20,8 @@ #include "resinst.h" #include "strings.h" -#include "libs/sound/sound.h" #include "uqm/build.h" +#include "uqm/setup.h" static LOCDATA syreen_desc = @@ -193,7 +193,7 @@ static LOCDATA syreen_desc = static void FriendlyExit (RESPONSE_REF R) { - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); if (PLAYER_SAID (R, bye)) NPCPhrase (GOODBYE); @@ -555,7 +555,7 @@ NormalSyreen (RESPONSE_REF R) { NPCPhrase (HORRIBLE_TRUTH); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); SET_GAME_STATE (SYREEN_HOME_VISITS, 0); SET_GAME_STATE (SYREEN_KNOW_ABOUT_MYCON, 1); @@ -652,7 +652,7 @@ InitialSyreen (RESPONSE_REF R) else if (PLAYER_SAID (R, we_are_vindicator0)) { NPCPhrase (WELCOME_VINDICATOR0); - if (speechVolumeScale == 0.0f) + if (!usingSpeech) { NPCPhrase (GLOBAL_PLAYER_NAME); NPCPhrase (WELCOME_VINDICATOR1); @@ -729,7 +729,7 @@ Intro (void) { NPCPhrase (OUT_TAKES); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); return; } @@ -740,7 +740,7 @@ Intro (void) { case 0: NPCPhrase (HELLO_AFTER_AMBUSH_1); - ActivateStarShip (SYREEN_SHIP, SET_ALLIED); + SetRaceAllied (SYREEN_SHIP, TRUE); break; case 1: NPCPhrase (HELLO_AFTER_AMBUSH_2); @@ -871,7 +871,7 @@ init_syreen_comm (void) syreen_desc.AlienTextBaseline.y = 0; syreen_desc.AlienTextWidth = SIS_TEXT_WIDTH - 16; - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); retval = &syreen_desc; return (retval); diff --git a/sc2/src/uqm/comm/talkpet/Makeinfo b/sc2/src/uqm/comm/talkpet/Makeinfo index 337fc2ea1..59f7d27b1 100644 --- a/sc2/src/uqm/comm/talkpet/Makeinfo +++ b/sc2/src/uqm/comm/talkpet/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="talkpet.c" +uqm_HFILES="resinst.h strings.h" diff --git a/sc2/src/uqm/comm/talkpet/resinst.h b/sc2/src/uqm/comm/talkpet/resinst.h index fa3f30243..20398f99d 100644 --- a/sc2/src/uqm/comm/talkpet/resinst.h +++ b/sc2/src/uqm/comm/talkpet/resinst.h @@ -1,5 +1,9 @@ -#define TALKING_PET_PMAP_ANIM "comm.talkingpet.graphics" -#define TALKING_PET_FONT "comm.talkingpet.font" +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define TALKING_PET_COLOR_MAP "comm.talkingpet.colortable" #define TALKING_PET_CONVERSATION_PHRASES "comm.talkingpet.dialogue" +#define TALKING_PET_FONT "comm.talkingpet.font" #define TALKING_PET_MUSIC "comm.talkingpet.music" +#define TALKING_PET_PMAP_ANIM "comm.talkingpet.graphics" diff --git a/sc2/src/uqm/comm/talkpet/talkpet.c b/sc2/src/uqm/comm/talkpet/talkpet.c index 1bcbd49d0..ce59011b7 100644 --- a/sc2/src/uqm/comm/talkpet/talkpet.c +++ b/sc2/src/uqm/comm/talkpet/talkpet.c @@ -213,7 +213,7 @@ static LOCDATA talkpet_desc = static void ExitConversation (RESPONSE_REF R) { - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); SET_GAME_STATE (SHIP_TO_COMPEL, 0); if (PLAYER_SAID (R, compel_urquan)) @@ -498,7 +498,7 @@ CompelPlayer (RESPONSE_REF R) { NPCPhrase (CANT_COMPEL); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } return; @@ -649,14 +649,14 @@ Intro (void) { NPCPhrase (OUT_TAKES); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); return; } if (LOBYTE (GLOBAL (CurrentActivity)) == IN_LAST_BATTLE) { SET_GAME_STATE (SHIP_TO_COMPEL, 0); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); if (!(GLOBAL (glob_flags) & CYBORG_ENABLED)) { NPCPhrase (HUMAN_PEP_TALK); @@ -679,13 +679,13 @@ Intro (void) else NPCPhrase (SOUP_UP_BOMB); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else if (GET_GAME_STATE (URQUAN_MESSED_UP)) { NPCPhrase (HELLO_AFTER_COMPEL_URQUAN); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else { @@ -769,18 +769,18 @@ Intro (void) else if (!GET_GAME_STATE (TAALO_PROTECTOR_ON_SHIP)) { SET_GAME_STATE (PLAYER_HYPNOTIZED, 1); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else { NPCPhrase (CANT_COMPEL); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } } else { - if (ActivateStarShip (UMGAH_SHIP, SPHERE_TRACKING)) + if (StartSphereTracking (UMGAH_SHIP)) { NPCPhrase (LETS_MAKE_A_DEAL); } @@ -828,11 +828,11 @@ init_talkpet_comm (void) if (LOBYTE (GLOBAL (CurrentActivity)) != IN_LAST_BATTLE) { - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else { - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } retval = &talkpet_desc; diff --git a/sc2/src/uqm/comm/thradd/Makeinfo b/sc2/src/uqm/comm/thradd/Makeinfo index 6c08c57c5..d49280055 100644 --- a/sc2/src/uqm/comm/thradd/Makeinfo +++ b/sc2/src/uqm/comm/thradd/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="thraddc.c" +uqm_HFILES="resinst.h strings.h" diff --git a/sc2/src/uqm/comm/thradd/resinst.h b/sc2/src/uqm/comm/thradd/resinst.h index c5fe93b09..977f1753c 100644 --- a/sc2/src/uqm/comm/thradd/resinst.h +++ b/sc2/src/uqm/comm/thradd/resinst.h @@ -1,5 +1,9 @@ -#define THRADD_PMAP_ANIM "comm.thraddash.graphics" -#define THRADD_FONT "comm.thraddash.font" +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define THRADD_COLOR_MAP "comm.thraddash.colortable" #define THRADD_CONVERSATION_PHRASES "comm.thraddash.dialogue" +#define THRADD_FONT "comm.thraddash.font" #define THRADD_MUSIC "comm.thraddash.music" +#define THRADD_PMAP_ANIM "comm.thraddash.graphics" diff --git a/sc2/src/uqm/comm/thradd/thraddc.c b/sc2/src/uqm/comm/thradd/thraddc.c index 52e4f3a2a..1be8a1e4a 100644 --- a/sc2/src/uqm/comm/thradd/thraddc.c +++ b/sc2/src/uqm/comm/thradd/thraddc.c @@ -239,7 +239,7 @@ LikeYouPhrase (BYTE which_phrase) static void ExitConversation (RESPONSE_REF R) { - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); if (PLAYER_SAID (R, bye_hostile_2)) NPCPhrase (GOODBYE_HOSTILE_2); @@ -261,7 +261,7 @@ ExitConversation (RESPONSE_REF R) { NPCPhrase (GOOD_IDEA); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); AddEvent (RELATIVE_EVENT, 0, 0, 0, ADVANCE_THRADD_MISSION); SET_GAME_STATE (THRADD_STACK_1, 5); } @@ -289,14 +289,14 @@ ExitConversation (RESPONSE_REF R) break; } SET_GAME_STATE (THRADD_STACK_1, NumVisits); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else if (PLAYER_SAID (R, may_i_land)) { NPCPhrase (SURE_LAND); SET_GAME_STATE (HELIX_UNPROTECTED, 1); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else if (PLAYER_SAID (R, demand_to_land)) NPCPhrase (NO_DEMAND); @@ -330,7 +330,7 @@ ExitConversation (RESPONSE_REF R) } NPCPhrase (WORK_TO_DO); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } } @@ -505,7 +505,7 @@ ThraddWorship (RESPONSE_REF R) SET_GAME_STATE (THRADD_VISITS, 0); SET_GAME_STATE (THRADD_MANNER, 1); SET_GAME_STATE (THRADD_STACK_1, 0); - ActivateStarShip (THRADDASH_SHIP, SET_ALLIED); + SetRaceAllied (THRADDASH_SHIP, TRUE); Response (be_polite, ThraddCulture); Response (speak_pig_latin, ThraddCulture); @@ -700,7 +700,7 @@ Intro (void) { NPCPhrase (OUT_TAKES); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); return; } @@ -719,7 +719,7 @@ Intro (void) } SET_GAME_STATE (HELIX_VISITS, NumVisits); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else if (GET_GAME_STATE (ILWRATH_FIGHT_THRADDASH)) { @@ -752,7 +752,7 @@ Intro (void) } SET_GAME_STATE (THRADD_VISITS, NumVisits); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else if (GET_GAME_STATE (THRADD_MANNER)) { @@ -942,11 +942,11 @@ init_thradd_comm (void) if (GET_GAME_STATE (THRADD_MANNER) || LOBYTE (GLOBAL (CurrentActivity)) == WON_LAST_BATTLE) { - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else { - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } retval = &thradd_desc; diff --git a/sc2/src/uqm/comm/umgah/Makeinfo b/sc2/src/uqm/comm/umgah/Makeinfo index 06b80c3d8..9cad00835 100644 --- a/sc2/src/uqm/comm/umgah/Makeinfo +++ b/sc2/src/uqm/comm/umgah/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="umgahc.c" +uqm_HFILES="resinst.h strings.h" diff --git a/sc2/src/uqm/comm/umgah/resinst.h b/sc2/src/uqm/comm/umgah/resinst.h index 6ea768089..7b7479d46 100644 --- a/sc2/src/uqm/comm/umgah/resinst.h +++ b/sc2/src/uqm/comm/umgah/resinst.h @@ -1,5 +1,9 @@ -#define UMGAH_PMAP_ANIM "comm.umgah.graphics" -#define UMGAH_FONT "comm.umgah.font" +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define UMGAH_COLOR_MAP "comm.umgah.colortable" #define UMGAH_CONVERSATION_PHRASES "comm.umgah.dialogue" +#define UMGAH_FONT "comm.umgah.font" #define UMGAH_MUSIC "comm.umgah.music" +#define UMGAH_PMAP_ANIM "comm.umgah.graphics" diff --git a/sc2/src/uqm/comm/umgah/umgahc.c b/sc2/src/uqm/comm/umgah/umgahc.c index ea46459e6..d9debd540 100644 --- a/sc2/src/uqm/comm/umgah/umgahc.c +++ b/sc2/src/uqm/comm/umgah/umgahc.c @@ -198,13 +198,13 @@ static LOCDATA umgah_desc = static void CombatIsInevitable (RESPONSE_REF R) { - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); if (PLAYER_SAID (R, bye_zombie)) { NPCPhrase (GOODBYE_ZOMBIE); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else if (PLAYER_SAID (R, bye_pre_zombie)) NPCPhrase (GOODBYE_PRE_ZOMBIE); @@ -235,14 +235,14 @@ CombatIsInevitable (RESPONSE_REF R) { NPCPhrase (GOODBYE_UNKNOWN); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else if (PLAYER_SAID (R, bye_post_zombie)) { NPCPhrase (FUNNY_IDEA); AlienTalkSegue ((COUNT)~0); - ActivateStarShip (UMGAH_SHIP, 4); + AddEscortShips (UMGAH_SHIP, 4); SET_GAME_STATE (UMGAH_HOSTILE, 1); } } @@ -346,14 +346,14 @@ Zombies (RESPONSE_REF R) { NPCPhrase (NOT_GIVE_UP); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); return; } else if (PLAYER_SAID (R, arilou_told_us)) { NPCPhrase (THEN_DIE); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); SET_GAME_STATE (KNOW_UMGAH_ZOMBIES, 1); SET_GAME_STATE (UMGAH_VISITS, 0); return; @@ -541,7 +541,7 @@ Intro (void) } SET_GAME_STATE (UMGAH_VISITS, NumVisits); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else if (GET_GAME_STATE (UMGAH_ZOMBIE_BLOBBIES)) { @@ -565,7 +565,7 @@ Intro (void) break; } - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else if (GET_GAME_STATE (KNOW_UMGAH_ZOMBIES)) { @@ -586,7 +586,7 @@ Intro (void) break; } - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else { @@ -681,7 +681,7 @@ Intro (void) } SET_GAME_STATE (UMGAH_VISITS, NumVisits); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } } } @@ -717,11 +717,11 @@ init_umgah_comm (void) if ((GET_GAME_STATE (TALKING_PET) && !GET_GAME_STATE (UMGAH_HOSTILE)) || LOBYTE (GLOBAL (CurrentActivity)) == WON_LAST_BATTLE) { - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else { - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } retval = &umgah_desc; diff --git a/sc2/src/uqm/comm/urquan/Makeinfo b/sc2/src/uqm/comm/urquan/Makeinfo index fc3d191c0..7b756fa17 100644 --- a/sc2/src/uqm/comm/urquan/Makeinfo +++ b/sc2/src/uqm/comm/urquan/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="urquanc.c" +uqm_HFILES="resinst.h strings.h" diff --git a/sc2/src/uqm/comm/urquan/resinst.h b/sc2/src/uqm/comm/urquan/resinst.h index 26f95edcb..5b69860dc 100644 --- a/sc2/src/uqm/comm/urquan/resinst.h +++ b/sc2/src/uqm/comm/urquan/resinst.h @@ -1,5 +1,9 @@ -#define URQUAN_PMAP_ANIM "comm.urquan.graphics" -#define URQUAN_FONT "comm.urquan.font" +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define URQUAN_COLOR_MAP "comm.urquan.colortable" #define URQUAN_CONVERSATION_PHRASES "comm.urquan.dialogue" +#define URQUAN_FONT "comm.urquan.font" #define URQUAN_MUSIC "comm.urquan.music" +#define URQUAN_PMAP_ANIM "comm.urquan.graphics" diff --git a/sc2/src/uqm/comm/urquan/urquanc.c b/sc2/src/uqm/comm/urquan/urquanc.c index 7fa39c10d..efdf7107d 100644 --- a/sc2/src/uqm/comm/urquan/urquanc.c +++ b/sc2/src/uqm/comm/urquan/urquanc.c @@ -123,7 +123,7 @@ static LOCDATA urquan_desc = static void CombatIsInevitable (RESPONSE_REF R) { - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); if (PLAYER_SAID (R, you_must_surrender)) NPCPhrase (NOPE); @@ -159,9 +159,7 @@ CombatIsInevitable (RESPONSE_REF R) { NPCPhrase (GOOD_CHOICE); - SET_GAME_STATE (BATTLE_SEGUE, 0); - GLOBAL_SIS (CrewEnlisted) = (COUNT)~0; - GLOBAL (CurrentActivity) |= CHECK_RESTART; + setSegue (Segue_defeat); } else if (PLAYER_SAID (R, like_to_leave)) NPCPhrase (INDEPENDENCE_IS_BAD); @@ -169,7 +167,7 @@ CombatIsInevitable (RESPONSE_REF R) { NPCPhrase (GOODBYE_WARS_OVER); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else if (PLAYER_SAID (R, bye_sub_hypno)) NPCPhrase (GOODBYE_AND_DIE_SUB_HYPNO); @@ -184,7 +182,7 @@ CombatIsInevitable (RESPONSE_REF R) { NPCPhrase (BAD_NEWS); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); SET_GAME_STATE (URQUAN_HYPNO_VISITS, 1); } else if (PLAYER_SAID (R, falling_asleep) @@ -192,7 +190,7 @@ CombatIsInevitable (RESPONSE_REF R) { NPCPhrase (SOUNDS_FAMILIAR); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); SET_GAME_STATE (URQUAN_HYPNO_VISITS, 1); } } @@ -415,7 +413,7 @@ Intro (void) { NPCPhrase (OUT_TAKES); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); return; } @@ -450,7 +448,7 @@ Intro (void) { NPCPhrase (CAUGHT_YA); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); return; } @@ -462,7 +460,7 @@ Intro (void) NPCPhrase (HELLO_SAMATRA); SET_GAME_STATE (AWARE_OF_SAMATRA, 1); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else { @@ -501,7 +499,7 @@ Intro (void) break; case 1: NPCPhrase (SUBSEQUENT_FLEE_HUMAN); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); --NumVisits; break; } @@ -545,11 +543,11 @@ init_urquan_comm (void) && GLOBAL (BattleGroupRef) && GLOBAL (BattleGroupRef) == GrpOffs)) { - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else { - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } retval = &urquan_desc; diff --git a/sc2/src/uqm/comm/utwig/Makeinfo b/sc2/src/uqm/comm/utwig/Makeinfo index 8e37e5c33..432250e55 100644 --- a/sc2/src/uqm/comm/utwig/Makeinfo +++ b/sc2/src/uqm/comm/utwig/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="utwigc.c" +uqm_HFILES="resinst.h strings.h" diff --git a/sc2/src/uqm/comm/utwig/resinst.h b/sc2/src/uqm/comm/utwig/resinst.h index 880f46dac..5176ecbab 100644 --- a/sc2/src/uqm/comm/utwig/resinst.h +++ b/sc2/src/uqm/comm/utwig/resinst.h @@ -1,6 +1,10 @@ -#define UTWIG_PMAP_ANIM "comm.utwig.graphics" -#define UTWIG_FONT "comm.utwig.font" +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define UTWIG_COLOR_MAP "comm.utwig.colortable" #define UTWIG_CONVERSATION_PHRASES "comm.utwig.dialogue" +#define UTWIG_FONT "comm.utwig.font" #define UTWIG_MUSIC "comm.utwig.music" +#define UTWIG_PMAP_ANIM "comm.utwig.graphics" #define UTWIG_ULTRON_MUSIC "comm.utwig.ultron.music" diff --git a/sc2/src/uqm/comm/utwig/utwigc.c b/sc2/src/uqm/comm/utwig/utwigc.c index 6ce4065fc..53bacbb26 100644 --- a/sc2/src/uqm/comm/utwig/utwigc.c +++ b/sc2/src/uqm/comm/utwig/utwigc.c @@ -200,7 +200,7 @@ static LOCDATA utwig_desc = static void ExitConversation (RESPONSE_REF R) { - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); if (PLAYER_SAID (R, bye_neutral)) NPCPhrase (GOODBYE_NEUTRAL); @@ -216,7 +216,7 @@ ExitConversation (RESPONSE_REF R) { NPCPhrase (GUARDS_FIGHT); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else if (PLAYER_SAID (R, got_ultron) || PLAYER_SAID (R, hey_wait_got_ultron)) @@ -244,7 +244,7 @@ ExitConversation (RESPONSE_REF R) { NPCPhrase (TRICKED_US_1); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } break; case 1: @@ -254,7 +254,7 @@ ExitConversation (RESPONSE_REF R) { NPCPhrase (TRICKED_US_2); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } break; } @@ -288,22 +288,22 @@ ExitConversation (RESPONSE_REF R) SET_GAME_STATE (SUPOX_HOSTILE, 0); SET_GAME_STATE (UTWIG_HOSTILE, 0); - ActivateStarShip (UTWIG_SHIP, SET_ALLIED); - ActivateStarShip (SUPOX_SHIP, SET_ALLIED); + SetRaceAllied (UTWIG_SHIP, TRUE); + SetRaceAllied (SUPOX_SHIP, TRUE); } } } else if (PLAYER_SAID (R, can_you_help)) { NPCPhrase (HOW_HELP); - if (ActivateStarShip (UTWIG_SHIP, FEASIBILITY_STUDY) == 0) + if (EscortFeasibilityStudy (UTWIG_SHIP) == 0) NPCPhrase (DONT_NEED); else { NPCPhrase (HAVE_4_SHIPS); AlienTalkSegue ((COUNT)~0); - ActivateStarShip (UTWIG_SHIP, 4); + AddEscortShips (UTWIG_SHIP, 4); } } } @@ -390,7 +390,7 @@ AlliedHome (RESPONSE_REF R) Response (what_now_homeworld, AlliedHome); if (PHRASE_ENABLED (how_is_ultron)) Response (how_is_ultron, AlliedHome); - if (NumVisits == 0) + if (NumVisits == 0 && EscortFeasibilityStudy (UTWIG_SHIP) != 0) Response (can_you_help, ExitConversation); Response (bye_allied_homeworld, ExitConversation); } @@ -497,7 +497,7 @@ NeutralUtwig (RESPONSE_REF R) { NPCPhrase (MOCK_OUR_PAIN); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); SET_GAME_STATE (UTWIG_STACK1, 4); SET_GAME_STATE (UTWIG_HOSTILE, 1); SET_GAME_STATE (UTWIG_INFO, 0); @@ -525,7 +525,7 @@ NeutralUtwig (RESPONSE_REF R) NPCPhrase (ABOUT_US_2); LastStack = 2; - ActivateStarShip (SUPOX_SHIP, SPHERE_TRACKING); + StartSphereTracking (SUPOX_SHIP); SET_GAME_STATE (UTWIG_WAR_NEWS, 2); } else if (PLAYER_SAID (R, what_about_you_3)) @@ -651,7 +651,7 @@ BombWorld (RESPONSE_REF R) { NPCPhrase (GUARDS_FIGHT); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); SET_GAME_STATE (UTWIG_HOSTILE, 1); SET_GAME_STATE (UTWIG_INFO, 0); SET_GAME_STATE (UTWIG_HOME_VISITS, 0); @@ -745,7 +745,7 @@ Intro (void) { NPCPhrase (OUT_TAKES); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); return; } @@ -800,14 +800,14 @@ Intro (void) if (!GET_GAME_STATE (ULTRON_CONDITION) || (GET_GAME_STATE (GLOBAL_FLAGS_AND_DATA) & (1 << 6))) { - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else { Response (hey_wait_got_ultron, ExitConversation); } } - else if (ActivateStarShip (UTWIG_SHIP, CHECK_ALLIANCE) == GOOD_GUY) + else if (CheckAlliance (UTWIG_SHIP) == GOOD_GUY) { if (GET_GAME_STATE (GLOBAL_FLAGS_AND_DATA) & (1 << 7)) { @@ -984,11 +984,11 @@ init_utwig_comm (void) if (GET_GAME_STATE (UTWIG_HAVE_ULTRON) || LOBYTE (GLOBAL (CurrentActivity)) == WON_LAST_BATTLE) { - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else { - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } retval = &utwig_desc; diff --git a/sc2/src/uqm/comm/vux/Makeinfo b/sc2/src/uqm/comm/vux/Makeinfo index d78b60993..da9446fca 100644 --- a/sc2/src/uqm/comm/vux/Makeinfo +++ b/sc2/src/uqm/comm/vux/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="vuxc.c" +uqm_HFILES="resinst.h strings.h" diff --git a/sc2/src/uqm/comm/vux/resinst.h b/sc2/src/uqm/comm/vux/resinst.h index 0cc7dca3e..5004523c1 100644 --- a/sc2/src/uqm/comm/vux/resinst.h +++ b/sc2/src/uqm/comm/vux/resinst.h @@ -1,5 +1,9 @@ -#define VUX_PMAP_ANIM "comm.vux.graphics" -#define VUX_FONT "comm.vux.font" +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define VUX_COLOR_MAP "comm.vux.colortable" #define VUX_CONVERSATION_PHRASES "comm.vux.dialogue" +#define VUX_FONT "comm.vux.font" #define VUX_MUSIC "comm.vux.music" +#define VUX_PMAP_ANIM "comm.vux.graphics" diff --git a/sc2/src/uqm/comm/vux/vuxc.c b/sc2/src/uqm/comm/vux/vuxc.c index ba660931f..7f7419cbb 100644 --- a/sc2/src/uqm/comm/vux/vuxc.c +++ b/sc2/src/uqm/comm/vux/vuxc.c @@ -205,7 +205,7 @@ CombatIsInevitable (RESPONSE_REF R) { BYTE NumVisits; - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); if (PLAYER_SAID (R, ok_take_beast)) { @@ -220,7 +220,7 @@ CombatIsInevitable (RESPONSE_REF R) SET_GAME_STATE (VUX_BEAST_ON_SHIP, 0); SET_GAME_STATE (ZEX_IS_DEAD, 1); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else if (PLAYER_SAID (R, try_any_way)) { @@ -290,7 +290,7 @@ CombatIsInevitable (RESPONSE_REF R) { NPCPhrase (GOODBYE_ZEX); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else { @@ -376,13 +376,13 @@ Menagerie (RESPONSE_REF R) { NPCPhrase (FIGHT_AGAIN); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else if (PLAYER_SAID (R, regardless)) { NPCPhrase (THEN_FIGHT); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); SET_GAME_STATE (ZEX_STACK_3, 2); SET_GAME_STATE (ZEX_VISITS, 0); } @@ -696,7 +696,7 @@ Intro (void) { NPCPhrase (OUT_TAKES); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); return; } @@ -784,11 +784,11 @@ init_vux_comm (void) if ((GET_GAME_STATE (GLOBAL_FLAGS_AND_DATA) & (1 << 6)) || LOBYTE (GLOBAL (CurrentActivity)) == WON_LAST_BATTLE) { - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else { - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } retval = &vux_desc; diff --git a/sc2/src/uqm/comm/yehat/Makeinfo b/sc2/src/uqm/comm/yehat/Makeinfo index 1e41aa120..f38674b6e 100644 --- a/sc2/src/uqm/comm/yehat/Makeinfo +++ b/sc2/src/uqm/comm/yehat/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="yehatc.c" +uqm_HFILES="resinst.h strings.h" diff --git a/sc2/src/uqm/comm/yehat/resinst.h b/sc2/src/uqm/comm/yehat/resinst.h index dc5e66bd6..3b0b20350 100644 --- a/sc2/src/uqm/comm/yehat/resinst.h +++ b/sc2/src/uqm/comm/yehat/resinst.h @@ -1,7 +1,11 @@ -#define YEHAT_PMAP_ANIM "comm.yehat.graphics" -#define YEHAT_FONT "comm.yehat.font" +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define REBEL_CONVERSATION_PHRASES "comm.yehat.rebel.dialogue" +#define REBEL_MUSIC "comm.yehat.rebel.music" #define YEHAT_COLOR_MAP "comm.yehat.colortable" #define YEHAT_CONVERSATION_PHRASES "comm.yehat.dialogue" -#define REBEL_MUSIC "comm.yehat.rebel.music" +#define YEHAT_FONT "comm.yehat.font" #define YEHAT_MUSIC "comm.yehat.music" +#define YEHAT_PMAP_ANIM "comm.yehat.graphics" diff --git a/sc2/src/uqm/comm/yehat/yehatc.c b/sc2/src/uqm/comm/yehat/yehatc.c index 645326bdd..c1860bf16 100644 --- a/sc2/src/uqm/comm/yehat/yehatc.c +++ b/sc2/src/uqm/comm/yehat/yehatc.c @@ -194,7 +194,7 @@ static LOCDATA yehat_desc = static void ExitConversation (RESPONSE_REF R) { - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); if (PLAYER_SAID (R, bye_homeworld)) NPCPhrase (GOODBYE_AND_DIE_HOMEWORLD); @@ -214,7 +214,7 @@ ExitConversation (RESPONSE_REF R) { NPCPhrase (GO_IN_PEACE); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } } else if (PLAYER_SAID (R, not_here) @@ -235,7 +235,7 @@ ExitConversation (RESPONSE_REF R) { NPCPhrase (WE_REVOLT); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); SET_GAME_STATE (YEHAT_CIVIL_WAR, 1); SET_GAME_STATE (YEHAT_VISITS, 0); SET_GAME_STATE (YEHAT_HOME_VISITS, 0); @@ -309,7 +309,7 @@ StartRevolt (RESPONSE_REF R) else if (PLAYER_SAID (R, shofixti_alive_2)) NPCPhrase (SEND_HIM_OVER_2); - if (ActivateStarShip (SHOFIXTI_SHIP, ESCORTING_FLAGSHIP)) + if (HaveEscortShip (SHOFIXTI_SHIP)) Response (ok_send, ExitConversation); else Response (not_here, ExitConversation); @@ -439,7 +439,7 @@ YehatSpace (RESPONSE_REF R) { NPCPhrase (WE_CANNOT_2); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); SET_GAME_STATE (NO_YEHAT_ALLY_SPACE, 2); return; @@ -565,7 +565,7 @@ Intro (void) { NPCPhrase (OUT_TAKES); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); return; } @@ -673,11 +673,11 @@ init_yehat_comm (void) if (LOBYTE (GLOBAL (CurrentActivity)) != WON_LAST_BATTLE) { - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else { - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } retval = &yehat_desc; diff --git a/sc2/src/uqm/comm/zoqfot/Makeinfo b/sc2/src/uqm/comm/zoqfot/Makeinfo index 3b54b07b0..6e1a2684a 100644 --- a/sc2/src/uqm/comm/zoqfot/Makeinfo +++ b/sc2/src/uqm/comm/zoqfot/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="zoqfotc.c" +uqm_HFILES="resinst.h strings.h" diff --git a/sc2/src/uqm/comm/zoqfot/resinst.h b/sc2/src/uqm/comm/zoqfot/resinst.h index 3273cf4a5..a9430d906 100644 --- a/sc2/src/uqm/comm/zoqfot/resinst.h +++ b/sc2/src/uqm/comm/zoqfot/resinst.h @@ -1,5 +1,9 @@ -#define ZOQFOTPIK_PMAP_ANIM "comm.zoqfotpik.graphics" -#define ZOQFOTPIK_FONT "comm.zoqfotpik.font" +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define ZOQFOTPIK_COLOR_MAP "comm.zoqfotpik.colortable" #define ZOQFOTPIK_CONVERSATION_PHRASES "comm.zoqfotpik.dialogue" +#define ZOQFOTPIK_FONT "comm.zoqfotpik.font" #define ZOQFOTPIK_MUSIC "comm.zoqfotpik.music" +#define ZOQFOTPIK_PMAP_ANIM "comm.zoqfotpik.graphics" diff --git a/sc2/src/uqm/comm/zoqfot/zoqfotc.c b/sc2/src/uqm/comm/zoqfot/zoqfotc.c index 123cd7977..d09a7f7bb 100644 --- a/sc2/src/uqm/comm/zoqfot/zoqfotc.c +++ b/sc2/src/uqm/comm/zoqfot/zoqfotc.c @@ -118,15 +118,12 @@ enum static int LastAlien; +// Queued and executes synchronously on the Starcon2Main thread static void -SelectAlienZOQ (void) +SelectAlienZOQ (CallbackArg arg) { if (LastAlien != ZOQ_ALIEN) { - // XXX: This should hold the GraphicsLock to block comm anims and - // prevent CommData half-updates, but if we do so, the stream - // decoder will deadlock with the drawing thread. - // Transition to neutral state first if Pik was talking if (LastAlien != FOT_ALIEN) CommData.AlienTransitionDesc.AnimFlags |= TALK_DONE; @@ -142,17 +139,16 @@ SelectAlienZOQ (void) CommData.AlienTextFColor = ZOQ_FG_COLOR; CommData.AlienTextBColor = ZOQ_BG_COLOR; } + + (void)arg; // ignored } +// Queued and executes synchronously on the Starcon2Main thread static void -SelectAlienPIK (void) +SelectAlienPIK (CallbackArg arg) { if (LastAlien != PIK_ALIEN) { - // XXX: This should hold the GraphicsLock to block comm anims and - // prevent CommData half-updates, but if we do so, the stream - // decoder will deadlock with the drawing thread. - // Transition to neutral state first if Zoq was talking if (LastAlien != FOT_ALIEN) CommData.AlienTransitionDesc.AnimFlags |= TALK_DONE; @@ -168,20 +164,22 @@ SelectAlienPIK (void) CommData.AlienTextFColor = PIK_FG_COLOR; CommData.AlienTextBColor = PIK_BG_COLOR; } + + (void)arg; // ignored } static void ZFPTalkSegue (COUNT wait_track) { LastAlien = FOT_ALIEN; - SelectAlienZOQ (); + SelectAlienZOQ (0); AlienTalkSegue (wait_track); } static void ExitConversation (RESPONSE_REF R) { - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); if (PLAYER_SAID (R, bye_homeworld)) { @@ -224,7 +222,7 @@ ExitConversation (RESPONSE_REF R) NPCPhrase_cb (WE_ALLY4, &SelectAlienZOQ); NPCPhrase_cb (WE_ALLY5, &SelectAlienPIK); ZFPTalkSegue ((COUNT)~0); - ActivateStarShip (ZOQFOTPIK_SHIP, SET_ALLIED); + SetRaceAllied (ZOQFOTPIK_SHIP, TRUE); AddEvent (RELATIVE_EVENT, 3, 0, 0, ZOQFOT_DISTRESS_EVENT); SET_GAME_STATE (ZOQFOT_HOME_VISITS, 0); } @@ -238,7 +236,7 @@ ExitConversation (RESPONSE_REF R) SET_GAME_STATE (ZOQFOT_HOSTILE, 1); SET_GAME_STATE (ZOQFOT_HOME_VISITS, 0); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else if (PLAYER_SAID (R, never)) { @@ -248,7 +246,7 @@ ExitConversation (RESPONSE_REF R) SET_GAME_STATE (ZOQFOT_HOME_VISITS, 0); SET_GAME_STATE (ZOQFOT_HOSTILE, 1); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } } @@ -735,7 +733,7 @@ ZoqFotHome (RESPONSE_REF R) NPCPhrase_cb (GOOD9, &SelectAlienPIK); ZFPTalkSegue ((COUNT)~0); - ActivateStarShip (ZOQFOTPIK_SHIP, SET_ALLIED); + SetRaceAllied (ZOQFOTPIK_SHIP, TRUE); AddEvent (RELATIVE_EVENT, 3, 0, 0, ZOQFOT_DISTRESS_EVENT); } else if (PLAYER_SAID (R, enough_info)) @@ -748,7 +746,7 @@ ZoqFotHome (RESPONSE_REF R) Response (whats_up_homeworld, ZoqFotHome); if (PHRASE_ENABLED (any_war_news)) Response (any_war_news, ZoqFotHome); - if (ActivateStarShip (ZOQFOTPIK_SHIP, CHECK_ALLIANCE) != GOOD_GUY) + if (CheckAlliance (ZOQFOTPIK_SHIP) != GOOD_GUY) Response (i_want_alliance, ZoqFotHome); else if (PHRASE_ENABLED (want_specific_info)) { @@ -779,7 +777,7 @@ Intro (void) NPCPhrase_cb (OUT_TAKES12, &SelectAlienZOQ); NPCPhrase_cb (OUT_TAKES13, &SelectAlienPIK); ZFPTalkSegue ((COUNT)~0); - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); return; } @@ -816,7 +814,7 @@ Intro (void) } SET_GAME_STATE (ZOQFOT_HOME_VISITS, NumVisits); - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } else if (!GET_GAME_STATE (MET_ZOQFOT)) { @@ -870,12 +868,12 @@ Intro (void) ZFPTalkSegue ((COUNT)~0); SET_GAME_STATE (ZOQFOT_DISTRESS, 0); - ActivateStarShip (ZOQFOTPIK_SHIP, MAX_ZFP_SHIPS); + AddEscortShips (ZOQFOTPIK_SHIP, MAX_ZFP_SHIPS); } else { NumVisits = GET_GAME_STATE (ZOQFOT_HOME_VISITS); - if (ActivateStarShip (ZOQFOTPIK_SHIP, CHECK_ALLIANCE) != GOOD_GUY) + if (CheckAlliance (ZOQFOTPIK_SHIP) != GOOD_GUY) { switch (NumVisits++) { @@ -960,14 +958,14 @@ init_zoqfot_comm (void) zoqfot_desc.AlienTextWidth = (SIS_TEXT_WIDTH >> 1) - TEXT_X_OFFS; - if (ActivateStarShip (ZOQFOTPIK_SHIP, CHECK_ALLIANCE) == GOOD_GUY + if (CheckAlliance (ZOQFOTPIK_SHIP) == GOOD_GUY || LOBYTE (GLOBAL (CurrentActivity)) == WON_LAST_BATTLE) { - SET_GAME_STATE (BATTLE_SEGUE, 0); + setSegue (Segue_peace); } else { - SET_GAME_STATE (BATTLE_SEGUE, 1); + setSegue (Segue_hostile); } retval = &zoqfot_desc; diff --git a/sc2/src/uqm/commanim.h b/sc2/src/uqm/commanim.h index bde0417bf..40527f5ab 100644 --- a/sc2/src/uqm/commanim.h +++ b/sc2/src/uqm/commanim.h @@ -20,6 +20,10 @@ #include "libs/compiler.h" #include "libs/gfxlib.h" +#if defined(__cplusplus) +extern "C" { +#endif + // Some background: every animation has a neutral frame which returns // the image to the state it was in before the animation began. Which // frame is neutral depends on the animation type. @@ -130,6 +134,8 @@ extern BOOLEAN DrawAlienFrame (SEQUENCE *pSeq, COUNT Num, BOOLEAN fullRedraw); extern void InitCommAnimations (void); extern BOOLEAN ProcessCommAnimations (BOOLEAN fullRedraw, BOOLEAN paused); +#if defined(__cplusplus) +} +#endif + #endif /* UQM_COMMANIM_H_ */ - - diff --git a/sc2/src/uqm/commglue.c b/sc2/src/uqm/commglue.c index a8f991b7a..d6b79ea78 100644 --- a/sc2/src/uqm/commglue.c +++ b/sc2/src/uqm/commglue.c @@ -18,6 +18,8 @@ #include "commglue.h" +#include "battle.h" + // For instantVictory #include "races.h" #include @@ -28,8 +30,10 @@ static int NPCNumberPhrase (int number, const char *fmt, UNICODE **ptrack); +// The CallbackFunction is queued and executes synchronously +// on the Starcon2Main thread void -NPCPhrase_cb (int index, TFB_TrackCB cb) +NPCPhrase_cb (int index, CallbackFunction cb) { UNICODE *pStr, buf[400]; void *pClip, *pTimeStamp; @@ -308,6 +312,48 @@ construct_response (UNICODE *buf, int R /* promoted from RESPONSE_REF */, ...) } } +void +setSegue (Segue segue) +{ + switch (segue) + { + case Segue_peace: + SET_GAME_STATE (BATTLE_SEGUE, 0); + break; + case Segue_hostile: + SET_GAME_STATE (BATTLE_SEGUE, 1); + break; + case Segue_victory: + instantVictory = TRUE; + SET_GAME_STATE (BATTLE_SEGUE, 1); + break; + case Segue_defeat: + SET_GAME_STATE (BATTLE_SEGUE, 0); + GLOBAL_SIS(CrewEnlisted) = (COUNT)~0; + GLOBAL(CurrentActivity) |= CHECK_RESTART; + break; + } +} + +Segue +getSegue (void) +{ + if (GET_GAME_STATE(BATTLE_SEGUE) == 0) { + if (GLOBAL_SIS(CrewEnlisted) == (COUNT)~0 && + (GLOBAL(CurrentActivity) & CHECK_RESTART)) { + return Segue_defeat; + } else { + return Segue_peace; + } + } else /* GET_GAME_STATE(BATTLE_SEGUE) == 1) */ { + if (instantVictory) { + return Segue_victory; + } else { + return Segue_hostile; + } + } +} + LOCDATA* init_race (CONVERSATION comm_id) { diff --git a/sc2/src/uqm/commglue.h b/sc2/src/uqm/commglue.h index 7e56dcd52..5a1e440f6 100644 --- a/sc2/src/uqm/commglue.h +++ b/sc2/src/uqm/commglue.h @@ -22,6 +22,11 @@ #include "globdata.h" #include "resinst.h" #include "libs/sound/trackplayer.h" +#include "libs/callback.h" + +#if defined(__cplusplus) +extern "C" { +#endif typedef enum { ARILOU_CONVERSATION, @@ -65,7 +70,6 @@ extern UNICODE shared_phrase_buf[2048]; (*(UNICODE *)GetStringAddress ( \ SetAbsStringTableIndex (CommData.ConversationPhrases, (p)-1) \ ) = '\0') -#define RESPONSE_TO_REF(R) (R) #define Response(i,a) \ DoResponsePhrase(i,(RESPONSE_FUNC)a,0) @@ -85,7 +89,9 @@ extern void DoResponsePhrase (RESPONSE_REF R, RESPONSE_FUNC response_func, UNICODE *ContstructStr); extern void DoNPCPhrase (UNICODE *pStr); -extern void NPCPhrase_cb (int index, TFB_TrackCB cb); +// The CallbackFunction is queued and executes synchronously +// on the Starcon2Main thread +extern void NPCPhrase_cb (int index, CallbackFunction cb); #define NPCPhrase(index) NPCPhrase_cb ((index), NULL) extern void NPCPhrase_splice (int index); extern void NPCNumber (int number, const char *fmt); @@ -96,6 +102,22 @@ extern void GetAllianceName (UNICODE *buf, RESPONSE_REF name_1); extern void construct_response (UNICODE *buf, int R /* promoted from RESPONSE_REF */, ...); +typedef enum { + Segue_peace, + // When initiating a conversation, open comms directly. + // When terminating a conversation, depart in peace. + Segue_hostile, + // When initiating a conversation, offer the choice to attack. + // When terminating a conversation, go into battle. + Segue_victory, + // (when terminating a conversation) instant victory + Segue_defeat, + // (when terminating a conversation) game over +} Segue; + +void setSegue (Segue segue); +Segue getSegue (void); + extern LOCDATA* init_race (CONVERSATION comm_id); extern LOCDATA* init_arilou_comm (void); @@ -154,5 +176,8 @@ extern LOCDATA* init_zoqfot_comm (void); extern LOCDATA* init_umgah_comm (void); -#endif /* UQM_COMMGLUE_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_COMMGLUE_H_ */ diff --git a/sc2/src/uqm/confirm.c b/sc2/src/uqm/confirm.c index 06434d4ed..a24472bd5 100644 --- a/sc2/src/uqm/confirm.c +++ b/sc2/src/uqm/confirm.c @@ -83,7 +83,8 @@ DoConfirmExit (void) if (PlayingTrack ()) PauseTrack (); - LockMutex (GraphicsLock); + PauseFlash (); + { RECT r; STAMP s; @@ -158,7 +159,8 @@ DoConfirmExit (void) SetContextClipRect (&oldRect); SetContext (oldContext); } - UnlockMutex (GraphicsLock); + + ContinueFlash (); if (PlayingTrack ()) ResumeTrack (); @@ -212,7 +214,7 @@ DoPopupWindow (const char *msg) label.line_count = SplitString (msg, '\n', 30, lines, bank); label.lines = lines; - LockMutex (GraphicsLock); + PauseFlash (); oldContext = SetContext (ScreenContext); GetContextClipRect (&oldRect); @@ -241,7 +243,8 @@ DoPopupWindow (const char *msg) DestroyDrawable (ReleaseDrawable (s.frame)); SetContextClipRect (&oldRect); SetContext (oldContext); - UnlockMutex (GraphicsLock); + ContinueFlash (); SetMenuSounds (s0, s1); StringBank_Free (bank); } + diff --git a/sc2/src/uqm/cons_res.h b/sc2/src/uqm/cons_res.h index 6ed5bd456..2325e1657 100644 --- a/sc2/src/uqm/cons_res.h +++ b/sc2/src/uqm/cons_res.h @@ -20,6 +20,10 @@ #include "libs/gfxlib.h" #include "libs/sndlib.h" +#if defined(__cplusplus) +extern "C" { +#endif + void load_gravity_well (BYTE selector); void free_gravity_well (void); @@ -27,4 +31,8 @@ FRAME load_life_form (BYTE selector); MUSIC_REF load_orbit_theme (BYTE selector); +#if defined(__cplusplus) +} +#endif + #endif /* CONS_RES_H_ */ diff --git a/sc2/src/uqm/controls.h b/sc2/src/uqm/controls.h index 240df2d20..8273aed3a 100644 --- a/sc2/src/uqm/controls.h +++ b/sc2/src/uqm/controls.h @@ -23,6 +23,10 @@ #include "libs/strlib.h" #include "libs/timelib.h" +#if defined(__cplusplus) +extern "C" { +#endif + // Enumerated type for controls enum { KEY_UP, @@ -115,9 +119,6 @@ BOOLEAN WaitForNoInputUntil (TimeCount timeOut, BOOLEAN resetInput); void DoPopupWindow(const char *msg); typedef void (InputFrameCallback) (void); -// Anything using input callbacks MUST NOT keep GraphicsLock across -// InputFunc executions. This also means NOT holding GraphicsLock -// when calling DoInput(). InputFrameCallback* SetInputCallback (InputFrameCallback *); // pInputState must point to a struct derived from INPUT_STATE_DESC void DoInput (void *pInputState, BOOLEAN resetInput); @@ -162,6 +163,10 @@ typedef struct textentry_state extern BOOLEAN DoTextEntry (TEXTENTRY_STATE *pTES); +#if defined(__cplusplus) +} +#endif + #endif diff --git a/sc2/src/uqm/credits.c b/sc2/src/uqm/credits.c index 932131808..188948488 100644 --- a/sc2/src/uqm/credits.c +++ b/sc2/src/uqm/credits.c @@ -240,7 +240,6 @@ Credits_RenderTextFrame (CONTEXT TempContext, int *istr, int dir, t.pStr = " "; t.CharCount = 1; - LockMutex (GraphicsLock); OldContext = SetContext (TempContext); // get font dimensions @@ -312,7 +311,6 @@ Credits_RenderTextFrame (CONTEXT TempContext, int *istr, int dir, SetContextFGFrame (OldFrame); SetContext (OldContext); - UnlockMutex (GraphicsLock); return f; } @@ -331,7 +329,6 @@ RenderCreditsScreen (CONTEXT targetContext) STAMP s; int i; - LockMutex (GraphicsLock); oldContext = SetContext (targetContext); // draw background s.origin.x = 0; @@ -358,7 +355,6 @@ RenderCreditsScreen (CONTEXT targetContext) } SetContext (oldContext); - UnlockMutex (GraphicsLock); } static void @@ -373,7 +369,6 @@ InitCredits (void) LocalContext = CreateContext ("Credits.LocalContext"); DrawContext = CreateContext ("Credits.DrawContext"); - LockMutex (GraphicsLock); targetFrame = GetContextFGFrame (); GetContextClipRect (&ctxRect); CreditsExtent = ctxRect.extent; @@ -402,7 +397,6 @@ InitCredits (void) SetContextFGFrame (targetFrame); SetContext (oldContext); - UnlockMutex (GraphicsLock); // Prepare the first screen frame RenderCreditsScreen (LocalContext); @@ -493,12 +487,10 @@ processCreditsFrame (void) s.origin.y = 0; s.frame = CreditsFrame; - LockMutex (GraphicsLock); OldContext = SetContext (DrawContext); DrawStamp (&s); SetContext (OldContext); FlushGraphics (); - UnlockMutex (GraphicsLock); // prepare next screen frame deficitHeight = calcDeficitHeight (); @@ -782,13 +774,11 @@ Credits (BOOLEAN WithOuttakes) hMusic = LoadMusic (CREDITS_MUSIC); - LockMutex (GraphicsLock); SetContext (ScreenContext); SetContextClipRect (NULL); GetContextClipRect (&screenRect); SetContextBackGroundColor (BLACK_COLOR); ClearDrawable (); - UnlockMutex (GraphicsLock); if (!LoadCredits ()) return; @@ -797,10 +787,8 @@ Credits (BOOLEAN WithOuttakes) s.origin.x = 0; s.origin.y = 0; s.frame = CreditsBack; - LockMutex (GraphicsLock); DrawStamp (&s); FadeScreen (FadeAllToColor, ONE_SECOND / 2); - UnlockMutex (GraphicsLock); // set the position of outtakes comm CommWndRect.corner.x = (screenRect.extent.width - CommWndRect.extent.width) @@ -836,11 +824,9 @@ Credits (BOOLEAN WithOuttakes) FadeMusic (0, ONE_SECOND / 2); UninitCredits (); - LockMutex (GraphicsLock); SetContext (ScreenContext); SleepThreadUntil (FadeScreen (FadeAllToBlack, ONE_SECOND / 2)); FlushColorXForms (); - UnlockMutex (GraphicsLock); if (hMusic) { diff --git a/sc2/src/uqm/credits.h b/sc2/src/uqm/credits.h index 28ef278ea..c007b3513 100644 --- a/sc2/src/uqm/credits.h +++ b/sc2/src/uqm/credits.h @@ -19,7 +19,14 @@ #include "libs/compiler.h" +#if defined(__cplusplus) +extern "C" { +#endif + extern void Credits (BOOLEAN WithOuttakes); -#endif /* UQM_CREDITS_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_CREDITS_H_ */ diff --git a/sc2/src/uqm/cyborg.c b/sc2/src/uqm/cyborg.c index 056c1b4e6..a50f3b8ca 100644 --- a/sc2/src/uqm/cyborg.c +++ b/sc2/src/uqm/cyborg.c @@ -1092,7 +1092,7 @@ if (!(ShipPtr->state_flags & FINITE_LIFE) if (GRAVITY_MASS (ed.ObjectPtr->mass_points)) { COUNT maneuver_turn, ship_bounds; - RECT ship_footprint; + RECT ship_footprint = {{0, 0}, {0, 0}}; if (UltraManeuverable) maneuver_turn = 16; diff --git a/sc2/src/uqm/demo.h b/sc2/src/uqm/demo.h index 9e4a8a992..25009c08a 100644 --- a/sc2/src/uqm/demo.h +++ b/sc2/src/uqm/demo.h @@ -19,6 +19,10 @@ #ifndef UQM_DEMO_H_ #define UQM_DEMO_H_ +#if defined(__cplusplus) +extern "C" { +#endif + #ifndef DEMO_MODE #define DEMO_MODE 0 #endif /* DEMO_MODE */ @@ -44,5 +48,8 @@ extern void JournalInput (INPUT_STATE InputState); #endif -#endif /* UQM_DEMO_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_DEMO_H_ */ diff --git a/sc2/src/uqm/displist.h b/sc2/src/uqm/displist.h index f7282aa0e..d9c2fc0ba 100644 --- a/sc2/src/uqm/displist.h +++ b/sc2/src/uqm/displist.h @@ -24,6 +24,10 @@ #include "libs/compiler.h" #include "libs/memlib.h" +#if defined(__cplusplus) +extern "C" { +#endif + // Note that we MUST use the QUEUE_TABLE variant at this time, because // certain gameplay elements depend on it. Namely, the maximum number // of HyperSpace encounter globes chasing the player is defined by the @@ -120,5 +124,8 @@ extern void RemoveQueue (QUEUE *pq, HLINK hLink); extern COUNT CountLinks (QUEUE *pq); void ForAllLinks(QUEUE *pq, void (*callback)(LINK *, void *), void *arg); -#endif /* UQM_DISPLIST_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_DISPLIST_H_ */ diff --git a/sc2/src/uqm/element.h b/sc2/src/uqm/element.h index 870bef683..dd4134089 100644 --- a/sc2/src/uqm/element.h +++ b/sc2/src/uqm/element.h @@ -24,6 +24,10 @@ #include "velocity.h" #include "libs/gfxlib.h" +#if defined(__cplusplus) +extern "C" { +#endif + #define NORMAL_LIFE 1 @@ -92,7 +96,8 @@ typedef struct state typedef struct element ELEMENT; -typedef void (CollisionFunc) (ELEMENT *ElementPtr0, POINT *pPt0, +typedef void (ElementProcessFunc) (ELEMENT *ElementPtr); +typedef void (ElementCollisionFunc) (ELEMENT *ElementPtr0, POINT *pPt0, ELEMENT *ElementPtr1, POINT *pPt1); // Any physical object in the simulation. @@ -101,10 +106,10 @@ struct element // LINK elements; must be first HELEMENT pred, succ; - void (*preprocess_func) (struct element *ElementPtr); - void (*postprocess_func) (struct element *ElementPtr); - CollisionFunc *collision_func; - void (*death_func) (struct element *ElementPtr); + ElementProcessFunc *preprocess_func; + ElementProcessFunc *postprocess_func; + ElementCollisionFunc *collision_func; + ElementProcessFunc *death_func; // Player this element belongs to // -1: neutral (planets, asteroids, crew, etc.) @@ -230,5 +235,8 @@ extern void MoveGalaxy (VIEW_STATE view_state, SIZE dx, SIZE dy); extern BOOLEAN CalculateGravity (ELEMENT *ElementPtr); -#endif /* UQM_ELEMENT_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_ELEMENT_H_ */ diff --git a/sc2/src/uqm/encount.c b/sc2/src/uqm/encount.c index dffd7d0b6..ceb5c503c 100644 --- a/sc2/src/uqm/encount.c +++ b/sc2/src/uqm/encount.c @@ -22,6 +22,7 @@ #include "battlecontrols.h" #include "build.h" #include "colors.h" +#include "starmap.h" #include "cons_res.h" #include "controls.h" #include "menustat.h" @@ -77,9 +78,7 @@ DoSelectAction (MENU_STATE *pMS) if (!GameOptions ()) return FALSE; DrawMenuStateStrings (PM_CONVERSE, pMS->CurState); - LockMutex (GraphicsLock); SetFlashRect (SFR_MENU_3DO); - UnlockMutex (GraphicsLock); break; default: printf ("Unknown option: %d\n", pMS->CurState); @@ -269,7 +268,6 @@ InitEncounter (void) extern FRAME planet[]; MUSIC_REF MR; - LockMutex (GraphicsLock); SetContext (SpaceContext); SetContextFont (TinyFont); @@ -277,11 +275,9 @@ InitEncounter (void) MR = LoadMusic (REDALERT_MUSIC); PlayMusic (MR, FALSE, 1); SegueFrame = CaptureDrawable (LoadGraphic (SEGUE_PMAP_ANIM)); - UnlockMutex (GraphicsLock); WaitForSoundEnd (TFBSOUND_WAIT_ALL); StopMusic (); DestroyMusic (MR); - LockMutex (GraphicsLock); s.origin.x = s.origin.y = 0; SetTransitionSource (NULL); @@ -300,7 +296,7 @@ InitEncounter (void) SetContextFont (MicroFont); SetContextForeGroundColor ( BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01)); - if (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE) + if (inHQSpace ()) { t.pStr = GAME_STRING (ENCOUNTER_STRING_BASE + 0); // "ENCOUNTER IN" @@ -393,7 +389,6 @@ InitEncounter (void) DestroyDrawable (ReleaseDrawable (SegueFrame)); ScreenTransition (3, NULL); - UnlockMutex (GraphicsLock); { MENU_STATE MenuState; @@ -402,15 +397,11 @@ InitEncounter (void) MenuState.Initialized = FALSE; DrawMenuStateStrings (PM_CONVERSE, MenuState.CurState = HAIL); - LockMutex (GraphicsLock); SetFlashRect (SFR_MENU_3DO); - UnlockMutex (GraphicsLock); DoInput (&MenuState, TRUE); - LockMutex (GraphicsLock); SetFlashRect (NULL); - UnlockMutex (GraphicsLock); return (MenuState.CurState); } @@ -450,10 +441,8 @@ DrawFadeText (const UNICODE *str1, const UNICODE *str2, BOOLEAN fade_in, { for (i = 0; i < (SIZE) NUM_FADES; ++i) { - UnlockMutex (GraphicsLock); if (AnyButtonPress (TRUE)) i = NUM_FADES - 1; - LockMutex (GraphicsLock); SetContextForeGroundColor (fade_cycle[i]); font_DrawText (&t1); @@ -466,10 +455,8 @@ DrawFadeText (const UNICODE *str1, const UNICODE *str2, BOOLEAN fade_in, { for (i = NUM_FADES - 1; i >= 0; --i) { - UnlockMutex (GraphicsLock); if (AnyButtonPress (TRUE)) i = 0; - LockMutex (GraphicsLock); SetContextForeGroundColor (fade_cycle[i]); font_DrawText (&t1); @@ -491,7 +478,6 @@ UninitEncounter (void) ships_killed = 0; - LockMutex (GraphicsLock); free_gravity_well (); if ((GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD)) @@ -580,7 +566,7 @@ UninitEncounter (void) { DrawSISFrame (); DrawSISMessage (NULL); - if (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE) + if (inHQSpace ()) DrawHyperCoords (GLOBAL (ShipStamp.origin)); else if (GLOBAL (ip_planet) == 0) DrawHyperCoords (CurStarDescPtr->star_pt); @@ -701,10 +687,8 @@ UninitEncounter (void) TimeCount Time = GetTimeCounter (); for (j = 0; j < NUM_SHIP_FADES; ++j) { - UnlockMutex (GraphicsLock); Sleepy = (BOOLEAN)!AnyButtonPress (TRUE) && !(GLOBAL (CurrentActivity) & CHECK_ABORT); - LockMutex (GraphicsLock); if (!Sleepy) break; @@ -737,9 +721,7 @@ UninitEncounter (void) DestroyDrawable (ReleaseDrawable (s.frame)); #endif /* NEVER */ - UnlockMutex (GraphicsLock); WaitForAnyButton (TRUE, ONE_SECOND * 3, FALSE); - LockMutex (GraphicsLock); if (!CurrentInputState.key[PlayerControls[0]][KEY_ESCAPE]) { DrawFadeText (str1, str2, FALSE, &scavenge_r); @@ -765,9 +747,7 @@ UninitEncounter (void) str2 = GAME_STRING (ENCOUNTER_STRING_BASE + 7); // "Scavenged" DrawFadeText (str1, str2, TRUE, &scavenge_r); - UnlockMutex (GraphicsLock); WaitForAnyButton (TRUE, ONE_SECOND * 2, FALSE); - LockMutex (GraphicsLock); if (!CurrentInputState.key[PlayerControls[0]][KEY_ESCAPE]) DrawFadeText (str1, str2, FALSE, &scavenge_r); } @@ -786,7 +766,6 @@ UninitEncounter (void) } } ExitUninitEncounter: - UnlockMutex (GraphicsLock); return (ships_killed); } @@ -798,7 +777,6 @@ EncounterBattle (void) extern UWORD nth_frame; InputContext *savedPlayerInput = NULL; - LockMutex (GraphicsLock); SET_GAME_STATE (BATTLE_SEGUE, 1); @@ -837,9 +815,7 @@ EncounterBattle (void) GameSounds = CaptureSound (LoadSound (GAME_SOUNDS)); - UnlockMutex (GraphicsLock); Battle (NULL); - LockMutex (GraphicsLock); DestroySound (ReleaseSound (GameSounds)); GameSounds = 0; @@ -863,6 +839,5 @@ EncounterBattle (void) GLOBAL (CurrentActivity) = OldActivity; - UnlockMutex (GraphicsLock); } diff --git a/sc2/src/uqm/encount.h b/sc2/src/uqm/encount.h index 88a0ef7d3..b623a4141 100644 --- a/sc2/src/uqm/encount.h +++ b/sc2/src/uqm/encount.h @@ -30,12 +30,24 @@ typedef struct encounter ENCOUNTER; #include "element.h" #include "races.h" +#if defined(__cplusplus) +extern "C" { +#endif + typedef HLINK HENCOUNTER; #define MAX_HYPER_SHIPS 7 + +// ENCOUNTER.flags +// XXX: Currently, the flags are combined with num_ships into a single BYTE +// in the savegames: num_ships occupy the low nibble and flags the high one. +// Bits 4 and 5 are available for more flags in the savegames, +// and bits 0-3 available in the game but will not be saved. #define ONE_SHOT_ENCOUNTER (1 << 7) #define ENCOUNTER_REFORMING (1 << 6) +#define ENCOUNTER_SHIPS_MASK 0x0f +#define ENCOUNTER_FLAGS_MASK 0xf0 struct brief_ship_info { @@ -57,9 +69,14 @@ struct encounter SIZE transition_state; POINT origin; COUNT radius; + BYTE race_id; + BYTE num_ships; + BYTE flags; + // See ENCOUNTER.flags above + POINT loc_pt; - STAR_DESC SD; BRIEF_SHIP_INFO ShipList[MAX_HYPER_SHIPS]; + // Only the crew_level member is currently used SDWORD log_x, log_y; }; @@ -76,78 +93,12 @@ struct encounter #define GetPredEncounter(l) _GetPredLink (l) #define GetSuccEncounter(l) _GetSuccLink (l) -enum -{ - SOL_DEFINED = 1, - SHOFIXTI_DEFINED, - MAIDENS_DEFINED, - START_COLONY_DEFINED, - SPATHI_DEFINED, - ZOQFOT_DEFINED, - - MELNORME0_DEFINED, - MELNORME1_DEFINED, - MELNORME2_DEFINED, - MELNORME3_DEFINED, - MELNORME4_DEFINED, - MELNORME5_DEFINED, - MELNORME6_DEFINED, - MELNORME7_DEFINED, - MELNORME8_DEFINED, - - TALKING_PET_DEFINED, - CHMMR_DEFINED, - SYREEN_DEFINED, - BURVIXESE_DEFINED, - SLYLANDRO_DEFINED, - DRUUGE_DEFINED, - BOMB_DEFINED, - AQUA_HELIX_DEFINED, - SUN_DEVICE_DEFINED, - TAALO_PROTECTOR_DEFINED, - SHIP_VAULT_DEFINED, - URQUAN_WRECK_DEFINED, - VUX_BEAST_DEFINED, - SAMATRA_DEFINED, - ZOQ_SCOUT_DEFINED, - MYCON_DEFINED, - EGG_CASE0_DEFINED, - EGG_CASE1_DEFINED, - EGG_CASE2_DEFINED, - PKUNK_DEFINED, - UTWIG_DEFINED, - SUPOX_DEFINED, - YEHAT_DEFINED, - VUX_DEFINED, - ORZ_DEFINED, - THRADD_DEFINED, - RAINBOW_DEFINED, - ILWRATH_DEFINED, - ANDROSYNTH_DEFINED, - MYCON_TRAP_DEFINED -}; - -#define UMGAH_DEFINED TALKING_PET_DEFINED - -// XXX: The stuff till EOC does not belong here -extern STAR_DESC *CurStarDescPtr; -extern STAR_DESC *star_array; - -#define NUM_SOLAR_SYSTEMS 502 - -extern STAR_DESC* FindStar (STAR_DESC *pLastStar, POINT *puniverse, - SIZE xbounds, SIZE ybounds); - -extern void GetClusterName (const STAR_DESC *pSD, UNICODE buf[]); -// <<< EOC - enum { HAIL = 0, ATTACK }; - extern void EncounterBattle (void); extern void BuildBattle (COUNT which_player); extern COUNT InitEncounter (void); @@ -155,40 +106,14 @@ extern COUNT UninitEncounter (void); extern BOOLEAN FleetIsInfinite (COUNT playerNr); extern void UpdateShipFragCrew (STARSHIP *); -// XXX: in comm.h, temporary, until solsys generation code is redone -extern COUNT InitCommunication (CONVERSATION which_comm); - -extern void GenerateSOL (BYTE control); -extern void GenerateShofixti (BYTE control); -extern void GenerateColony (BYTE control); -extern void GenerateSpathi (BYTE control); -extern void GenerateZoqFotPik (BYTE control); -extern void GenerateMelnorme (BYTE control); -extern void GenerateTalkingPet (BYTE control); -extern void GenerateChmmr (BYTE control); -extern void GenerateSyreen (BYTE control); -extern void GenerateBurvixes (BYTE control); -extern void GenerateSlylandro (BYTE control); -extern void GenerateDruuge (BYTE control); -extern void GenerateUtwig (BYTE control); -extern void GenerateThradd (BYTE control); -extern void GenerateMycon (BYTE control); -extern void GenerateOrz (BYTE control); -extern void GenerateShipVault (BYTE control); -extern void GenerateUrquanWreck (BYTE control); -extern void GenerateVUX (BYTE control); -extern void GenerateSamatra (BYTE control); -extern void GenerateYehat (BYTE control); -extern void GeneratePkunk (BYTE control); -extern void GenerateSupox (BYTE control); -extern void GenerateRainbow (BYTE control); -extern void GenerateIlwrath (BYTE control); - // Last race the player battled with, or -1 if no battle took place. // Set to -1 by some funcs to inhibit IP groups from intercepting // the flagship. extern SIZE EncounterRace; extern BYTE EncounterGroup; -#endif /* UQM_ENCOUNT_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_ENCOUNT_H_ */ diff --git a/sc2/src/uqm/flash.c b/sc2/src/uqm/flash.c index cececaa74..2c73ed011 100644 --- a/sc2/src/uqm/flash.c +++ b/sc2/src/uqm/flash.c @@ -18,6 +18,12 @@ // areas, drawing directly to the screen, using a cache, are // currently in use. +// NOTE: +// - If you change the properties of the original CONTEXT, specifically the +// dimensions and origin, you'll need to call Flash_preUpdate() before and +// Flash_postUpdate() after that change. Note that this may change which +// part of the screen is flashing. + // TODO: // - During a few frames during the sequence, the frame to be displayed // is equal to a frame which was supplied as a parameter to the flash @@ -30,8 +36,6 @@ #define FLASH_INTERNAL #include "flash.h" -#include "setup.h" - // For GraphicsLock. #include "libs/log.h" #include "libs/memlib.h" #include "libs/threadlib.h" @@ -211,6 +215,7 @@ Flash_terminate (FlashContext *context) Flash_drawFrame (context, context->original); Flash_clearCache (context); + HFree (context->cache); DestroyDrawable (ReleaseDrawable (context->original)); } @@ -274,37 +279,36 @@ Flash_process (FlashContext *context) now = GetTimeCounter (); - if (context->state == FlashState_fadeIn) + switch (context->state) { - if (now >= context->lastStateTime + context->fadeInTime) - { + case FlashState_fadeIn: + if (now >= context->lastStateTime + context->fadeInTime) + { + Flash_nextState (context); + context->lastStateTime = now; + } + context->lastFrameTime = now; + break; + case FlashState_on: + if (now < context->lastStateTime + context->onTime) + return; Flash_nextState (context); context->lastStateTime = now; - } - context->lastFrameTime = now; - } - else if (context->state == FlashState_on) - { - if (now < context->lastStateTime + context->onTime) - return; - Flash_nextState (context); - context->lastStateTime = now; - } - else if (context->state == FlashState_fadeOut) - { - if (now >= context->lastStateTime + context->fadeOutTime) - { + break; + case FlashState_fadeOut: + if (now >= context->lastStateTime + context->fadeOutTime) + { + Flash_nextState (context); + context->lastStateTime = now; + } + context->lastFrameTime = now; + break; + case FlashState_off: + if (now < context->lastStateTime + context->offTime) + return; Flash_nextState (context); context->lastStateTime = now; - } - context->lastFrameTime = now; - } - else /* context->state == FlashState_off */ - { - if (now < context->lastStateTime + context->offTime) - return; - Flash_nextState (context); - context->lastStateTime = now; + break; } Flash_drawCurrentFrame (context); @@ -472,7 +476,8 @@ Flash_setOverlay (FlashContext *context, const POINT *origin, FRAME overlay) } } -// Call before you update the graphics in the currently flashing area. +// Call before you update the graphics in the currently flashing area, +// or before you change the dimensions or origin of the graphics context. void Flash_preUpdate (FlashContext *context) { @@ -483,7 +488,8 @@ Flash_preUpdate (FlashContext *context) } } -// Call after you update the graphics in the currently flashing area. +// Call after you update the graphics in the currently flashing area, +// or after you change the dimensions or origin of the graphics context. void Flash_postUpdate (FlashContext *context) { @@ -537,7 +543,6 @@ Flash_grabOriginal (FlashContext *context) if (context->original != (FRAME) 0) DestroyDrawable (ReleaseDrawable (context->original)); - LockMutex (GraphicsLock); oldGfxContext = SetContext (context->gfxContext); context->original = CaptureDrawable (CopyContextRect (&context->rect)); SetContext (oldGfxContext); @@ -545,7 +550,6 @@ Flash_grabOriginal (FlashContext *context) // CopyContextRect() may have queued the command to read // a rectangle from the screen; a FlushGraphics() // is necessary to ensure that it can actually be used. - UnlockMutex (GraphicsLock); } static inline void @@ -581,7 +585,6 @@ Flash_makeFrame (FlashContext *context, FRAME dest, int numer, int denom) Flash_blendFraction (context, numer, denom, &blendedNumer, &blendedDenom); - LockMutex (GraphicsLock); oldGfxContext = SetContext (workGfxContext); SetContextFGFrame (dest); @@ -642,7 +645,6 @@ Flash_makeFrame (FlashContext *context, FRAME dest, int numer, int denom) } SetContext (oldGfxContext); - UnlockMutex (GraphicsLock); } // Prepare an entry in the cache. @@ -678,7 +680,6 @@ Flash_drawFrame (FlashContext *context, FRAME frame) CONTEXT oldGfxContext; STAMP stamp; - LockMutex (GraphicsLock); oldGfxContext = SetContext (context->gfxContext); stamp.origin = context->rect.corner; @@ -686,7 +687,6 @@ Flash_drawFrame (FlashContext *context, FRAME frame) DrawStamp(&stamp); SetContext (oldGfxContext); - UnlockMutex (GraphicsLock); } static void @@ -803,5 +803,3 @@ Flash_drawCurrentFrame (FlashContext *context) Flash_drawCachedFrame (context, numer, denom); } - - diff --git a/sc2/src/uqm/flash.h b/sc2/src/uqm/flash.h index d0b9a4bce..0488fd388 100644 --- a/sc2/src/uqm/flash.h +++ b/sc2/src/uqm/flash.h @@ -31,18 +31,17 @@ * * // We create the flash context; it is used to manipulate the flash * // rectangle while it exists. - * FlashContext *fc = Flash_createHighlight (context, (FRAME) 0, rect); + * FlashContext *fc = Flash_createHighlight (gfxContext, rect); * * // Specify how bright the flash is at the beginning and ending of the * // sequence. - * Flash_setMergeFactors(context, 2, 3, 2); + * Flash_setMergeFactors(fc, 2, 3, 2); * * // We change the flashing speed from the defaults. - * Flash_setSpeed (ONE_SECOND, ONE_SECOND, ONE_SECOND, ONE_SECOND); + * Flash_setSpeed (fc, ONE_SECOND, ONE_SECOND, ONE_SECOND, ONE_SECOND); * * // During cross-fades, update 8 times per second. - * Flash_setFrameTime (gmstate.player[playerI].flashContext, - * ONE_SECOND / 8); + * Flash_setFrameTime (fc, ONE_SECOND / 8); * * // We start the flashing. The default is to start from the "off" state. * Flash_start (fc); @@ -63,7 +62,7 @@ * ... * // Modifying the graphics of the area that is flashing: * void Flash_preUpdate (fc); - * ... // do Drawing + * ... // do drawing * void Flash_postUpdate (fc); * ... * // We're done. Terminating the flash restores the flash area to its @@ -78,18 +77,24 @@ * * Limitations: * - * 2) Functions that draw to the gfxContext or read the original gfxContext - * contents, which is most of them, must be called with gfxContext having - * the same clip-rect as it did when other drawing functions were called. - * Otherwise, original contents restoration may draw to the wrong area, or - * the wrong area may be read. - * There may be cases where one would *want* that to happen, and such - * cases are not covered by this limitation. + * * Functions that draw to the gfxContext or read the original gfxContext + * contents, which is most of them, must be called with gfxContext having + * the same clip-rect as it did when other drawing functions were called. + * Otherwise, original contents restoration may draw to the wrong area, or + * the wrong area may be read. + * There may be cases where one would *want* that to happen, and such + * cases are not covered by this limitation. + * * Multiple flashes may be used simultaneously, but don't let them + * overlap; artifacts would occur. */ #include "libs/gfxlib.h" #include "libs/timelib.h" +#if defined(__cplusplus) +extern "C" { +#endif + typedef enum { FlashState_fadeIn = 0, // Someway between on and off, going towards on. @@ -159,8 +164,8 @@ struct FlashContext { TimeCount lastFrameTime; // Time of the last frame draw. - BOOLEAN started : 1; - BOOLEAN paused : 1; + BOOLEAN started; + BOOLEAN paused; FRAME *cache; COUNT cacheSize; @@ -211,5 +216,8 @@ void Flash_setCacheSize (FlashContext *context, COUNT size); COUNT Flash_getCacheSize (const FlashContext *context); -#endif /* UQM_FLASH_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_FLASH_H_ */ diff --git a/sc2/src/uqm/fmv.c b/sc2/src/uqm/fmv.c index 32dc21f8c..b567901d0 100644 --- a/sc2/src/uqm/fmv.c +++ b/sc2/src/uqm/fmv.c @@ -79,13 +79,11 @@ SplashScreen (void (* DoProcessing)(DWORD TimeOut)) DWORD TimeOut; SleepThreadUntil (FadeScreen (FadeAllToBlack, ONE_SECOND / 120)); - LockMutex (GraphicsLock); SetContext (ScreenContext); s.origin.x = s.origin.y = 0; s.frame = CaptureDrawable (LoadGraphic (TITLE_ANIM)); DrawStamp (&s); DestroyDrawable (ReleaseDrawable (s.frame)); - UnlockMutex (GraphicsLock); TimeOut = FadeScreen (FadeAllToColor, ONE_SECOND / 2); diff --git a/sc2/src/uqm/fmv.h b/sc2/src/uqm/fmv.h index 2569b0959..6ff4dd85f 100644 --- a/sc2/src/uqm/fmv.h +++ b/sc2/src/uqm/fmv.h @@ -20,6 +20,11 @@ #include "libs/compiler.h" #include "libs/sndlib.h" #include "libs/gfxlib.h" + +#if defined(__cplusplus) +extern "C" { +#endif + #define WANT_SHIP_SPINS extern void SplashScreen (void (* DoProcessing)(DWORD TimeOut)); @@ -29,5 +34,8 @@ extern void DoShipSpin (COUNT index, MUSIC_REF hMusic); extern BOOLEAN ShowPresentation (RESOURCE presentation); -#endif /* UQM_FMV_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_FMV_H_ */ diff --git a/sc2/src/uqm/galaxy.c b/sc2/src/uqm/galaxy.c index 9fdac7574..7e145846e 100644 --- a/sc2/src/uqm/galaxy.c +++ b/sc2/src/uqm/galaxy.c @@ -268,7 +268,7 @@ InitGalaxy (void) else { SetPrimType (&DisplayArray[p], POINT_PRIM); - if (LOBYTE (GLOBAL (CurrentActivity)) != IN_HYPERSPACE) + if (!inHQSpace ()) SetPrimColor (&DisplayArray[p], BUILD_COLOR (MAKE_RGB15 (0x15, 0x15, 0x15), 0x07)); else if (GET_GAME_STATE (ARILOU_SPACE_SIDE) <= 1) @@ -327,7 +327,7 @@ MoveGalaxy (VIEW_STATE view_state, SIZE dx, SIZE dy) if (view_state == VIEW_CHANGE) { - if (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE) + if (inHQSpace ()) { for (iss = 0, pprim = DisplayArray; iss < 2; ++iss) { @@ -385,7 +385,7 @@ MoveGalaxy (VIEW_STATE view_state, SIZE dx, SIZE dy) } } - if (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE) + if (inHQSpace ()) { for (i = BIG_STAR_COUNT + MED_STAR_COUNT, pprim = DisplayArray; i > 0; --i, ++pprim) @@ -406,7 +406,7 @@ MoveGalaxy (VIEW_STATE view_state, SIZE dx, SIZE dy) WrapStarBlock (1, dx, dy); WrapStarBlock (0, dx, dy); - if (LOBYTE (GLOBAL (CurrentActivity)) != IN_HYPERSPACE) + if (!inHQSpace ()) { dx = SpaceOrg.x; dy = SpaceOrg.y; diff --git a/sc2/src/uqm/gameev.c b/sc2/src/uqm/gameev.c index 5af82ce84..83df601e2 100644 --- a/sc2/src/uqm/gameev.c +++ b/sc2/src/uqm/gameev.c @@ -19,8 +19,8 @@ #include "build.h" #include "clock.h" -// XXX: for CurStarDescPtr and XXX_DEFINED constants -#include "encount.h" +#include "starmap.h" +#include "gendef.h" #include "globdata.h" #include "hyper.h" #include "libs/compiler.h" @@ -60,8 +60,7 @@ EventHandler (BYTE selector) break; case HYPERSPACE_ENCOUNTER_EVENT: check_race_growth (); - if (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE - && GET_GAME_STATE (ARILOU_SPACE_SIDE) <= 1) + if (inHyperSpace ()) check_hyperspace_encounter (); AddEvent (RELATIVE_EVENT, 0, 1, 0, HYPERSPACE_ENCOUNTER_EVENT); @@ -120,7 +119,7 @@ EventHandler (BYTE selector) } break; case SHOFIXTI_RETURN_EVENT: - ActivateStarShip (SHOFIXTI_SHIP, SET_ALLIED); + SetRaceAllied (SHOFIXTI_SHIP, TRUE); GLOBAL (CrewCost) -= 2; /* crew is not an issue anymore */ SET_GAME_STATE (CREW_PURCHASED0, 0); @@ -145,7 +144,7 @@ EventHandler (BYTE selector) if (SpathiPtr->actual_strength) { - ActivateStarShip (SPATHI_SHIP, SET_NOT_ALLIED); + SetRaceAllied (SPATHI_SHIP, FALSE); SET_GAME_STATE (SPATHI_SHIELDED_SELVES, 1); SpathiPtr->actual_strength = 0; } @@ -181,7 +180,7 @@ EventHandler (BYTE selector) RebelPtr->loc.y = 0; UnlockFleetInfo (&GLOBAL (avail_race_q), hRoyalist); UnlockFleetInfo (&GLOBAL (avail_race_q), hRebel); - ActivateStarShip (YEHAT_REBEL_SHIP, SPHERE_TRACKING); + StartSphereTracking (YEHAT_REBEL_SHIP); break; } case SLYLANDRO_RAMP_UP: @@ -439,7 +438,7 @@ pkunk_mission (void) { SET_GAME_STATE (YEHAT_ABSORBED_PKUNK, 1); PkunkPtr->allied_state = DEAD_GUY; - ActivateStarShip (YEHAT_SHIP, SPHERE_TRACKING); + StartSphereTracking (YEHAT_SHIP); } else { @@ -577,7 +576,7 @@ ilwrath_mission (void) SET_GAME_STATE (THRADD_VISITS, 0); if (ThraddPtr->allied_state == GOOD_GUY) - ActivateStarShip (THRADDASH_SHIP, SET_NOT_ALLIED); + SetRaceAllied (THRADDASH_SHIP, FALSE); } ThraddState = GET_GAME_STATE (THRADD_MISSION); diff --git a/sc2/src/uqm/gameev.h b/sc2/src/uqm/gameev.h index f4b8571d2..8c2e13796 100644 --- a/sc2/src/uqm/gameev.h +++ b/sc2/src/uqm/gameev.h @@ -20,6 +20,10 @@ #include "libs/compiler.h" #include "libs/gfxlib.h" +#if defined(__cplusplus) +extern "C" { +#endif + enum { @@ -57,5 +61,8 @@ extern void SetRaceDest (BYTE which_race, COORD x, COORD y, BYTE days_left, BYTE func_index); -#endif /* UQM_GAMEEV_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_GAMEEV_H_ */ diff --git a/sc2/src/uqm/gameinp.c b/sc2/src/uqm/gameinp.c index cd2745599..66e667fe0 100644 --- a/sc2/src/uqm/gameinp.c +++ b/sc2/src/uqm/gameinp.c @@ -28,6 +28,7 @@ #include "sounds.h" #include "tactrans.h" #include "uqmdebug.h" +#include "libs/async.h" #include "libs/inplib.h" #include "libs/timelib.h" #include "libs/threadlib.h" @@ -274,6 +275,11 @@ UpdateInputState (void) if (CurrentInputState.menu[KEY_EXIT]) ExitRequested = TRUE; + +#if defined(DEBUG) || defined(USE_DEBUG_KEY) + if (PulsedInputState.menu[KEY_DEBUG]) + debugKeyPressedSynchronous (); +#endif } InputFrameCallback * @@ -359,23 +365,11 @@ DoInput (void *pInputState, BOOLEAN resetInput) do { MENU_SOUND_FLAGS soundFlags; + Async_process (); TaskSwitch (); UpdateInputState (); -#ifdef DEBUG - if (doInputDebugHook != NULL) - { - void (*saveDebugHook) (void); - saveDebugHook = doInputDebugHook; - doInputDebugHook = NULL; - // No further debugHook calls unless the called - // function resets doInputDebugHook. - (*saveDebugHook) (); - continue; - } -#endif - #if DEMO_MODE || CREATE_JOURNAL if (ArrowInput != DemoInput) #endif diff --git a/sc2/src/uqm/gameopt.c b/sc2/src/uqm/gameopt.c index 5a02e2c58..726f0b2ce 100644 --- a/sc2/src/uqm/gameopt.c +++ b/sc2/src/uqm/gameopt.c @@ -21,8 +21,7 @@ #include "build.h" #include "colors.h" #include "controls.h" -// XXX: for FindStart(), GetClusterName() -#include "encount.h" +#include "starmap.h" #include "menustat.h" #include "sis.h" #include "units.h" @@ -168,15 +167,33 @@ FeedbackSetting (BYTE which_setting) break; } - LockMutex (GraphicsLock); DrawStatusMessage (buf); - UnlockMutex (GraphicsLock); } #define DDSHS_NORMAL 0 #define DDSHS_EDIT 1 #define DDSHS_BLOCKCUR 2 +static const RECT captainNameRect = { + /* .corner = */ { + /* .x = */ 3, + /* .y = */ 10 + }, /* .extent = */ { + /* .width = */ SHIP_NAME_WIDTH - 2, + /* .height = */ SHIP_NAME_HEIGHT + } +}; +static const RECT shipNameRect = { + /* .corner = */ { + /* .x = */ 2, + /* .y = */ 20 + }, /* .extent = */ { + /* .width = */ SHIP_NAME_WIDTH, + /* .height = */ SHIP_NAME_HEIGHT + } +}; + + static BOOLEAN DrawNameString (bool nameCaptain, UNICODE *Str, COUNT CursorPos, COUNT state) @@ -186,20 +203,11 @@ DrawNameString (bool nameCaptain, UNICODE *Str, COUNT CursorPos, Color BackGround, ForeGround; FONT Font; - LockMutex (GraphicsLock); - { - r.corner.x = 2; - r.extent.width = SHIP_NAME_WIDTH; - r.extent.height = SHIP_NAME_HEIGHT; - - SetContext (StatusContext); if (nameCaptain) { // Naming the captain Font = TinyFont; - r.corner.y = 10; - ++r.corner.x; - r.extent.width -= 2; + r = captainNameRect; lf.baseline.x = r.corner.x + (r.extent.width >> 1) - 1; BackGround = BUILD_COLOR (MAKE_RGB15 (0x0A, 0x0A, 0x1F), 0x09); @@ -208,7 +216,7 @@ DrawNameString (bool nameCaptain, UNICODE *Str, COUNT CursorPos, else { // Naming the flagship Font = StarConFont; - r.corner.y = 20; + r = shipNameRect; lf.baseline.x = r.corner.x + (r.extent.width >> 1); BackGround = BUILD_COLOR (MAKE_RGB15 (0x0F, 0x00, 0x00), 0x2D); @@ -219,6 +227,7 @@ DrawNameString (bool nameCaptain, UNICODE *Str, COUNT CursorPos, lf.align = ALIGN_CENTER; } + SetContext (StatusContext); SetContextFont (Font); lf.pStr = Str; lf.CharCount = (COUNT)~0; @@ -241,10 +250,11 @@ DrawNameString (bool nameCaptain, UNICODE *Str, COUNT CursorPos, if ((text_r.extent.width + 2) >= r.extent.width) { // the text does not fit the input box size and so // will not fit when displayed later - UnlockMutex (GraphicsLock); // disallow the change return (FALSE); } + + PreUpdateFlashRect (); SetContextForeGroundColor (BackGround); DrawFilledRectangle (&r); @@ -282,11 +292,10 @@ DrawNameString (bool nameCaptain, UNICODE *Str, COUNT CursorPos, SetContextForeGroundColor (ForeGround); font_DrawText (&lf); - - SetFlashRect (&r); + + PostUpdateFlashRect (); } - UnlockMutex (GraphicsLock); return (TRUE); } @@ -309,15 +318,11 @@ NameCaptainOrShip (bool nameCaptain) TEXTENTRY_STATE tes; UNICODE *Setting; - LockMutex (GraphicsLock); - SetFlashRect (NULL); - UnlockMutex (GraphicsLock); + SetFlashRect (nameCaptain ? &captainNameRect : &shipNameRect); DrawNameString (nameCaptain, buf, 0, DDSHS_EDIT); - LockMutex (GraphicsLock); DrawStatusMessage (GAME_STRING (NAMING_STRING_BASE + 0)); - UnlockMutex (GraphicsLock); if (nameCaptain) { @@ -343,9 +348,7 @@ NameCaptainOrShip (bool nameCaptain) else utf8StringCopy (buf, sizeof (buf), Setting); - LockMutex (GraphicsLock); SetFlashRect (SFR_MENU_3DO); - UnlockMutex (GraphicsLock); DrawNameString (nameCaptain, buf, 0, DDSHS_NORMAL); @@ -434,9 +437,7 @@ SettingsMenu (void) MenuState.InputFunc = DoSettings; DoInput (&MenuState, FALSE); - LockMutex (GraphicsLock); DrawStatusMessage (NULL); - UnlockMutex (GraphicsLock); } typedef struct @@ -661,10 +662,8 @@ DrawSavegameSummary (PICK_GAME_STATE *pickState, COUNT gameIndex) r.corner.y = SIS_ORG_Y + 84; r.extent = OldRect.extent; SetContextClipRect (&r); - UnlockMutex (GraphicsLock); // draw the lander with upgrades InitLander (pSD->Flags | OVERRIDE_LANDER_FLAGS); - LockMutex (GraphicsLock); SetContextClipRect (&OldRect); SetContext (SpaceContext); @@ -925,11 +924,9 @@ DoPickGame (MENU_STATE *pMS) if (NewState != pMS->CurState) { - LockMutex (GraphicsLock); pMS->CurState = NewState; SetContext (SpaceContext); RedrawPickDisplay (pickState, pMS->CurState); - UnlockMutex (GraphicsLock); } SleepThreadUntil (TimeIn + ONE_SECOND / 30); @@ -949,9 +946,7 @@ SaveLoadGame (PICK_GAME_STATE *pickState, COUNT gameIndex) // TODO: fix ConfirmSaveLoad() interface so it does not rely on // MsgStamp != NULL parameter. - LockMutex (GraphicsLock); ConfirmSaveLoad (pickState->saving ? &saveStamp : NULL); - UnlockMutex (GraphicsLock); if (pickState->saving) success = SaveGame (gameIndex, desc); @@ -962,9 +957,7 @@ SaveLoadGame (PICK_GAME_STATE *pickState, COUNT gameIndex) // display a load problem message if (pickState->saving) { // restore the screen under "SAVING..." message - LockMutex (GraphicsLock); DrawStamp (&saveStamp); - UnlockMutex (GraphicsLock); } DestroyDrawable (ReleaseDrawable (saveStamp.frame)); @@ -999,12 +992,10 @@ PickGame (BOOLEAN saving, BOOLEAN fromMainMenu) LoadGameDescriptions (pickState.summary); - LockMutex (GraphicsLock); OldContext = SetContext (SpaceContext); // Save the current state of the screen for later restoration DlgStamp = SaveContextFrame (NULL); GetContextClipRect (&DlgRect); - UnlockMutex (GraphicsLock); SleepThreadUntil (TimeOut); PauseMusic (); @@ -1012,7 +1003,6 @@ PickGame (BOOLEAN saving, BOOLEAN fromMainMenu) FadeMusic (NORMAL_VOLUME, 0); // draw the current savegame and fade in - LockMutex (GraphicsLock); SetTransitionSource (NULL); BatchGraphics (); @@ -1034,7 +1024,6 @@ PickGame (BOOLEAN saving, BOOLEAN fromMainMenu) ScreenTransition (3, &ctxRect); UnbatchGraphics (); } - UnlockMutex (GraphicsLock); SetMenuSounds (MENU_SOUND_ARROWS | MENU_SOUND_PAGEUP | MENU_SOUND_PAGEDOWN, 0); @@ -1060,9 +1049,7 @@ PickGame (BOOLEAN saving, BOOLEAN fromMainMenu) // reload and redraw everything LoadGameDescriptions (pickState.summary); - LockMutex (GraphicsLock); RedrawPickDisplay (&pickState, MenuState.CurState); - UnlockMutex (GraphicsLock); } SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT); @@ -1075,20 +1062,16 @@ PickGame (BOOLEAN saving, BOOLEAN fromMainMenu) if (!(GLOBAL (CurrentActivity) & CHECK_ABORT) && (saving || (!pickState.success && !fromMainMenu))) { // Restore previous screen - LockMutex (GraphicsLock); SetTransitionSource (&DlgRect); BatchGraphics (); DrawStamp (&DlgStamp); ScreenTransition (3, &DlgRect); UnbatchGraphics (); - UnlockMutex (GraphicsLock); } DestroyDrawable (ReleaseDrawable (DlgStamp.frame)); - LockMutex (GraphicsLock); SetContext (OldContext); - UnlockMutex (GraphicsLock); ResumeMusic (); @@ -1116,14 +1099,10 @@ DoGameOptions (MENU_STATE *pMS) { case SAVE_GAME: case LOAD_GAME: - LockMutex (GraphicsLock); SetFlashRect (NULL); - UnlockMutex (GraphicsLock); if (PickGame (pMS->CurState == SAVE_GAME, FALSE)) return FALSE; - LockMutex (GraphicsLock); SetFlashRect (SFR_MENU_3DO); - UnlockMutex (GraphicsLock); break; case QUIT_GAME: if (ConfirmExit ()) @@ -1165,17 +1144,13 @@ GameOptions (void) MenuState.CurState = SAVE_GAME; DrawMenuStateStrings (PM_SAVE_GAME, MenuState.CurState); - LockMutex (GraphicsLock); SetFlashRect (SFR_MENU_3DO); - UnlockMutex (GraphicsLock); SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT); MenuState.InputFunc = DoGameOptions; DoInput (&MenuState, TRUE); - LockMutex (GraphicsLock); SetFlashRect (NULL); - UnlockMutex (GraphicsLock); return !(GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD)); } diff --git a/sc2/src/uqm/gameopt.h b/sc2/src/uqm/gameopt.h index 23180c8d4..1e149068a 100644 --- a/sc2/src/uqm/gameopt.h +++ b/sc2/src/uqm/gameopt.h @@ -19,11 +19,18 @@ #include "libs/compiler.h" #include "libs/gfxlib.h" +#if defined(__cplusplus) +extern "C" { +#endif + extern void ConfirmSaveLoad (STAMP *MsgStamp); extern BOOLEAN GameOptions (void); typedef void (NamingCallback) (void); extern void SetNamingCallback (NamingCallback *); -#endif /* UQM_GAMEOPT_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_GAMEOPT_H_ */ diff --git a/sc2/src/uqm/gamestr.h b/sc2/src/uqm/gamestr.h index 38916822c..60f784350 100644 --- a/sc2/src/uqm/gamestr.h +++ b/sc2/src/uqm/gamestr.h @@ -25,6 +25,10 @@ #include "libs/strlib.h" +#if defined(__cplusplus) +extern "C" { +#endif + #define STAR_STRING_COUNT 133 #define DEVICE_STRING_COUNT 29 #define CARGO_STRING_COUNT 10 @@ -82,5 +86,8 @@ extern STRING GameStrings; -#endif /* UQM_GAMESTR_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_GAMESTR_H_ */ diff --git a/sc2/src/uqm/gendef.c b/sc2/src/uqm/gendef.c index 6980222b9..6a0137762 100644 --- a/sc2/src/uqm/gendef.c +++ b/sc2/src/uqm/gendef.c @@ -17,7 +17,6 @@ */ #include "gendef.h" -#include "encount.h" #include "planets/generate.h" diff --git a/sc2/src/uqm/gendef.h b/sc2/src/uqm/gendef.h index c763130c8..b5a292af7 100644 --- a/sc2/src/uqm/gendef.h +++ b/sc2/src/uqm/gendef.h @@ -4,7 +4,68 @@ #include "planets/generate.h" #include "libs/compiler.h" +#if defined(__cplusplus) +extern "C" { +#endif + const GenerateFunctions *getGenerateFunctions (BYTE Index); +enum +{ + SOL_DEFINED = 1, + SHOFIXTI_DEFINED, + MAIDENS_DEFINED, + START_COLONY_DEFINED, + SPATHI_DEFINED, + ZOQFOT_DEFINED, + + MELNORME0_DEFINED, + MELNORME1_DEFINED, + MELNORME2_DEFINED, + MELNORME3_DEFINED, + MELNORME4_DEFINED, + MELNORME5_DEFINED, + MELNORME6_DEFINED, + MELNORME7_DEFINED, + MELNORME8_DEFINED, + + TALKING_PET_DEFINED, + CHMMR_DEFINED, + SYREEN_DEFINED, + BURVIXESE_DEFINED, + SLYLANDRO_DEFINED, + DRUUGE_DEFINED, + BOMB_DEFINED, + AQUA_HELIX_DEFINED, + SUN_DEVICE_DEFINED, + TAALO_PROTECTOR_DEFINED, + SHIP_VAULT_DEFINED, + URQUAN_WRECK_DEFINED, + VUX_BEAST_DEFINED, + SAMATRA_DEFINED, + ZOQ_SCOUT_DEFINED, + MYCON_DEFINED, + EGG_CASE0_DEFINED, + EGG_CASE1_DEFINED, + EGG_CASE2_DEFINED, + PKUNK_DEFINED, + UTWIG_DEFINED, + SUPOX_DEFINED, + YEHAT_DEFINED, + VUX_DEFINED, + ORZ_DEFINED, + THRADD_DEFINED, + RAINBOW_DEFINED, + ILWRATH_DEFINED, + ANDROSYNTH_DEFINED, + MYCON_TRAP_DEFINED +}; + +#define UMGAH_DEFINED TALKING_PET_DEFINED + +#if defined(__cplusplus) +} +#endif + #endif /* GENDEF_H */ diff --git a/sc2/src/uqm/globdata.c b/sc2/src/uqm/globdata.c index 153a71577..20e39a470 100644 --- a/sc2/src/uqm/globdata.c +++ b/sc2/src/uqm/globdata.c @@ -20,6 +20,7 @@ #include "coderes.h" #include "encount.h" +#include "starmap.h" #include "master.h" #include "setup.h" #include "units.h" @@ -31,6 +32,7 @@ #include "grpinfo.h" #include "gamestr.h" +#include #include #ifdef STATE_DEBUG # include "libs/log.h" @@ -44,8 +46,6 @@ FRAME PlayFrame; GLOBDATA GlobData; -static BOOLEAN initedGameStructs = FALSE; - BYTE getGameState (int startBit, int endBit) @@ -336,7 +336,7 @@ InitGameStructures (void) sizeof (GLOBAL_SIS (CommanderName)), GAME_STRING (NAMING_STRING_BASE + 3)); - ActivateStarShip (HUMAN_SHIP, SET_ALLIED); + SetRaceAllied (HUMAN_SHIP, TRUE); CloneShipFragment (HUMAN_SHIP, &GLOBAL (built_ship_q), 0); GLOBAL_SIS (log_x) = UNIVERSE_TO_LOGX (SOL_X); @@ -345,17 +345,6 @@ InitGameStructures (void) GLOBAL (autopilot.x) = ~0; GLOBAL (autopilot.y) = ~0; - /* In case the program is exited before the full game is terminated, - * make sure that the temporary files are deleted. - * This can be removed if we make sure if the full game is terminated - * before the game is exited. - * The initedSIS variable is added so the uninit won't happen more - * than once, as you can't remove the atexit function (when the full game - * ends). - */ - initedGameStructs = TRUE; - atexit (UninitGameStructures); - return (TRUE); } @@ -377,9 +366,6 @@ UninitGameStructures (void) { HFLEETINFO hStarShip; - if (!initedGameStructs) - return; - UninitQueue (&GLOBAL (encounter_q)); UninitQueue (&GLOBAL (ip_group_q)); UninitQueue (&GLOBAL (npc_built_ship_q)); @@ -407,7 +393,6 @@ UninitGameStructures (void) DestroyDrawable (ReleaseDrawable (PlayFrame)); PlayFrame = 0; - initedGameStructs = FALSE; } void @@ -423,4 +408,88 @@ InitGlobData (void) } +BOOLEAN +inFullGame (void) +{ + ACTIVITY act = LOBYTE (GLOBAL (CurrentActivity)); + return (act == IN_LAST_BATTLE || act == IN_ENCOUNTER || + act == IN_HYPERSPACE || act == IN_INTERPLANETARY || + act == WON_LAST_BATTLE); +} + +BOOLEAN +inSuperMelee (void) +{ + return (LOBYTE (GLOBAL (CurrentActivity)) == SUPER_MELEE); + // TODO: && !inMainMenu () +} + +#if 0 +BOOLEAN +inBattle (void) +{ + // TODO: IN_BATTLE is also set while in HyperSpace/QuasiSpace. + return ((GLOBAL (CurrentActivity) & IN_BATTLE) != 0); +} +#endif + +#if 0 +// Disabled for now as there are similar functions in uqm/planets/planets.h +// Pre: inFullGame() +BOOLEAN +inInterPlanetary (void) +{ + assert (inFullGame ()); + return (pSolarSysState != NULL); +} + +// Pre: inFullGame() +BOOLEAN +inSolarSystem (void) +{ + assert (inFullGame ()); + return (LOBYTE (GLOBAL (CurrentActivity)) == IN_INTERPLANETARY); +} + +// Pre: inFullGame() +BOOLEAN +inOrbit (void) +{ + assert (inFullGame ()); + return (pSolarSysState != NULL) && + (pSolarSysState->pOrbitalDesc != NULL); +} +#endif + +// In HyperSpace or QuasiSpace +// Pre: inFullGame() +BOOLEAN +inHQSpace (void) +{ + //assert (inFullGame ()); + return (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE); + // IN_HYPERSPACE is also set for QuasiSpace +} + +// In HyperSpace +// Pre: inFullGame() +BOOLEAN +inHyperSpace (void) +{ + //assert (inFullGame ()); + return (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE) && + (GET_GAME_STATE (ARILOU_SPACE_SIDE) <= 1); + // IN_HYPERSPACE is also set for QuasiSpace +} + +// In QuasiSpace +// Pre: inFullGame() +BOOLEAN +inQuasiSpace (void) +{ + //assert (inFullGame ()); + return (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE) && + (GET_GAME_STATE (ARILOU_SPACE_SIDE) > 1); + // IN_HYPERSPACE is also set for QuasiSpace +} diff --git a/sc2/src/uqm/globdata.h b/sc2/src/uqm/globdata.h index 4dfc87b57..acd5b53ee 100644 --- a/sc2/src/uqm/globdata.h +++ b/sc2/src/uqm/globdata.h @@ -27,6 +27,10 @@ #include "velocity.h" #include "commanim.h" +#if defined(__cplusplus) +extern "C" { +#endif + // general numbers-speech generator info // should accomodate most common base-10 languages @@ -595,6 +599,7 @@ START_GAME_STATE ADD_GAME_STATE (MELNORME_INFO_PROCEDURE, 1) ADD_GAME_STATE (MELNORME_TECH_STACK, 4) + /* MELNORME_TECH_STACK is now unused */ ADD_GAME_STATE (MELNORME_EVENTS_INFO_STACK, 5) ADD_GAME_STATE (MELNORME_ALIEN_INFO_STACK, 5) ADD_GAME_STATE (MELNORME_HISTORY_INFO_STACK, 5) @@ -887,7 +892,7 @@ enum SUPER_MELEE = 0, /* Is also used while in the main menu */ IN_LAST_BATTLE, IN_ENCOUNTER, - IN_HYPERSPACE /* in Hyperspace or Quasispace */, + IN_HYPERSPACE /* in HyperSpace or QuasiSpace */, IN_INTERPLANETARY, WON_LAST_BATTLE, @@ -899,6 +904,7 @@ enum CHECK_PAUSE = MAKE_WORD (0, (1 << 0)), IN_BATTLE = MAKE_WORD (0, (1 << 1)), + /* Is also set while in HyperSpace/QuasiSpace */ START_ENCOUNTER = MAKE_WORD (0, (1 << 2)), START_INTERPLANETARY = MAKE_WORD (0, (1 << 3)), CHECK_LOAD = MAKE_WORD (0, (1 << 4)), @@ -1006,8 +1012,21 @@ extern BOOLEAN LoadSC2Data (void); extern void InitGlobData (void); +BOOLEAN inFullGame (void); +BOOLEAN inSuperMelee (void); +//BOOLEAN inBattle (void); +//BOOLEAN inInterPlanetary (void); +//BOOLEAN inSolarSystem (void); +//BOOLEAN inOrbit (void); +BOOLEAN inHQSpace (void); +BOOLEAN inHyperSpace (void); +BOOLEAN inQuasiSpace (void); + extern BOOLEAN InitGameStructures (void); extern void UninitGameStructures (void); -#endif /* UQM_GLOBDATA_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_GLOBDATA_H_ */ diff --git a/sc2/src/uqm/grpinfo.c b/sc2/src/uqm/grpinfo.c index 572077c1c..dc7be0f4c 100644 --- a/sc2/src/uqm/grpinfo.c +++ b/sc2/src/uqm/grpinfo.c @@ -17,8 +17,8 @@ */ #include "build.h" -// XXX: for CurStarDescPtr and XXX_DEFINED constants -#include "encount.h" +#include "starmap.h" +#include "gendef.h" #include "libs/file.h" #include "globdata.h" #include "intel.h" @@ -71,7 +71,7 @@ typedef struct } GROUP_HEADER; static void -ReadGroupHeader (void *fp, GROUP_HEADER *pGH) +ReadGroupHeader (GAME_STATE_FILE *fp, GROUP_HEADER *pGH) { sread_8 (fp, &pGH->NumGroups); sread_8 (fp, &pGH->day_index); @@ -83,7 +83,7 @@ ReadGroupHeader (void *fp, GROUP_HEADER *pGH) } static void -WriteGroupHeader (void *fp, const GROUP_HEADER *pGH) +WriteGroupHeader (GAME_STATE_FILE *fp, const GROUP_HEADER *pGH) { swrite_8 (fp, pGH->NumGroups); swrite_8 (fp, pGH->day_index); @@ -95,7 +95,7 @@ WriteGroupHeader (void *fp, const GROUP_HEADER *pGH) } static void -ReadShipFragment (void *fp, SHIP_FRAGMENT *FragPtr) +ReadShipFragment (GAME_STATE_FILE *fp, SHIP_FRAGMENT *FragPtr) { BYTE tmpb; @@ -117,7 +117,7 @@ ReadShipFragment (void *fp, SHIP_FRAGMENT *FragPtr) } static void -WriteShipFragment (void *fp, const SHIP_FRAGMENT *FragPtr) +WriteShipFragment (GAME_STATE_FILE *fp, const SHIP_FRAGMENT *FragPtr) { swrite_16 (fp, 0); /* unused: was which_side */ swrite_8 (fp, FragPtr->captains_name_index); @@ -135,7 +135,7 @@ WriteShipFragment (void *fp, const SHIP_FRAGMENT *FragPtr) } static void -ReadIpGroup (void *fp, IP_GROUP *GroupPtr) +ReadIpGroup (GAME_STATE_FILE *fp, IP_GROUP *GroupPtr) { BYTE tmpb; @@ -158,7 +158,7 @@ ReadIpGroup (void *fp, IP_GROUP *GroupPtr) } static void -WriteIpGroup (void *fp, const IP_GROUP *GroupPtr) +WriteIpGroup (GAME_STATE_FILE *fp, const IP_GROUP *GroupPtr) { swrite_16 (fp, 0); /* unused; was which_side */ swrite_8 (fp, 0); /* unused; was captains_name_index */ @@ -181,7 +181,7 @@ WriteIpGroup (void *fp, const IP_GROUP *GroupPtr) void InitGroupInfo (BOOLEAN FirstTime) { - void *fp; + GAME_STATE_FILE *fp; assert (NUM_SAVED_BATTLE_GROUPS >= MAX_BATTLE_GROUPS); @@ -413,7 +413,7 @@ FoundHome: } static void -FlushGroupInfo (GROUP_HEADER* pGH, DWORD offset, BYTE which_group, void *fp) +FlushGroupInfo (GROUP_HEADER* pGH, DWORD offset, BYTE which_group, GAME_STATE_FILE *fp) { if (which_group == GROUP_LIST) { @@ -549,7 +549,7 @@ FlushGroupInfo (GROUP_HEADER* pGH, DWORD offset, BYTE which_group, void *fp) BOOLEAN GetGroupInfo (DWORD offset, BYTE which_group) { - void *fp; + GAME_STATE_FILE *fp; GROUP_HEADER GH; if (offset != GROUPS_RANDOM && which_group != GROUP_LIST) @@ -828,7 +828,7 @@ GetGroupInfo (DWORD offset, BYTE which_group) DWORD PutGroupInfo (DWORD offset, BYTE which_group) { - void *fp; + GAME_STATE_FILE *fp; GROUP_HEADER GH; if (offset != GROUPS_RANDOM && which_group != GROUP_LIST) diff --git a/sc2/src/uqm/grpinfo.h b/sc2/src/uqm/grpinfo.h index 7db29b8fa..65286aa1b 100644 --- a/sc2/src/uqm/grpinfo.h +++ b/sc2/src/uqm/grpinfo.h @@ -24,6 +24,10 @@ // for POINT #include +#if defined(__cplusplus) +extern "C" { +#endif + // XXX: Needed to maintain savegame compatibility #define NUM_SAVED_BATTLE_GROUPS 64 @@ -82,4 +86,8 @@ LockIpGroup (const QUEUE *pq, HIPGROUP h) extern HIPGROUP BuildGroup (QUEUE *pDstQueue, BYTE race_id); +#if defined(__cplusplus) +} +#endif + #endif /* UQM_GRPINFO_H_ */ diff --git a/sc2/src/uqm/hyper.c b/sc2/src/uqm/hyper.c index b39f18103..d09695271 100644 --- a/sc2/src/uqm/hyper.c +++ b/sc2/src/uqm/hyper.c @@ -26,6 +26,7 @@ #include "menustat.h" // for DrawMenuStateStrings() #include "encount.h" +#include "starmap.h" #include "ship.h" #include "shipcont.h" #include "process.h" @@ -225,13 +226,13 @@ check_hyperspace_encounter (void) encounter_flags = ONE_SHOT_ENCOUNTER; } - + // There can be only one! (of either Slylandro or Melnorme) for (hEncounter = GetHeadEncounter (); hEncounter; hEncounter = hNextEncounter) { LockEncounter (hEncounter, &EncounterPtr); hNextEncounter = GetSuccEncounter (EncounterPtr); - if (EncounterPtr->SD.Type == Type) + if (EncounterPtr->race_id == Type) { percent = 0; hNextEncounter = 0; @@ -266,8 +267,8 @@ check_hyperspace_encounter (void) memset (EncounterPtr, 0, sizeof (*EncounterPtr)); EncounterPtr->origin = FleetPtr->loc; EncounterPtr->radius = encounter_radius; - EncounterPtr->SD.Index = encounter_flags; - EncounterPtr->SD.Type = Type; + EncounterPtr->flags = encounter_flags; + EncounterPtr->race_id = Type; UnlockEncounter (hEncounter); PutEncounter (hEncounter); @@ -758,7 +759,7 @@ arilou_space_collision (ELEMENT *ElementPtr0, } static HELEMENT -AllocHyperElement (STAR_DESC *SDPtr) +AllocHyperElement (const POINT *elem_pt) { HELEMENT hHyperSpaceElement; @@ -776,11 +777,11 @@ AllocHyperElement (STAR_DESC *SDPtr) { long lx, ly; - lx = UNIVERSE_TO_LOGX (SDPtr->star_pt.x) + lx = UNIVERSE_TO_LOGX (elem_pt->x) + (LOG_SPACE_WIDTH >> 1) - GLOBAL_SIS (log_x); HyperSpaceElementPtr->current.location.x = WRAP_X (lx); - ly = UNIVERSE_TO_LOGY (SDPtr->star_pt.y) + ly = UNIVERSE_TO_LOGY (elem_pt->y) + (LOG_SPACE_HEIGHT >> 1) - GLOBAL_SIS (log_y); HyperSpaceElementPtr->current.location.y = WRAP_Y (ly); } @@ -951,25 +952,25 @@ AddEncounterElement (ENCOUNTER *EncounterPtr, POINT *puniverse) { BOOLEAN NewEncounter; HELEMENT hElement; - STAR_DESC SD; + POINT enc_pt; if (GET_GAME_STATE (ARILOU_SPACE_SIDE) >= 2) return 0; - if (EncounterPtr->SD.Index & ENCOUNTER_REFORMING) + if (EncounterPtr->flags & ENCOUNTER_REFORMING) { - EncounterPtr->SD.Index &= ~ENCOUNTER_REFORMING; + EncounterPtr->flags &= ~ENCOUNTER_REFORMING; EncounterPtr->transition_state = 100; - if ((EncounterPtr->SD.Index & ONE_SHOT_ENCOUNTER) - || LONIBBLE (EncounterPtr->SD.Index) == 0) + if ((EncounterPtr->flags & ONE_SHOT_ENCOUNTER) + || EncounterPtr->num_ships == 0) return 0; } - if (LONIBBLE (EncounterPtr->SD.Index)) + if (EncounterPtr->num_ships) { NewEncounter = FALSE; - SD.star_pt = EncounterPtr->SD.star_pt; + enc_pt = EncounterPtr->loc_pt; } else { @@ -987,7 +988,7 @@ AddEncounterElement (ENCOUNTER *EncounterPtr, POINT *puniverse) radius_squared = (DWORD)EncounterPtr->radius * EncounterPtr->radius; - Type = EncounterPtr->SD.Type; + Type = EncounterPtr->race_id; NumShips = LONIBBLE (EncounterMakeup[Type]); for (i = HINIBBLE (EncounterMakeup[Type]) - NumShips; i; --i) { @@ -998,9 +999,7 @@ AddEncounterElement (ENCOUNTER *EncounterPtr, POINT *puniverse) if (NumShips > MAX_HYPER_SHIPS) NumShips = MAX_HYPER_SHIPS; - - EncounterPtr->SD.Index = - MAKE_BYTE (NumShips, HINIBBLE (EncounterPtr->SD.Index)); + EncounterPtr->num_ships = NumShips; for (i = 0; i < NumShips; ++i) { BRIEF_SHIP_INFO *BSIPtr = &EncounterPtr->ShipList[i]; @@ -1021,29 +1020,29 @@ AddEncounterElement (ENCOUNTER *EncounterPtr, POINT *puniverse) rand_val = TFB_Random (); - SD.star_pt.x = puniverse->x + enc_pt.x = puniverse->x + (LOWORD (rand_val) % (XOFFS << 1)) - XOFFS; - if (SD.star_pt.x < 0) - SD.star_pt.x = 0; - else if (SD.star_pt.x > MAX_X_UNIVERSE) - SD.star_pt.x = MAX_X_UNIVERSE; - SD.star_pt.y = puniverse->y + if (enc_pt.x < 0) + enc_pt.x = 0; + else if (enc_pt.x > MAX_X_UNIVERSE) + enc_pt.x = MAX_X_UNIVERSE; + enc_pt.y = puniverse->y + (HIWORD (rand_val) % (YOFFS << 1)) - YOFFS; - if (SD.star_pt.y < 0) - SD.star_pt.y = 0; - else if (SD.star_pt.y > MAX_Y_UNIVERSE) - SD.star_pt.y = MAX_Y_UNIVERSE; + if (enc_pt.y < 0) + enc_pt.y = 0; + else if (enc_pt.y > MAX_Y_UNIVERSE) + enc_pt.y = MAX_Y_UNIVERSE; - dx = SD.star_pt.x - EncounterPtr->origin.x; - dy = SD.star_pt.y - EncounterPtr->origin.y; + dx = enc_pt.x - EncounterPtr->origin.x; + dy = enc_pt.y - EncounterPtr->origin.y; } while ((DWORD)((long)dx * dx + (long)dy * dy) > radius_squared); - EncounterPtr->SD.star_pt = SD.star_pt; - EncounterPtr->log_x = UNIVERSE_TO_LOGX (SD.star_pt.x); - EncounterPtr->log_y = UNIVERSE_TO_LOGY (SD.star_pt.y); + EncounterPtr->loc_pt = enc_pt; + EncounterPtr->log_x = UNIVERSE_TO_LOGX (enc_pt.x); + EncounterPtr->log_y = UNIVERSE_TO_LOGY (enc_pt.y); } - hElement = AllocHyperElement (&SD); + hElement = AllocHyperElement (&enc_pt); if (hElement) { SIZE i; @@ -1197,8 +1196,8 @@ ProcessEncounter (ENCOUNTER *EncounterPtr, POINT *puniverse, cur_facing = ANGLE_TO_FACING ( GetVelocityTravelAngle (&ElementPtr->velocity)); delta_facing = NORMALIZE_FACING (cur_facing - ANGLE_TO_FACING ( - ARCTAN (puniverse->x - EncounterPtr->SD.star_pt.x, - puniverse->y - EncounterPtr->SD.star_pt.y))); + ARCTAN (puniverse->x - EncounterPtr->loc_pt.x, + puniverse->y - EncounterPtr->loc_pt.y))); if (delta_facing || (delta_x == 0 && delta_y == 0)) { SIZE speed; @@ -1208,7 +1207,7 @@ ProcessEncounter (ENCOUNTER *EncounterPtr, POINT *puniverse, }; #define ENCOUNTER_TRACK_WAIT 3 - speed = RaceHyperSpeed[EncounterPtr->SD.Type]; + speed = RaceHyperSpeed[EncounterPtr->race_id]; if (delta_facing < ANGLE_TO_FACING (HALF_CIRCLE)) --cur_facing; else @@ -1233,14 +1232,14 @@ ProcessEncounter (ENCOUNTER *EncounterPtr, POINT *puniverse, } EncounterPtr->log_x += delta_x; EncounterPtr->log_y -= delta_y; - EncounterPtr->SD.star_pt.x = LOGX_TO_UNIVERSE (EncounterPtr->log_x); - EncounterPtr->SD.star_pt.y = LOGY_TO_UNIVERSE (EncounterPtr->log_y); + EncounterPtr->loc_pt.x = LOGX_TO_UNIVERSE (EncounterPtr->log_x); + EncounterPtr->loc_pt.y = LOGY_TO_UNIVERSE (EncounterPtr->log_y); encounter_radius = EncounterPtr->radius + (GRID_OFFSET >> 1); - delta_x = EncounterPtr->SD.star_pt.x - EncounterPtr->origin.x; + delta_x = EncounterPtr->loc_pt.x - EncounterPtr->origin.x; if (delta_x < 0) delta_x = -delta_x; - delta_y = EncounterPtr->SD.star_pt.y - EncounterPtr->origin.y; + delta_y = EncounterPtr->loc_pt.y - EncounterPtr->origin.y; if (delta_y < 0) delta_y = -delta_y; if ((COUNT)delta_x >= encounter_radius @@ -1248,6 +1247,7 @@ ProcessEncounter (ENCOUNTER *EncounterPtr, POINT *puniverse, || (DWORD)delta_x * delta_x + (DWORD)delta_y * delta_y >= (DWORD)encounter_radius * encounter_radius) { + // Encounter globe traveled outside the SoI and now disappears ElementPtr->state_flags |= NONSOLID; ElementPtr->life_span = 0; @@ -1266,8 +1266,8 @@ ProcessEncounter (ENCOUNTER *EncounterPtr, POINT *puniverse, } } - ex = EncounterPtr->SD.star_pt.x; - ey = EncounterPtr->SD.star_pt.y; + ex = EncounterPtr->loc_pt.x; + ey = EncounterPtr->loc_pt.y; if (ex - puniverse->x >= -UNIT_SCREEN_WIDTH && ex - puniverse->x <= UNIT_SCREEN_WIDTH && ey - puniverse->y >= -UNIT_SCREEN_HEIGHT @@ -1482,7 +1482,7 @@ SeedUniverse (void) || ey > (YOFFS / NUM_RADAR_SCREENS)) continue; - hHyperSpaceElement = AllocHyperElement (&SD[i]); + hHyperSpaceElement = AllocHyperElement (&SD[i].star_pt); if (hHyperSpaceElement == 0) continue; @@ -1527,7 +1527,7 @@ SeedUniverse (void) || ey > (YOFFS / NUM_RADAR_SCREENS)) continue; - hHyperSpaceElement = AllocHyperElement (SDPtr); + hHyperSpaceElement = AllocHyperElement (&SDPtr->star_pt); if (hHyperSpaceElement == 0) continue; @@ -1633,9 +1633,7 @@ DoHyperspaceMenu (MENU_STATE *pMS) if (!select) return TRUE; - LockMutex (GraphicsLock); SetFlashRect (NULL); - UnlockMutex (GraphicsLock); switch (pMS->CurState) { @@ -1675,9 +1673,7 @@ DoHyperspaceMenu (MENU_STATE *pMS) pMS->CurState = NAVIGATION; DrawMenuStateStrings (PM_STARMAP, pMS->CurState); } - LockMutex (GraphicsLock); SetFlashRect (SFR_MENU_3DO); - UnlockMutex (GraphicsLock); } return TRUE; @@ -1695,7 +1691,6 @@ UnbatchGraphics (); OldContext = SetContext (SpaceContext); OldColor = SetContextBackGroundColor (BLACK_COLOR); - UnlockMutex (GraphicsLock); memset (&MenuState, 0, sizeof (MenuState)); MenuState.InputFunc = DoHyperspaceMenu; @@ -1703,14 +1698,11 @@ UnbatchGraphics (); MenuState.CurState = STARMAP; DrawMenuStateStrings (PM_STARMAP, STARMAP); - LockMutex (GraphicsLock); SetFlashRect (SFR_MENU_3DO); - UnlockMutex (GraphicsLock); SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT); DoInput (&MenuState, TRUE); - LockMutex (GraphicsLock); SetFlashRect (NULL); SetContext (SpaceContext); @@ -1718,9 +1710,7 @@ UnbatchGraphics (); if (!(GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD))) { ClearSISRect (CLEAR_SIS_RADAR); - UnlockMutex (GraphicsLock); WaitForNoInput (ONE_SECOND / 2, FALSE); - LockMutex (GraphicsLock); } SetContextBackGroundColor (OldColor); diff --git a/sc2/src/uqm/hyper.h b/sc2/src/uqm/hyper.h index f4b207a80..b53c324d3 100644 --- a/sc2/src/uqm/hyper.h +++ b/sc2/src/uqm/hyper.h @@ -23,6 +23,10 @@ #include "units.h" // for UNIT_SCREEN_WIDTH/HEIGHT +#if defined(__cplusplus) +extern "C" { +#endif + #define NUM_RADAR_SCREENS 12 #define RADAR_SCAN_WIDTH (UNIT_SCREEN_WIDTH * NUM_RADAR_SCREENS) @@ -79,5 +83,8 @@ extern BOOLEAN hyper_transition (ELEMENT *ElementPtr); extern void HyperspaceMenu (void); extern void SaveSisHyperState (void); -#endif /* UQM_HYPER_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_HYPER_H_ */ diff --git a/sc2/src/uqm/init.c b/sc2/src/uqm/init.c index b2c77886b..7831d089e 100644 --- a/sc2/src/uqm/init.c +++ b/sc2/src/uqm/init.c @@ -187,7 +187,7 @@ InitShips (void) InitDisplayList (); InitGalaxy (); - if (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE) + if (inHQSpace ()) { ReinitQueue (&race_q[0]); ReinitQueue (&race_q[1]); @@ -311,9 +311,6 @@ UninitShips (void) crew_retrieved; } - if (StarShipPtr->RaceDescPtr->uninit_func != NULL) - (*StarShipPtr->RaceDescPtr->uninit_func) ( - StarShipPtr->RaceDescPtr); /* Record crew left after battle */ StarShipPtr->crew_level = StarShipPtr->RaceDescPtr->ship_info.crew_level; @@ -346,7 +343,7 @@ UninitShips (void) for (i = 0; i < NUM_PLAYERS; i++) ReinitQueue (&race_q[i]); - if (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE) + if (inHQSpace ()) FreeHyperspace (); } } diff --git a/sc2/src/uqm/init.h b/sc2/src/uqm/init.h index f0356a570..69867f0d3 100644 --- a/sc2/src/uqm/init.h +++ b/sc2/src/uqm/init.h @@ -20,6 +20,10 @@ #include "libs/gfxlib.h" #include "libs/reslib.h" +#if defined(__cplusplus) +extern "C" { +#endif + #define NUM_PLAYERS 2 #define NUM_SIDES 2 @@ -35,5 +39,8 @@ extern BOOLEAN load_animation (FRAME *pixarray, RESOURCE big_res, RESOURCE med_res, RESOURCE sml_res); extern BOOLEAN free_image (FRAME *pixarray); -#endif /* UQM_INIT_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_INIT_H_ */ diff --git a/sc2/src/uqm/intel.h b/sc2/src/uqm/intel.h index 9c6fac8f7..6e63e51db 100644 --- a/sc2/src/uqm/intel.h +++ b/sc2/src/uqm/intel.h @@ -24,6 +24,10 @@ #include "element.h" #include "races.h" +#if defined(__cplusplus) +extern "C" { +#endif + #define MANEUVERABILITY(pi) ((pi)->ManeuverabilityIndex) #define WEAPON_RANGE(pi) ((pi)->WeaponRange) @@ -74,6 +78,8 @@ extern BOOLEAN ThrustShip (ELEMENT *ShipPtr, COUNT angle); #define AWESOME_RATING (BYTE)(1 << 6) +#if defined(__cplusplus) +} +#endif + #endif /* UQM_INTEL_H_ */ - - diff --git a/sc2/src/uqm/intro.c b/sc2/src/uqm/intro.c index 3f90f6bc9..092c42828 100644 --- a/sc2/src/uqm/intro.c +++ b/sc2/src/uqm/intro.c @@ -160,7 +160,6 @@ Present_BatchGraphics (PRESENTATION_INPUT_STATE* pPIS) if (!pPIS->Batched) { pPIS->Batched = TRUE; - LockMutex (GraphicsLock); BatchGraphics (); } } @@ -171,7 +170,6 @@ Present_UnbatchGraphics (PRESENTATION_INPUT_STATE* pPIS, BOOLEAN bYield) if (pPIS->Batched) { UnbatchGraphics (); - UnlockMutex (GraphicsLock); pPIS->Batched = FALSE; if (bYield) TaskSwitch (); @@ -196,7 +194,6 @@ Present_GenerateSIS (PRESENTATION_INPUT_STATE* pPIS) COUNT piece; Color SisBack; - LockMutex (GraphicsLock); OldContext = SetContext (OffScreenContext); SkelFrame = CaptureDrawable (LoadGraphic (SISSKEL_MASK_PMAP_ANIM)); @@ -264,7 +261,6 @@ Present_GenerateSIS (PRESENTATION_INPUT_STATE* pPIS) SetContext (OldContext); FlushGraphics (); - UnlockMutex (GraphicsLock); pPIS->SisFrame = SisFrame; } @@ -277,9 +273,7 @@ Present_DrawMovieFrame (PRESENTATION_INPUT_STATE* pPIS) s.origin.x = 0; s.origin.y = 0; s.frame = SetAbsFrameIndex (pPIS->Frame, pPIS->MovieFrame); - LockMutex (GraphicsLock); DrawStamp (&s); - UnlockMutex (GraphicsLock); } static BOOLEAN @@ -362,9 +356,7 @@ DoPresentation (void *pIS) /* center on screen */ pPIS->clip_r.corner.x = (SCREEN_WIDTH - w) / 2; pPIS->clip_r.corner.y = (SCREEN_HEIGHT - h) / 2; - LockMutex (GraphicsLock); SetContextClipRect (&pPIS->clip_r); - UnlockMutex (GraphicsLock); } } else if (strcmp (Opcode, "FONT") == 0) @@ -390,11 +382,7 @@ DoPresentation (void *pIS) *pFont = LoadFontFile (pPIS->Buffer); } - if (!pPIS->Batched) - LockMutex (GraphicsLock); SetContextFont (*pFont); - if (!pPIS->Batched) - UnlockMutex (GraphicsLock); } else if (strcmp (Opcode, "ANI") == 0) { /* set ani */ @@ -490,12 +478,8 @@ DoPresentation (void *pIS) t.CharCount = (COUNT)~0; t.baseline.x = x; t.baseline.y = y; - if (!pPIS->Batched) - LockMutex (GraphicsLock); DrawTextEffect (&t, pPIS->TextColor, pPIS->TextBackColor, pPIS->TextEffect); - if (!pPIS->Batched) - UnlockMutex (GraphicsLock); } } else if (strcmp (Opcode, "TFI") == 0) @@ -510,9 +494,7 @@ DoPresentation (void *pIS) Present_UnbatchGraphics (pPIS, TRUE); - LockMutex (GraphicsLock); GetContextFontLeading (&leading); - UnlockMutex (GraphicsLock); switch (pPIS->TextVPos) { @@ -536,7 +518,6 @@ DoPresentation (void *pIS) pPIS->TextLines[i].baseline.y = y; } - LockMutex (GraphicsLock); for (i = 0; i < pPIS->LinesCount; ++i) DrawTextEffect (pPIS->TextLines + i, pPIS->TextFadeColor, pPIS->TextFadeColor, pPIS->TextEffect); @@ -550,7 +531,6 @@ DoPresentation (void *pIS) ScreenTransition (3, &pPIS->tfade_r); UnbatchGraphics (); - UnlockMutex (GraphicsLock); } else if (strcmp (Opcode, "TFO") == 0) { /* text fade-out */ @@ -558,7 +538,6 @@ DoPresentation (void *pIS) Present_UnbatchGraphics (pPIS, TRUE); - LockMutex (GraphicsLock); /* do transition */ SetTransitionSource (&pPIS->tfade_r); BatchGraphics (); @@ -567,7 +546,6 @@ DoPresentation (void *pIS) pPIS->TextFadeColor, pPIS->TextEffect); ScreenTransition (3, &pPIS->tfade_r); UnbatchGraphics (); - UnlockMutex (GraphicsLock); } else if (strcmp (Opcode, "SAVEBG") == 0) { /* save background */ @@ -652,15 +630,11 @@ DoPresentation (void *pIS) } s.origin.x = x; s.origin.y = y; - if (!pPIS->Batched) - LockMutex (GraphicsLock); old_mode = SetGraphicScaleMode (scale_mode); old_scale = SetGraphicScale (scale); DrawStamp (&s); SetGraphicScale (old_scale); SetGraphicScaleMode (old_mode); - if (!pPIS->Batched) - UnlockMutex (GraphicsLock); } else if (strcmp (Opcode, "BATCH") == 0) { /* batch graphics */ @@ -689,9 +663,7 @@ DoPresentation (void *pIS) { /* clear screen */ Present_UnbatchGraphics (pPIS, TRUE); - LockMutex (GraphicsLock); ClearDrawable (); - UnlockMutex (GraphicsLock); } else if (strcmp (Opcode, "CALL") == 0) { /* call another script */ @@ -712,12 +684,8 @@ DoPresentation (void *pIS) l.second.x = x2; l.second.y = y2; - if (!pPIS->Batched) - LockMutex (GraphicsLock); SetContextForeGroundColor (pPIS->TextColor); DrawLine (&l); - if (!pPIS->Batched) - UnlockMutex (GraphicsLock); } else { @@ -771,12 +739,10 @@ ShowSlidePresentation (STRING PresStr) pis.SlideShow = SetAbsStringTableIndex (pis.SlideShow, 0); pis.OperIndex = 0; - LockMutex (GraphicsLock); OldContext = SetContext (ScreenContext); GetContextClipRect (&OldRect); OldFont = SetContextFont (NULL); SetContextBackGroundColor (BLACK_COLOR); - UnlockMutex (GraphicsLock); SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE); pis.InputFunc = DoPresentation; @@ -797,11 +763,9 @@ ShowSlidePresentation (STRING PresStr) for (i = 0; i < MAX_FONTS; ++i) DestroyFont (pis.Fonts[i]); - LockMutex (GraphicsLock); SetContextFont (OldFont); SetContextClipRect (&OldRect); SetContext (OldContext); - UnlockMutex (GraphicsLock); return TRUE; } @@ -853,11 +817,9 @@ FadeClearScreen (void) SleepThreadUntil (FadeScreen (FadeAllToBlack, ONE_SECOND / 2)); // clear the screen with black - LockMutex (GraphicsLock); SetContext (ScreenContext); SetContextBackGroundColor (BLACK_COLOR); ClearDrawable (); - UnlockMutex (GraphicsLock); FadeScreen (FadeAllToColor, 0); } diff --git a/sc2/src/uqm/ipdisp.h b/sc2/src/uqm/ipdisp.h index 1321e2fa6..6b910cadb 100644 --- a/sc2/src/uqm/ipdisp.h +++ b/sc2/src/uqm/ipdisp.h @@ -19,6 +19,10 @@ #include "libs/compiler.h" +#if defined(__cplusplus) +extern "C" { +#endif + extern void NotifyOthers (COUNT which_race, BYTE target_loc); // Special target locations for NotifyOthers() #define IPNL_INTERCEPT_PLAYER 0 @@ -26,4 +30,8 @@ extern void NotifyOthers (COUNT which_race, BYTE target_loc); extern void DoMissions (void); +#if defined(__cplusplus) +} +#endif + #endif /* UQM_IPDISP_H_INCL_ */ diff --git a/sc2/src/uqm/load.c b/sc2/src/uqm/load.c index 0c1e3de60..98924f173 100644 --- a/sc2/src/uqm/load.c +++ b/sc2/src/uqm/load.c @@ -23,6 +23,7 @@ #include "build.h" #include "libs/declib.h" #include "encount.h" +#include "starmap.h" #include "libs/file.h" #include "globdata.h" #include "load.h" @@ -325,6 +326,7 @@ static void LoadEncounter (ENCOUNTER *EncounterPtr, DECODE_REF fh) { COUNT i; + BYTE tmpb; cread_ptr (fh); /* useless ptr; HENCOUNTER pred */ EncounterPtr->pred = 0; @@ -336,18 +338,19 @@ LoadEncounter (ENCOUNTER *EncounterPtr, DECODE_REF fh) cread_16s (fh, &EncounterPtr->origin.x); cread_16s (fh, &EncounterPtr->origin.y); cread_16 (fh, &EncounterPtr->radius); - // STAR_DESC fields - cread_16s (fh, &EncounterPtr->SD.star_pt.x); - cread_16s (fh, &EncounterPtr->SD.star_pt.y); - cread_8 (fh, &EncounterPtr->SD.Type); - cread_8 (fh, &EncounterPtr->SD.Index); + // former STAR_DESC fields + cread_16s (fh, &EncounterPtr->loc_pt.x); + cread_16s (fh, &EncounterPtr->loc_pt.y); + cread_8 (fh, &EncounterPtr->race_id); + cread_8 (fh, &tmpb); + EncounterPtr->num_ships = tmpb & ENCOUNTER_SHIPS_MASK; + EncounterPtr->flags = tmpb & ENCOUNTER_FLAGS_MASK; cread_16 (fh, NULL); /* alignment padding */ // Load each entry in the BRIEF_SHIP_INFO array for (i = 0; i < MAX_HYPER_SHIPS; i++) { BRIEF_SHIP_INFO *ShipInfo = &EncounterPtr->ShipList[i]; - BYTE tmpb; cread_16 (fh, NULL); /* useless; was SHIP_INFO.ship_flags */ cread_8 (fh, &ShipInfo->race_id); diff --git a/sc2/src/uqm/load.h b/sc2/src/uqm/load.h index 4a04871b1..6f2cce0f5 100644 --- a/sc2/src/uqm/load.h +++ b/sc2/src/uqm/load.h @@ -22,10 +22,17 @@ #include "libs/compiler.h" #include "globdata.h" +#if defined(__cplusplus) +extern "C" { +#endif + extern ACTIVITY NextActivity; extern BOOLEAN LoadGame (COUNT which_game, SUMMARY_DESC *summary_desc); -#endif /* UQM_LOAD_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_LOAD_H_ */ diff --git a/sc2/src/uqm/loadship.c b/sc2/src/uqm/loadship.c index 3e73c1f41..339613415 100644 --- a/sc2/src/uqm/loadship.c +++ b/sc2/src/uqm/loadship.c @@ -170,6 +170,9 @@ void free_ship (RACE_DESC *raceDescPtr, BOOLEAN FreeIconData, BOOLEAN FreeBattleData) { + if (raceDescPtr->uninit_func != NULL) + (*raceDescPtr->uninit_func) (raceDescPtr); + if (FreeBattleData) { DATA_STUFF *shipData = &raceDescPtr->ship_data; diff --git a/sc2/src/uqm/master.h b/sc2/src/uqm/master.h index aedcf4486..adcf6e54b 100644 --- a/sc2/src/uqm/master.h +++ b/sc2/src/uqm/master.h @@ -20,6 +20,10 @@ #include "races.h" #include "libs/compiler.h" +#if defined(__cplusplus) +extern "C" { +#endif + typedef HLINK HMASTERSHIP; typedef struct @@ -58,5 +62,8 @@ COUNT GetShipCostFromIndex (unsigned Index); FRAME GetShipIconsFromIndex (unsigned Index); FRAME GetShipMeleeIconsFromIndex (unsigned Index); -#endif /* UQM_MASTER_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_MASTER_H_ */ diff --git a/sc2/src/uqm/menu.c b/sc2/src/uqm/menu.c index f8cd69839..fc46e3b4c 100644 --- a/sc2/src/uqm/menu.c +++ b/sc2/src/uqm/menu.c @@ -28,9 +28,6 @@ #include "libs/tasklib.h" #include "libs/log.h" -extern Task flash_task; -extern RECT flash_rect; - static BYTE GetEndMenuState (BYTE BaseState); static BYTE GetBeginMenuState (BYTE BaseState); static BYTE FixMenuState (BYTE BadState); @@ -500,7 +497,7 @@ DrawMenuStateStrings (BYTE beg_index, SWORD NewState) if (NewState <= end_index - beg_index) s.frame = SetAbsFrameIndex (PlayFrame, beg_index + NewState); - LockMutex (GraphicsLock); + PreUpdateFlashRect (); OldContext = SetContext (StatusContext); GetContextClipRect (&r); s.origin.x = RADAR_X - r.corner.x; @@ -600,13 +597,7 @@ DrawMenuStateStrings (BYTE beg_index, SWORD NewState) } } UnbatchGraphics (); - if (flash_task - && flash_rect.corner.x == RADAR_X - && flash_rect.corner.y == RADAR_Y - && flash_rect.extent.width == RADAR_WIDTH - && flash_rect.extent.height == RADAR_HEIGHT) - SetFlashRect (SFR_MENU_3DO); SetContext (OldContext); - UnlockMutex (GraphicsLock); + PostUpdateFlashRect (); } diff --git a/sc2/src/uqm/menustat.h b/sc2/src/uqm/menustat.h index 9baf19801..2aa864dd9 100644 --- a/sc2/src/uqm/menustat.h +++ b/sc2/src/uqm/menustat.h @@ -23,6 +23,10 @@ #include "libs/sndlib.h" #include "flash.h" +#if defined(__cplusplus) +extern "C" { +#endif + typedef struct menu_state { // Standard field required by DoInput() @@ -120,5 +124,8 @@ enum extern BOOLEAN DoMenuChooser (MENU_STATE *pMS, BYTE BaseState); extern void DrawMenuStateStrings (BYTE beg_index, SWORD NewState); -#endif /* UQM_MENUSTAT_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_MENUSTAT_H_ */ diff --git a/sc2/src/uqm/oscill.c b/sc2/src/uqm/oscill.c index 72736db43..61ac98368 100644 --- a/sc2/src/uqm/oscill.c +++ b/sc2/src/uqm/oscill.c @@ -79,7 +79,8 @@ DrawOscilloscope (void) assert ((size_t)scopeSize.width <= sizeof scope_data); assert (scopeSize.height < 256); - if (GraphForegroundStream (scope_data, scopeSize.width, scopeSize.height)) + if (GraphForegroundStream (scope_data, scopeSize.width, scopeSize.height, + usingSpeech)) { int i; CONTEXT oldContext; diff --git a/sc2/src/uqm/oscill.h b/sc2/src/uqm/oscill.h index e2fc25a37..bd021a479 100644 --- a/sc2/src/uqm/oscill.h +++ b/sc2/src/uqm/oscill.h @@ -20,6 +20,10 @@ #include "libs/compiler.h" #include "libs/gfxlib.h" +#if defined(__cplusplus) +extern "C" { +#endif + extern BOOLEAN sliderDisabled; extern BOOLEAN oscillDisabled; @@ -32,5 +36,8 @@ extern void InitSlider (int x, int y, int width, FRAME sliderFrame, extern void SetSliderImage (FRAME f); void DrawSlider (void); -#endif /* UQM_OSCILL_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_OSCILL_H_ */ diff --git a/sc2/src/uqm/outfit.c b/sc2/src/uqm/outfit.c index eaed262f5..458dfa00c 100644 --- a/sc2/src/uqm/outfit.c +++ b/sc2/src/uqm/outfit.c @@ -85,7 +85,8 @@ DrawModuleStrings (MENU_STATE *pMS, BYTE NewModule) t.align = ALIGN_RIGHT; t.CharCount = (COUNT)~0; t.pStr = buf; - sprintf (buf, "%u", GLOBAL (ModuleCost[NewModule]) * MODULE_COST_SCALE); + sprintf (buf, "%u", + GLOBAL (ModuleCost[NewModule]) * MODULE_COST_SCALE); SetContextFont (TinyFont); SetContextForeGroundColor ( BUILD_COLOR (MAKE_RGB15 (0x00, 0x1F, 0x00), 0x02)); @@ -98,43 +99,38 @@ DrawModuleStrings (MENU_STATE *pMS, BYTE NewModule) static void RedistributeFuel (void) { - COUNT m; - DWORD FuelVolume; + const DWORD FuelVolume = GLOBAL_SIS (FuelOnBoard); + const CONTEXT OldContext = SetContext (SpaceContext); RECT r; - - FuelVolume = GLOBAL_SIS (FuelOnBoard); - if (FuelVolume <= FUEL_RESERVE) - return; - - GLOBAL_SIS (FuelOnBoard) = 0; - m = FUEL_VOLUME_PER_ROW; - - r.extent.width = 3; r.extent.height = 1; - while (FuelVolume -= m) - { - GLOBAL_SIS (FuelOnBoard) += FUEL_VOLUME_PER_ROW; - GetFTankCapacity (&r.corner); - DrawPoint (&r.corner); - r.corner.x += r.extent.width + 1; - DrawPoint (&r.corner); - r.corner.x -= r.extent.width; - SetContextForeGroundColor (SetContextBackGroundColor (BLACK_COLOR)); - DrawFilledRectangle (&r); - if (FuelVolume < FUEL_VOLUME_PER_ROW) - m = (COUNT)FuelVolume; - } - FuelVolume = GLOBAL_SIS (FuelOnBoard) + m; - - r.extent.width = 5; - while ((GLOBAL_SIS (FuelOnBoard) += FUEL_VOLUME_PER_ROW) < - GetFTankCapacity (&r.corner)) + // Loop through all the rows to draw + BatchGraphics (); + for (GLOBAL_SIS (FuelOnBoard) = FUEL_RESERVE; + GLOBAL_SIS (FuelOnBoard) < GetFTankCapacity (&r.corner); + GLOBAL_SIS (FuelOnBoard) += FUEL_VOLUME_PER_ROW) { - SetContextForeGroundColor ( - BUILD_COLOR (MAKE_RGB15 (0x0B, 0x00, 0x00), 0x2E)); + // If we're less than the fuel level, draw fuel. + if (GLOBAL_SIS (FuelOnBoard) < FuelVolume) + { + r.extent.width = 3; + DrawPoint (&r.corner); + r.corner.x += r.extent.width + 1; + DrawPoint (&r.corner); + r.corner.x -= r.extent.width; + SetContextForeGroundColor ( + SetContextBackGroundColor (BLACK_COLOR)); + } + else // Otherwise, draw an empty bar. + { + r.extent.width = 5; + SetContextForeGroundColor ( + BUILD_COLOR (MAKE_RGB15 (0x0B, 0x00, 0x00), 0x2E)); + } DrawFilledRectangle (&r); } + UnbatchGraphics (); + SetContext (OldContext); GLOBAL_SIS (FuelOnBoard) = FuelVolume; } @@ -238,7 +234,6 @@ DoInstallModule (MENU_STATE *pMS) pMS->InputFunc = DoInstallModule; - LockMutex (GraphicsLock); SetContext (SpaceContext); ClearSISRect (CLEAR_SIS_RADAR); @@ -300,7 +295,6 @@ DoInstallModule (MENU_STATE *pMS) } } - LockMutex (GraphicsLock); SetContext (SpaceContext); SetFlashRect (NULL); @@ -348,7 +342,8 @@ DoInstallModule (MENU_STATE *pMS) GLOBAL (ModuleCost[old_slot_piece]) * MODULE_COST_SCALE); - if (pMS->CurState == PLANET_LANDER || pMS->CurState == EMPTY_SLOT + 3) + if (pMS->CurState == PLANET_LANDER || + pMS->CurState == EMPTY_SLOT + 3) DisplayLanders (pMS); else { @@ -385,15 +380,12 @@ DoInstallModule (MENU_STATE *pMS) else { SetContext (StatusContext); - UnlockMutex (GraphicsLock); DrawMenuStateStrings (PM_FUEL, pMS->CurState = OUTFIT_MODULES); - LockMutex (GraphicsLock); SetFlashRect (SFR_MENU_3DO); pMS->InputFunc = DoOutfit; ClearSISRect (DRAW_SIS_DISPLAY); } - UnlockMutex (GraphicsLock); } else if (motion) { @@ -402,7 +394,8 @@ DoInstallModule (MENU_STATE *pMS) NewItem = NewState < EMPTY_SLOT ? pMS->CurState : pMS->delta_item; do { - if (NewState >= EMPTY_SLOT && (PulsedInputState.menu[KEY_MENU_UP] || PulsedInputState.menu[KEY_MENU_DOWN])) + if (NewState >= EMPTY_SLOT && (PulsedInputState.menu[KEY_MENU_UP] + || PulsedInputState.menu[KEY_MENU_DOWN])) { if (PulsedInputState.menu[KEY_MENU_UP]) { @@ -442,15 +435,14 @@ DoInstallModule (MENU_STATE *pMS) || (NewItem >= GUN_WEAPON && NewItem <= CANNON_WEAPON && pMS->delta_item > 0 && pMS->delta_item < 13))); - LockMutex (GraphicsLock); if (NewState < EMPTY_SLOT) { if (NewItem != pMS->CurState) { pMS->CurState = NewItem; + PreUpdateFlashRect (); DrawModuleStrings (pMS, NewItem); - // flash with PC menus too - SetFlashRect (SFR_MENU_ANY); + PostUpdateFlashRect (); } } else if (NewItem != pMS->delta_item || NewState != pMS->CurState) @@ -542,7 +534,6 @@ InitFlash: else SetFlashRect (&pMS->flash_rect0); } - UnlockMutex (GraphicsLock); } return (TRUE); @@ -551,64 +542,55 @@ InitFlash: static void ChangeFuelQuantity (void) { - RECT r; + int incr = 0; // Fuel increment in fuel points (not units). - r.extent.height = 1; - - if (PulsedInputState.menu[KEY_MENU_UP]) - { - LockMutex (GraphicsLock); - SetContext (SpaceContext); - if (GetFTankCapacity (&r.corner) > GLOBAL_SIS (FuelOnBoard) - && GLOBAL_SIS (ResUnits) >= (DWORD)GLOBAL (FuelCost)) - { - if (GLOBAL_SIS (FuelOnBoard) >= FUEL_RESERVE) - { - r.extent.width = 3; - DrawPoint (&r.corner); - r.corner.x += r.extent.width + 1; - DrawPoint (&r.corner); - r.corner.x -= r.extent.width; - SetContextForeGroundColor ( - SetContextBackGroundColor (BLACK_COLOR)); - DrawFilledRectangle (&r); - } - DeltaSISGauges (0, FUEL_TANK_SCALE, -GLOBAL (FuelCost)); - SetContext (StatusContext); - GetGaugeRect (&r, FALSE); - SetFlashRect (&r); - } - else - { // no more room for fuel or not enough RUs - PlayMenuSound (MENU_SOUND_FAILURE); - } - UnlockMutex (GraphicsLock); - } + if (PulsedInputState.menu[KEY_MENU_UP]) + incr = FUEL_TANK_SCALE; // +1 Unit else if (PulsedInputState.menu[KEY_MENU_DOWN]) + incr = -FUEL_TANK_SCALE; // -1 Unit + else if (PulsedInputState.menu[KEY_MENU_PAGE_UP]) + incr = FUEL_VOLUME_PER_ROW; // +1 Bar + else if (PulsedInputState.menu[KEY_MENU_PAGE_DOWN]) + incr = -FUEL_VOLUME_PER_ROW; // -1 Bar + else + return; + + // Clamp incr to what we can afford/hold/have. { - LockMutex (GraphicsLock); - SetContext (SpaceContext); - if (GLOBAL_SIS (FuelOnBoard)) - { - DeltaSISGauges (0, -FUEL_TANK_SCALE, GLOBAL (FuelCost)); - if (GLOBAL_SIS (FuelOnBoard) % FUEL_VOLUME_PER_ROW == 0 && - GLOBAL_SIS (FuelOnBoard) >= FUEL_RESERVE) - { - GetFTankCapacity (&r.corner); - SetContextForeGroundColor ( - BUILD_COLOR (MAKE_RGB15 (0x0B, 0x00, 0x00), 0x2E)); - r.extent.width = 5; - DrawFilledRectangle (&r); - } - } - else - { // no fuel left to drain - PlayMenuSound (MENU_SOUND_FAILURE); - } - SetContext (StatusContext); + const int maxFit = GetFuelTankCapacity () - GLOBAL_SIS (FuelOnBoard); + const int maxAfford = GLOBAL_SIS (ResUnits) / GLOBAL (FuelCost); + const int minFit = - (int) GLOBAL_SIS (FuelOnBoard); + + if (incr > maxFit) + incr = maxFit; // All we can hold. + + if (incr > maxAfford * FUEL_TANK_SCALE) + incr = maxAfford * FUEL_TANK_SCALE; // All we can afford. + + if (incr < minFit) + incr = minFit; // All we have. + } + + if (!incr) + { + // No more room, not enough RUs, or no fuel left to drain. + PlayMenuSound (MENU_SOUND_FAILURE); + } + else + { + const int cost = (incr / FUEL_TANK_SCALE) * GLOBAL (FuelCost); + PreUpdateFlashRect (); + DeltaSISGauges (0, incr, -cost); + PostUpdateFlashRect (); + RedistributeFuel (); + } + + { // Make fuel gauge flash. + RECT r; + CONTEXT oldContext = SetContext (StatusContext); GetGaugeRect (&r, FALSE); SetFlashRect (&r); - UnlockMutex (GraphicsLock); + SetContext (oldContext); } } @@ -616,9 +598,7 @@ static void onNamingDone (void) { // In case player just named a ship, redraw it - LockMutex (GraphicsLock); DrawFlagshipName (FALSE); - UnlockMutex (GraphicsLock); } BOOLEAN @@ -648,7 +628,6 @@ DoOutfit (MENU_STATE *pMS) s.frame = CaptureDrawable ( LoadGraphic (OUTFIT_PMAP_ANIM)); - LockMutex (GraphicsLock); SetTransitionSource (NULL); BatchGraphics (); DrawSISFrame (); @@ -710,21 +689,16 @@ DoOutfit (MENU_STATE *pMS) DrawStamp (&s); } - UnlockMutex (GraphicsLock); DrawMenuStateStrings (PM_FUEL, pMS->CurState); - LockMutex (GraphicsLock); DrawFlagshipName (FALSE); if (optWhichFonts == OPT_PC) DrawFlagshipStats (); - UnlockMutex (GraphicsLock); ScreenTransition (3, NULL); PlayMusic (pMS->hMusic, TRUE, 1); UnbatchGraphics (); - LockMutex (GraphicsLock); SetFlashRect (SFR_MENU_3DO); - UnlockMutex (GraphicsLock); GLOBAL_SIS (FuelOnBoard) = (GLOBAL_SIS (FuelOnBoard) @@ -741,9 +715,7 @@ DoOutfit (MENU_STATE *pMS) if (pMS->CurState == OUTFIT_DOFUEL) { pMS->CurState = OUTFIT_FUEL; - LockMutex (GraphicsLock); SetFlashRect (SFR_MENU_3DO); - UnlockMutex (GraphicsLock); } else { @@ -767,18 +739,14 @@ ExitOutfit: RECT r; pMS->CurState = OUTFIT_DOFUEL; - LockMutex (GraphicsLock); SetContext (StatusContext); GetGaugeRect (&r, FALSE); SetFlashRect (&r); - UnlockMutex (GraphicsLock); break; } case OUTFIT_DOFUEL: pMS->CurState = OUTFIT_FUEL; - LockMutex (GraphicsLock); SetFlashRect (SFR_MENU_3DO); - UnlockMutex (GraphicsLock); break; case OUTFIT_MODULES: pMS->CurState = EMPTY_SLOT + 2; @@ -795,9 +763,7 @@ ExitOutfit: if (!GameOptions ()) goto ExitOutfit; DrawMenuStateStrings (PM_FUEL, pMS->CurState); - LockMutex (GraphicsLock); SetFlashRect (SFR_MENU_3DO); - UnlockMutex (GraphicsLock); break; } } @@ -806,7 +772,9 @@ ExitOutfit: switch (pMS->CurState) { case OUTFIT_DOFUEL: - SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, MENU_SOUND_SELECT | MENU_SOUND_CANCEL); + SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN | + MENU_SOUND_PAGEUP | MENU_SOUND_PAGEDOWN, + MENU_SOUND_SELECT | MENU_SOUND_CANCEL); break; default: SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT); diff --git a/sc2/src/uqm/pickship.c b/sc2/src/uqm/pickship.c index 7b68c82b3..3dcced0d5 100644 --- a/sc2/src/uqm/pickship.c +++ b/sc2/src/uqm/pickship.c @@ -61,7 +61,6 @@ DoPickBattleShip (MENU_STATE *pMS) pMS->Initialized = TRUE; pMS->InputFunc = DoPickBattleShip; - LockMutex (GraphicsLock); goto ChangeSelection; } @@ -106,7 +105,6 @@ DoPickBattleShip (MENU_STATE *pMS) PlayMenuSound (MENU_SOUND_MOVE); - LockMutex (GraphicsLock); #ifdef NEVER SetContextForeGroundColor ( @@ -240,7 +238,6 @@ ChangeSelection: SetFlashRect (NULL); SetFlashRect (&pMS->flash_rect0); - UnlockMutex (GraphicsLock); } } @@ -278,10 +275,8 @@ OldContext = SetContext (SpaceContext); MenuState.flash_rect1.corner = pick_r.corner; MenuState.flash_rect1.extent.width = 0; - UnlockMutex (GraphicsLock); SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT); DoInput (&MenuState, FALSE); - LockMutex (GraphicsLock); SetFlashRect (NULL); @@ -309,7 +304,7 @@ SetContext (OldContext); HSTARSHIP GetEncounterStarShip (STARSHIP *LastStarShipPtr, COUNT which_player) { - if (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE) + if (inHQSpace ()) { assert (which_player == RPG_PLAYER_NUM); // SIS for the Hyperspace flight diff --git a/sc2/src/uqm/pickship.h b/sc2/src/uqm/pickship.h index b52540187..f5a55b365 100644 --- a/sc2/src/uqm/pickship.h +++ b/sc2/src/uqm/pickship.h @@ -20,8 +20,16 @@ #include "libs/compiler.h" #include "races.h" +#if defined(__cplusplus) +extern "C" { +#endif + extern HSTARSHIP GetEncounterStarShip (STARSHIP *LastStarShipPtr, COUNT which_player); extern void DrawArmadaPickShip (BOOLEAN draw_salvage_frame, RECT *pPickRect); +#if defined(__cplusplus) +} +#endif + #endif /* UQM_PICKSHIP_H_INCL_ */ diff --git a/sc2/src/uqm/plandata.c b/sc2/src/uqm/plandata.c index 8637fbffb..a79c2d512 100644 --- a/sc2/src/uqm/plandata.c +++ b/sc2/src/uqm/plandata.c @@ -16,8 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// XXX: for XXX_DEFINED constants -#include "encount.h" +#include "gendef.h" #include "resinst.h" #include "planets/planets.h" #include "planets/elemdata.h" diff --git a/sc2/src/uqm/planets/Makeinfo b/sc2/src/uqm/planets/Makeinfo index 2a8d1fe48..da4026f9a 100644 --- a/sc2/src/uqm/planets/Makeinfo +++ b/sc2/src/uqm/planets/Makeinfo @@ -2,3 +2,6 @@ uqm_SUBDIRS="generate" uqm_CFILES="calc.c cargo.c devices.c gentopo.c lander.c orbits.c oval.c pl_stuff.c planets.c plangen.c pstarmap.c report.c roster.c scan.c solarsys.c surface.c" +uqm_HFILES="elemdata.h generate.h lander.h lifeform.h plandata.h planets.h + scan.h solarsys.h sundata.h" + diff --git a/sc2/src/uqm/planets/calc.c b/sc2/src/uqm/planets/calc.c index ac663ebf5..09bd46167 100644 --- a/sc2/src/uqm/planets/calc.c +++ b/sc2/src/uqm/planets/calc.c @@ -17,7 +17,8 @@ */ /* ----------------------------- INCLUDES ---------------------------- */ -#include "../encount.h" +#include "planets.h" +#include "uqm/starmap.h" #include "libs/mathlib.h" #include "libs/log.h" /* -------------------------------- DATA -------------------------------- */ @@ -26,9 +27,6 @@ //#define DEBUG_PLANET_CALC -#define CalcMass(b) CalcFromBase (b, b) -#define CalcRadius(b) CalcFromBase (b, ((b) >> 1) + 1) - #define LOW_TEMP 0 #define MED_TEMP 500 #define HIGH_TEMP 1500 @@ -36,15 +34,6 @@ #define MED_TEMP_BONUS 25 #define HIGH_TEMP_BONUS 50 #define MAX_TECTONICS 255 -#ifdef OLD -#define CalcTectonics(b,t) (CalcFromBase(b, 3 << 5) \ - + (UWORD)((t) < LOW_TEMP ? 0 : \ - ((t) < MED_TEMP ? LOW_TEMP_BONUS : \ - ((t) < HIGH_TEMP ? MED_TEMP_BONUS : \ - HIGH_TEMP_BONUS)))) -#else /* OLD */ -#define CalcTectonics(b,t) CalcFromBase(b, 3 << 5) -#endif /* OLD */ enum { @@ -56,6 +45,18 @@ enum WHITE_SUN_INTENSITY }; +static UWORD +CalcFromBase (UWORD base, UWORD variance) +{ + return base + LOWORD (RandomContext_Random (SysGenRNG)) % variance; +} + +static inline UWORD +CalcHalfBaseVariance (UWORD base) +{ + return CalcFromBase (base, (base >> 1) + 1); +} + static void CalcSysInfo (SYSTEM_INFO *SysInfoPtr) { @@ -149,7 +150,7 @@ GeneratePlanetComposition (PLANET_INFO *PlanetInfoPtr, SIZE SurfaceTemp, PlanetInfoPtr->Weather += 1 << 5; else if (radius > 10) PlanetInfoPtr->Weather -= 1 << 5; - atmo = CalcFromBase (atmo, (atmo >> 1) + 1); + atmo = CalcHalfBaseVariance (atmo); } } @@ -165,6 +166,11 @@ GeneratePlanetComposition (PLANET_INFO *PlanetInfoPtr, SIZE SurfaceTemp, // have the colour you'd expect based on the true temperature. // (eg. Beta Corvi I). I don't know what the idea behind this is, // but the if statement must be there for a reason. -- SvdB +// Update 2013-03-28: The contents of the if() block is probably there to +// model a greenhouse effect. It seems that it is taken into account when +// calculating the actual temperature (when landing or scanning), but not +// when determining the colors of the drawn orbits. (Thanks to James Scott +// for this insight.) static SIZE CalcTemp (SYSTEM_INFO *SysInfoPtr, SIZE radius) { @@ -194,7 +200,7 @@ CalcTemp (SYSTEM_INFO *SysInfoPtr, SIZE radius) bonus = COLD_BONUS; bonus <<= HINIBBLE (SysInfoPtr->PlanetInfo.PlanDataPtr->AtmoAndDensity); - bonus = CalcFromBase (bonus, (bonus >> 1) + 1); + bonus = CalcHalfBaseVariance (bonus); } return (centigrade + bonus); @@ -204,11 +210,11 @@ static COUNT CalcRotation (PLANET_INFO *PlanetInfoPtr) { if (PLANSIZE (PlanetInfoPtr->PlanDataPtr->Type) == GAS_GIANT) - return ((COUNT)CalcFromBase (80, 80)); - else if (((BYTE)TFB_Random () % 10) == 0) - return ((COUNT)CalcFromBase ((UWORD)50 * 240, (UWORD)200 * 240)); + return CalcFromBase (80, 80); + else if (LOBYTE (RandomContext_Random (SysGenRNG)) % 10 == 0) + return CalcFromBase (50 * 240, 200 * 240); else - return ((COUNT)CalcFromBase (150, 150)); + return CalcFromBase (150, 150); } static SIZE @@ -223,22 +229,138 @@ CalcTilt (void) i = NUM_TOSSES; do /* Using added Randomom values to give bell curve */ { - tilt += (UWORD)TFB_Random () % ((TILT_RANGE / NUM_TOSSES) + 1); + tilt += LOWORD (RandomContext_Random (SysGenRNG)) + % ((TILT_RANGE / NUM_TOSSES) + 1); } while (--i); return (tilt); } -// NB. Returns the RNG to the state it found it in. -DWORD +UWORD +CalcGravity (const PLANET_INFO *PlanetInfoPtr) +{ + return (DWORD)PlanetInfoPtr->PlanetDensity * PlanetInfoPtr->PlanetRadius + / 100; +} + +static UWORD +CalcTectonics (UWORD base, UWORD temp) +{ + UWORD tect = CalcFromBase (base, 3 << 5); +#ifdef OLD + if (temp >= HIGH_TEMP) + tect += HIGH_TEMP_BONUS; + else if (temp >= MED_TEMP) + tect += MED_TEMP_BONUS; + else if (temp >= LOW_TEMP) + tect += LOW_TEMP_BONUS; +#else /* !OLD */ + (void) temp; /* silence compiler whining */ +#endif /* OLD */ + return tect; +} + +// This code moved from planets/surface.c:CalcLifeForms() +static int +CalcLifeChance (const PLANET_INFO *PlanetInfoPtr) +{ + SIZE life_var = 0; + + if (PLANSIZE (PlanetInfoPtr->PlanDataPtr->Type) == GAS_GIANT) + return -1; + + if (PlanetInfoPtr->SurfaceTemperature < -151) + life_var -= 300; + else if (PlanetInfoPtr->SurfaceTemperature < -51) + life_var -= 100; + else if (PlanetInfoPtr->SurfaceTemperature < 0) + life_var += 100; + else if (PlanetInfoPtr->SurfaceTemperature < 50) + life_var += 300; + else if (PlanetInfoPtr->SurfaceTemperature < 150) + life_var += 50; + else if (PlanetInfoPtr->SurfaceTemperature < 250) + life_var -= 100; + else if (PlanetInfoPtr->SurfaceTemperature < 500) + life_var -= 400; + else + life_var -= 800; + + if (PlanetInfoPtr->AtmoDensity == 0) + life_var -= 1000; + else if (PlanetInfoPtr->AtmoDensity < 15) + life_var += 100; + else if (PlanetInfoPtr->AtmoDensity < 30) + life_var += 200; + else if (PlanetInfoPtr->AtmoDensity < 100) + life_var += 300; + else if (PlanetInfoPtr->AtmoDensity < 1000) + life_var += 150; + else if (PlanetInfoPtr->AtmoDensity < 2500) + ; + else + life_var -= 100; + +#ifndef NOTYET + life_var += 200 + 80 + 80; +#else /* NOTYET */ + if (PlanetInfoPtr->SurfaceGravity < 10) + ; + else if (PlanetInfoPtr->SurfaceGravity < 35) + life_var += 50; + else if (PlanetInfoPtr->SurfaceGravity < 75) + life_var += 100; + else if (PlanetInfoPtr->SurfaceGravity < 150) + life_var += 200; + else if (PlanetInfoPtr->SurfaceGravity < 400) + life_var += 50; + else if (PlanetInfoPtr->SurfaceGravity < 800) + ; + else + life_var -= 100; + + if (PlanetInfoPtr->Tectonics < 1) + life_var += 80; + else if (PlanetInfoPtr->Tectonics < 2) + life_var += 70; + else if (PlanetInfoPtr->Tectonics < 3) + life_var += 60; + else if (PlanetInfoPtr->Tectonics < 4) + life_var += 50; + else if (PlanetInfoPtr->Tectonics < 5) + life_var += 25; + else if (PlanetInfoPtr->Tectonics < 6) + ; + else + life_var -= 100; + + if (PlanetInfoPtr->Weather < 1) + life_var += 80; + else if (PlanetInfoPtr->Weather < 2) + life_var += 70; + else if (PlanetInfoPtr->Weather < 3) + life_var += 60; + else if (PlanetInfoPtr->Weather < 4) + life_var += 50; + else if (PlanetInfoPtr->Weather < 5) + life_var += 25; + else if (PlanetInfoPtr->Weather < 6) + ; + else + life_var -= 100; +#endif /* NOTYET */ + + return life_var; +} + +// Sets the SysGenRNG to the required state first. +void DoPlanetaryAnalysis (SYSTEM_INFO *SysInfoPtr, PLANET_DESC *pPlanetDesc) { - DWORD old_seed; + assert ((pPlanetDesc->data_index & ~WORLD_TYPE_SPECIAL) + < NUMBER_OF_PLANET_TYPES); - if (pPlanetDesc->data_index == HIERARCHY_STARBASE) - return (0); - - old_seed = TFB_SeedRandom (pPlanetDesc->rand_seed); + RandomContext_SeedRandom (SysGenRNG, pPlanetDesc->rand_seed); CalcSysInfo (SysInfoPtr); @@ -303,18 +425,18 @@ DoPlanetaryAnalysis (SYSTEM_INFO *SysInfoPtr, PLANET_DESC *pPlanetDesc) } SysInfoPtr->PlanetInfo.PlanetDensity += (SysInfoPtr->PlanetInfo.PlanetDensity / 20) - - ((COUNT)TFB_Random () + - (LOWORD (RandomContext_Random (SysGenRNG)) % (SysInfoPtr->PlanetInfo.PlanetDensity / 10)); switch (PLANSIZE (SysInfoPtr->PlanetInfo.PlanDataPtr->Type)) { case SMALL_ROCKY_WORLD: #define SMALL_RADIUS 25 - SysInfoPtr->PlanetInfo.PlanetRadius = CalcRadius (SMALL_RADIUS); + SysInfoPtr->PlanetInfo.PlanetRadius = CalcHalfBaseVariance (SMALL_RADIUS); break; case LARGE_ROCKY_WORLD: #define LARGE_RADIUS 75 - SysInfoPtr->PlanetInfo.PlanetRadius = CalcRadius (LARGE_RADIUS); + SysInfoPtr->PlanetInfo.PlanetRadius = CalcHalfBaseVariance (LARGE_RADIUS); break; case GAS_GIANT: #define MIN_GAS_RADIUS 300 @@ -325,9 +447,7 @@ DoPlanetaryAnalysis (SYSTEM_INFO *SysInfoPtr, PLANET_DESC *pPlanetDesc) } SysInfoPtr->PlanetInfo.RotationPeriod = CalcRotation (&SysInfoPtr->PlanetInfo); - SysInfoPtr->PlanetInfo.SurfaceGravity = - CalcGravity (SysInfoPtr->PlanetInfo.PlanetDensity, - SysInfoPtr->PlanetInfo.PlanetRadius); + SysInfoPtr->PlanetInfo.SurfaceGravity = CalcGravity (&SysInfoPtr->PlanetInfo); SysInfoPtr->PlanetInfo.AxialTilt = CalcTilt (); if ((SysInfoPtr->PlanetInfo.Tectonics = CalcTectonics (SysInfoPtr->PlanetInfo.PlanDataPtr->BaseTectonics, @@ -341,6 +461,8 @@ DoPlanetaryAnalysis (SYSTEM_INFO *SysInfoPtr, PLANET_DESC *pPlanetDesc) SysInfoPtr->PlanetInfo.Tectonics >>= 5; SysInfoPtr->PlanetInfo.Weather >>= 5; + SysInfoPtr->PlanetInfo.LifeChance = CalcLifeChance (&SysInfoPtr->PlanetInfo); + #ifdef DEBUG_PLANET_CALC radius = (SIZE)((DWORD)UNSCALE_RADIUS (radius) * 100 / UNSCALE_RADIUS (EARTH_RADIUS)); log_add (log_Debug, "\tOrbital Distance : %d.%02d AU", radius / 100, radius % 100); @@ -404,7 +526,5 @@ DoPlanetaryAnalysis (SYSTEM_INFO *SysInfoPtr, PLANET_DESC *pPlanetDesc) } #endif /* DEBUG_PLANET_CALC */ } - - return (TFB_SeedRandom (old_seed)); } diff --git a/sc2/src/uqm/planets/cargo.c b/sc2/src/uqm/planets/cargo.c index d9ed028fb..147d95aad 100644 --- a/sc2/src/uqm/planets/cargo.c +++ b/sc2/src/uqm/planets/cargo.c @@ -239,8 +239,6 @@ DrawCargoStrings (BYTE OldElement, BYTE NewElement) { CONTEXT OldContext; - LockMutex (GraphicsLock); - OldContext = SetContext (StatusContext); SetContextFont (TinyFont); @@ -266,15 +264,12 @@ DrawCargoStrings (BYTE OldElement, BYTE NewElement) UnbatchGraphics (); SetContext (OldContext); - UnlockMutex (GraphicsLock); } static void DrawElementDescription (COUNT element) { - LockMutex (GraphicsLock); DrawStatusMessage (GAME_STRING (element + (CARGO_STRING_BASE + 2))); - UnlockMutex (GraphicsLock); } static BOOLEAN @@ -302,10 +297,8 @@ DoDiscardCargo (MENU_STATE *pMS) --GLOBAL_SIS (ElementAmounts[pMS->CurState]); DrawCargoStrings (pMS->CurState, pMS->CurState); - LockMutex (GraphicsLock); --GLOBAL_SIS (TotalElementMass); ShowRemainingCapacity (); - UnlockMutex (GraphicsLock); } else { // no element left in cargo hold @@ -358,8 +351,6 @@ CargoMenu (void) DoInput (&MenuState, TRUE); // erase the cargo display - LockMutex (GraphicsLock); ClearSISRect (DRAW_SIS_DISPLAY); - UnlockMutex (GraphicsLock); } diff --git a/sc2/src/uqm/planets/devices.c b/sc2/src/uqm/planets/devices.c index 927c4ca25..99b0ac379 100644 --- a/sc2/src/uqm/planets/devices.c +++ b/sc2/src/uqm/planets/devices.c @@ -18,6 +18,8 @@ #include "../build.h" #include "../colors.h" +#include "../gendef.h" +#include "../starmap.h" #include "../encount.h" #include "../gamestr.h" #include "../controls.h" @@ -183,7 +185,6 @@ DrawDevicesDisplay (DEVICES_STATE *devState) static void DrawDevices (DEVICES_STATE *devState, COUNT OldDevice, COUNT NewDevice) { - LockMutex (GraphicsLock); BatchGraphics (); SetContext (StatusContext); @@ -209,7 +210,6 @@ DrawDevices (DEVICES_STATE *devState, COUNT OldDevice, COUNT NewDevice) } UnbatchGraphics (); - UnlockMutex (GraphicsLock); } // Returns TRUE if the broadcaster has been successfully activated, @@ -217,7 +217,7 @@ DrawDevices (DEVICES_STATE *devState, COUNT OldDevice, COUNT NewDevice) static BOOLEAN UseCaster (void) { - if (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE) + if (inHQSpace ()) { if (GET_GAME_STATE (ARILOU_SPACE_SIDE) <= 1) { @@ -256,7 +256,7 @@ UseCaster (void) HIPGROUP hGroup; FoundIlwrath = (CurStarDescPtr->Index == ILWRATH_DEFINED) - && ActivateStarShip (ILWRATH_SHIP, SPHERE_TRACKING); + && StartSphereTracking (ILWRATH_SHIP); // In the Ilwrath home system and they are alive? if (!FoundIlwrath && @@ -372,7 +372,7 @@ InvokeDevice (BYTE which_device) NextActivity |= CHECK_LOAD; /* fake a load game */ GLOBAL (CurrentActivity) |= START_ENCOUNTER; SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 0); - if (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE) + if (inHQSpace ()) { if (GetHeadEncounter ()) { @@ -443,8 +443,7 @@ InvokeDevice (BYTE which_device) break; case PORTAL_SPAWNER_DEVICE: #define PORTAL_FUEL_COST (10 * FUEL_TANK_SCALE) - if (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE - && GET_GAME_STATE (ARILOU_SPACE_SIDE) <= 1 + if (inHyperSpace () && GLOBAL_SIS (FuelOnBoard) >= PORTAL_FUEL_COST) { /* No DeltaSISGauges because the flagship picture @@ -491,13 +490,11 @@ DoManipulateDevices (MENU_STATE *pMS) { DeviceStatus status; - LockMutex (GraphicsLock); status = InvokeDevice (devState->list[pMS->CurState]); if (status == DEVICE_FAILURE) PlayMenuSound (MENU_SOUND_FAILURE); else if (status == DEVICE_SUCCESS) PlayMenuSound (MENU_SOUND_INVOKED); - UnlockMutex (GraphicsLock); return (status == DEVICE_FAILURE); } @@ -680,9 +677,7 @@ DevicesMenu (void) if (GLOBAL_SIS (CrewEnlisted) != (COUNT)~0 && !(GLOBAL (CurrentActivity) & CHECK_ABORT)) { - LockMutex (GraphicsLock); ClearSISRect (DRAW_SIS_DISPLAY); - UnlockMutex (GraphicsLock); if (!GET_GAME_STATE (PORTAL_COUNTER) && !(GLOBAL (CurrentActivity) & START_ENCOUNTER) diff --git a/sc2/src/uqm/planets/elemdata.h b/sc2/src/uqm/planets/elemdata.h index b9efd8394..53d228cfd 100644 --- a/sc2/src/uqm/planets/elemdata.h +++ b/sc2/src/uqm/planets/elemdata.h @@ -21,6 +21,9 @@ #include "libs/compiler.h" +#if defined(__cplusplus) +extern "C" { +#endif /*------------------------------ Type Defines ----------------------------- */ enum @@ -205,5 +208,8 @@ enum extern const BYTE *Elements; -#endif /* UQM_PLANETS_ELEMDATA_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_PLANETS_ELEMDATA_H_ */ diff --git a/sc2/src/uqm/planets/generate.h b/sc2/src/uqm/planets/generate.h index 57d9603d5..9942e8283 100644 --- a/sc2/src/uqm/planets/generate.h +++ b/sc2/src/uqm/planets/generate.h @@ -23,6 +23,10 @@ typedef struct GenerateFunctions GenerateFunctions; #include "planets.h" #include "libs/compiler.h" +#if defined(__cplusplus) +extern "C" { +#endif + /* * To do (for further cleanups): * - split off generateOrbital in a calculation and an activation @@ -52,16 +56,16 @@ typedef bool (*GenerateMoonsFunction)(SOLARSYS_STATE *solarSys, PLANET_DESC *planet); typedef bool (*GenerateOrbitalFunction)(SOLARSYS_STATE *solarSys, PLANET_DESC *world); -typedef bool (*GenerateNameFunction)(SOLARSYS_STATE *solarSys, - PLANET_DESC *world); +typedef bool (*GenerateNameFunction)(const SOLARSYS_STATE *, + const PLANET_DESC *world); // The following functions return the number of objects being generated // (or the index of the current object in some cases) -typedef COUNT (*GenerateMineralsFunction)(SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); -typedef COUNT (*GenerateEnergyFunction)(SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); -typedef COUNT (*GenerateLifeFunction)(SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); +typedef COUNT (*GenerateMineralsFunction)(const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); +typedef COUNT (*GenerateEnergyFunction)(const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); +typedef COUNT (*GenerateLifeFunction)(const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); // The following functions return true if the node should be removed // from the surface, i.e. picked up. typedef bool (*PickupMineralsFunction)(SOLARSYS_STATE *solarSys, @@ -98,6 +102,9 @@ struct GenerateFunctions { PickupLifeFunction pickupLife; }; +#if defined(__cplusplus) +} +#endif #endif /* GENERATE_H */ diff --git a/sc2/src/uqm/planets/generate/Makeinfo b/sc2/src/uqm/planets/generate/Makeinfo index 16dc6fec2..520af9d5a 100644 --- a/sc2/src/uqm/planets/generate/Makeinfo +++ b/sc2/src/uqm/planets/generate/Makeinfo @@ -3,3 +3,4 @@ uqm_CFILES="gendefault.c genand.c genburv.c genchmmr.c gencol.c gendru.c gensam.c genshof.c gensly.c gensol.c genspa.c gensup.c gensyr.c genthrad.c gentrap.c genutw.c genvault.c genvux.c genwreck.c genyeh.c genzfpscout.c genzoq.c" +uqm_HFILES="genall.h gendefault.h" diff --git a/sc2/src/uqm/planets/generate/genand.c b/sc2/src/uqm/planets/generate/genand.c index 755b5a172..457b5ff96 100644 --- a/sc2/src/uqm/planets/generate/genand.c +++ b/sc2/src/uqm/planets/generate/genand.c @@ -30,8 +30,8 @@ static bool GenerateAndrosynth_generatePlanets (SOLARSYS_STATE *solarSys); static bool GenerateAndrosynth_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world); -static COUNT GenerateAndrosynth_generateEnergy (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); +static COUNT GenerateAndrosynth_generateEnergy (const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); static bool GenerateAndrosynth_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, COUNT whichNode); @@ -152,12 +152,12 @@ GenerateAndrosynth_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, } static COUNT -GenerateAndrosynth_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT whichNode) +GenerateAndrosynth_generateEnergy (const SOLARSYS_STATE *solarSys, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) { if (matchWorld (solarSys, world, 1, MATCH_PLANET)) { - return GenerateDefault_generateRuins (solarSys, whichNode); + return GenerateDefault_generateRuins (solarSys, whichNode, info); } return 0; diff --git a/sc2/src/uqm/planets/generate/genburv.c b/sc2/src/uqm/planets/generate/genburv.c index 06541e2d4..aa5b6bdfa 100644 --- a/sc2/src/uqm/planets/generate/genburv.c +++ b/sc2/src/uqm/planets/generate/genburv.c @@ -30,8 +30,8 @@ static bool GenerateBurvixese_generateMoons (SOLARSYS_STATE *solarSys, PLANET_DESC *planet); static bool GenerateBurvixese_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world); -static COUNT GenerateBurvixese_generateEnergy (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); +static COUNT GenerateBurvixese_generateEnergy (const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); static bool GenerateBurvixese_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, COUNT whichNode); @@ -85,7 +85,7 @@ GenerateBurvixese_generateMoons (SOLARSYS_STATE *solarSys, PLANET_DESC *planet) solarSys->MoonDesc[0].data_index = SELENIC_WORLD; solarSys->MoonDesc[0].radius = MIN_MOON_RADIUS + (MAX_MOONS - 1) * MOON_DELTA; - rand_val = TFB_Random (); + rand_val = RandomContext_Random (SysGenRNG); angle = NORMALIZE_ANGLE (LOWORD (rand_val)); solarSys->MoonDesc[0].location.x = COSINE (angle, solarSys->MoonDesc[0].radius); @@ -98,18 +98,17 @@ GenerateBurvixese_generateMoons (SOLARSYS_STATE *solarSys, PLANET_DESC *planet) static bool GenerateBurvixese_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) { - COUNT i; DWORD rand_val; - rand_val = DoPlanetaryAnalysis (&solarSys->SysInfo, world); + DoPlanetaryAnalysis (&solarSys->SysInfo, world); + rand_val = RandomContext_GetSeed (SysGenRNG); solarSys->SysInfo.PlanetInfo.ScanSeed[BIOLOGICAL_SCAN] = rand_val; - i = (COUNT)~0; - rand_val = GenerateLifeForms (&solarSys->SysInfo, &i); + GenerateLifeForms (&solarSys->SysInfo, GENERATE_ALL, NULL); + rand_val = RandomContext_GetSeed (SysGenRNG); solarSys->SysInfo.PlanetInfo.ScanSeed[MINERAL_SCAN] = rand_val; - i = (COUNT)~0; - GenerateMineralDeposits (&solarSys->SysInfo, &i); + GenerateMineralDeposits (&solarSys->SysInfo, GENERATE_ALL, NULL); solarSys->SysInfo.PlanetInfo.ScanSeed[ENERGY_SCAN] = rand_val; @@ -141,12 +140,12 @@ GenerateBurvixese_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) } static COUNT -GenerateBurvixese_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT whichNode) +GenerateBurvixese_generateEnergy (const SOLARSYS_STATE *solarSys, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) { if (matchWorld (solarSys, world, 0, MATCH_PLANET)) { - return GenerateDefault_generateRuins (solarSys, whichNode); + return GenerateDefault_generateRuins (solarSys, whichNode, info); } if (matchWorld (solarSys, world, 0, 0)) @@ -158,7 +157,7 @@ GenerateBurvixese_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, return 0; } - return GenerateDefault_generateArtifact (solarSys, whichNode); + return GenerateDefault_generateArtifact (solarSys, whichNode, info); } return 0; diff --git a/sc2/src/uqm/planets/generate/genchmmr.c b/sc2/src/uqm/planets/generate/genchmmr.c index 644b2e6b4..672d977b9 100644 --- a/sc2/src/uqm/planets/generate/genchmmr.c +++ b/sc2/src/uqm/planets/generate/genchmmr.c @@ -77,7 +77,7 @@ GenerateChmmr_generateMoons (SOLARSYS_STATE *solarSys, PLANET_DESC *planet) solarSys->MoonDesc[0].data_index = HIERARCHY_STARBASE; solarSys->MoonDesc[0].radius = MIN_MOON_RADIUS; - rand_val = TFB_Random (); + rand_val = RandomContext_Random (SysGenRNG); angle = NORMALIZE_ANGLE (LOWORD (rand_val)); solarSys->MoonDesc[0].location.x = COSINE (angle, solarSys->MoonDesc[0].radius); @@ -107,7 +107,7 @@ GenerateChmmr_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) } else if (GET_GAME_STATE (SUN_DEVICE_ON_SHIP) && !GET_GAME_STATE (ILWRATH_DECEIVED) - && ActivateStarShip (ILWRATH_SHIP, SPHERE_TRACKING)) + && StartSphereTracking (ILWRATH_SHIP)) { PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); ReinitQueue (&GLOBAL (ip_group_q)); @@ -133,8 +133,6 @@ GenerateChmmr_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) else if (matchWorld (solarSys, world, 1, 0)) { /* Starbase */ - LockMutex (GraphicsLock); - LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo); solarSys->SysInfo.PlanetInfo.DiscoveryString = CaptureStringTable (LoadStringTable (CHMMR_BASE_STRTAB)); @@ -146,8 +144,6 @@ GenerateChmmr_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) solarSys->SysInfo.PlanetInfo.DiscoveryString = 0; FreeLanderFont (&solarSys->SysInfo.PlanetInfo); - UnlockMutex (GraphicsLock); - return true; } diff --git a/sc2/src/uqm/planets/generate/gendefault.c b/sc2/src/uqm/planets/generate/gendefault.c index dfa4fc54d..a88b89cb7 100644 --- a/sc2/src/uqm/planets/generate/gendefault.c +++ b/sc2/src/uqm/planets/generate/gendefault.c @@ -27,17 +27,6 @@ #include "libs/mathlib.h" -bool GenerateDefault_initNpcs (SOLARSYS_STATE *solarSys); -bool GenerateDefault_reinitNpcs (SOLARSYS_STATE *solarSys); -bool GenerateDefault_uninitNpcs (SOLARSYS_STATE *solarSys); -bool GenerateDefault_generatePlanets (SOLARSYS_STATE *solarSys); -bool GenerateDefault_generateMoons (SOLARSYS_STATE *solarSys, - PLANET_DESC *planet); -bool GenerateDefault_generateName (SOLARSYS_STATE *solarSys, - PLANET_DESC *world); -bool GenerateDefault_generateOrbital (SOLARSYS_STATE *solarSys, - PLANET_DESC *world); - static void GeneratePlanets (SOLARSYS_STATE *system); static void check_yehat_rebellion (void); @@ -113,7 +102,8 @@ GenerateDefault_generateMoons (SOLARSYS_STATE *solarSys, PLANET_DESC *planet) } bool -GenerateDefault_generateName (SOLARSYS_STATE *solarSys, PLANET_DESC *world) +GenerateDefault_generateName (const SOLARSYS_STATE *solarSys, + const PLANET_DESC *world) { COUNT i = planetIndex (solarSys, world); utf8StringCopy (GLOBAL_SIS (PlanetName), sizeof (GLOBAL_SIS (PlanetName)), @@ -126,7 +116,6 @@ GenerateDefault_generateName (SOLARSYS_STATE *solarSys, PLANET_DESC *world) bool GenerateDefault_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) { - COUNT i; DWORD rand_val; SYSTEM_INFO *sysInfo; @@ -146,15 +135,15 @@ GenerateDefault_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) sysInfo = &solarSys->SysInfo; - rand_val = DoPlanetaryAnalysis (sysInfo, world); + DoPlanetaryAnalysis (sysInfo, world); + rand_val = RandomContext_GetSeed (SysGenRNG); sysInfo->PlanetInfo.ScanSeed[BIOLOGICAL_SCAN] = rand_val; - i = (COUNT)~0; - rand_val = GenerateLifeForms (sysInfo, &i); + GenerateLifeForms (sysInfo, GENERATE_ALL, NULL); + rand_val = RandomContext_GetSeed (SysGenRNG); sysInfo->PlanetInfo.ScanSeed[MINERAL_SCAN] = rand_val; - i = (COUNT)~0; - GenerateMineralDeposits (sysInfo, &i); + GenerateMineralDeposits (sysInfo, GENERATE_ALL, NULL); sysInfo->PlanetInfo.ScanSeed[ENERGY_SCAN] = rand_val; LoadPlanet (NULL); @@ -163,12 +152,11 @@ GenerateDefault_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) } COUNT -GenerateDefault_generateMinerals (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode) +GenerateDefault_generateMinerals (const SOLARSYS_STATE *solarSys, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) { - GenerateMineralDeposits (&solarSys->SysInfo, &whichNode); + return GenerateMineralDeposits (&solarSys->SysInfo, whichNode, info); (void) world; - return whichNode; } bool @@ -183,12 +171,13 @@ GenerateDefault_pickupMinerals (SOLARSYS_STATE *solarSys, PLANET_DESC *world, } COUNT -GenerateDefault_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT whichNode) +GenerateDefault_generateEnergy (const SOLARSYS_STATE *solarSys, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) { (void) whichNode; (void) solarSys; (void) world; + (void) info; return 0; } @@ -206,12 +195,11 @@ GenerateDefault_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, } COUNT -GenerateDefault_generateLife (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT whichNode) +GenerateDefault_generateLife (const SOLARSYS_STATE *solarSys, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) { - GenerateLifeForms (&solarSys->SysInfo, &whichNode); + return GenerateLifeForms (&solarSys->SysInfo, whichNode, info); (void) world; - return whichNode; } bool @@ -226,20 +214,21 @@ GenerateDefault_pickupLife (SOLARSYS_STATE *solarSys, PLANET_DESC *world, } COUNT -GenerateDefault_generateArtifact (SOLARSYS_STATE *solarSys, COUNT whichNode) +GenerateDefault_generateArtifact (const SOLARSYS_STATE *solarSys, + COUNT whichNode, NODE_INFO *info) { // Generate an energy node at a random location - GenerateRandomNodes (&solarSys->SysInfo, ENERGY_SCAN, 1, 0, &whichNode); - return whichNode; + return GenerateRandomNodes (&solarSys->SysInfo, ENERGY_SCAN, 1, 0, + whichNode, info); } COUNT -GenerateDefault_generateRuins (SOLARSYS_STATE *solarSys, COUNT whichNode) +GenerateDefault_generateRuins (const SOLARSYS_STATE *solarSys, + COUNT whichNode, NODE_INFO *info) { // Generate a standard spread of city ruins of a destroyed civilization - GenerateRandomNodes (&solarSys->SysInfo, ENERGY_SCAN, NUM_RACE_RUINS, - 0, &whichNode); - return whichNode; + return GenerateRandomNodes (&solarSys->SysInfo, ENERGY_SCAN, NUM_RACE_RUINS, + 0, whichNode, info); } static inline void @@ -309,7 +298,7 @@ GeneratePlanets (SOLARSYS_STATE *solarSys) BYTE num_moons; BYTE type; - rand_val = TFB_Random (); + rand_val = RandomContext_Random (SysGenRNG); byte_val = LOBYTE (rand_val); num_moons = 0; diff --git a/sc2/src/uqm/planets/generate/gendefault.h b/sc2/src/uqm/planets/generate/gendefault.h index f0a49e314..a6d0e71b5 100644 --- a/sc2/src/uqm/planets/generate/gendefault.h +++ b/sc2/src/uqm/planets/generate/gendefault.h @@ -21,22 +21,26 @@ #include "../planets.h" #include "libs/compiler.h" +#if defined(__cplusplus) +extern "C" { +#endif + bool GenerateDefault_initNpcs (SOLARSYS_STATE *solarSys); bool GenerateDefault_reinitNpcs (SOLARSYS_STATE *solarSys); bool GenerateDefault_uninitNpcs (SOLARSYS_STATE *solarSys); bool GenerateDefault_generatePlanets (SOLARSYS_STATE *solarSys); bool GenerateDefault_generateMoons (SOLARSYS_STATE *solarSys, PLANET_DESC *planet); -bool GenerateDefault_generateName (SOLARSYS_STATE *solarSys, - PLANET_DESC *world); +bool GenerateDefault_generateName (const SOLARSYS_STATE *, + const PLANET_DESC *world); bool GenerateDefault_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world); -COUNT GenerateDefault_generateMinerals (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); -COUNT GenerateDefault_generateEnergy (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); -COUNT GenerateDefault_generateLife (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); +COUNT GenerateDefault_generateMinerals (const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); +COUNT GenerateDefault_generateEnergy (const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); +COUNT GenerateDefault_generateLife (const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); bool GenerateDefault_pickupMinerals (SOLARSYS_STATE *, PLANET_DESC *world, COUNT whichNode); bool GenerateDefault_pickupEnergy (SOLARSYS_STATE *, PLANET_DESC *world, @@ -44,13 +48,19 @@ bool GenerateDefault_pickupEnergy (SOLARSYS_STATE *, PLANET_DESC *world, bool GenerateDefault_pickupLife (SOLARSYS_STATE *, PLANET_DESC *world, COUNT whichNode); -COUNT GenerateDefault_generateArtifact (SOLARSYS_STATE *, COUNT whichNode); -COUNT GenerateDefault_generateRuins (SOLARSYS_STATE *, COUNT whichNode); +COUNT GenerateDefault_generateArtifact (const SOLARSYS_STATE *, + COUNT whichNode, NODE_INFO *info); +COUNT GenerateDefault_generateRuins (const SOLARSYS_STATE *, + COUNT whichNode, NODE_INFO *info); bool GenerateDefault_landerReport (SOLARSYS_STATE *); bool GenerateDefault_landerReportCycle (SOLARSYS_STATE *); extern const GenerateFunctions generateDefaultFunctions; +#if defined(__cplusplus) +} +#endif + #endif /* GENDEFAULT_H */ diff --git a/sc2/src/uqm/planets/generate/gendru.c b/sc2/src/uqm/planets/generate/gendru.c index 811d36ca4..72020100a 100644 --- a/sc2/src/uqm/planets/generate/gendru.c +++ b/sc2/src/uqm/planets/generate/gendru.c @@ -33,8 +33,8 @@ static bool GenerateDruuge_generatePlanets (SOLARSYS_STATE *solarSys); static bool GenerateDruuge_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world); -static COUNT GenerateDruuge_generateEnergy (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); +static COUNT GenerateDruuge_generateEnergy (const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); static bool GenerateDruuge_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, COUNT whichNode); @@ -88,7 +88,7 @@ GenerateDruuge_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) { if (matchWorld (solarSys, world, 0, MATCH_PLANET)) { - if (ActivateStarShip (DRUUGE_SHIP, SPHERE_TRACKING)) + if (StartSphereTracking (DRUUGE_SHIP)) { NotifyOthers (DRUUGE_SHIP, IPNL_ALL_CLEAR); PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); @@ -156,12 +156,12 @@ GenerateDruuge_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, } static COUNT -GenerateDruuge_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT whichNode) +GenerateDruuge_generateEnergy (const SOLARSYS_STATE *solarSys, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) { if (matchWorld (solarSys, world, 0, MATCH_PLANET)) { - return GenerateDefault_generateRuins (solarSys, whichNode); + return GenerateDefault_generateRuins (solarSys, whichNode, info); } return 0; diff --git a/sc2/src/uqm/planets/generate/genilw.c b/sc2/src/uqm/planets/generate/genilw.c index 62a5819c8..31a8fc4fe 100644 --- a/sc2/src/uqm/planets/generate/genilw.c +++ b/sc2/src/uqm/planets/generate/genilw.c @@ -30,8 +30,8 @@ static bool GenerateIlwrath_generatePlanets (SOLARSYS_STATE *solarSys); static bool GenerateIlwrath_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world); -static COUNT GenerateIlwrath_generateEnergy (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); +static COUNT GenerateIlwrath_generateEnergy (const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); static bool GenerateIlwrath_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, COUNT whichNode); @@ -78,7 +78,7 @@ GenerateIlwrath_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) { if (matchWorld (solarSys, world, 0, MATCH_PLANET)) { - if (ActivateStarShip (ILWRATH_SHIP, SPHERE_TRACKING)) + if (StartSphereTracking (ILWRATH_SHIP)) { NotifyOthers (ILWRATH_SHIP, IPNL_ALL_CLEAR); PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); @@ -123,12 +123,12 @@ GenerateIlwrath_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) } static COUNT -GenerateIlwrath_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT whichNode) +GenerateIlwrath_generateEnergy (const SOLARSYS_STATE *solarSys, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) { if (matchWorld (solarSys, world, 0, MATCH_PLANET)) { - return GenerateDefault_generateRuins (solarSys, whichNode); + return GenerateDefault_generateRuins (solarSys, whichNode, info); } return 0; diff --git a/sc2/src/uqm/planets/generate/genmel.c b/sc2/src/uqm/planets/generate/genmel.c index a5a81be1d..27f31b647 100644 --- a/sc2/src/uqm/planets/generate/genmel.c +++ b/sc2/src/uqm/planets/generate/genmel.c @@ -18,7 +18,8 @@ #include "genall.h" #include "../../build.h" -#include "../../encount.h" +#include "../../gendef.h" +#include "../../starmap.h" #include "../../globdata.h" #include "../../state.h" #include "libs/log.h" diff --git a/sc2/src/uqm/planets/generate/genmyc.c b/sc2/src/uqm/planets/generate/genmyc.c index f9abf2442..ead32c71a 100644 --- a/sc2/src/uqm/planets/generate/genmyc.c +++ b/sc2/src/uqm/planets/generate/genmyc.c @@ -22,7 +22,8 @@ #include "../scan.h" #include "../../build.h" #include "../../comm.h" -#include "../../encount.h" +#include "../../gendef.h" +#include "../../starmap.h" #include "../../globdata.h" #include "../../ipdisp.h" #include "../../nameref.h" @@ -34,10 +35,10 @@ static bool GenerateMycon_generatePlanets (SOLARSYS_STATE *solarSys); static bool GenerateMycon_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world); -static COUNT GenerateMycon_generateEnergy (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); -static COUNT GenerateMycon_generateLife (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); +static COUNT GenerateMycon_generateEnergy (const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); +static COUNT GenerateMycon_generateLife (const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); static bool GenerateMycon_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, COUNT whichNode); @@ -88,7 +89,7 @@ GenerateMycon_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) { if ((CurStarDescPtr->Index == MYCON_DEFINED || CurStarDescPtr->Index == SUN_DEVICE_DEFINED) - && ActivateStarShip (MYCON_SHIP, SPHERE_TRACKING)) + && StartSphereTracking (MYCON_SHIP)) { if (CurStarDescPtr->Index == MYCON_DEFINED || !GET_GAME_STATE (SUN_DEVICE_UNGUARDED)) @@ -141,9 +142,7 @@ GenerateMycon_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) return true; SET_GAME_STATE (SUN_DEVICE_UNGUARDED, 1); - LockMutex (GraphicsLock); RepairSISBorder (); - UnlockMutex (GraphicsLock); } } } @@ -188,8 +187,8 @@ GenerateMycon_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) } static COUNT -GenerateMycon_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT whichNode) +GenerateMycon_generateEnergy (const SOLARSYS_STATE *solarSys, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) { if (CurStarDescPtr->Index == SUN_DEVICE_DEFINED && matchWorld (solarSys, world, 0, MATCH_PLANET)) @@ -201,7 +200,7 @@ GenerateMycon_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, return 0; } - return GenerateDefault_generateArtifact (solarSys, whichNode); + return GenerateDefault_generateArtifact (solarSys, whichNode, info); } if ((CurStarDescPtr->Index == EGG_CASE0_DEFINED @@ -218,7 +217,7 @@ GenerateMycon_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, return 0; } - return GenerateDefault_generateArtifact (solarSys, whichNode); + return GenerateDefault_generateArtifact (solarSys, whichNode, info); } return 0; @@ -274,12 +273,14 @@ GenerateMycon_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, } static COUNT -GenerateMycon_generateLife (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT whichNode) +GenerateMycon_generateLife (const SOLARSYS_STATE *solarSys, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) { + // Gee, I wonder why there isn't any life in Mycon systems... (void) whichNode; (void) solarSys; (void) world; + (void) info; return 0; } diff --git a/sc2/src/uqm/planets/generate/genorz.c b/sc2/src/uqm/planets/generate/genorz.c index fbe847ecb..a50f318cc 100644 --- a/sc2/src/uqm/planets/generate/genorz.c +++ b/sc2/src/uqm/planets/generate/genorz.c @@ -21,7 +21,8 @@ #include "../planets.h" #include "../../build.h" #include "../../comm.h" -#include "../../encount.h" +#include "../../gendef.h" +#include "../../starmap.h" #include "../../globdata.h" #include "../../ipdisp.h" #include "../../nameref.h" @@ -33,8 +34,8 @@ static bool GenerateOrz_generatePlanets (SOLARSYS_STATE *solarSys); static bool GenerateOrz_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world); -static COUNT GenerateOrz_generateEnergy (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); +static COUNT GenerateOrz_generateEnergy (const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); static bool GenerateOrz_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, COUNT whichNode); @@ -92,7 +93,7 @@ GenerateOrz_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) if ((CurStarDescPtr->Index == ORZ_DEFINED || !GET_GAME_STATE (TAALO_UNPROTECTED)) - && ActivateStarShip (ORZ_SHIP, SPHERE_TRACKING)) + && StartSphereTracking (ORZ_SHIP)) { NotifyOthers (ORZ_SHIP, IPNL_ALL_CLEAR); PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); @@ -134,9 +135,7 @@ GenerateOrz_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) if (OrzSurvivors) return true; - LockMutex (GraphicsLock); RepairSISBorder (); - UnlockMutex (GraphicsLock); } } @@ -167,8 +166,8 @@ GenerateOrz_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) } static COUNT -GenerateOrz_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT whichNode) +GenerateOrz_generateEnergy (const SOLARSYS_STATE *solarSys, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) { if (CurStarDescPtr->Index == TAALO_PROTECTOR_DEFINED && matchWorld (solarSys, world, 1, 2)) @@ -180,13 +179,13 @@ GenerateOrz_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, return 0; } - return GenerateDefault_generateArtifact (solarSys, whichNode); + return GenerateDefault_generateArtifact (solarSys, whichNode, info); } if (CurStarDescPtr->Index == ORZ_DEFINED && matchWorld (solarSys, world, 0, MATCH_PLANET)) { - return GenerateDefault_generateRuins (solarSys, whichNode); + return GenerateDefault_generateRuins (solarSys, whichNode, info); } return 0; diff --git a/sc2/src/uqm/planets/generate/genpet.c b/sc2/src/uqm/planets/generate/genpet.c index f2027cff7..4c5515c54 100644 --- a/sc2/src/uqm/planets/generate/genpet.c +++ b/sc2/src/uqm/planets/generate/genpet.c @@ -21,6 +21,7 @@ #include "../../build.h" #include "../../comm.h" #include "../../encount.h" +#include "../../starmap.h" #include "../../globdata.h" #include "../../ipdisp.h" #include "../../nameref.h" @@ -32,8 +33,8 @@ static bool GenerateTalkingPet_generatePlanets (SOLARSYS_STATE *solarSys); static bool GenerateTalkingPet_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world); -static COUNT GenerateTalkingPet_generateEnergy (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); +static COUNT GenerateTalkingPet_generateEnergy (const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); static bool GenerateTalkingPet_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, COUNT whichNode); @@ -82,14 +83,14 @@ GenerateTalkingPet_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world if (matchWorld (solarSys, world, 0, MATCH_PLANET) && (GET_GAME_STATE (UMGAH_ZOMBIE_BLOBBIES) || !GET_GAME_STATE (TALKING_PET) - || ActivateStarShip (UMGAH_SHIP, SPHERE_TRACKING))) + || StartSphereTracking (UMGAH_SHIP))) { NotifyOthers (UMGAH_SHIP, IPNL_ALL_CLEAR); PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); ReinitQueue (&GLOBAL (ip_group_q)); assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); - if (ActivateStarShip (UMGAH_SHIP, SPHERE_TRACKING)) + if (StartSphereTracking (UMGAH_SHIP)) { GLOBAL (CurrentActivity) |= START_INTERPLANETARY; SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 7); @@ -128,7 +129,7 @@ GenerateTalkingPet_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world // Defeated the zombie fleet. InitCommunication (TALKING_PET_CONVERSATION); } - else if (!(ActivateStarShip (UMGAH_SHIP, SPHERE_TRACKING))) + else if (!(StartSphereTracking (UMGAH_SHIP))) { // The Kohr-Ah have destroyed the Umgah, but the // talking pet survived. @@ -160,12 +161,12 @@ GenerateTalkingPet_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world } static COUNT -GenerateTalkingPet_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT whichNode) +GenerateTalkingPet_generateEnergy (const SOLARSYS_STATE *solarSys, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) { if (matchWorld (solarSys, world, 0, MATCH_PLANET)) { - return GenerateDefault_generateRuins (solarSys, whichNode); + return GenerateDefault_generateRuins (solarSys, whichNode, info); } return 0; @@ -211,17 +212,18 @@ ZapToUrquanEncounter (void) TemplatePtr = LockFleetInfo (&GLOBAL (avail_race_q), hStarShip); EncounterPtr->origin = TemplatePtr->loc; EncounterPtr->radius = TemplatePtr->actual_strength; - EncounterPtr->SD.Type = URQUAN_SHIP; - EncounterPtr->SD.Index = MAKE_BYTE (1, 0) | ONE_SHOT_ENCOUNTER; + EncounterPtr->race_id = URQUAN_SHIP; + EncounterPtr->num_ships = 1; + EncounterPtr->flags = ONE_SHOT_ENCOUNTER; BSIPtr = &EncounterPtr->ShipList[0]; BSIPtr->race_id = URQUAN_SHIP; BSIPtr->crew_level = TemplatePtr->crew_level; BSIPtr->max_crew = TemplatePtr->max_crew; BSIPtr->max_energy = TemplatePtr->max_energy; - EncounterPtr->SD.star_pt.x = 5288; - EncounterPtr->SD.star_pt.y = 4892; - EncounterPtr->log_x = UNIVERSE_TO_LOGX (EncounterPtr->SD.star_pt.x); - EncounterPtr->log_y = UNIVERSE_TO_LOGY (EncounterPtr->SD.star_pt.y); + EncounterPtr->loc_pt.x = 5288; + EncounterPtr->loc_pt.y = 4892; + EncounterPtr->log_x = UNIVERSE_TO_LOGX (EncounterPtr->loc_pt.x); + EncounterPtr->log_y = UNIVERSE_TO_LOGY (EncounterPtr->loc_pt.y); GLOBAL_SIS (log_x) = EncounterPtr->log_x; GLOBAL_SIS (log_y) = EncounterPtr->log_y; UnlockFleetInfo (&GLOBAL (avail_race_q), hStarShip); @@ -229,19 +231,16 @@ ZapToUrquanEncounter (void) { #define LOST_DAYS 15 SleepThreadUntil (FadeScreen (FadeAllToBlack, ONE_SECOND * 2)); - LockMutex (GraphicsLock); MoveGameClockDays (LOST_DAYS); - UnlockMutex (GraphicsLock); } GLOBAL (CurrentActivity) = MAKE_WORD (IN_HYPERSPACE, 0) | START_ENCOUNTER; - dx = CurStarDescPtr->star_pt.x - EncounterPtr->SD.star_pt.x; - dy = CurStarDescPtr->star_pt.y - EncounterPtr->SD.star_pt.y; + dx = CurStarDescPtr->star_pt.x - EncounterPtr->loc_pt.x; + dy = CurStarDescPtr->star_pt.y - EncounterPtr->loc_pt.y; dx = (SIZE)square_root ((long)dx * dx + (long)dy * dy) + (FUEL_TANK_SCALE >> 1); - LockMutex (GraphicsLock); DeltaSISGauges (0, -dx, 0); if (GLOBAL_SIS (FuelOnBoard) < 5 * FUEL_TANK_SCALE) { @@ -250,8 +249,7 @@ ZapToUrquanEncounter (void) DeltaSISGauges (0, dx, 0); } DrawSISMessage (NULL); - DrawHyperCoords (EncounterPtr->SD.star_pt); - UnlockMutex (GraphicsLock); + DrawHyperCoords (EncounterPtr->loc_pt); UnlockEncounter (hEncounter); } diff --git a/sc2/src/uqm/planets/generate/genpku.c b/sc2/src/uqm/planets/generate/genpku.c index 4c44c50e8..64b996525 100644 --- a/sc2/src/uqm/planets/generate/genpku.c +++ b/sc2/src/uqm/planets/generate/genpku.c @@ -31,8 +31,8 @@ static bool GeneratePkunk_generatePlanets (SOLARSYS_STATE *solarSys); static bool GeneratePkunk_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world); -static COUNT GeneratePkunk_generateEnergy (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); +static COUNT GeneratePkunk_generateEnergy (const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); static bool GeneratePkunk_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, COUNT whichNode); @@ -79,7 +79,7 @@ GeneratePkunk_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) { if (matchWorld (solarSys, world, 0, MATCH_PLANET)) { - if (ActivateStarShip (PKUNK_SHIP, SPHERE_TRACKING)) + if (StartSphereTracking (PKUNK_SHIP)) { NotifyOthers (PKUNK_SHIP, IPNL_ALL_CLEAR); PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); @@ -146,12 +146,12 @@ GeneratePkunk_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, } static COUNT -GeneratePkunk_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT whichNode) +GeneratePkunk_generateEnergy (const SOLARSYS_STATE *solarSys, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) { if (matchWorld (solarSys, world, 0, MATCH_PLANET)) { - return GenerateDefault_generateRuins (solarSys, whichNode); + return GenerateDefault_generateRuins (solarSys, whichNode, info); } return 0; diff --git a/sc2/src/uqm/planets/generate/genrain.c b/sc2/src/uqm/planets/generate/genrain.c index 4e19aaa8b..c149b2978 100644 --- a/sc2/src/uqm/planets/generate/genrain.c +++ b/sc2/src/uqm/planets/generate/genrain.c @@ -18,7 +18,8 @@ #include "genall.h" #include "../planets.h" -#include "../../encount.h" +#include "../../gendef.h" +#include "../../starmap.h" #include "../../globdata.h" #include "libs/mathlib.h" diff --git a/sc2/src/uqm/planets/generate/gensam.c b/sc2/src/uqm/planets/generate/gensam.c index 4043acfd4..b2398b354 100644 --- a/sc2/src/uqm/planets/generate/gensam.c +++ b/sc2/src/uqm/planets/generate/gensam.c @@ -150,7 +150,7 @@ GenerateSaMatra_generateMoons (SOLARSYS_STATE *solarSys, PLANET_DESC *planet) solarSys->MoonDesc[0].data_index = SA_MATRA; solarSys->MoonDesc[0].radius = MIN_MOON_RADIUS + (2 * MOON_DELTA); - rand_val = TFB_Random (); + rand_val = RandomContext_Random (SysGenRNG); angle = NORMALIZE_ANGLE (LOWORD (rand_val)); solarSys->MoonDesc[0].location.x = COSINE (angle, solarSys->MoonDesc[0].radius); @@ -215,9 +215,8 @@ GenerateSaMatra_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) EncounterRace = -1; GLOBAL (CurrentActivity) = IN_LAST_BATTLE | START_ENCOUNTER; if (GET_GAME_STATE (YEHAT_CIVIL_WAR) - && ActivateStarShip (YEHAT_SHIP, SPHERE_TRACKING) - && ActivateStarShip (YEHAT_REBEL_SHIP, - FEASIBILITY_STUDY)) + && StartSphereTracking (YEHAT_SHIP) + && EscortFeasibilityStudy (YEHAT_REBEL_SHIP)) InitCommunication (YEHAT_REBEL_CONVERSATION); } } diff --git a/sc2/src/uqm/planets/generate/gensol.c b/sc2/src/uqm/planets/generate/gensol.c index 83ee07c91..d6041f363 100644 --- a/sc2/src/uqm/planets/generate/gensol.c +++ b/sc2/src/uqm/planets/generate/gensol.c @@ -35,14 +35,14 @@ static bool GenerateSol_reinitNpcs (SOLARSYS_STATE *solarSys); static bool GenerateSol_generatePlanets (SOLARSYS_STATE *solarSys); static bool GenerateSol_generateMoons (SOLARSYS_STATE *solarSys, PLANET_DESC *planet); -static bool GenerateSol_generateName (SOLARSYS_STATE *solarSys, - PLANET_DESC *world); +static bool GenerateSol_generateName (const SOLARSYS_STATE *, + const PLANET_DESC *world); static bool GenerateSol_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world); -static COUNT GenerateSol_generateEnergy (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); -static COUNT GenerateSol_generateLife (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); +static COUNT GenerateSol_generateEnergy (const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); +static COUNT GenerateSol_generateLife (const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); static bool GenerateSol_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, COUNT whichNode); @@ -108,7 +108,7 @@ GenerateSol_generatePlanets (SOLARSYS_STATE *solarSys) COUNT planetI; #define SOL_SEED 334241042L - TFB_SeedRandom (SOL_SEED); + RandomContext_SeedRandom (SysGenRNG, SOL_SEED); solarSys->SunDesc[0].NumPlanets = 9; for (planetI = 0; planetI < 9; ++planetI) @@ -118,7 +118,8 @@ GenerateSol_generatePlanets (SOLARSYS_STATE *solarSys) UWORD word_val; PLANET_DESC *pCurDesc = &solarSys->PlanetDesc[planetI]; - pCurDesc->rand_seed = rand_val = TFB_Random (); + pCurDesc->rand_seed = RandomContext_Random (SysGenRNG); + rand_val = pCurDesc->rand_seed; word_val = LOWORD (rand_val); angle = NORMALIZE_ANGLE ((COUNT)HIBYTE (word_val)); @@ -208,7 +209,7 @@ GenerateSol_generateMoons (SOLARSYS_STATE *solarSys, PLANET_DESC *planet) solarSys->MoonDesc[1].data_index = SELENIC_WORLD; solarSys->MoonDesc[1].radius = MIN_MOON_RADIUS + (MAX_MOONS - 1) * MOON_DELTA; - rand_val = TFB_Random (); + rand_val = RandomContext_Random (SysGenRNG); angle = NORMALIZE_ANGLE (LOWORD (rand_val)); solarSys->MoonDesc[1].location.x = COSINE (angle, solarSys->MoonDesc[1].radius); @@ -240,7 +241,8 @@ GenerateSol_generateMoons (SOLARSYS_STATE *solarSys, PLANET_DESC *planet) } static bool -GenerateSol_generateName (SOLARSYS_STATE *solarSys, PLANET_DESC *world) +GenerateSol_generateName (const SOLARSYS_STATE *solarSys, + const PLANET_DESC *world) { COUNT planetNr = planetIndex (solarSys, world); utf8StringCopy (GLOBAL_SIS (PlanetName), sizeof (GLOBAL_SIS (PlanetName)), @@ -269,15 +271,12 @@ GenerateSol_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) return true; } - rand_val = DoPlanetaryAnalysis (&solarSys->SysInfo, world); - if (rand_val) - { - COUNT i; + DoPlanetaryAnalysis (&solarSys->SysInfo, world); + rand_val = RandomContext_GetSeed (SysGenRNG); - solarSys->SysInfo.PlanetInfo.ScanSeed[MINERAL_SCAN] = rand_val; - i = (COUNT)~0; - rand_val = GenerateMineralDeposits (&solarSys->SysInfo, &i); - } + solarSys->SysInfo.PlanetInfo.ScanSeed[MINERAL_SCAN] = rand_val; + GenerateMineralDeposits (&solarSys->SysInfo, GENERATE_ALL, NULL); + rand_val = RandomContext_GetSeed (SysGenRNG); planetNr = planetIndex (solarSys, world); if (worldIsPlanet (solarSys, world)) @@ -405,8 +404,7 @@ GenerateSol_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) } solarSys->SysInfo.PlanetInfo.SurfaceGravity = - CalcGravity (solarSys->SysInfo.PlanetInfo.PlanetDensity, - solarSys->SysInfo.PlanetInfo.PlanetRadius); + CalcGravity (&solarSys->SysInfo.PlanetInfo); LoadPlanet (planetNr == 2 ? CaptureDrawable (LoadGraphic (EARTH_MASK_ANIM)) : NULL); } @@ -421,6 +419,10 @@ GenerateSol_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) switch (planetNr) { case 2: /* moons of EARTH */ + // NOTE: Even though we save the seed here, it is irrelevant. + // The seed will be used to randomly place the tractors, but + // since they are mobile, they will be moved to different + // locations not governed by this seed. solarSys->SysInfo.PlanetInfo.ScanSeed[BIOLOGICAL_SCAN] = rand_val; @@ -505,8 +507,7 @@ GenerateSol_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) } solarSys->SysInfo.PlanetInfo.SurfaceGravity = - CalcGravity (solarSys->SysInfo.PlanetInfo.PlanetDensity, - solarSys->SysInfo.PlanetInfo.PlanetRadius); + CalcGravity (&solarSys->SysInfo.PlanetInfo); LoadPlanet (NULL); } @@ -514,8 +515,8 @@ GenerateSol_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) } static COUNT -GenerateSol_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT whichNode) +GenerateSol_generateEnergy (const SOLARSYS_STATE *solarSys, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) { if (matchWorld (solarSys, world, 8, MATCH_PLANET)) { @@ -527,8 +528,11 @@ GenerateSol_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, return 0; } - solarSys->SysInfo.PlanetInfo.CurPt.x = 20; - solarSys->SysInfo.PlanetInfo.CurPt.y = MAP_HEIGHT - 8; + if (info) + { + info->loc_pt.x = 20; + info->loc_pt.y = MAP_HEIGHT - 8; + } return 1; // only matters when count is requested } @@ -543,8 +547,11 @@ GenerateSol_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, return 0; } - solarSys->SysInfo.PlanetInfo.CurPt.x = MAP_WIDTH * 3 / 4; - solarSys->SysInfo.PlanetInfo.CurPt.y = MAP_HEIGHT * 1 / 4; + if (info) + { + info->loc_pt.x = MAP_WIDTH * 3 / 4; + info->loc_pt.y = MAP_HEIGHT * 1 / 4; + } return 1; // only matters when count is requested } @@ -595,15 +602,14 @@ GenerateSol_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, } static COUNT -GenerateSol_generateLife (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT whichNode) +GenerateSol_generateLife (const SOLARSYS_STATE *solarSys, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) { if (matchWorld (solarSys, world, 2, 1)) { /* Earth Moon */ - GenerateRandomNodes (&solarSys->SysInfo, BIOLOGICAL_SCAN, 10, - NUM_CREATURE_TYPES + 1, &whichNode); - return whichNode; + return GenerateRandomNodes (&solarSys->SysInfo, BIOLOGICAL_SCAN, 10, + NUM_CREATURE_TYPES + 1, whichNode, info); } return 0; diff --git a/sc2/src/uqm/planets/generate/genspa.c b/sc2/src/uqm/planets/generate/genspa.c index c80e1342e..26bc412f0 100644 --- a/sc2/src/uqm/planets/generate/genspa.c +++ b/sc2/src/uqm/planets/generate/genspa.c @@ -35,10 +35,10 @@ static bool GenerateSpathi_generateMoons (SOLARSYS_STATE *solarSys, PLANET_DESC *planet); static bool GenerateSpathi_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world); -static COUNT GenerateSpathi_generateEnergy (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); -static COUNT GenerateSpathi_generateLife (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); +static COUNT GenerateSpathi_generateEnergy (const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); +static COUNT GenerateSpathi_generateLife (const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); static bool GenerateSpathi_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, COUNT whichNode); static bool GenerateSpathi_pickupLife (SOLARSYS_STATE *solarSys, @@ -102,7 +102,7 @@ GenerateSpathi_generateMoons (SOLARSYS_STATE *solarSys, PLANET_DESC *planet) solarSys->MoonDesc[0].data_index = PELLUCID_WORLD; solarSys->MoonDesc[0].radius = MIN_MOON_RADIUS + MOON_DELTA; - angle = NORMALIZE_ANGLE (LOWORD (TFB_Random ())); + angle = NORMALIZE_ANGLE (LOWORD (RandomContext_Random (SysGenRNG))); solarSys->MoonDesc[0].location.x = COSINE (angle, solarSys->MoonDesc[0].radius); solarSys->MoonDesc[0].location.y = @@ -116,13 +116,12 @@ static bool GenerateSpathi_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) { DWORD rand_val; - COUNT i; if (matchWorld (solarSys, world, 0, 0)) { /* Spathiwa's moon */ if (!GET_GAME_STATE (SPATHI_SHIELDED_SELVES) - && ActivateStarShip (SPATHI_SHIP, SPHERE_TRACKING)) + && StartSphereTracking (SPATHI_SHIP)) { NotifyOthers (SPATHI_SHIP, IPNL_ALL_CLEAR); PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); @@ -144,15 +143,16 @@ GenerateSpathi_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) } return true; } - rand_val = DoPlanetaryAnalysis (&solarSys->SysInfo, world); + + DoPlanetaryAnalysis (&solarSys->SysInfo, world); + rand_val = RandomContext_GetSeed (SysGenRNG); solarSys->SysInfo.PlanetInfo.ScanSeed[BIOLOGICAL_SCAN] = rand_val; - i = (COUNT)~0; - rand_val = GenerateLifeForms (&solarSys->SysInfo, &i); + GenerateLifeForms (&solarSys->SysInfo, GENERATE_ALL, NULL); + rand_val = RandomContext_GetSeed (SysGenRNG); solarSys->SysInfo.PlanetInfo.ScanSeed[MINERAL_SCAN] = rand_val; - i = (COUNT)~0; - GenerateMineralDeposits (&solarSys->SysInfo, &i); + GenerateMineralDeposits (&solarSys->SysInfo, GENERATE_ALL, NULL); solarSys->SysInfo.PlanetInfo.ScanSeed[ENERGY_SCAN] = rand_val; @@ -181,18 +181,18 @@ GenerateSpathi_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) else if (matchWorld (solarSys, world, 0, MATCH_PLANET)) { /* visiting Spathiwa */ - rand_val = DoPlanetaryAnalysis (&solarSys->SysInfo, world); + DoPlanetaryAnalysis (&solarSys->SysInfo, world); + rand_val = RandomContext_GetSeed (SysGenRNG); solarSys->SysInfo.PlanetInfo.ScanSeed[MINERAL_SCAN] = rand_val; - i = (COUNT)~0; - rand_val = GenerateMineralDeposits (&solarSys->SysInfo, &i); + GenerateMineralDeposits (&solarSys->SysInfo, GENERATE_ALL, NULL); + rand_val = RandomContext_GetSeed (SysGenRNG); solarSys->SysInfo.PlanetInfo.ScanSeed[BIOLOGICAL_SCAN] = rand_val; solarSys->SysInfo.PlanetInfo.PlanetRadius = 120; solarSys->SysInfo.PlanetInfo.SurfaceGravity = - CalcGravity (solarSys->SysInfo.PlanetInfo.PlanetDensity, - solarSys->SysInfo.PlanetInfo.PlanetRadius); + CalcGravity (&solarSys->SysInfo.PlanetInfo); solarSys->SysInfo.PlanetInfo.Weather = 0; solarSys->SysInfo.PlanetInfo.Tectonics = 0; solarSys->SysInfo.PlanetInfo.SurfaceTemperature = 31; @@ -207,8 +207,8 @@ GenerateSpathi_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) } static COUNT -GenerateSpathi_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT whichNode) +GenerateSpathi_generateEnergy (const SOLARSYS_STATE *solarSys, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) { if (matchWorld (solarSys, world, 0, 0)) { @@ -219,7 +219,7 @@ GenerateSpathi_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, return 0; } - return GenerateDefault_generateArtifact (solarSys, whichNode); + return GenerateDefault_generateArtifact (solarSys, whichNode, info); } return 0; @@ -247,15 +247,14 @@ GenerateSpathi_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, } static COUNT -GenerateSpathi_generateLife (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT whichNode) +GenerateSpathi_generateLife (const SOLARSYS_STATE *solarSys, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) { if (matchWorld (solarSys, world, 0, MATCH_PLANET)) { #define NUM_EVIL_ONES 32 - GenerateRandomNodes (&solarSys->SysInfo, BIOLOGICAL_SCAN, NUM_EVIL_ONES, - NUM_CREATURE_TYPES, &whichNode); - return whichNode; + return GenerateRandomNodes (&solarSys->SysInfo, BIOLOGICAL_SCAN, NUM_EVIL_ONES, + NUM_CREATURE_TYPES, whichNode, info); } return 0; diff --git a/sc2/src/uqm/planets/generate/gensup.c b/sc2/src/uqm/planets/generate/gensup.c index 5f1291bed..a618c89e7 100644 --- a/sc2/src/uqm/planets/generate/gensup.c +++ b/sc2/src/uqm/planets/generate/gensup.c @@ -31,8 +31,8 @@ static bool GenerateSupox_generatePlanets (SOLARSYS_STATE *solarSys); static bool GenerateSupox_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world); -static COUNT GenerateSupox_generateEnergy (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); +static COUNT GenerateSupox_generateEnergy (const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); static bool GenerateSupox_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, COUNT whichNode); @@ -79,7 +79,7 @@ GenerateSupox_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) { if (matchWorld (solarSys, world, 0, MATCH_PLANET)) { - if (ActivateStarShip (SUPOX_SHIP, SPHERE_TRACKING)) + if (StartSphereTracking (SUPOX_SHIP)) { NotifyOthers (SUPOX_SHIP, IPNL_ALL_CLEAR); PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); @@ -146,12 +146,12 @@ GenerateSupox_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, } static COUNT -GenerateSupox_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT whichNode) +GenerateSupox_generateEnergy (const SOLARSYS_STATE *solarSys, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) { if (matchWorld (solarSys, world, 0, MATCH_PLANET)) { - return GenerateDefault_generateRuins (solarSys, whichNode); + return GenerateDefault_generateRuins (solarSys, whichNode, info); } return 0; diff --git a/sc2/src/uqm/planets/generate/genthrad.c b/sc2/src/uqm/planets/generate/genthrad.c index ad5194b35..875e5823a 100644 --- a/sc2/src/uqm/planets/generate/genthrad.c +++ b/sc2/src/uqm/planets/generate/genthrad.c @@ -21,7 +21,8 @@ #include "../planets.h" #include "../../build.h" #include "../../comm.h" -#include "../../encount.h" +#include "../../gendef.h" +#include "../../starmap.h" #include "../../globdata.h" #include "../../ipdisp.h" #include "../../nameref.h" @@ -33,8 +34,8 @@ static bool GenerateThraddash_generatePlanets (SOLARSYS_STATE *solarSys); static bool GenerateThraddash_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world); -static COUNT GenerateThraddash_generateEnergy (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); +static COUNT GenerateThraddash_generateEnergy (const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); static bool GenerateThraddash_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, COUNT whichNode); @@ -95,7 +96,7 @@ GenerateThraddash_generateOrbital (SOLARSYS_STATE *solarSys, { if (matchWorld (solarSys, world, 0, MATCH_PLANET)) { - if (ActivateStarShip (THRADDASH_SHIP, SPHERE_TRACKING) + if (StartSphereTracking (THRADDASH_SHIP) && (CurStarDescPtr->Index == THRADD_DEFINED || (!GET_GAME_STATE (HELIX_UNPROTECTED) && (BYTE)(GET_GAME_STATE (THRADD_MISSION) - 1) >= 3))) @@ -131,9 +132,7 @@ GenerateThraddash_generateOrbital (SOLARSYS_STATE *solarSys, && (BYTE)(GET_GAME_STATE (THRADD_MISSION) - 1) >= 3)) return true; - LockMutex (GraphicsLock); RepairSISBorder (); - UnlockMutex (GraphicsLock); } if (CurStarDescPtr->Index == AQUA_HELIX_DEFINED @@ -160,13 +159,13 @@ GenerateThraddash_generateOrbital (SOLARSYS_STATE *solarSys, } static COUNT -GenerateThraddash_generateEnergy (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode) +GenerateThraddash_generateEnergy (const SOLARSYS_STATE *solarSys, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) { if (CurStarDescPtr->Index == THRADD_DEFINED && matchWorld (solarSys, world, 0, MATCH_PLANET)) { - return GenerateDefault_generateRuins (solarSys, whichNode); + return GenerateDefault_generateRuins (solarSys, whichNode, info); } if (CurStarDescPtr->Index == AQUA_HELIX_DEFINED @@ -179,7 +178,7 @@ GenerateThraddash_generateEnergy (SOLARSYS_STATE *solarSys, return 0; } - return GenerateDefault_generateArtifact (solarSys, whichNode); + return GenerateDefault_generateArtifact (solarSys, whichNode, info); } return 0; diff --git a/sc2/src/uqm/planets/generate/genutw.c b/sc2/src/uqm/planets/generate/genutw.c index d1e0cfcd1..71ac2aa49 100644 --- a/sc2/src/uqm/planets/generate/genutw.c +++ b/sc2/src/uqm/planets/generate/genutw.c @@ -21,7 +21,8 @@ #include "../planets.h" #include "../../build.h" #include "../../comm.h" -#include "../../encount.h" +#include "../../gendef.h" +#include "../../starmap.h" #include "../../globdata.h" #include "../../ipdisp.h" #include "../../nameref.h" @@ -34,8 +35,8 @@ static bool GenerateUtwig_initNpcs (SOLARSYS_STATE *solarSys); static bool GenerateUtwig_generatePlanets (SOLARSYS_STATE *solarSys); static bool GenerateUtwig_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world); -static COUNT GenerateUtwig_generateEnergy (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); +static COUNT GenerateUtwig_generateEnergy (const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); static bool GenerateUtwig_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, COUNT whichNode); @@ -108,7 +109,7 @@ GenerateUtwig_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) { if ((CurStarDescPtr->Index == UTWIG_DEFINED || !GET_GAME_STATE (UTWIG_HAVE_ULTRON)) - && ActivateStarShip (UTWIG_SHIP, SPHERE_TRACKING)) + && StartSphereTracking (UTWIG_SHIP)) { NotifyOthers (UTWIG_SHIP, IPNL_ALL_CLEAR); PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); @@ -140,7 +141,7 @@ GenerateUtwig_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) if (CurStarDescPtr->Index == BOMB_DEFINED && !GET_GAME_STATE (BOMB_UNPROTECTED) - && ActivateStarShip (DRUUGE_SHIP, SPHERE_TRACKING)) + && StartSphereTracking (DRUUGE_SHIP)) { COUNT i; @@ -173,9 +174,7 @@ GenerateUtwig_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) if (DruugeSurvivors) return true; - LockMutex (GraphicsLock); RepairSISBorder (); - UnlockMutex (GraphicsLock); SET_GAME_STATE (BOMB_UNPROTECTED, 1); } } @@ -211,13 +210,13 @@ GenerateUtwig_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) } static COUNT -GenerateUtwig_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT whichNode) +GenerateUtwig_generateEnergy (const SOLARSYS_STATE *solarSys, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) { if (CurStarDescPtr->Index == UTWIG_DEFINED && matchWorld (solarSys, world, 0, MATCH_PLANET)) { - return GenerateDefault_generateRuins (solarSys, whichNode); + return GenerateDefault_generateRuins (solarSys, whichNode, info); } if (CurStarDescPtr->Index == BOMB_DEFINED @@ -230,7 +229,7 @@ GenerateUtwig_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, return 0; } - return GenerateDefault_generateArtifact (solarSys, whichNode); + return GenerateDefault_generateArtifact (solarSys, whichNode, info); } return 0; diff --git a/sc2/src/uqm/planets/generate/genvault.c b/sc2/src/uqm/planets/generate/genvault.c index e6985a266..e1898971f 100644 --- a/sc2/src/uqm/planets/generate/genvault.c +++ b/sc2/src/uqm/planets/generate/genvault.c @@ -27,8 +27,8 @@ static bool GenerateVault_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world); -static COUNT GenerateVault_generateEnergy (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); +static COUNT GenerateVault_generateEnergy (const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); static bool GenerateVault_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, COUNT whichNode); @@ -79,12 +79,12 @@ GenerateVault_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) } static COUNT -GenerateVault_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT whichNode) +GenerateVault_generateEnergy (const SOLARSYS_STATE *solarSys, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) { if (matchWorld (solarSys, world, 0, 0)) { - return GenerateDefault_generateArtifact (solarSys, whichNode); + return GenerateDefault_generateArtifact (solarSys, whichNode, info); } return 0; diff --git a/sc2/src/uqm/planets/generate/genvux.c b/sc2/src/uqm/planets/generate/genvux.c index 2218681fd..d4a0642cb 100644 --- a/sc2/src/uqm/planets/generate/genvux.c +++ b/sc2/src/uqm/planets/generate/genvux.c @@ -22,7 +22,8 @@ #include "../planets.h" #include "../../build.h" #include "../../comm.h" -#include "../../encount.h" +#include "../../gendef.h" +#include "../../starmap.h" #include "../../globdata.h" #include "../../ipdisp.h" #include "../../nameref.h" @@ -35,10 +36,10 @@ static bool GenerateVux_generatePlanets (SOLARSYS_STATE *solarSys); static bool GenerateVux_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world); -static COUNT GenerateVux_generateEnergy (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); -static COUNT GenerateVux_generateLife (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); +static COUNT GenerateVux_generateEnergy (const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); +static COUNT GenerateVux_generateLife (const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); static bool GenerateVux_pickupEnergy (SOLARSYS_STATE *, PLANET_DESC *world, COUNT whichNode); static bool GenerateVux_pickupLife (SOLARSYS_STATE *, PLANET_DESC *world, @@ -124,7 +125,7 @@ GenerateVux_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) && (CurStarDescPtr->Index == VUX_DEFINED || (CurStarDescPtr->Index == MAIDENS_DEFINED && !GET_GAME_STATE (ZEX_IS_DEAD)))) - && ActivateStarShip (VUX_SHIP, SPHERE_TRACKING)) + && StartSphereTracking (VUX_SHIP)) { NotifyOthers (VUX_SHIP, IPNL_ALL_CLEAR); PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); @@ -157,9 +158,7 @@ GenerateVux_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) || !GET_GAME_STATE (ZEX_IS_DEAD)) return true; - LockMutex (GraphicsLock); RepairSISBorder (); - UnlockMutex (GraphicsLock); } } @@ -210,8 +209,8 @@ GenerateVux_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) } static COUNT -GenerateVux_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT whichNode) +GenerateVux_generateEnergy (const SOLARSYS_STATE *solarSys, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) { if (CurStarDescPtr->Index == MAIDENS_DEFINED && matchWorld (solarSys, world, 0, MATCH_PLANET)) @@ -223,8 +222,11 @@ GenerateVux_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, return 0; } - solarSys->SysInfo.PlanetInfo.CurPt.x = MAP_WIDTH / 3; - solarSys->SysInfo.PlanetInfo.CurPt.y = MAP_HEIGHT * 5 / 8; + if (info) + { + info->loc_pt.x = MAP_WIDTH / 3; + info->loc_pt.y = MAP_HEIGHT * 5 / 8; + } return 1; // only matters when count is requested } @@ -232,7 +234,7 @@ GenerateVux_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, if (CurStarDescPtr->Index == VUX_DEFINED && matchWorld (solarSys, world, 0, MATCH_PLANET)) { - return GenerateDefault_generateRuins (solarSys, whichNode); + return GenerateDefault_generateRuins (solarSys, whichNode, info); } return 0; @@ -269,62 +271,37 @@ GenerateVux_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, } static COUNT -GenerateVux_generateLife (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT whichNode) +GenerateVux_generateLife (const SOLARSYS_STATE *solarSys, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) { if (CurStarDescPtr->Index == MAIDENS_DEFINED && matchWorld (solarSys, world, 0, MATCH_PLANET)) { - COUNT i; - DWORD old_rand; - - old_rand = TFB_SeedRandom ( - solarSys->SysInfo.PlanetInfo.ScanSeed[BIOLOGICAL_SCAN]); - - for (i = 0; i <= whichNode && i < 12; ++i) + static const SBYTE life[] = { - GenerateRandomLocation (&solarSys->SysInfo); - if (i < 4) - solarSys->SysInfo.PlanetInfo.CurType = 9; - else if (i < 8) - solarSys->SysInfo.PlanetInfo.CurType = 14; - else /* if (i < 12) */ - solarSys->SysInfo.PlanetInfo.CurType = 18; - } - - TFB_SeedRandom (old_rand); - - return 12; // only matters when count is requested + 9, 9, 9, 9, /* Carousel Beast */ + 14, 14, 14, 14, /* Amorphous Trandicula */ + 18, 18, 18, 18, /* Penguin Cyclops */ + -1 /* term */ + }; + return GeneratePresetLife (&solarSys->SysInfo, life, whichNode, info); } if (CurStarDescPtr->Index == VUX_BEAST_DEFINED && matchWorld (solarSys, world, 0, MATCH_PLANET)) { - COUNT i; - DWORD old_rand; - - old_rand = TFB_SeedRandom ( - solarSys->SysInfo.PlanetInfo.ScanSeed[BIOLOGICAL_SCAN]); - - for (i = 0; i <= whichNode && i < 11; ++i) + static const SBYTE life[] = { - GenerateRandomLocation (&solarSys->SysInfo); - if (i == 0) /* VUX Beast */ - solarSys->SysInfo.PlanetInfo.CurType = NUM_CREATURE_TYPES + 2; - else if (i <= 5) - /* {SPEED_MOTIONLESS | DANGER_NORMAL, MAKE_BYTE (5, 3)}, */ - solarSys->SysInfo.PlanetInfo.CurType = 3; - else /* if (i <= 10) */ - /* {BEHAVIOR_UNPREDICTABLE | SPEED_SLOW | DANGER_NORMAL, MAKE_BYTE (3, 8)}, */ - solarSys->SysInfo.PlanetInfo.CurType = 8; - } - - TFB_SeedRandom (old_rand); - - return 11; // only matters when count is requested + NUM_CREATURE_TYPES + 2, /* VUX Beast */ + // Must be the first node, see pickupLife() below + 3, 3, 3, 3, 3, /* Whackin' Bush */ + 8, 8, 8, 8, 8, /* Glowing Medusa */ + -1 /* term */ + }; + return GeneratePresetLife (&solarSys->SysInfo, life, whichNode, info); } - return GenerateDefault_generateLife (solarSys, world, whichNode); + return GenerateDefault_generateLife (solarSys, world, whichNode, info); } static bool diff --git a/sc2/src/uqm/planets/generate/genwreck.c b/sc2/src/uqm/planets/generate/genwreck.c index 669fe5cb0..05e956e29 100644 --- a/sc2/src/uqm/planets/generate/genwreck.c +++ b/sc2/src/uqm/planets/generate/genwreck.c @@ -27,8 +27,8 @@ static bool GenerateWreck_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world); -static COUNT GenerateWreck_generateEnergy (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); +static COUNT GenerateWreck_generateEnergy (const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); static bool GenerateWreck_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, COUNT whichNode); @@ -73,12 +73,12 @@ GenerateWreck_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) } static COUNT -GenerateWreck_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT whichNode) +GenerateWreck_generateEnergy (const SOLARSYS_STATE *solarSys, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) { if (matchWorld (solarSys, world, 6, MATCH_PLANET)) { - return GenerateDefault_generateArtifact (solarSys, whichNode); + return GenerateDefault_generateArtifact (solarSys, whichNode, info); } return 0; diff --git a/sc2/src/uqm/planets/generate/genyeh.c b/sc2/src/uqm/planets/generate/genyeh.c index e49347673..caae54332 100644 --- a/sc2/src/uqm/planets/generate/genyeh.c +++ b/sc2/src/uqm/planets/generate/genyeh.c @@ -30,8 +30,8 @@ static bool GenerateYehat_generatePlanets (SOLARSYS_STATE *solarSys); static bool GenerateYehat_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world); -static COUNT GenerateYehat_generateEnergy (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); +static COUNT GenerateYehat_generateEnergy (const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); static bool GenerateYehat_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, COUNT whichNode); @@ -77,7 +77,7 @@ GenerateYehat_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) { if (matchWorld (solarSys, world, 0, MATCH_PLANET)) { - if (ActivateStarShip (YEHAT_SHIP, SPHERE_TRACKING)) + if (StartSphereTracking (YEHAT_SHIP)) { NotifyOthers (YEHAT_SHIP, IPNL_ALL_CLEAR); PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); @@ -113,12 +113,12 @@ GenerateYehat_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) } static COUNT -GenerateYehat_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT whichNode) +GenerateYehat_generateEnergy (const SOLARSYS_STATE *solarSys, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) { if (matchWorld (solarSys, world, 0, MATCH_PLANET)) { - return GenerateDefault_generateRuins (solarSys, whichNode); + return GenerateDefault_generateRuins (solarSys, whichNode, info); } return 0; diff --git a/sc2/src/uqm/planets/generate/genzoq.c b/sc2/src/uqm/planets/generate/genzoq.c index 2d9e0dab8..9b30f89fd 100644 --- a/sc2/src/uqm/planets/generate/genzoq.c +++ b/sc2/src/uqm/planets/generate/genzoq.c @@ -30,8 +30,8 @@ static bool GenerateZoqFotPik_initNpcs (SOLARSYS_STATE *solarSys); static bool GenerateZoqFotPik_generatePlanets (SOLARSYS_STATE *solarSys); static bool GenerateZoqFotPik_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world); -static COUNT GenerateZoqFotPik_generateEnergy (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); +static COUNT GenerateZoqFotPik_generateEnergy (const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); static bool GenerateZoqFotPik_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, COUNT whichNode); @@ -87,7 +87,7 @@ GenerateZoqFotPik_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) { if (matchWorld (solarSys, world, 0, MATCH_PLANET)) { - if (ActivateStarShip (ZOQFOTPIK_SHIP, SPHERE_TRACKING)) + if (StartSphereTracking (ZOQFOTPIK_SHIP)) { PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); ReinitQueue (&GLOBAL (ip_group_q)); @@ -143,12 +143,12 @@ GenerateZoqFotPik_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) } static COUNT -GenerateZoqFotPik_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT whichNode) +GenerateZoqFotPik_generateEnergy (const SOLARSYS_STATE *solarSys, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) { if (matchWorld (solarSys, world, 0, MATCH_PLANET)) { - return GenerateDefault_generateRuins (solarSys, whichNode); + return GenerateDefault_generateRuins (solarSys, whichNode, info); } return 0; diff --git a/sc2/src/uqm/planets/gentopo.c b/sc2/src/uqm/planets/gentopo.c index f7c336b03..521214343 100644 --- a/sc2/src/uqm/planets/gentopo.c +++ b/sc2/src/uqm/planets/gentopo.c @@ -43,9 +43,10 @@ DeltaTopography (COUNT num_iterations, SBYTE *DepthArray, RECT *pRect, DWORD rand_val; SBYTE *lpDst; - depth_delta = ((((SIZE)TFB_Random () & 1) << 1) - 1) * depth_delta; + if ((RandomContext_Random (SysGenRNG) & 1) == 0) + depth_delta = -depth_delta; - rand_val = TFB_Random (); + rand_val = RandomContext_Random (SysGenRNG); w1 = LOWORD (rand_val); w2 = HIWORD (rand_val); diff --git a/sc2/src/uqm/planets/lander.c b/sc2/src/uqm/planets/lander.c index 7d8041799..17aad8fe5 100644 --- a/sc2/src/uqm/planets/lander.c +++ b/sc2/src/uqm/planets/lander.c @@ -23,8 +23,6 @@ #include "../cons_res.h" #include "../controls.h" #include "../colors.h" -// XXX: for CurStarDescPtr and XXX_DEFINED -#include "../encount.h" #include "../process.h" #include "../units.h" #include "../gamestr.h" @@ -1144,7 +1142,6 @@ ScrollPlanetSide (SIZE dx, SIZE dy, int landingOffset) curLanderLoc = new_pt; - LockMutex (GraphicsLock); OldContext = SetContext (PlanetContext); BatchGraphics (); @@ -1254,7 +1251,6 @@ ScrollPlanetSide (SIZE dx, SIZE dy, int landingOffset) UnbatchGraphics (); SetContext (OldContext); - UnlockMutex (GraphicsLock); } static void @@ -1264,9 +1260,7 @@ animationInterframe (TimeCount *TimeIn, COUNT periods) for ( ; periods; --periods) { - LockMutex (GraphicsLock); RotatePlanetSphere (TRUE); - UnlockMutex (GraphicsLock); SleepThreadUntil (*TimeIn + ANIM_FRAME_RATE); *TimeIn = GetTimeCounter (); @@ -1281,12 +1275,12 @@ AnimateLaunch (FRAME farray) COUNT num_frames; TimeCount NextTime; - LockMutex (GraphicsLock); SetContext (PlanetContext); r.corner.x = 0; r.corner.y = 0; r.extent.width = 0; + r.extent.height = 0; s.origin.x = 0; s.origin.y = 0; s.frame = farray; @@ -1304,18 +1298,14 @@ AnimateLaunch (FRAME farray) #endif DrawStamp (&s); UnbatchGraphics (); - UnlockMutex (GraphicsLock); GetFrameRect (s.frame, &r); s.frame = IncFrameIndex (s.frame); SleepThreadUntil (NextTime); - - LockMutex (GraphicsLock); } RepairBackRect (&r); - UnlockMutex (GraphicsLock); } static void @@ -1326,18 +1316,14 @@ AnimateLanderWarmup (void) CONTEXT OldContext; TimeCount TimeIn = GetTimeCounter (); - LockMutex (GraphicsLock); OldContext = SetContext (RadarContext); - UnlockMutex (GraphicsLock); s.origin.x = 0; s.origin.y = 0; s.frame = SetAbsFrameIndex (LanderFrame[0], (ANGLE_TO_FACING (FULL_CIRCLE) << 1) + 1); - LockMutex (GraphicsLock); DrawStamp (&s); - UnlockMutex (GraphicsLock); animationInterframe (&TimeIn, 2); @@ -1346,10 +1332,8 @@ AnimateLanderWarmup (void) { animationInterframe (&TimeIn, 1); - LockMutex (GraphicsLock); DeltaSISGauges (-1, 0, 0); DeltaLanderCrew (1, 0); - UnlockMutex (GraphicsLock); } animationInterframe (&TimeIn, 2); @@ -1359,9 +1343,7 @@ AnimateLanderWarmup (void) else s.frame = SetAbsFrameIndex (s.frame, (ANGLE_TO_FACING (FULL_CIRCLE) << 1) + 2); - LockMutex (GraphicsLock); DrawStamp (&s); - UnlockMutex (GraphicsLock); animationInterframe (&TimeIn, 2); @@ -1371,26 +1353,20 @@ AnimateLanderWarmup (void) { s.frame = SetAbsFrameIndex (s.frame, (ANGLE_TO_FACING (FULL_CIRCLE) << 1) + 3); - LockMutex (GraphicsLock); DrawStamp (&s); - UnlockMutex (GraphicsLock); animationInterframe (&TimeIn, 2); s.frame = IncFrameIndex (s.frame); } - LockMutex (GraphicsLock); DrawStamp (&s); - UnlockMutex (GraphicsLock); if (GET_GAME_STATE (IMPROVED_LANDER_CARGO)) { animationInterframe (&TimeIn, 2); s.frame = SetAbsFrameIndex (s.frame, 59); - LockMutex (GraphicsLock); DrawStamp (&s); - UnlockMutex (GraphicsLock); } animationInterframe (&TimeIn, 2); @@ -1420,7 +1396,6 @@ InitPlanetSide (POINT pt) curLanderLoc = pt; - LockMutex (GraphicsLock); SetContext (PlanetContext); SetContextFont (TinyFont); @@ -1453,7 +1428,6 @@ InitPlanetSide (POINT pt) UnbatchGraphics (); } - UnlockMutex (GraphicsLock); SET_GAME_STATE (PLANETARY_LANDING, 1); } @@ -1750,7 +1724,6 @@ ReturnToOrbit (void) CONTEXT OldContext; RECT r; - LockMutex (GraphicsLock); OldContext = SetContext (PlanetContext); GetContextClipRect (&r); @@ -1763,7 +1736,6 @@ ReturnToOrbit (void) UnbatchGraphics (); SetContext (OldContext); - UnlockMutex (GraphicsLock); } static void @@ -1857,40 +1829,65 @@ KillLanderCrewSeq (COUNT numKilled, DWORD period) return crew_left > 0; } +// Maps a temperature to a (0-7) hazard rating. +// Thermal hazards aren't exposed to the user as a hazard number, +// but the code still works with them that way. +#define ARRAY_SIZE(array) (sizeof(array) / sizeof (*array)) +unsigned +GetThermalHazardRating (int temp) +{ + static const int tempBreakpoints[] = { 50, 100, 150, 250, 350, 550, 800 }; + const size_t numBreakpoints = ARRAY_SIZE (tempBreakpoints); + unsigned i; + + for (i = 0; i < numBreakpoints; ++i) + { + if (temp < tempBreakpoints[i]) + return i; + } + + return numBreakpoints; +} + +// Given a hazard type and rating, return the chance (out of 256) of the hazard +// being generated. +static BYTE +GetHazardChance (int hazardType, unsigned HazardRating) +{ + static const BYTE TectonicsChanceTab[] = {0*3, 0*3, 1*3, 2*3, 4*3, 8*3, 16*3, 32*3}; + static const BYTE WeatherChanceTab [] = {0*3, 0*3, 1*3, 2*3, 3*3, 6*3, 12*3, 24*3}; + static const BYTE FireChanceTab [] = {0*3, 0*3, 1*3, 2*3, 4*3, 12*3, 24*3, 48*3}; + + switch (hazardType) + { + case EARTHQUAKE_DISASTER: + return TectonicsChanceTab[HazardRating]; + case LIGHTNING_DISASTER: + return WeatherChanceTab[HazardRating]; + case LAVASPOT_DISASTER: + return FireChanceTab[HazardRating]; + } + + return 0; +} + void PlanetSide (POINT planetLoc) { SIZE index; LanderInputState landerInputState; PLANETSIDE_DESC PSD; - BYTE TectonicsChanceTab[] = {0*3, 0*3, 1*3, 2*3, 4*3, 8*3, 16*3, 32*3}; - BYTE WeatherChanceTab[] = {0*3, 0*3, 1*3, 2*3, 3*3, 6*3, 12*3, 24*3}; - BYTE FireChanceTab[] = {0*3, 0*3, 1*3, 2*3, 4*3, 12*3, 24*3, 48*3}; memset (&PSD, 0, sizeof (PSD)); PSD.InTransit = TRUE; - PSD.TectonicsChance = - TectonicsChanceTab[pSolarSysState->SysInfo.PlanetInfo.Tectonics]; - PSD.WeatherChance = - WeatherChanceTab[pSolarSysState->SysInfo.PlanetInfo.Weather]; - index = pSolarSysState->SysInfo.PlanetInfo.SurfaceTemperature; - if (index < 50) - PSD.FireChance = FireChanceTab[0]; - else if (index < 100) - PSD.FireChance = FireChanceTab[1]; - else if (index < 150) - PSD.FireChance = FireChanceTab[2]; - else if (index < 250) - PSD.FireChance = FireChanceTab[3]; - else if (index < 350) - PSD.FireChance = FireChanceTab[4]; - else if (index < 550) - PSD.FireChance = FireChanceTab[5]; - else if (index < 800) - PSD.FireChance = FireChanceTab[6]; - else - PSD.FireChance = FireChanceTab[7]; + // Set our chances of hazards occurring. + PSD.TectonicsChance = GetHazardChance (EARTHQUAKE_DISASTER, + pSolarSysState->SysInfo.PlanetInfo.Tectonics); + PSD.WeatherChance = GetHazardChance (LIGHTNING_DISASTER, + pSolarSysState->SysInfo.PlanetInfo.Weather); + PSD.FireChance = GetHazardChance (LAVASPOT_DISASTER, GetThermalHazardRating ( + pSolarSysState->SysInfo.PlanetInfo.SurfaceTemperature)); PSD.ElementLevel = GetStorageBayCapacity () - GLOBAL_SIS (TotalElementMass); PSD.MaxElementLevel = MAX_SCROUNGED; @@ -1948,9 +1945,7 @@ PlanetSide (POINT planetLoc) if (crew_left == 0) { --GLOBAL_SIS (NumLanders); - LockMutex (GraphicsLock); DrawLanders (); - UnlockMutex (GraphicsLock); ReturnToOrbit (); } @@ -1964,7 +1959,6 @@ PlanetSide (POINT planetLoc) ReturnToOrbit (); AnimateLaunch (LanderFrame[6]); - LockMutex (GraphicsLock); DeltaSISGauges (crew_left, 0, 0); if (PSD.ElementLevel) @@ -1978,7 +1972,6 @@ PlanetSide (POINT planetLoc) } DrawStorageBays (FALSE); } - UnlockMutex (GraphicsLock); GLOBAL_SIS (TotalBioMass) += PSD.BiologicalLevel; } @@ -2018,10 +2011,7 @@ InitLander (BYTE LanderFlags) { RECT r; - LockMutex (GraphicsLock); - SetContext (RadarContext); - BatchGraphics (); r.corner.x = 0; @@ -2108,6 +2098,4 @@ InitLander (BYTE LanderFlags) } UnbatchGraphics (); - - UnlockMutex (GraphicsLock); } diff --git a/sc2/src/uqm/planets/lander.h b/sc2/src/uqm/planets/lander.h index 1d3e8ff2b..d41129b13 100644 --- a/sc2/src/uqm/planets/lander.h +++ b/sc2/src/uqm/planets/lander.h @@ -26,6 +26,9 @@ #include "libs/timelib.h" #include "../element.h" +#if defined(__cplusplus) +extern "C" { +#endif // Surface magnification shift (x4) #define MAG_SHIFT 2 @@ -69,6 +72,8 @@ extern void object_animation (ELEMENT *ElementPtr); extern void SetLanderTakeoff (void); extern bool KillLanderCrewSeq (COUNT numKilled, DWORD period); +extern unsigned GetThermalHazardRating (int temp); + // ELEMENT.playerNr constants enum { @@ -76,5 +81,8 @@ enum PS_NON_PLAYER, }; -#endif /* UQM_PLANETS_LANDER_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_PLANETS_LANDER_H_ */ diff --git a/sc2/src/uqm/planets/lifeform.h b/sc2/src/uqm/planets/lifeform.h index 88b9609b7..fbe2d9de8 100644 --- a/sc2/src/uqm/planets/lifeform.h +++ b/sc2/src/uqm/planets/lifeform.h @@ -21,6 +21,9 @@ #include "libs/compiler.h" +#if defined(__cplusplus) +extern "C" { +#endif #define BEHAVIOR_HUNT (0 << 0) #define BEHAVIOR_FLEE (1 << 0) @@ -65,5 +68,8 @@ typedef struct extern const LIFEFORM_DESC CreatureData[]; -#endif /* UQM_PLANETS_LIFEFORM_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_PLANETS_LIFEFORM_H */ diff --git a/sc2/src/uqm/planets/orbits.c b/sc2/src/uqm/planets/orbits.c index 144bc2922..f1ad0f457 100644 --- a/sc2/src/uqm/planets/orbits.c +++ b/sc2/src/uqm/planets/orbits.c @@ -17,8 +17,7 @@ */ #include "planets.h" -// XXX: for CurStarDescPtr -#include "../encount.h" +#include "../starmap.h" #include "libs/compiler.h" #include "libs/mathlib.h" #include "libs/log.h" @@ -499,10 +498,15 @@ char scolor[] = {'B', 'G', 'O', 'R', 'W', 'Y'}; if (NumPlanets == (BYTE)~0) { -#define MAX_GENERATED_PLANETS 10 - while ((NumPlanets = (BYTE)(LOWORD (TFB_Random()) - % MAX_GENERATED_PLANETS)) == 0) - ; +#define MAX_GENERATED_PLANETS 9 + // XXX: This is pretty funny. Instead of calling RNG once, like so: + // 1 + Random % MAX_GENERATED_PLANETS + // we spin in a loop until the result > 0. + // Note that this behavior must be kept to preserve the universe. + do + NumPlanets = LOWORD (RandomContext_Random (SysGenRNG)) + % (MAX_GENERATED_PLANETS + 1); + while (NumPlanets == 0); system->SunDesc[0].NumPlanets = NumPlanets; } @@ -528,7 +532,7 @@ char scolor[] = {'B', 'G', 'O', 'R', 'W', 'Y'}; do { - rand_val = TFB_Random (); + rand_val = RandomContext_Random (SysGenRNG); if (TypesDefined) rand_val = 0; else @@ -564,7 +568,7 @@ char scolor[] = {'B', 'G', 'O', 'R', 'W', 'Y'}; else min_radius = Suns[StarSize].MinGasGDist; RelocatePlanet: - rand_val = TFB_Random (); + rand_val = RandomContext_Random (SysGenRNG); if (GeneratingMoons) { pPD->radius = MIN_MOON_RADIUS @@ -592,7 +596,7 @@ RelocatePlanet: } } - rand_val = TFB_Random (); + rand_val = RandomContext_Random (SysGenRNG); angle = NORMALIZE_ANGLE (LOWORD (rand_val)); pPD->location.x = COSINE (angle, pPD->radius); pPD->location.y = SINE (angle, pPD->radius); diff --git a/sc2/src/uqm/planets/oval.c b/sc2/src/uqm/planets/oval.c index 720316ca1..411299792 100644 --- a/sc2/src/uqm/planets/oval.c +++ b/sc2/src/uqm/planets/oval.c @@ -21,6 +21,7 @@ #include "libs/graphics/context.h" #include "libs/graphics/drawable.h" +#include "planets.h" #define NUM_QUADS 4 diff --git a/sc2/src/uqm/planets/pl_stuff.c b/sc2/src/uqm/planets/pl_stuff.c index 465f4e0ef..073e21505 100644 --- a/sc2/src/uqm/planets/pl_stuff.c +++ b/sc2/src/uqm/planets/pl_stuff.c @@ -192,7 +192,6 @@ ZoomInPlanetSphere (void) pt.y = PLANET_ORG_Y + (int) (dy * (1.0 - scale) * (SCAN_SCREEN_HEIGHT * 6 / 10) + 0.5); - LockMutex (GraphicsLock); SetContext (PlanetContext); BatchGraphics (); @@ -206,7 +205,6 @@ ZoomInPlanetSphere (void) SetGraphicScaleMode (oldMode); UnbatchGraphics (); - UnlockMutex (GraphicsLock); repairRect.corner.x = pt.x + frameRect.corner.x; repairRect.corner.y = pt.y + frameRect.corner.y; diff --git a/sc2/src/uqm/planets/plandata.h b/sc2/src/uqm/planets/plandata.h index a1a04670a..cd2a1c731 100644 --- a/sc2/src/uqm/planets/plandata.h +++ b/sc2/src/uqm/planets/plandata.h @@ -21,6 +21,9 @@ #include "libs/reslib.h" +#if defined(__cplusplus) +extern "C" { +#endif /*------------------------------ Type Defines ----------------------------- */ #define NUMBER_OF_ORBITS 16 @@ -276,25 +279,6 @@ typedef struct DWORD ScanSeed[NUM_SCAN_TYPES]; DWORD ScanRetrieveMask[NUM_SCAN_TYPES]; - // The CurPt, CurDensity and CurType fields are filled in - // when a GENERATE_MINERAL, GENERATE_ENERGY, or GENERATE_LIFE - // call is made. - POINT CurPt; - // Position of the mineral/bio/energy node on the planet. - COUNT CurDensity; - // For bio and energy: undefined - // For minerals the low byte is the gross size of the - // deposit (this determines the image), and the high - // byte is the fine size (the actual quantity). - COUNT CurType; - // For minerals: the type of element - // For bio: the type of the creature. - // 0 through NUM_CREATURE_TYPES - 1 are normal creatures, - // NUM_CREATURE_TYPES is an Evil One - // NUM_CREATURE_TYPES + 1 is a Brainbox Bulldozer - // NUM_CREATURE_TYPES + 2 is Zex' Beauty - // For energy: undefined - STRING DiscoveryString; FONT LanderFont; FRAME LanderFontEff; @@ -310,8 +294,7 @@ enum SUPER_DENSITY }; -#define CalcGravity(d,r) (UWORD)((DWORD)(d) * (r) / 100) -#define CalcFromBase(b,v) ((UWORD)(b) + ((UWORD)TFB_Random () % (v))) +extern UWORD CalcGravity (const PLANET_INFO*); #define EARTH_ATMOSPHERE 50 @@ -328,5 +311,8 @@ enum extern const PlanetFrame *PlanData; -#endif /* UQM_PLANETS_PLANDATA_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_PLANETS_PLANDATA_H_ */ diff --git a/sc2/src/uqm/planets/planets.c b/sc2/src/uqm/planets/planets.c index 6132c361b..c76c2bbe6 100644 --- a/sc2/src/uqm/planets/planets.c +++ b/sc2/src/uqm/planets/planets.c @@ -59,8 +59,6 @@ CreatePlanetContext (void) assert (PlanetContext == NULL); - LockMutex (GraphicsLock); - // PlanetContext rect is relative to SpaceContext oldContext = SetContext (SpaceContext); GetContextClipRect (&r); @@ -72,7 +70,6 @@ CreatePlanetContext (void) SetContextClipRect (&r); SetContext (oldContext); - UnlockMutex (GraphicsLock); } static void @@ -263,9 +260,7 @@ LoadPlanet (FRAME SurfDefFrame) if (WaitMode) { - LockMutex (GraphicsLock); DrawOrbitalDisplay (DRAW_ORBITAL_WAIT); - UnlockMutex (GraphicsLock); } StopMusic (); @@ -281,15 +276,11 @@ LoadPlanet (FRAME SurfDefFrame) if (WaitMode) { ZoomInPlanetSphere (); - LockMutex (GraphicsLock); DrawOrbitalDisplay (DRAW_ORBITAL_UPDATE); - UnlockMutex (GraphicsLock); } else { - LockMutex (GraphicsLock); DrawOrbitalDisplay (DRAW_ORBITAL_FULL); - UnlockMutex (GraphicsLock); } } @@ -302,7 +293,6 @@ FreePlanet (void) UninitSphereRotation (); StopMusic (); - LockMutex (GraphicsLock); for (i = 0; i < sizeof (pSolarSysState->PlanetSideFrame) / sizeof (pSolarSysState->PlanetSideFrame[0]); ++i) @@ -353,7 +343,6 @@ FreePlanet (void) DestroyPlanetContext (); DestroyScanContext (); - UnlockMutex (GraphicsLock); } void @@ -391,9 +380,7 @@ DoPlanetOrbit (MENU_STATE *pMS) if (!select) return TRUE; - LockMutex (GraphicsLock); SetFlashRect (NULL); - UnlockMutex (GraphicsLock); switch (pMS->CurState) { @@ -431,9 +418,7 @@ DoPlanetOrbit (MENU_STATE *pMS) // Deactivate planet rotation oldCallback = SetInputCallback (NULL); - LockMutex (GraphicsLock); RepairSISBorder (); - UnlockMutex (GraphicsLock); AutoPilotSet = StarMap (); if (GLOBAL (CurrentActivity) & CHECK_ABORT) @@ -444,9 +429,7 @@ DoPlanetOrbit (MENU_STATE *pMS) if (!AutoPilotSet) { // Redraw the orbital display - LockMutex (GraphicsLock); DrawOrbitalDisplay (DRAW_ORBITAL_FULL); - UnlockMutex (GraphicsLock); break; } // Fall through !!! @@ -463,9 +446,7 @@ DoPlanetOrbit (MENU_STATE *pMS) pMS->CurState = NAVIGATION; DrawMenuStateStrings (PM_SCAN, pMS->CurState); } - LockMutex (GraphicsLock); SetFlashRect (SFR_MENU_3DO); - UnlockMutex (GraphicsLock); } return TRUE; @@ -474,9 +455,7 @@ DoPlanetOrbit (MENU_STATE *pMS) static void on_input_frame (void) { - LockMutex (GraphicsLock); RotatePlanetSphere (TRUE); - UnlockMutex (GraphicsLock); } void @@ -488,9 +467,7 @@ PlanetOrbitMenu (void) memset (&MenuState, 0, sizeof MenuState); DrawMenuStateStrings (PM_SCAN, SCAN); - LockMutex (GraphicsLock); SetFlashRect (SFR_MENU_3DO); - UnlockMutex (GraphicsLock); MenuState.CurState = SCAN; SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT); @@ -501,8 +478,6 @@ PlanetOrbitMenu (void) SetInputCallback (oldCallback); - LockMutex (GraphicsLock); SetFlashRect (NULL); - UnlockMutex (GraphicsLock); DrawMenuStateStrings (PM_STARMAP, -NAVIGATION); } diff --git a/sc2/src/uqm/planets/planets.h b/sc2/src/uqm/planets/planets.h index 8792a1e39..c6f440daf 100644 --- a/sc2/src/uqm/planets/planets.h +++ b/sc2/src/uqm/planets/planets.h @@ -19,6 +19,8 @@ #ifndef UQM_PLANETS_PLANETS_H_ #define UQM_PLANETS_PLANETS_H_ +#include "libs/mathlib.h" + #define END_INTERPLANETARY START_INTERPLANETARY enum PlanetScanTypes @@ -86,6 +88,7 @@ enum typedef struct planet_desc PLANET_DESC; typedef struct star_desc STAR_DESC; +typedef struct node_info NODE_INFO; typedef struct planet_orbit PLANET_ORBIT; typedef struct solarsys_state SOLARSYS_STATE; @@ -99,6 +102,9 @@ typedef struct solarsys_state SOLARSYS_STATE; #include "plandata.h" #include "sundata.h" +#if defined(__cplusplus) +extern "C" { +#endif struct planet_desc { @@ -126,7 +132,26 @@ struct star_desc BYTE Postfix; }; -typedef void (*PLAN_GEN_FUNC) (BYTE control); +struct node_info +{ + // This structire is filled in when a generateMinerals, generateEnergy, + // or generateLife call is made. + POINT loc_pt; + // Position of the mineral/bio/energy node on the planet. + COUNT density; + // For bio and energy: undefined + // For minerals the low byte is the gross size of the + // deposit (this determines the image), and the high + // byte is the fine size (the actual quantity). + COUNT type; + // For minerals: the type of element + // For bio: the type of the creature. + // 0 through NUM_CREATURE_TYPES - 1 are normal creatures, + // NUM_CREATURE_TYPES is an Evil One + // NUM_CREATURE_TYPES + 1 is a Brainbox Bulldozer + // NUM_CREATURE_TYPES + 2 is Zex' Beauty + // For energy: undefined +}; struct planet_orbit { @@ -230,6 +255,9 @@ extern SOLARSYS_STATE *pSolarSysState; extern MUSIC_REF SpaceMusic; extern CONTEXT PlanetContext; +// Random context used for all solar system, planets and surfaces generation +extern RandomContext *SysGenRNG; + bool playerInSolarSystem (void); bool playerInPlanetOrbit (void); bool playerInInnerSystem (void); @@ -241,6 +269,8 @@ COUNT moonIndex (const SOLARSYS_STATE *solarSys, const PLANET_DESC *moon); bool matchWorld (const SOLARSYS_STATE *solarSys, const PLANET_DESC *world, BYTE planetI, BYTE moonI); +DWORD GetRandomSeedForStar (const STAR_DESC *star); + POINT locationToDisplay (POINT pt, SIZE scaleRadius); POINT displayToLocation (POINT pt, SIZE scaleRadius); POINT planetOuterLocation (COUNT planetI); @@ -254,7 +284,6 @@ extern void FreeLanderFont (PLANET_INFO *info); extern void ExploreSolarSys (void); extern void DrawStarBackGround (void); extern void XFormIPLoc (POINT *pIn, POINT *pOut, BOOLEAN ToDisplay); -extern PLAN_GEN_FUNC GenerateIP (BYTE Index); extern void DrawOval (RECT *pRect, BYTE num_off_pixels); extern void DrawFilledOval (RECT *pRect); extern void FillOrbits (SOLARSYS_STATE *system, BYTE NumPlanets, @@ -286,5 +315,8 @@ extern void GetPlanetOrMoonName (UNICODE *buf, COUNT bufsize); extern void PlanetOrbitMenu (void); extern void SaveSolarSysLocation (void); -#endif /* UQM_PLANETS_PLANETS_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_PLANETS_PLANETS_H_ */ diff --git a/sc2/src/uqm/planets/plangen.c b/sc2/src/uqm/planets/plangen.c index ca5dbb50c..005a968c9 100644 --- a/sc2/src/uqm/planets/plangen.c +++ b/sc2/src/uqm/planets/plangen.c @@ -842,7 +842,7 @@ DitherMap (SBYTE *DepthArray) { // Use up the random value byte by byte if ((i & 3) == 0) - rand_val = TFB_Random (); + rand_val = RandomContext_Random (SysGenRNG); else rand_val >>= 8; @@ -1066,7 +1066,7 @@ MakeStorms (COUNT storm_count, SBYTE *DepthArray) intersect = FALSE; - rand_val = TFB_Random (); + rand_val = RandomContext_Random (SysGenRNG); loword = LOWORD (rand_val); hiword = HIWORD (rand_val); switch (HIBYTE (hiword) & 31) @@ -1094,7 +1094,7 @@ MakeStorms (COUNT storm_count, SBYTE *DepthArray) if (pstorm_r->extent.height <= 4) pstorm_r->extent.height += 4; - rand_val = TFB_Random (); + rand_val = RandomContext_Random (SysGenRNG); loword = LOWORD (rand_val); hiword = HIWORD (rand_val); @@ -1183,7 +1183,7 @@ MakeGasGiant (COUNT num_bands, SBYTE *DepthArray, RECT *pRect, SIZE band_error = num_bands >> 1; lpDst = DepthArray; - band_delta = ((LOWORD (TFB_Random ()) + band_delta = ((LOWORD (RandomContext_Random (SysGenRNG)) & (NUM_BAND_COLORS - 1)) << RANGE_SHIFT) + (1 << (RANGE_SHIFT - 1)); last_y = next_y = 0; @@ -1191,7 +1191,7 @@ MakeGasGiant (COUNT num_bands, SBYTE *DepthArray, RECT *pRect, SIZE { COORD cur_y; - rand_val = TFB_Random (); + rand_val = RandomContext_Random (SysGenRNG); loword = LOWORD (rand_val); hiword = HIWORD (rand_val); @@ -1232,7 +1232,7 @@ MakeGasGiant (COUNT num_bands, SBYTE *DepthArray, RECT *pRect, SIZE & (((1 << RANGE_SHIFT) * NUM_BAND_COLORS) - 1); } - MakeStorms (4 + (TFB_Random () & 3) + 1, DepthArray); + MakeStorms (4 + (RandomContext_Random (SysGenRNG) & 3) + 1, DepthArray); DitherMap (DepthArray); } @@ -1572,8 +1572,8 @@ get_vblock_avg (elev_block_t *pblk, SBYTE *pTopo, int x, int y) if (y1 > MAP_HEIGHT) y1 = MAP_HEIGHT; - elev = pTopo + y0 * MAP_HEIGHT + x; - for (i = y0; i < y1; ++i, elev += MAP_HEIGHT) + elev = pTopo + y0 * MAP_WIDTH + x; + for (i = y0; i < y1; ++i, elev += MAP_WIDTH) { int delta = abs (i - y); int weight = 255; // full weight @@ -1589,7 +1589,7 @@ get_vblock_avg (elev_block_t *pblk, SBYTE *pTopo, int x, int y) max = v; if (v < min) min = v; - avg += pblk->avg * weight; + avg += v * weight; total_weight += weight; } avg /= total_weight; @@ -1718,11 +1718,11 @@ GenerateLightMap (SBYTE *pTopo, int w, int h) } } +// Sets the SysGenRNG to the required state first. void GeneratePlanetSurface (PLANET_DESC *pPlanetDesc, FRAME SurfDefFrame) { RECT r; - DWORD old_seed; const PlanetFrame *PlanDataPtr; PLANET_INFO *PlanetInfo = &pSolarSysState->SysInfo.PlanetInfo; COUNT i, y; @@ -1732,10 +1732,9 @@ GeneratePlanetSurface (PLANET_DESC *pPlanetDesc, FRAME SurfDefFrame) PLANET_ORBIT *Orbit = &pSolarSysState->Orbit; BOOLEAN shielded = (pPlanetDesc->data_index & PLANET_SHIELDED) != 0; - old_seed = TFB_SeedRandom (pPlanetDesc->rand_seed); + RandomContext_SeedRandom (SysGenRNG, pPlanetDesc->rand_seed); TopoContext = CreateContext ("Plangen.TopoContext"); - LockMutex (GraphicsLock); OldContext = SetContext (TopoContext); planet_orbit_init (); @@ -1818,7 +1817,7 @@ GeneratePlanetSurface (PLANET_DESC *pPlanetDesc, FRAME SurfDefFrame) RECT crater_r; UWORD loword; - loword = LOWORD (TFB_Random ()); + loword = LOWORD (RandomContext_Random (SysGenRNG)); switch (HIBYTE (loword) & 31) { case 0: @@ -1841,7 +1840,7 @@ GeneratePlanetSurface (PLANET_DESC *pPlanetDesc, FRAME SurfDefFrame) break; } - loword = LOWORD (TFB_Random ()); + loword = LOWORD (RandomContext_Random (SysGenRNG)); crater_r.extent.height = crater_r.extent.width; crater_r.corner.x = HIBYTE (loword) % (MAP_WIDTH - crater_r.extent.width); @@ -1950,9 +1949,6 @@ GeneratePlanetSurface (PLANET_DESC *pPlanetDesc, FRAME SurfDefFrame) } SetContext (OldContext); - UnlockMutex (GraphicsLock); DestroyContext (TopoContext); - - TFB_SeedRandom (old_seed); } diff --git a/sc2/src/uqm/planets/pstarmap.c b/sc2/src/uqm/planets/pstarmap.c index 53eb8d03d..cd3385870 100644 --- a/sc2/src/uqm/planets/pstarmap.c +++ b/sc2/src/uqm/planets/pstarmap.c @@ -20,8 +20,7 @@ #include "../colors.h" #include "../controls.h" #include "../menustat.h" -// XXX: for stuff that does not belong there -#include "../encount.h" +#include "../starmap.h" #include "../races.h" #include "../gameopt.h" #include "../gamestr.h" @@ -68,18 +67,18 @@ signedDivWithError (long val, long divisor) #define MAP_FIT_X ((MAX_X_UNIVERSE + 1) / SIS_SCREEN_WIDTH + 1) static inline COORD -universeToDispx (COORD ux) +universeToDispx (long ux) { - return signedDivWithError ((((long)ux - mapOrigin.x) << zoomLevel) + return signedDivWithError (((ux - mapOrigin.x) << zoomLevel) * SIS_SCREEN_WIDTH, MAX_X_UNIVERSE + MAP_FIT_X) + ((SIS_SCREEN_WIDTH - 1) >> 1); } #define UNIVERSE_TO_DISPX(ux) universeToDispx(ux) static inline COORD -universeToDispy (COORD uy) +universeToDispy (long uy) { - return signedDivWithError ((((long)mapOrigin.y - uy) << zoomLevel) + return signedDivWithError (((mapOrigin.y - uy) << zoomLevel) * SIS_SCREEN_HEIGHT, MAX_Y_UNIVERSE + 2) + ((SIS_SCREEN_HEIGHT - 1) >> 1); } @@ -124,7 +123,6 @@ flashCurrentLocation (POINT *where) NextTime = GetTimeCounter () + (ONE_SECOND / 16); - LockMutex (GraphicsLock); OldContext = SetContext (SpaceContext); if (c == 0x00 || c == 0x1A) @@ -139,7 +137,6 @@ flashCurrentLocation (POINT *where) SetContextForeGroundColor (OldColor); SetContext (OldContext); - UnlockMutex (GraphicsLock); } } @@ -164,7 +161,7 @@ DrawAutoPilot (POINT *pDstPt) cycle, delta; POINT pt; - if (LOBYTE (GLOBAL (CurrentActivity)) != IN_HYPERSPACE) + if (!inHQSpace ()) pt = CurStarDescPtr->star_pt; else { @@ -300,7 +297,6 @@ DrawStarMap (COUNT race_update, RECT *pClipRect) } else { - LockMutex (GraphicsLock); draw_cursor = TRUE; } @@ -343,13 +339,14 @@ DrawStarMap (COUNT race_update, RECT *pClipRect) } ClearDrawable (); + // Draw the fuel range circle if (race_update == 0 && which_space < 2 && (diameter = (long)GLOBAL_SIS (FuelOnBoard) << 1)) { Color OldColor; - if (LOBYTE (GLOBAL (CurrentActivity)) != IN_HYPERSPACE) + if (!inHQSpace ()) r.corner = CurStarDescPtr->star_pt; else { @@ -357,6 +354,10 @@ DrawStarMap (COUNT race_update, RECT *pClipRect) r.corner.y = LOGY_TO_UNIVERSE (GLOBAL_SIS (log_y)); } + // Cap the diameter to a sane range + if (diameter > MAX_X_UNIVERSE * 4) + diameter = MAX_X_UNIVERSE * 4; + r.extent.width = UNIVERSE_TO_DISPX (diameter) - UNIVERSE_TO_DISPX (0); if (r.extent.width < 0) @@ -555,9 +556,6 @@ DrawStarMap (COUNT race_update, RECT *pClipRect) UNIVERSE_TO_DISPY (cursorLoc.y)); } } - - if (draw_cursor) - UnlockMutex (GraphicsLock); } static void @@ -587,9 +585,7 @@ EraseCursor (COORD curs_x, COORD curs_y) #else /* NEW */ r.extent.height += r.corner.y & 1; r.corner.y &= ~1; - UnlockMutex (GraphicsLock); DrawStarMap (0, &r); - LockMutex (GraphicsLock); #endif /* OLD */ } @@ -689,11 +685,9 @@ UpdateCursorLocation (int sx, int sy, const POINT *newpt) } else { - LockMutex (GraphicsLock); EraseCursor (pt.x, pt.y); // ClearDrawable (); DrawCursor (s.origin.x, s.origin.y); - UnlockMutex (GraphicsLock); } } @@ -763,14 +757,12 @@ UpdateCursorInfo (UNICODE *prevbuf) } } - LockMutex (GraphicsLock); DrawHyperCoords (cursorLoc); if (strcmp (buf, prevbuf) != 0) { strcpy (prevbuf, buf); DrawSISMessage (buf); } - UnlockMutex (GraphicsLock); } static void @@ -781,7 +773,7 @@ UpdateFuelRequirement (void) DWORD f; POINT pt; - if (LOBYTE (GLOBAL (CurrentActivity)) != IN_HYPERSPACE) + if (!inHQSpace ()) pt = CurStarDescPtr->star_pt; else { @@ -802,9 +794,7 @@ UpdateFuelRequirement (void) fuel_required / FUEL_TANK_SCALE, (fuel_required % FUEL_TANK_SCALE) / 10); - LockMutex (GraphicsLock); DrawStatusMessage (buf); - UnlockMutex (GraphicsLock); } #define STAR_SEARCH_BUFSIZE 256 @@ -1055,10 +1045,8 @@ DrawMatchedStarName (TEXTENTRY_STATE *pTES) flags |= DSME_BLOCKCUR; } - LockMutex (GraphicsLock); DrawSISMessageEx (buf, CurPos, ExPos, flags); DrawHyperCoords (cursorLoc); - UnlockMutex (GraphicsLock); } static void @@ -1129,9 +1117,7 @@ OnStarNameChange (TEXTENTRY_STATE *pTES) if (pTES->JoystickMode) flags |= DSME_BLOCKCUR; - LockMutex (GraphicsLock); ret = DrawSISMessageEx (pSS->Text, pTES->CursorPos, -1, flags); - UnlockMutex (GraphicsLock); } else { @@ -1192,9 +1178,7 @@ DoStarSearch (MENU_STATE *pMS) if (!pss) return FALSE; - LockMutex (GraphicsLock); DrawSISMessageEx ("", 0, 0, DSME_SETFR); - UnlockMutex (GraphicsLock); pss->pMS = pMS; pss->LastChangeTime = 0; @@ -1216,9 +1200,7 @@ DoStarSearch (MENU_STATE *pMS) SetDefaultMenuRepeatDelay (); success = DoTextEntry (&tes); - LockMutex (GraphicsLock); DrawSISMessageEx (pss->Text, -1, -1, DSME_CLEARFR); - UnlockMutex (GraphicsLock); HFree (pss); @@ -1241,7 +1223,7 @@ DoMoveCursor (MENU_STATE *pMS) pMS->Initialized = TRUE; pMS->InputFunc = DoMoveCursor; - if (LOBYTE (GLOBAL (CurrentActivity)) != IN_HYPERSPACE) + if (!inHQSpace ()) universe = CurStarDescPtr->star_pt; else { @@ -1268,7 +1250,7 @@ DoMoveCursor (MENU_STATE *pMS) { PlayMenuSound (MENU_SOUND_INVOKED); - if (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE) + if (inHQSpace ()) { // Move to the new location immediately. doInstantMove (); @@ -1597,7 +1579,7 @@ StarMap (void) mapOrigin.y = MAX_Y_UNIVERSE >> 1; StarMapFrame = SetAbsFrameIndex (MiscDataFrame, 48); - if (LOBYTE (GLOBAL (CurrentActivity)) != IN_HYPERSPACE) + if (!inHQSpace ()) universe = CurStarDescPtr->star_pt; else { @@ -1616,8 +1598,6 @@ StarMap (void) if (GET_GAME_STATE (ARILOU_SPACE_SIDE) <= 1) UpdateMap (); - LockMutex (GraphicsLock); - DrawStarMap (0, (RECT*)-1); transition_pending = FALSE; @@ -1629,7 +1609,6 @@ StarMap (void) DrawCursor (UNIVERSE_TO_DISPX (cursorLoc.x), UNIVERSE_TO_DISPY (cursorLoc.y)); UnbatchGraphics (); - UnlockMutex (GraphicsLock); SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE); SetMenuRepeatDelay (MIN_ACCEL_DELAY, MAX_ACCEL_DELAY, STEP_ACCEL_DELAY, @@ -1638,11 +1617,9 @@ StarMap (void) SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT); SetDefaultMenuRepeatDelay (); - LockMutex (GraphicsLock); DrawHyperCoords (universe); DrawSISMessage (NULL); DrawStatusMessage (NULL); - UnlockMutex (GraphicsLock); if (GLOBAL (autopilot.x) == universe.x && GLOBAL (autopilot.y) == universe.y) diff --git a/sc2/src/uqm/planets/report.c b/sc2/src/uqm/planets/report.c index 1b2a4db4e..5defbe76e 100644 --- a/sc2/src/uqm/planets/report.c +++ b/sc2/src/uqm/planets/report.c @@ -102,7 +102,6 @@ MakeReport (SOUND ReadOutSounds, UNICODE *pStr, COUNT StrLen) t.pStr = pStr; Sleepy = TRUE; - UnlockMutex (GraphicsLock); FlushInput (); // XXX: this is a pretty ugly goto @@ -163,9 +162,7 @@ MakeReport (SOUND ReadOutSounds, UNICODE *pStr, COUNT StrLen) font_DrawText (&t); else { - LockMutex (GraphicsLock); font_DrawText (&t); - UnlockMutex (GraphicsLock); PlaySound (ReadOutSounds, NotPositional (), NULL, GAME_SOUND_PRIORITY); @@ -183,7 +180,6 @@ MakeReport (SOUND ReadOutSounds, UNICODE *pStr, COUNT StrLen) { Sleepy = FALSE; // We draw the whole thing at once after this - LockMutex (GraphicsLock); BatchGraphics (); } } @@ -204,7 +200,6 @@ MakeReport (SOUND ReadOutSounds, UNICODE *pStr, COUNT StrLen) if (!Sleepy) { UnbatchGraphics (); - UnlockMutex (GraphicsLock); } if (!WaitForAnyButton (TRUE, WAIT_INFINITE, FALSE)) @@ -216,18 +211,14 @@ InitPageCell: row_cells = 0; if (StrLen) { - LockMutex (GraphicsLock); if (!Sleepy) BatchGraphics (); ClearReportArea(); SetContextForeGroundColor ( BUILD_COLOR (MAKE_RGB15 (0x00, 0x1F, 0x00), 0xFF)); - if (Sleepy) - UnlockMutex (GraphicsLock); } } } - LockMutex (GraphicsLock); } void @@ -274,9 +265,7 @@ DoDiscoveryReport (SOUND ReadOutSounds) DestroyDrawable (ReleaseDrawable (saveStamp.frame)); - UnlockMutex (GraphicsLock); WaitForNoInput (WAIT_INFINITE, TRUE); - LockMutex (GraphicsLock); } diff --git a/sc2/src/uqm/planets/roster.c b/sc2/src/uqm/planets/roster.c index cd289e4b2..663ac2836 100644 --- a/sc2/src/uqm/planets/roster.c +++ b/sc2/src/uqm/planets/roster.c @@ -198,7 +198,9 @@ DeltaSupportCrew (ROSTER_STATE *rosterState, SIZE crew_delta) StarShipPtr->crew_level, TemplatePtr->crew_level); + PreUpdateFlashRect (); DrawStatusMessage (buf); + PostUpdateFlashRect (); DeltaSISGauges (-crew_delta, 0, 0); if (crew_delta) { @@ -252,7 +254,6 @@ DoModifyRoster (MENU_STATE *pMS) } else if (select || cancel) { - LockMutex (GraphicsLock); rosterState->modifyingCrew ^= true; if (!rosterState->modifyingCrew) { @@ -266,7 +267,6 @@ DoModifyRoster (MENU_STATE *pMS) SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, MENU_SOUND_SELECT | MENU_SOUND_CANCEL); } - UnlockMutex (GraphicsLock); } else if (rosterState->modifyingCrew) { @@ -290,9 +290,7 @@ DoModifyRoster (MENU_STATE *pMS) if (delta != 0) { - LockMutex (GraphicsLock); failed = !DeltaSupportCrew (rosterState, delta); - UnlockMutex (GraphicsLock); } if (failed) @@ -348,7 +346,6 @@ DoModifyRoster (MENU_STATE *pMS) --NewState; } - LockMutex (GraphicsLock); BatchGraphics (); SetContext (StatusContext); @@ -364,7 +361,6 @@ DoModifyRoster (MENU_STATE *pMS) flashSupportShip (rosterState); UnbatchGraphics (); - UnlockMutex (GraphicsLock); } SleepThread (ONE_SECOND / 30); @@ -414,22 +410,18 @@ RosterMenu (void) qsort (RosterState.shipPos, RosterState.count, sizeof (RosterState.shipPos[0]), compShipPos); - LockMutex (GraphicsLock); SetContext (StatusContext); selectSupportShip (&RosterState, MenuState.CurState); - UnlockMutex (GraphicsLock); SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT); MenuState.InputFunc = DoModifyRoster; DoInput (&MenuState, TRUE); - LockMutex (GraphicsLock); SetContext (StatusContext); // unselect the last ship drawSupportShip (&RosterState, FALSE); DrawStatusMessage (NULL); - UnlockMutex (GraphicsLock); return TRUE; } diff --git a/sc2/src/uqm/planets/scan.c b/sc2/src/uqm/planets/scan.c index f3c4f8656..ed063337b 100644 --- a/sc2/src/uqm/planets/scan.c +++ b/sc2/src/uqm/planets/scan.c @@ -85,15 +85,12 @@ RepairBackRect (RECT *pRect) static void EraseCoarseScan (void) { - LockMutex (GraphicsLock); SetContext (PlanetContext); BatchGraphics (); DrawStarBackGround (); DrawDefaultPlanetSphere (); UnbatchGraphics (); - - UnlockMutex (GraphicsLock); } static void @@ -160,7 +157,6 @@ PrintCoarseScanPC (void) GetPlanetTitle (buf, sizeof (buf)); - LockMutex (GraphicsLock); SetContext (PlanetContext); t.align = ALIGN_CENTER; @@ -174,7 +170,6 @@ PrintCoarseScanPC (void) font_DrawText (&t); SetContextFont (TinyFont); - UnlockMutex (GraphicsLock); #define LEFT_SIDE_BASELINE_X_PC 5 #define RIGHT_SIDE_BASELINE_X_PC (SIS_SCREEN_WIDTH - 75) @@ -183,7 +178,6 @@ PrintCoarseScanPC (void) t.baseline.y = SCAN_BASELINE_Y_PC; t.align = ALIGN_LEFT; - LockMutex (GraphicsLock); PrintScanTitlePC (&t, &r, GAME_STRING (ORBITSCAN_STRING_BASE), LEFT_SIDE_BASELINE_X_PC); // "Orbit: " val = ((pSolarSysState->SysInfo.PlanetInfo.PlanetToSunDist * 100L @@ -194,9 +188,7 @@ PrintCoarseScanPC (void) t.CharCount = (COUNT)~0; font_DrawText (&t); t.baseline.y += SCAN_LEADING_PC; - UnlockMutex (GraphicsLock); - LockMutex (GraphicsLock); PrintScanTitlePC (&t, &r, GAME_STRING (ORBITSCAN_STRING_BASE + 2), LEFT_SIDE_BASELINE_X_PC); // "Atmo: " if (pSolarSysState->SysInfo.PlanetInfo.AtmoDensity == GAS_GIANT_ATMOSPHERE) @@ -216,9 +208,7 @@ PrintCoarseScanPC (void) t.CharCount = (COUNT)~0; font_DrawText (&t); t.baseline.y += SCAN_LEADING_PC; - UnlockMutex (GraphicsLock); - LockMutex (GraphicsLock); PrintScanTitlePC (&t, &r, GAME_STRING (ORBITSCAN_STRING_BASE + 6), LEFT_SIDE_BASELINE_X_PC); // "Temp: " sprintf (buf, "%d" STR_DEGREE_SIGN " c", @@ -227,9 +217,7 @@ PrintCoarseScanPC (void) t.CharCount = (COUNT)~0; font_DrawText (&t); t.baseline.y += SCAN_LEADING_PC; - UnlockMutex (GraphicsLock); - LockMutex (GraphicsLock); PrintScanTitlePC (&t, &r, GAME_STRING (ORBITSCAN_STRING_BASE + 7), LEFT_SIDE_BASELINE_X_PC); // "Weather: " if (pSolarSysState->SysInfo.PlanetInfo.AtmoDensity == 0) @@ -244,9 +232,7 @@ PrintCoarseScanPC (void) t.CharCount = (COUNT)~0; font_DrawText (&t); t.baseline.y += SCAN_LEADING_PC; - UnlockMutex (GraphicsLock); - LockMutex (GraphicsLock); PrintScanTitlePC (&t, &r, GAME_STRING (ORBITSCAN_STRING_BASE + 10), LEFT_SIDE_BASELINE_X_PC); // "Tectonics: " if (PLANSIZE (pSolarSysState->SysInfo.PlanetInfo.PlanDataPtr->Type) == @@ -261,11 +247,9 @@ PrintCoarseScanPC (void) } t.CharCount = (COUNT)~0; font_DrawText (&t); - UnlockMutex (GraphicsLock); t.baseline.y = SCAN_BASELINE_Y_PC; - LockMutex (GraphicsLock); PrintScanTitlePC (&t, &r, GAME_STRING (ORBITSCAN_STRING_BASE + 11), RIGHT_SIDE_BASELINE_X_PC); // "Mass: " val = pSolarSysState->SysInfo.PlanetInfo.PlanetRadius; @@ -280,9 +264,7 @@ PrintCoarseScanPC (void) t.CharCount = (COUNT)~0; font_DrawText (&t); t.baseline.y += SCAN_LEADING_PC; - UnlockMutex (GraphicsLock); - LockMutex (GraphicsLock); PrintScanTitlePC (&t, &r, GAME_STRING (ORBITSCAN_STRING_BASE + 13), RIGHT_SIDE_BASELINE_X_PC); // "Radius: " val = pSolarSysState->SysInfo.PlanetInfo.PlanetRadius; @@ -292,9 +274,7 @@ PrintCoarseScanPC (void) t.CharCount = (COUNT)~0; font_DrawText (&t); t.baseline.y += SCAN_LEADING_PC; - UnlockMutex (GraphicsLock); - LockMutex (GraphicsLock); PrintScanTitlePC (&t, &r, GAME_STRING (ORBITSCAN_STRING_BASE + 14), RIGHT_SIDE_BASELINE_X_PC); // "Gravity: " val = pSolarSysState->SysInfo.PlanetInfo.SurfaceGravity; @@ -306,9 +286,7 @@ PrintCoarseScanPC (void) t.CharCount = (COUNT)~0; font_DrawText (&t); t.baseline.y += SCAN_LEADING_PC; - UnlockMutex (GraphicsLock); - LockMutex (GraphicsLock); PrintScanTitlePC (&t, &r, GAME_STRING (ORBITSCAN_STRING_BASE + 16), RIGHT_SIDE_BASELINE_X_PC); // "Day: " val = (SDWORD)pSolarSysState->SysInfo.PlanetInfo.RotationPeriod @@ -319,9 +297,7 @@ PrintCoarseScanPC (void) t.CharCount = (COUNT)~0; font_DrawText (&t); t.baseline.y += SCAN_LEADING_PC; - UnlockMutex (GraphicsLock); - LockMutex (GraphicsLock); PrintScanTitlePC (&t, &r, GAME_STRING (ORBITSCAN_STRING_BASE + 18), RIGHT_SIDE_BASELINE_X_PC); // "Tilt: " val = pSolarSysState->SysInfo.PlanetInfo.AxialTilt; @@ -331,7 +307,6 @@ PrintCoarseScanPC (void) sprintf (buf, "%d" STR_DEGREE_SIGN, val); t.CharCount = (COUNT)~0; font_DrawText (&t); - UnlockMutex (GraphicsLock); } static void @@ -345,7 +320,6 @@ PrintCoarseScan3DO (void) GetPlanetTitle (buf, sizeof (buf)); - LockMutex (GraphicsLock); SetContext (PlanetContext); t.align = ALIGN_CENTER; @@ -363,8 +337,6 @@ PrintCoarseScan3DO (void) s.frame = SetAbsFrameIndex (SpaceJunkFrame, 20); DrawStamp (&s); - UnlockMutex (GraphicsLock); - #define LEFT_SIDE_BASELINE_X (27 + (16 - SAFE_X)) #define RIGHT_SIDE_BASELINE_X (SIS_SCREEN_WIDTH - LEFT_SIDE_BASELINE_X) #define SCAN_BASELINE_Y 25 @@ -373,7 +345,6 @@ PrintCoarseScan3DO (void) t.baseline.y = SCAN_BASELINE_Y; t.align = ALIGN_LEFT; - LockMutex (GraphicsLock); t.pStr = buf; val = ((pSolarSysState->SysInfo.PlanetInfo.PlanetToSunDist * 100L + (EARTH_RADIUS >> 1)) / EARTH_RADIUS); @@ -381,9 +352,7 @@ PrintCoarseScan3DO (void) t.CharCount = (COUNT)~0; font_DrawText (&t); t.baseline.y += SCAN_LEADING; - UnlockMutex (GraphicsLock); - LockMutex (GraphicsLock); t.pStr = buf; if (pSolarSysState->SysInfo.PlanetInfo.AtmoDensity == GAS_GIANT_ATMOSPHERE) strcpy (buf, STR_INFINITY_SIGN); @@ -396,27 +365,21 @@ PrintCoarseScan3DO (void) t.CharCount = (COUNT)~0; font_DrawText (&t); t.baseline.y += SCAN_LEADING; - UnlockMutex (GraphicsLock); - LockMutex (GraphicsLock); t.pStr = buf; sprintf (buf, "%d" STR_DEGREE_SIGN, pSolarSysState->SysInfo.PlanetInfo.SurfaceTemperature); t.CharCount = (COUNT)~0; font_DrawText (&t); t.baseline.y += SCAN_LEADING; - UnlockMutex (GraphicsLock); - LockMutex (GraphicsLock); t.pStr = buf; sprintf (buf, "<%u>", pSolarSysState->SysInfo.PlanetInfo.AtmoDensity == 0 ? 0 : (pSolarSysState->SysInfo.PlanetInfo.Weather + 1)); t.CharCount = (COUNT)~0; font_DrawText (&t); t.baseline.y += SCAN_LEADING; - UnlockMutex (GraphicsLock); - LockMutex (GraphicsLock); t.pStr = buf; sprintf (buf, "<%u>", PLANSIZE ( @@ -425,13 +388,11 @@ PrintCoarseScan3DO (void) ? 0 : (pSolarSysState->SysInfo.PlanetInfo.Tectonics + 1)); t.CharCount = (COUNT)~0; font_DrawText (&t); - UnlockMutex (GraphicsLock); t.baseline.x = RIGHT_SIDE_BASELINE_X; t.baseline.y = SCAN_BASELINE_Y; t.align = ALIGN_RIGHT; - LockMutex (GraphicsLock); t.pStr = buf; val = pSolarSysState->SysInfo.PlanetInfo.PlanetRadius; val = ((DWORD) val * (DWORD) val * (DWORD) val / 100L @@ -443,9 +404,7 @@ PrintCoarseScan3DO (void) t.CharCount = (COUNT)~0; font_DrawText (&t); t.baseline.y += SCAN_LEADING; - UnlockMutex (GraphicsLock); - LockMutex (GraphicsLock); t.pStr = buf; val = pSolarSysState->SysInfo.PlanetInfo.PlanetRadius; MakeScanValue (buf, val, STR_EARTH_SIGN); @@ -453,9 +412,7 @@ PrintCoarseScan3DO (void) t.CharCount = (COUNT)~0; font_DrawText (&t); t.baseline.y += SCAN_LEADING; - UnlockMutex (GraphicsLock); - LockMutex (GraphicsLock); t.pStr = buf; val = pSolarSysState->SysInfo.PlanetInfo.SurfaceGravity; if (val == 0) @@ -464,9 +421,7 @@ PrintCoarseScan3DO (void) t.CharCount = (COUNT)~0; font_DrawText (&t); t.baseline.y += SCAN_LEADING; - UnlockMutex (GraphicsLock); - LockMutex (GraphicsLock); t.pStr = buf; val = pSolarSysState->SysInfo.PlanetInfo.AxialTilt; if (val < 0) @@ -475,16 +430,13 @@ PrintCoarseScan3DO (void) t.CharCount = (COUNT)~0; font_DrawText (&t); t.baseline.y += SCAN_LEADING; - UnlockMutex (GraphicsLock); - LockMutex (GraphicsLock); t.pStr = buf; val = (SDWORD)pSolarSysState->SysInfo.PlanetInfo.RotationPeriod * 10 / 24; MakeScanValue (buf, val, STR_EARTH_SIGN); t.CharCount = (COUNT)~0; font_DrawText (&t); - UnlockMutex (GraphicsLock); } static void @@ -667,11 +619,9 @@ DispatchLander (void) // Deactivate planet rotation callback oldCallback = SetInputCallback (NULL); - LockMutex (GraphicsLock); DeltaSISGauges (0, -landingFuel, 0); SetContext (ScanContext); drawPlanetCursor (FALSE); - UnlockMutex (GraphicsLock); PlanetSide (planetLoc); if (GLOBAL (CurrentActivity) & CHECK_ABORT) @@ -749,7 +699,6 @@ DoPickPlanetSide (MENU_STATE *pMS) if (CurrentInputState.menu[KEY_MENU_DOWN]) dy = 1; - LockMutex (GraphicsLock); BatchGraphics (); dx = dx << MAG_SHIFT; @@ -777,7 +726,6 @@ DoPickPlanetSide (MENU_STATE *pMS) flashPlanetLocation (); UnbatchGraphics (); - UnlockMutex (GraphicsLock); SleepThreadUntil (TimeIn + ONE_SECOND / 40); } @@ -799,9 +747,7 @@ drawLandingFuelUsage (COUNT fuel) static void eraseLandingFuelUsage (void) { - LockMutex (GraphicsLock); DrawStatusMessage (NULL); - UnlockMutex (GraphicsLock); } static BOOLEAN @@ -815,7 +761,6 @@ PickPlanetSide (void) memset (&MenuState, 0, sizeof MenuState); MenuState.privData = &PickState; - LockMutex (GraphicsLock); ClearSISRect (CLEAR_SIS_RADAR); SetContext (ScanContext); BatchGraphics (); @@ -827,7 +772,6 @@ PickPlanetSide (void) // Set the current flash location setPlanetCursorLoc (planetLoc); savePlanetLocationImage (); - UnlockMutex (GraphicsLock); InitLander (0); @@ -844,9 +788,7 @@ PickPlanetSide (void) } else { // player bailed out - LockMutex (GraphicsLock); restorePlanetLocationImage (); - UnlockMutex (GraphicsLock); } SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT); @@ -935,20 +877,20 @@ DrawScannedStuff (COUNT y, COUNT scan) } COUNT -callGenerateForScanType (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT node, BYTE scanType) +callGenerateForScanType (const SOLARSYS_STATE *solarSys, + const PLANET_DESC *world, COUNT node, BYTE scanType, NODE_INFO *info) { switch (scanType) { case MINERAL_SCAN: return (*solarSys->genFuncs->generateMinerals) ( - solarSys, world, node); + solarSys, world, node, info); case ENERGY_SCAN: return (*solarSys->genFuncs->generateEnergy) ( - solarSys, world, node); + solarSys, world, node, info); case BIOLOGICAL_SCAN: return (*solarSys->genFuncs->generateLife) ( - solarSys, world, node); + solarSys, world, node, info); } assert (false); @@ -1026,7 +968,6 @@ ScanPlanet (COUNT scanType) t.pStr = GAME_STRING (SCAN_STRING_BASE + scan); - LockMutex (GraphicsLock); SetContext (PlanetContext); r.corner.x = 0; r.corner.y = t.baseline.y - 10; @@ -1041,14 +982,11 @@ ScanPlanet (COUNT scanType) font_DrawText (&t); SetContext (ScanContext); - UnlockMutex (GraphicsLock); // Draw a virgin surface - LockMutex (GraphicsLock); BatchGraphics (); DrawPlanet (0, BLACK_COLOR); UnbatchGraphics (); - UnlockMutex (GraphicsLock); tintColor = tintColors[scan]; @@ -1060,7 +998,6 @@ ScanPlanet (COUNT scanType) if (WaitForAnyButtonUntil (TRUE, TimeOut, FALSE)) break; - LockMutex (GraphicsLock); BatchGraphics (); DrawPlanet (i, tintColor); DrawScannedStuff (i, scan); @@ -1068,21 +1005,17 @@ ScanPlanet (COUNT scanType) #ifdef SPIN_ON_SCAN RotatePlanetSphere (TRUE); #endif - UnlockMutex (GraphicsLock); } if (i < SCAN_LINES) { // Aborted by a keypress; draw in finished state - LockMutex (GraphicsLock); BatchGraphics (); DrawPlanet (SCAN_LINES - 1, tintColor); DrawScannedStuff (SCAN_LINES - 1, scan); UnbatchGraphics (); - UnlockMutex (GraphicsLock); } } - LockMutex (GraphicsLock); SetContext (PlanetContext); RepairBackRect (&r); @@ -1093,7 +1026,6 @@ ScanPlanet (COUNT scanType) DrawScannedObjects (FALSE); } - UnlockMutex (GraphicsLock); FlushInput (); } @@ -1135,17 +1067,13 @@ DoScan (MENU_STATE *pMS) return TRUE; } - LockMutex (GraphicsLock); SetFlashRect (NULL); - UnlockMutex (GraphicsLock); if (!PickPlanetSide ()) return FALSE; DrawMenuStateStrings (PM_MIN_SCAN, pMS->CurState); - LockMutex (GraphicsLock); SetFlashRect (SFR_MENU_3DO); - UnlockMutex (GraphicsLock); return TRUE; } @@ -1235,9 +1163,7 @@ ScanSystem (void) memset (&MenuState, 0, sizeof MenuState); - LockMutex (GraphicsLock); GetScanContext (NULL); - UnlockMutex (GraphicsLock); if (optWhichMenu == OPT_3DO && ((pSolarSysState->pOrbitalDesc->data_index & PLANET_SHIELDED) @@ -1252,17 +1178,13 @@ ScanSystem (void) planetLoc.x = (MAP_WIDTH >> 1) << MAG_SHIFT; planetLoc.y = (MAP_HEIGHT >> 1) << MAG_SHIFT; - LockMutex (GraphicsLock); initPlanetLocationImage (); SetContext (ScanContext); DrawScannedObjects (FALSE); - UnlockMutex (GraphicsLock); } DrawMenuStateStrings (PM_MIN_SCAN, MenuState.CurState); - LockMutex (GraphicsLock); SetFlashRect (SFR_MENU_3DO); - UnlockMutex (GraphicsLock); if (optWhichCoarseScan == OPT_PC) PrintCoarseScanPC (); @@ -1274,18 +1196,14 @@ ScanSystem (void) MenuState.InputFunc = DoScan; DoInput (&MenuState, FALSE); - LockMutex (GraphicsLock); SetFlashRect (NULL); - UnlockMutex (GraphicsLock); // cleanup scan graphics - LockMutex (GraphicsLock); BatchGraphics (); SetContext (ScanContext); DrawPlanet (0, BLACK_COLOR); EraseCoarseScan (); UnbatchGraphics (); - UnlockMutex (GraphicsLock); DestroyDrawable (ReleaseDrawable (eraseFrame)); eraseFrame = NULL; @@ -1293,17 +1211,16 @@ ScanSystem (void) static void generateBioNode (SOLARSYS_STATE *system, ELEMENT *NodeElementPtr, - BYTE *life_init_tab) + BYTE *life_init_tab, COUNT creatureType) { COUNT i; - COUNT creatureType; - - creatureType = system->SysInfo.PlanetInfo.CurType; + // NOTE: TFB_Random() calls here are NOT part of the deterministic planet + // generation PRNG flow. if (CreatureData[creatureType].Attributes & SPEED_MASK) { // Place moving creatures at a random location. - i = (COUNT)TFB_Random (); + i = TFB_Random (); NodeElementPtr->current.location.x = (LOBYTE (i) % (MAP_WIDTH - (8 << 1))) + 8; NodeElementPtr->current.location.y = @@ -1359,12 +1276,13 @@ GeneratePlanetSide (void) NUM_SCANDOT_TRANSITIONS * (scan - ENERGY_SCAN)); num_nodes = callGenerateForScanType (pSolarSysState, - pSolarSysState->pOrbitalDesc, ~0, scan); + pSolarSysState->pOrbitalDesc, GENERATE_ALL, scan, NULL); while (num_nodes--) { HELEMENT hNodeElement; ELEMENT *NodeElementPtr; + NODE_INFO info; if (isNodeRetrieved (&pSolarSysState->SysInfo.PlanetInfo, scan, num_nodes)) @@ -1378,30 +1296,24 @@ GeneratePlanetSide (void) callGenerateForScanType (pSolarSysState, pSolarSysState->pOrbitalDesc, num_nodes, - scan); + scan, &info); NodeElementPtr->scan_node = MAKE_WORD (scan, num_nodes + 1); NodeElementPtr->playerNr = PS_NON_PLAYER; - NodeElementPtr->current.location.x = - pSolarSysState->SysInfo.PlanetInfo.CurPt.x; - NodeElementPtr->current.location.y = - pSolarSysState->SysInfo.PlanetInfo.CurPt.y; + NodeElementPtr->current.location.x = info.loc_pt.x; + NodeElementPtr->current.location.y = info.loc_pt.y; SetPrimType (&DisplayArray[NodeElementPtr->PrimIndex], STAMP_PRIM); if (scan == MINERAL_SCAN) { - COUNT EType; - - EType = pSolarSysState->SysInfo.PlanetInfo.CurType; - NodeElementPtr->turn_wait = (BYTE)EType; - NodeElementPtr->mass_points = HIBYTE ( - pSolarSysState->SysInfo.PlanetInfo.CurDensity); + NodeElementPtr->turn_wait = info.type; + NodeElementPtr->mass_points = HIBYTE (info.density); NodeElementPtr->current.image.frame = SetAbsFrameIndex ( MiscDataFrame, (NUM_SCANDOT_TRANSITIONS * 2) - + ElementCategory (EType) * 5); + + ElementCategory (info.type) * 5); NodeElementPtr->next.image.frame = SetRelFrameIndex ( - NodeElementPtr->current.image.frame, LOBYTE ( - pSolarSysState->SysInfo.PlanetInfo.CurDensity) + 1); + NodeElementPtr->current.image.frame, + LOBYTE (info.density) + 1); DisplayArray[NodeElementPtr->PrimIndex].Object.Stamp.frame = IncFrameIndex (NodeElementPtr->next.image.frame); } @@ -1421,7 +1333,7 @@ GeneratePlanetSide (void) else /* (scan == BIOLOGICAL_SCAN) */ { generateBioNode (pSolarSysState, NodeElementPtr, - life_init_tab); + life_init_tab, info.type); } } diff --git a/sc2/src/uqm/planets/scan.h b/sc2/src/uqm/planets/scan.h index b8e683da2..f66fb0e9c 100644 --- a/sc2/src/uqm/planets/scan.h +++ b/sc2/src/uqm/planets/scan.h @@ -26,6 +26,9 @@ typedef struct scan_block SCAN_BLOCK; #include "libs/gfxlib.h" #include "planets.h" +#if defined(__cplusplus) +extern "C" { +#endif struct scan_desc { @@ -47,8 +50,8 @@ extern void ScanSystem (void); extern void RepairBackRect (RECT *pRect); extern void GeneratePlanetSide (void); -extern COUNT callGenerateForScanType (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT node, BYTE scanType); +extern COUNT callGenerateForScanType (const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT node, BYTE scanType, NODE_INFO *); // Returns true if the node should be removed from the surface extern bool callPickupForScanType (SOLARSYS_STATE *solarSys, PLANET_DESC *world, COUNT node, BYTE scanType); @@ -62,5 +65,8 @@ COUNT countNodesRetrieved (PLANET_INFO *planetInfo, BYTE scanType); void setNodeRetrieved (PLANET_INFO *planetInfo, BYTE scanType, BYTE nodeNr); void setNodeNotRetrieved (PLANET_INFO *planetInfo, BYTE scanType, BYTE nodeNr); -#endif /* UQM_PLANETS_SCAN_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_PLANETS_SCAN_H_ */ diff --git a/sc2/src/uqm/planets/solarsys.c b/sc2/src/uqm/planets/solarsys.c index 21484081d..677b9dfdb 100644 --- a/sc2/src/uqm/planets/solarsys.c +++ b/sc2/src/uqm/planets/solarsys.c @@ -16,12 +16,13 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include "solarsys.h" #include "lander.h" #include "../colors.h" #include "../controls.h" #include "../menustat.h" // for DrawMenuStateStrings() -#include "../encount.h" +#include "../starmap.h" #include "../races.h" #include "../gamestr.h" #include "../gendef.h" @@ -94,6 +95,7 @@ static FRAME SolarSysFrame; static RECT scaleRect; // system zooms in when the flagship enters this rect +RandomContext *SysGenRNG; #define DISPLAY_TO_LOC (DISPLAY_FACTOR >> 1) @@ -210,15 +212,15 @@ playerInInnerSystem (void) return pSolarSysState->pBaseDesc != pSolarSysState->PlanetDesc; } +// Sets the SysGenRNG to the required state first. static void GenerateMoons (SOLARSYS_STATE *system, PLANET_DESC *planet) { COUNT i; COUNT facing; PLANET_DESC *pMoonDesc; - DWORD old_seed; - old_seed = TFB_SeedRandom (planet->rand_seed); + RandomContext_SeedRandom (SysGenRNG, planet->rand_seed); (*system->genFuncs->generateName) (system, planet); (*system->genFuncs->generateMoons) (system, planet); @@ -234,8 +236,6 @@ GenerateMoons (SOLARSYS_STATE *system, PLANET_DESC *planet) pMoonDesc->temp_color = planet->temp_color; } - - TFB_SeedRandom (old_seed); } void @@ -255,6 +255,9 @@ FreeIPData (void) SpaceJunkFrame = 0; DestroyMusic (SpaceMusic); SpaceMusic = 0; + + RandomContext_Delete (SysGenRNG); + SysGenRNG = NULL; } void @@ -274,6 +277,11 @@ LoadIPData (void) SpaceMusic = LoadMusic (IP_MUSIC); } + + if (!SysGenRNG) + { + SysGenRNG = RandomContext_New (); + } } @@ -349,11 +357,10 @@ initSolarSysSISCharacteristics (void) } } -static DWORD -seedRandomForSolarSys (void) +DWORD +GetRandomSeedForStar (const STAR_DESC *star) { - return TFB_SeedRandom (MAKE_DWORD (CurStarDescPtr->star_pt.x, - CurStarDescPtr->star_pt.y)); + return MAKE_DWORD (star->star_pt.x, star->star_pt.y); } // Returns an orbital PLANET_DESC when player is in orbit @@ -363,7 +370,6 @@ LoadSolarSys (void) COUNT i; PLANET_DESC *orbital = NULL; PLANET_DESC *pCurDesc; - DWORD old_seed; #define NUM_TEMP_RANGES 5 static const Color temp_color_array[NUM_TEMP_RANGES] = { @@ -374,13 +380,13 @@ LoadSolarSys (void) BUILD_COLOR (MAKE_RGB15_INIT (0x0F, 0x08, 0x00), 0x75), }; - old_seed = seedRandomForSolarSys (); + RandomContext_SeedRandom (SysGenRNG, GetRandomSeedForStar (CurStarDescPtr)); SunFrame = SetAbsFrameIndex (SunFrame, STAR_TYPE (CurStarDescPtr->Type)); pCurDesc = &pSolarSysState->SunDesc[0]; pCurDesc->pPrevDesc = 0; - pCurDesc->rand_seed = TFB_Random (); + pCurDesc->rand_seed = RandomContext_Random (SysGenRNG); pCurDesc->data_index = STAR_TYPE (CurStarDescPtr->Type); pCurDesc->location.x = 0; @@ -466,9 +472,6 @@ LoadSolarSys (void) GLOBAL (ShipStamp.frame) = SetAbsFrameIndex (SISIPFrame, i - 1); } - // Restore RNG state: - TFB_SeedRandom (old_seed); - return orbital; } @@ -527,7 +530,7 @@ getCollisionFrame (PLANET_DESC *planet, COUNT WaitPlanet) // Returns the planet with which the flagship is colliding static PLANET_DESC * -CheckIntersect (BOOLEAN just_checking) +CheckIntersect (void) { COUNT i; PLANET_DESC *pCurDesc; @@ -618,16 +621,9 @@ CheckIntersect (BOOLEAN just_checking) continue; } - if (playerInInnerSystem ()) - { // Collision in the inner system (starts orbital) - pSolarSysState->WaitIntersect = NewWaitPlanet; - } - else - { // Going into an inner system - // So there is now no existing collision - if (!just_checking) - pSolarSysState->WaitIntersect = 0; - } + // Collision with a new planet/moon. This may cause a transition + // to an inner system or start an orbital view. + pSolarSysState->WaitIntersect = NewWaitPlanet; return pCurDesc; } } @@ -942,7 +938,7 @@ leaveInnerSystem (PLANET_DESC *planet) // See if we also intersect with another planet, and if we do, // disable collisions comletely until we stop intersecting // with any planet at all. - CheckIntersect (TRUE); + CheckIntersect (); if (pSolarSysState->WaitIntersect != outerPlanetWait) pSolarSysState->WaitIntersect = (COUNT)~0; } @@ -998,7 +994,7 @@ CheckShipLocation (SIZE *newRadius) if (GLOBAL (autopilot.x) == ~0 && GLOBAL (autopilot.y) == ~0) { // Not on autopilot -- may collide with a planet - PLANET_DESC *planet = CheckIntersect (FALSE); + PLANET_DESC *planet = CheckIntersect (); if (planet) { // Collision with a planet if (playerInInnerSystem ()) @@ -1034,10 +1030,8 @@ DrawSystemTransition (BOOLEAN inner) static void TransitionSystemIn (void) { - LockMutex (GraphicsLock); SetContext (SpaceContext); DrawSystemTransition (playerInInnerSystem ()); - UnlockMutex (GraphicsLock); } static void @@ -1121,7 +1115,6 @@ IP_frame (void) BOOLEAN locChange; SIZE newRadius; - LockMutex (GraphicsLock); SetContext (SpaceContext); GameClockTick (); @@ -1152,7 +1145,6 @@ IP_frame (void) UnbatchGraphics (); } - UnlockMutex (GraphicsLock); } static BOOLEAN @@ -1241,7 +1233,12 @@ ResetSolarSys (void) DoMissions (); // Figure out and note which planet/moon we just left, if any - CheckIntersect (TRUE); + // This records any existing collision and prevents the ship + // from entering planets until a new collision occurs. + // TODO: this may need logic similar to one in leaveInnerSystem() + // for when the ship collides with more than one planet at + // the same time. While quite rare, it's still possible. + CheckIntersect (); pSolarSysState->InIpFlight = TRUE; @@ -1310,9 +1307,7 @@ EnterPlanetOrbit (void) ValidateInnerOrbits (); ResetSolarSys (); - LockMutex (GraphicsLock); RepairSISBorder (); - UnlockMutex (GraphicsLock); TransitionSystemIn (); } } @@ -1324,11 +1319,9 @@ InitSolarSys (void) BOOLEAN Reentry; PLANET_DESC *orbital; - LockMutex (GraphicsLock); LoadIPData (); LoadLanderData (); - UnlockMutex (GraphicsLock); Reentry = (GLOBAL (ShipFacing) != 0); if (!Reentry) @@ -1343,7 +1336,6 @@ InitSolarSys (void) MAX_ZOOM_RADIUS); } - LockMutex (GraphicsLock); StarsFrame = CreateStarBackGround (); @@ -1351,7 +1343,6 @@ InitSolarSys (void) SetContextFGFrame (Screen); SetContextBackGroundColor (BLACK_COLOR); - UnlockMutex (GraphicsLock); orbital = LoadSolarSys (); InnerSystem = CheckZoomLevel (); @@ -1379,7 +1370,6 @@ InitSolarSys (void) } else { // Draw the borders, the system (inner or outer) and fade/transition - LockMutex (GraphicsLock); SetContext (SpaceContext); SetTransitionSource (NULL); @@ -1417,8 +1407,6 @@ InitSolarSys (void) LastActivity &= ~CHECK_LOAD; } - - UnlockMutex (GraphicsLock); } } @@ -1657,11 +1645,11 @@ CreateStarBackGround (void) COUNT i, j; DWORD rand_val; STAMP s; - DWORD old_seed; CONTEXT oldContext; RECT clipRect; FRAME frame; + // Use SpaceContext to find out the dimensions of the background oldContext = SetContext (SpaceContext); GetContextClipRect (&clipRect); @@ -1675,7 +1663,7 @@ CreateStarBackGround (void) ClearDrawable (); - old_seed = seedRandomForSolarSys (); + RandomContext_SeedRandom (SysGenRNG, GetRandomSeedForStar (CurStarDescPtr)); #define NUM_DIM_PIECES 8 s.frame = SpaceJunkFrame; @@ -1684,7 +1672,7 @@ CreateStarBackGround (void) #define NUM_DIM_DRAWN 5 for (j = 0; j < NUM_DIM_DRAWN; ++j) { - rand_val = TFB_Random (); + rand_val = RandomContext_Random (SysGenRNG); s.origin.x = LOWORD (rand_val) % SIS_SCREEN_WIDTH; s.origin.y = HIWORD (rand_val) % SIS_SCREEN_HEIGHT; @@ -1698,7 +1686,7 @@ CreateStarBackGround (void) #define NUM_BRT_DRAWN 30 for (j = 0; j < NUM_BRT_DRAWN; ++j) { - rand_val = TFB_Random (); + rand_val = RandomContext_Random (SysGenRNG); s.origin.x = LOWORD (rand_val) % SIS_SCREEN_WIDTH; s.origin.y = HIWORD (rand_val) % SIS_SCREEN_HEIGHT; @@ -1707,8 +1695,6 @@ CreateStarBackGround (void) s.frame = IncFrameIndex (s.frame); } - TFB_SeedRandom (old_seed); - SetContext (oldContext); return frame; @@ -1929,9 +1915,7 @@ DoSolarSysMenu (MENU_STATE *pMS) if (!select) return TRUE; - LockMutex (GraphicsLock); SetFlashRect (NULL); - UnlockMutex (GraphicsLock); switch (pMS->CurState) { @@ -1972,9 +1956,7 @@ DoSolarSysMenu (MENU_STATE *pMS) pMS->CurState = NAVIGATION; DrawMenuStateStrings (PM_STARMAP, pMS->CurState); } - LockMutex (GraphicsLock); SetFlashRect (SFR_MENU_3DO); - UnlockMutex (GraphicsLock); } return TRUE; @@ -1997,10 +1979,8 @@ SolarSysMenu (void) MenuState.CurState = STARMAP; } - LockMutex (GraphicsLock); DrawStatusMessage (NULL); SetFlashRect (SFR_MENU_3DO); - UnlockMutex (GraphicsLock); SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT); MenuState.InputFunc = DoSolarSysMenu; diff --git a/sc2/src/uqm/planets/solarsys.h b/sc2/src/uqm/planets/solarsys.h new file mode 100644 index 000000000..0f86fdd74 --- /dev/null +++ b/sc2/src/uqm/planets/solarsys.h @@ -0,0 +1,34 @@ +//Copyright (C) 2011, Scott A. Colcord + +/* + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef SOLARSYS_H +#define SOLARSYS_H + +#if defined(__cplusplus) +extern "C" { +#endif + +extern void LoadIPData (void); +extern void FreeIPData (void); + +#if defined(__cplusplus) +} +#endif + +#endif /* SOLARSYS_H */ + diff --git a/sc2/src/uqm/planets/sundata.h b/sc2/src/uqm/planets/sundata.h index ceea9d4a5..6d7888e32 100644 --- a/sc2/src/uqm/planets/sundata.h +++ b/sc2/src/uqm/planets/sundata.h @@ -22,6 +22,9 @@ #include "plandata.h" #include "libs/compiler.h" +#if defined(__cplusplus) +extern "C" { +#endif /*------------------------------ Global Data ------------------------------ */ @@ -39,13 +42,19 @@ typedef struct PLANET_INFO PlanetInfo; } SYSTEM_INFO; + +#define GENERATE_ALL ((COUNT)~0) -extern DWORD GenerateMineralDeposits (SYSTEM_INFO *SysInfoPtr, - COUNT *pwhich_deposit); -extern DWORD GenerateLifeForms (SYSTEM_INFO *SysInfoPtr, COUNT *pwhich_life); -extern void GenerateRandomLocation (SYSTEM_INFO *); -extern DWORD GenerateRandomNodes (SYSTEM_INFO *, COUNT scan, COUNT numNodes, - COUNT type, COUNT *whichNode); +extern COUNT GenerateMineralDeposits (const SYSTEM_INFO *, COUNT whichDeposit, + NODE_INFO *info); +extern COUNT GenerateLifeForms (const SYSTEM_INFO *, COUNT whichLife, + NODE_INFO *info); +extern void GenerateRandomLocation (POINT *loc); +extern COUNT GenerateRandomNodes (const SYSTEM_INFO *, COUNT scan, COUNT numNodes, + COUNT type, COUNT whichNode, NODE_INFO *info); +// Generate lifeforms from a preset lifeTypes[] array +extern COUNT GeneratePresetLife (const SYSTEM_INFO *, + const SBYTE *lifeTypes, COUNT whichLife, NODE_INFO *info); #define DWARF_ELEMENT_DENSITY 1 #define GIANT_ELEMENT_DENSITY 3 @@ -53,10 +62,12 @@ extern DWORD GenerateRandomNodes (SYSTEM_INFO *, COUNT scan, COUNT numNodes, #define MAX_ELEMENT_DENSITY ((MAX_ELEMENT_UNITS * SUPERGIANT_ELEMENT_DENSITY) << 1) -extern DWORD DoPlanetaryAnalysis (SYSTEM_INFO *SysInfoPtr, +extern void DoPlanetaryAnalysis (SYSTEM_INFO *SysInfoPtr, PLANET_DESC *pPlanetDesc); -extern SYSTEM_INFO CurSysInfo; +#if defined(__cplusplus) +} +#endif #endif /* UQM_PLANETS_SUNDATA_H_ */ diff --git a/sc2/src/uqm/planets/surface.c b/sc2/src/uqm/planets/surface.c index 0fb50056b..79f9e7564 100644 --- a/sc2/src/uqm/planets/surface.c +++ b/sc2/src/uqm/planets/surface.c @@ -28,7 +28,8 @@ const BYTE *Elements; const PlanetFrame *PlanData; static COUNT -CalcMineralDeposits (SYSTEM_INFO *SysInfoPtr, COUNT which_deposit) +CalcMineralDeposits (const SYSTEM_INFO *SysInfoPtr, COUNT which_deposit, + NODE_INFO *info) { BYTE j; COUNT num_deposits; @@ -41,16 +42,16 @@ CalcMineralDeposits (SYSTEM_INFO *SysInfoPtr, COUNT which_deposit) { BYTE num_possible; - num_possible = (BYTE)((BYTE)TFB_Random () - % (DEPOSIT_QUANTITY (eptr->Density) + 1)); + num_possible = LOBYTE (RandomContext_Random (SysGenRNG)) + % (DEPOSIT_QUANTITY (eptr->Density) + 1); while (num_possible--) { #define MEDIUM_DEPOSIT_THRESHOLD 150 #define LARGE_DEPOSIT_THRESHOLD 225 - COUNT deposit_quality_fine, - deposit_quality_gross; + COUNT deposit_quality_fine; + COUNT deposit_quality_gross; - deposit_quality_fine = ((COUNT)TFB_Random () % 100) + deposit_quality_fine = (LOWORD (RandomContext_Random (SysGenRNG)) % 100) + ( DEPOSIT_QUALITY (eptr->Density) + SysInfoPtr->StarSize @@ -62,222 +63,189 @@ CalcMineralDeposits (SYSTEM_INFO *SysInfoPtr, COUNT which_deposit) else deposit_quality_gross = 2; - GenerateRandomLocation (SysInfoPtr); + GenerateRandomLocation (&info->loc_pt); - SysInfoPtr->PlanetInfo.CurDensity = - MAKE_WORD ( - deposit_quality_gross, deposit_quality_fine / 10 + 1 - ); - SysInfoPtr->PlanetInfo.CurType = eptr->ElementType; + info->density = MAKE_WORD ( + deposit_quality_gross, deposit_quality_fine / 10 + 1); + info->type = eptr->ElementType; #ifdef DEBUG_SURFACE log_add (log_Debug, "\t\t%d units of %Fs", - SysInfoPtr->PlanetInfo.CurDensity, + info->density, Elements[eptr->ElementType].name); #endif /* DEBUG_SURFACE */ if (num_deposits >= which_deposit || ++num_deposits == sizeof (DWORD) * 8) - goto ExitCalcMinerals; + { // reached the maximum or the requested node + return num_deposits; + } } ++eptr; } while (--j); -ExitCalcMinerals: - return (num_deposits); + return num_deposits; } -DWORD -GenerateMineralDeposits (SYSTEM_INFO *SysInfoPtr, COUNT *pwhich_deposit) +// Returns: +// for whichLife==~0 : the number of nodes generated +// for whichLife<32 : the index of the last node (no known usage exists) +// Sets the SysGenRNG to the required state first. +COUNT +GenerateMineralDeposits (const SYSTEM_INFO *SysInfoPtr, COUNT whichDeposit, + NODE_INFO *info) { - DWORD old_rand; - - old_rand = TFB_SeedRandom (SysInfoPtr->PlanetInfo.ScanSeed[MINERAL_SCAN]); - *pwhich_deposit = CalcMineralDeposits (SysInfoPtr, *pwhich_deposit); - return (TFB_SeedRandom (old_rand)); + NODE_INFO temp_info; + if (!info) // user not interested in info but we need space for it + info = &temp_info; + RandomContext_SeedRandom (SysGenRNG, + SysInfoPtr->PlanetInfo.ScanSeed[MINERAL_SCAN]); + return CalcMineralDeposits (SysInfoPtr, whichDeposit, info); } static COUNT -CalcLifeForms (SYSTEM_INFO *SysInfoPtr, COUNT which_life) +CalcLifeForms (const SYSTEM_INFO *SysInfoPtr, COUNT which_life, + NODE_INFO *info) { COUNT num_life_forms; num_life_forms = 0; - if (PLANSIZE (SysInfoPtr->PlanetInfo.PlanDataPtr->Type) == GAS_GIANT) - SysInfoPtr->PlanetInfo.LifeChance = -1; - else + if (PLANSIZE (SysInfoPtr->PlanetInfo.PlanDataPtr->Type) != GAS_GIANT) { #define MIN_LIFE_CHANCE 10 SIZE life_var; - life_var = 0; - - if (SysInfoPtr->PlanetInfo.SurfaceTemperature < -151) - life_var -= 300; - else if (SysInfoPtr->PlanetInfo.SurfaceTemperature < -51) - life_var -= 100; - else if (SysInfoPtr->PlanetInfo.SurfaceTemperature < 0) - life_var += 100; - else if (SysInfoPtr->PlanetInfo.SurfaceTemperature < 50) - life_var += 300; - else if (SysInfoPtr->PlanetInfo.SurfaceTemperature < 150) - life_var += 50; - else if (SysInfoPtr->PlanetInfo.SurfaceTemperature < 250) - life_var -= 100; - else if (SysInfoPtr->PlanetInfo.SurfaceTemperature < 500) - life_var -= 400; - else - life_var -= 800; - - if (SysInfoPtr->PlanetInfo.AtmoDensity == 0) - life_var -= 1000; - else if (SysInfoPtr->PlanetInfo.AtmoDensity < 15) - life_var += 100; - else if (SysInfoPtr->PlanetInfo.AtmoDensity < 30) - life_var += 200; - else if (SysInfoPtr->PlanetInfo.AtmoDensity < 100) - life_var += 300; - else if (SysInfoPtr->PlanetInfo.AtmoDensity < 1000) - life_var += 150; - else if (SysInfoPtr->PlanetInfo.AtmoDensity < 2500) - ; - else - life_var -= 100; - -#ifndef NOTYET - life_var += 200 + 80 + 80; -#else /* NOTYET */ - if (SysInfoPtr->PlanetInfo.SurfaceGravity < 10) - ; - else if (SysInfoPtr->PlanetInfo.SurfaceGravity < 35) - life_var += 50; - else if (SysInfoPtr->PlanetInfo.SurfaceGravity < 75) - life_var += 100; - else if (SysInfoPtr->PlanetInfo.SurfaceGravity < 150) - life_var += 200; - else if (SysInfoPtr->PlanetInfo.SurfaceGravity < 400) - life_var += 50; - else if (SysInfoPtr->PlanetInfo.SurfaceGravity < 800) - ; - else - life_var -= 100; - - if (SysInfoPtr->PlanetInfo.Tectonics < 1) - life_var += 80; - else if (SysInfoPtr->PlanetInfo.Tectonics < 2) - life_var += 70; - else if (SysInfoPtr->PlanetInfo.Tectonics < 3) - life_var += 60; - else if (SysInfoPtr->PlanetInfo.Tectonics < 4) - life_var += 50; - else if (SysInfoPtr->PlanetInfo.Tectonics < 5) - life_var += 25; - else if (SysInfoPtr->PlanetInfo.Tectonics < 6) - ; - else - life_var -= 100; - - if (SysInfoPtr->PlanetInfo.Weather < 1) - life_var += 80; - else if (SysInfoPtr->PlanetInfo.Weather < 2) - life_var += 70; - else if (SysInfoPtr->PlanetInfo.Weather < 3) - life_var += 60; - else if (SysInfoPtr->PlanetInfo.Weather < 4) - life_var += 50; - else if (SysInfoPtr->PlanetInfo.Weather < 5) - life_var += 25; - else if (SysInfoPtr->PlanetInfo.Weather < 6) - ; - else - life_var -= 100; -#endif /* NOTYET */ - - SysInfoPtr->PlanetInfo.LifeChance = life_var; - - life_var = (COUNT)TFB_Random () & 1023; + life_var = RandomContext_Random (SysGenRNG) & 1023; if (life_var < SysInfoPtr->PlanetInfo.LifeChance || (SysInfoPtr->PlanetInfo.LifeChance < MIN_LIFE_CHANCE && life_var < MIN_LIFE_CHANCE)) { BYTE num_types; - num_types = (BYTE)(((BYTE)TFB_Random () % MAX_LIFE_VARIATION) + 1); + num_types = 1 + LOBYTE (RandomContext_Random (SysGenRNG)) + % MAX_LIFE_VARIATION; do { BYTE index, num_creatures; UWORD rand_val; - rand_val = (UWORD)TFB_Random (); + rand_val = RandomContext_Random (SysGenRNG); index = LOBYTE (rand_val) % NUM_CREATURE_TYPES; - num_creatures = (BYTE)((HIBYTE (rand_val) % 10) + 1); + num_creatures = 1 + HIBYTE (rand_val) % 10; do { - GenerateRandomLocation (SysInfoPtr); - SysInfoPtr->PlanetInfo.CurType = index; + GenerateRandomLocation (&info->loc_pt); + info->type = index; + info->density = 0; if (num_life_forms >= which_life || ++num_life_forms == sizeof (DWORD) * 8) - { - num_types = 1; - break; + { // reached the maximum or the requested node + return num_life_forms; } } while (--num_creatures); } while (--num_types); } #ifdef DEBUG_SURFACE else + { log_add (log_Debug, "It's dead, Jim! (%d >= %d)", life_var, SysInfoPtr->PlanetInfo.LifeChance); + } #endif /* DEBUG_SURFACE */ } - return (num_life_forms); + return num_life_forms; } -DWORD -GenerateLifeForms (SYSTEM_INFO *SysInfoPtr, COUNT *pwhich_life) +// Returns: +// for whichLife==~0 : the number of lifeforms generated +// for whichLife<32 : the index of the last lifeform (no known usage exists) +// Sets the SysGenRNG to the required state first. +COUNT +GenerateLifeForms (const SYSTEM_INFO *SysInfoPtr, COUNT whichLife, + NODE_INFO *info) { - DWORD old_rand; - - old_rand = TFB_SeedRandom ( + NODE_INFO temp_info; + if (!info) // user not interested in info but we need space for it + info = &temp_info; + RandomContext_SeedRandom (SysGenRNG, SysInfoPtr->PlanetInfo.ScanSeed[BIOLOGICAL_SCAN]); - *pwhich_life = CalcLifeForms (SysInfoPtr, *pwhich_life); - return (TFB_SeedRandom (old_rand)); + return CalcLifeForms (SysInfoPtr, whichLife, info); } -void -GenerateRandomLocation (SYSTEM_INFO *SysInfoPtr) +// Returns: +// for whichLife==~0 : the number of lifeforms generated +// for whichLife<32 : the index of the last lifeform (no known usage exists) +// Sets the SysGenRNG to the required state first. +// lifeTypes[] is terminated with -1 +COUNT +GeneratePresetLife (const SYSTEM_INFO *SysInfoPtr, const SBYTE *lifeTypes, + COUNT whichLife, NODE_INFO *info) { - UWORD rand_val; - - rand_val = (UWORD)TFB_Random (); - SysInfoPtr->PlanetInfo.CurPt.x = - (LOBYTE (rand_val) % (MAP_WIDTH - (8 << 1))) + 8; - SysInfoPtr->PlanetInfo.CurPt.y = - (HIBYTE (rand_val) % (MAP_HEIGHT - (8 << 1))) + 8; -} - -DWORD -GenerateRandomNodes (SYSTEM_INFO *SysInfoPtr, COUNT scan, COUNT numNodes, - COUNT type, COUNT *whichNode) -{ - DWORD old_rand; COUNT i; + NODE_INFO temp_info; - old_rand = TFB_SeedRandom (SysInfoPtr->PlanetInfo.ScanSeed[scan]); + if (!info) // user not interested in info but we need space for it + info = &temp_info; - for (i = 0; i < numNodes; ++i) + // This function may look unnecessarily complicated, but it must be + // kept this way to preserve the universe. That is done by preserving + // the order and number of Random() calls. + + RandomContext_SeedRandom (SysGenRNG, + SysInfoPtr->PlanetInfo.ScanSeed[BIOLOGICAL_SCAN]); + + for (i = 0; lifeTypes[i] >= 0; ++i) { - GenerateRandomLocation (SysInfoPtr); - // CurType is irrelevant for energy nodes - SysInfoPtr->PlanetInfo.CurType = type; - // CurDensity is irrelevant for energy and bio nodes - SysInfoPtr->PlanetInfo.CurDensity = 0; + GenerateRandomLocation (&info->loc_pt); + info->type = lifeTypes[i]; + // density is irrelevant for bio nodes + info->density = 0; - if (i >= *whichNode) + if (i >= whichLife) break; } - *whichNode = i; // only matters when count is requested + return i; +} - return (TFB_SeedRandom (old_rand)); +void +GenerateRandomLocation (POINT *loc) +{ + UWORD rand_val; + + rand_val = RandomContext_Random (SysGenRNG); + loc->x = 8 + LOBYTE (rand_val) % (MAP_WIDTH - (8 << 1)); + loc->y = 8 + HIBYTE (rand_val) % (MAP_HEIGHT - (8 << 1)); +} + +// Returns: +// for whichNode==~0 : the number of nodes generated +// for whichNode<32 : the index of the last node (no known usage exists) +// Sets the SysGenRNG to the required state first. +COUNT +GenerateRandomNodes (const SYSTEM_INFO *SysInfoPtr, COUNT scan, COUNT numNodes, + COUNT type, COUNT whichNode, NODE_INFO *info) +{ + COUNT i; + NODE_INFO temp_info; + + if (!info) // user not interested in info but we need space for it + info = &temp_info; + + RandomContext_SeedRandom (SysGenRNG, + SysInfoPtr->PlanetInfo.ScanSeed[scan]); + + for (i = 0; i < numNodes; ++i) + { + GenerateRandomLocation (&info->loc_pt); + // type is irrelevant for energy nodes + info->type = type; + // density is irrelevant for energy and bio nodes + info->density = 0; + + if (i >= whichNode) + break; + } + + return i; } diff --git a/sc2/src/uqm/process.c b/sc2/src/uqm/process.c index ddf85ccba..142c58e34 100644 --- a/sc2/src/uqm/process.c +++ b/sc2/src/uqm/process.c @@ -308,12 +308,11 @@ CalcView (POINT *pNewScrollPt, SIZE next_reduction, dy = -ORG_JUMP_Y; } - if ((dx || dy) && LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE) + if ((dx || dy) && inHQSpace ()) MoveSIS (&dx, &dy); if (zoom_out == next_reduction) - view_state = dx == 0 && dy == 0 - && LOBYTE (GLOBAL (CurrentActivity)) != IN_HYPERSPACE + view_state = dx == 0 && dy == 0 && !inHQSpace () ? VIEW_STABLE : VIEW_SCROLL; else { diff --git a/sc2/src/uqm/process.h b/sc2/src/uqm/process.h index 80618749d..d794a2e60 100644 --- a/sc2/src/uqm/process.h +++ b/sc2/src/uqm/process.h @@ -21,9 +21,17 @@ #include "libs/gfxlib.h" #include "element.h" +#if defined(__cplusplus) +extern "C" { +#endif + extern void RedrawQueue (BOOLEAN clear); extern void InitDisplayList (void); extern void SetUpElement (ELEMENT *ElementPtr); extern void InsertPrim (PRIM_LINKS *pLinks, COUNT primIndex, COUNT iPI); +#if defined(__cplusplus) +} +#endif + #endif /* UQM_PROCESS_H_INCL_ */ diff --git a/sc2/src/uqm/races.h b/sc2/src/uqm/races.h index f4744da42..b1a1617f1 100644 --- a/sc2/src/uqm/races.h +++ b/sc2/src/uqm/races.h @@ -31,6 +31,10 @@ typedef HLINK HSTARSHIP; #include "libs/sndlib.h" #include "libs/reslib.h" +#if defined(__cplusplus) +extern "C" { +#endif + // TODO: remove RACES_PER_PLAYER remnant of SC1 #define RACES_PER_PLAYER 7 @@ -217,7 +221,7 @@ struct race_desc POSTPROCESS_FUNC *postprocess_func; INIT_WEAPON_FUNC *init_weapon_func; - intptr_t data; // private ship data, ship code owns this + void* data; // private ship data, ship code owns this void *CodeRef; }; @@ -380,9 +384,9 @@ typedef struct // Values for FLEET_INFO.allied_state enum { - DEAD_GUY = 0, - GOOD_GUY, - BAD_GUY, + DEAD_GUY = 0, // Race is extinct + GOOD_GUY, // Race is allied with the player + BAD_GUY, // Race is not allied with the player }; static inline FLEET_INFO * @@ -664,5 +668,8 @@ enum BUILD_COLOR (MAKE_RGB15_INIT (0x06, 0x06, 0x06), 0x20), /* BLACK_URQUAN_SHIP */ \ BUILD_COLOR (MAKE_RGB15_INIT (0x14, 0x07, 0x1F), 0x39), /* YEHAT_REBEL_SHIP */ -#endif /* UQM_RACES_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_RACES_H_ */ diff --git a/sc2/src/uqm/restart.c b/sc2/src/uqm/restart.c index 7b4f6f9f3..b877a2edb 100644 --- a/sc2/src/uqm/restart.c +++ b/sc2/src/uqm/restart.c @@ -21,8 +21,7 @@ #include "colors.h" #include "controls.h" #include "credits.h" -// XXX: for star_array[] -#include "encount.h" +#include "starmap.h" #include "fmv.h" #include "menustat.h" #include "gamestr.h" @@ -43,10 +42,6 @@ #include "libs/inplib.h" -// TODO: This entire module fails to uphold the GraphicsLock semantics -// This either has to be fixed, or GraphicsLock completely ignored, -// or will become irrelevant if GraphicsLock completely removed. - enum { START_NEW_GAME = 0, @@ -65,8 +60,7 @@ DrawRestartMenuGraphic (MENU_STATE *pMS) TEXT t; UNICODE buf[64]; - s.frame = CaptureDrawable (LoadGraphic (RESTART_PMAP_ANIM)); - pMS->CurFrame = s.frame; + s.frame = pMS->CurFrame; GetFrameRect (s.frame, &r); s.origin.x = (SCREEN_WIDTH - r.extent.width) >> 1; s.origin.y = (SCREEN_HEIGHT - r.extent.height) >> 1; @@ -75,7 +69,6 @@ DrawRestartMenuGraphic (MENU_STATE *pMS) BatchGraphics (); ClearDrawable (); FlushColorXForms (); - LockMutex (GraphicsLock); DrawStamp (&s); // Put the version number in the bottom right corner. @@ -90,7 +83,6 @@ DrawRestartMenuGraphic (MENU_STATE *pMS) SetContextForeGroundColor (WHITE_COLOR); font_DrawText (&t); - UnlockMutex (GraphicsLock); UnbatchGraphics (); } @@ -307,6 +299,9 @@ RestartMenu (MENU_STATE *pMS) SleepThreadUntil (FadeScreen (FadeAllToBlack, TimeOut)); if (TimeOut == ONE_SECOND / 8) SleepThread (ONE_SECOND * 3); + + pMS->CurFrame = CaptureDrawable (LoadGraphic (RESTART_PMAP_ANIM)); + DrawRestartMenuGraphic (pMS); GLOBAL (CurrentActivity) &= ~CHECK_ABORT; SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, MENU_SOUND_SELECT); @@ -321,7 +316,9 @@ RestartMenu (MENU_STATE *pMS) } Flash_terminate (pMS->flashContext); + pMS->flashContext = 0; DestroyDrawable (ReleaseDrawable (pMS->CurFrame)); + pMS->CurFrame = 0; if (GLOBAL (CurrentActivity) == (ACTIVITY)~0) return (FALSE); // timed out diff --git a/sc2/src/uqm/restart.h b/sc2/src/uqm/restart.h index e7a402934..0eef97fea 100644 --- a/sc2/src/uqm/restart.h +++ b/sc2/src/uqm/restart.h @@ -19,8 +19,15 @@ #include "libs/compiler.h" +#if defined(__cplusplus) +extern "C" { +#endif + extern BOOLEAN StartGame (void); -#endif /* UQM_RESTART_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_RESTART_H_ */ diff --git a/sc2/src/uqm/save.c b/sc2/src/uqm/save.c index 43a21d16e..c49fe505e 100644 --- a/sc2/src/uqm/save.c +++ b/sc2/src/uqm/save.c @@ -22,6 +22,7 @@ #include "build.h" #include "controls.h" +#include "starmap.h" #include "encount.h" #include "libs/file.h" #include "gamestr.h" @@ -276,11 +277,13 @@ SaveEncounter (const ENCOUNTER *EncounterPtr, DECODE_REF fh) cwrite_16 (fh, EncounterPtr->origin.x); cwrite_16 (fh, EncounterPtr->origin.y); cwrite_16 (fh, EncounterPtr->radius); - // STAR_DESC fields - cwrite_16 (fh, EncounterPtr->SD.star_pt.x); - cwrite_16 (fh, EncounterPtr->SD.star_pt.y); - cwrite_8 (fh, EncounterPtr->SD.Type); - cwrite_8 (fh, EncounterPtr->SD.Index); + // former STAR_DESC fields + cwrite_16 (fh, EncounterPtr->loc_pt.x); + cwrite_16 (fh, EncounterPtr->loc_pt.y); + cwrite_8 (fh, EncounterPtr->race_id); + // XXX: writing combined fields to maintain savegame compatibility + cwrite_8 (fh, (EncounterPtr->num_ships & ENCOUNTER_SHIPS_MASK) + | (EncounterPtr->flags & ENCOUNTER_FLAGS_MASK)); cwrite_16 (fh, 0); /* alignment padding */ // Save each entry in the BRIEF_SHIP_INFO array @@ -483,7 +486,7 @@ PrepareSummary (SUMMARY_DESC *SummPtr) switch (SummPtr->Activity) { case IN_HYPERSPACE: - if (GET_GAME_STATE (ARILOU_SPACE_SIDE) > 1) + if (inQuasiSpace ()) SummPtr->Activity = IN_QUASISPACE; break; case IN_INTERPLANETARY: @@ -603,26 +606,22 @@ SaveProblem (void) STAMP s; CONTEXT OldContext; - LockMutex (GraphicsLock); OldContext = SetContext (SpaceContext); SaveProblemMessage (&s); FlushGraphics (); - UnlockMutex (GraphicsLock); WaitForAnyButton (TRUE, WAIT_INFINITE, FALSE); - LockMutex (GraphicsLock); // Restore the screen under the message DrawStamp (&s); SetContext (OldContext); DestroyDrawable (ReleaseDrawable (s.frame)); - UnlockMutex (GraphicsLock); } static void SaveFlagshipState (void) { - if (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE) + if (inHQSpace ()) { // Player is in HyperSpace or QuasiSpace. SaveSisHyperState (); diff --git a/sc2/src/uqm/save.h b/sc2/src/uqm/save.h index 054884954..2521cf27d 100644 --- a/sc2/src/uqm/save.h +++ b/sc2/src/uqm/save.h @@ -21,8 +21,15 @@ // for SUMMARY_DESC #include "libs/compiler.h" +#if defined(__cplusplus) +extern "C" { +#endif + extern void SaveProblem (void); extern BOOLEAN SaveGame (COUNT which_game, SUMMARY_DESC *summary_desc); -#endif /* UQM_SAVE_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_SAVE_H_ */ diff --git a/sc2/src/uqm/settings.h b/sc2/src/uqm/settings.h index c57f1c79b..f903bc827 100644 --- a/sc2/src/uqm/settings.h +++ b/sc2/src/uqm/settings.h @@ -19,6 +19,10 @@ #include "libs/sndlib.h" +#if defined(__cplusplus) +extern "C" { +#endif + extern void ToggleMusic (void); extern void StopMusic (void); extern void ResumeMusic (void); @@ -30,5 +34,8 @@ extern void PlaySoundEffect (SOUND S, COUNT Channel, SoundPosition Pos, void *PositionalObject, BYTE Priority); -#endif /* UQM_SETTINGS_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_SETTINGS_H_ */ diff --git a/sc2/src/uqm/setup.c b/sc2/src/uqm/setup.c index 00984b304..bfdf90adf 100644 --- a/sc2/src/uqm/setup.c +++ b/sc2/src/uqm/setup.c @@ -65,13 +65,14 @@ FRAME StatusFrame; FRAME FlagStatFrame; FRAME MiscDataFrame; FRAME FontGradFrame; -Mutex GraphicsLock; STRING GameStrings; QUEUE disp_q; uio_Repository *repository; uio_DirHandle *rootDir; +BOOLEAN usingSpeech; + static void InitPlayerInput (void) @@ -119,9 +120,11 @@ LoadKernel (int argc, char *argv[]) loadAddon ("3domusic"); } - /* Always try to use voice data */ - if (!loadAddon ("3dovoice")) - speechVolumeScale = 0.0f; // XXX: need better no-speech indicator + usingSpeech = optSpeech; + if (optSpeech && !loadAddon ("3dovoice")) + { + usingSpeech = FALSE; + } if (optRemixMusic) { diff --git a/sc2/src/uqm/setup.h b/sc2/src/uqm/setup.h index a03f42e43..ffdbff35e 100644 --- a/sc2/src/uqm/setup.h +++ b/sc2/src/uqm/setup.h @@ -24,6 +24,10 @@ #include "libs/gfxlib.h" #include "libs/threadlib.h" +#if defined(__cplusplus) +extern "C" { +#endif + extern RESOURCE_INDEX hResIndex; extern FRAME Screen; @@ -47,7 +51,6 @@ extern FONT StarConFont; extern FONT MicroFont; extern FONT TinyFont; -extern Mutex GraphicsLock; extern CondVar RenderingCond; extern QUEUE race_q[]; @@ -58,6 +61,10 @@ extern ACTIVITY LastActivity; extern BYTE PlayerControl[]; +extern BOOLEAN usingSpeech; + // Actual speech presence indicator which decouples reality from + // the user option, thus the user option remains as pure intent + BOOLEAN InitContexts (void); void UninitPlayerInput (void); BOOLEAN InitGameKernel (void); @@ -75,6 +82,8 @@ void ClearPlayerInput (COUNT playerI); void ClearPlayerInputAll (void); +#if defined(__cplusplus) +} +#endif + #endif /* UQM_SETUP_H_ */ - - diff --git a/sc2/src/uqm/setupmenu.c b/sc2/src/uqm/setupmenu.c index 1da42d3b3..5d2321481 100644 --- a/sc2/src/uqm/setupmenu.c +++ b/sc2/src/uqm/setupmenu.c @@ -37,6 +37,8 @@ #include "libs/memlib.h" #include "resinst.h" #include "nameref.h" +#include + static STRING SetupTab; @@ -67,8 +69,8 @@ static void rebind_control (WIDGET_CONTROLENTRY *widget); static void clear_control (WIDGET_CONTROLENTRY *widget); #define MENU_COUNT 8 -#define CHOICE_COUNT 22 -#define SLIDER_COUNT 3 +#define CHOICE_COUNT 24 +#define SLIDER_COUNT 4 #define BUTTON_COUNT 10 #define LABEL_COUNT 4 #define TEXTENTRY_COUNT 1 @@ -90,25 +92,13 @@ typedef int (*HANDLER)(WIDGET *, int); static int choice_widths[CHOICE_COUNT] = { 3, 2, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 3, 3, 2, 3, 3, - 3, 2 }; + 3, 2, 2, 2 }; static HANDLER button_handlers[BUTTON_COUNT] = { quit_main_menu, quit_sub_menu, do_graphics, do_engine, do_audio, do_resources, do_keyconfig, do_advanced, do_editkeys, do_keyconfig }; -static int menu_sizes[MENU_COUNT] = { - 7, 5, 7, 9, 2, 5, -#ifdef HAVE_OPENGL - 5, -#else - 4, -#endif - 11 -}; - -static int menu_bgs[MENU_COUNT] = { 0, 1, 1, 2, 3, 1, 2, 1 }; - /* These refer to uninitialized widgets, but that's OK; we'll fill * them in before we touch them */ static WIDGET *main_widgets[] = { @@ -118,14 +108,18 @@ static WIDGET *main_widgets[] = { (WIDGET *)(&buttons[5]), (WIDGET *)(&buttons[6]), (WIDGET *)(&buttons[7]), - (WIDGET *)(&buttons[0]) }; + (WIDGET *)(&buttons[0]), + NULL }; static WIDGET *graphics_widgets[] = { (WIDGET *)(&choices[0]), + (WIDGET *)(&choices[23]), (WIDGET *)(&choices[10]), + (WIDGET *)(&sliders[3]), (WIDGET *)(&choices[2]), (WIDGET *)(&choices[3]), - (WIDGET *)(&buttons[1]) }; + (WIDGET *)(&buttons[1]), + NULL }; static WIDGET *audio_widgets[] = { (WIDGET *)(&sliders[0]), @@ -134,7 +128,9 @@ static WIDGET *audio_widgets[] = { (WIDGET *)(&choices[14]), (WIDGET *)(&choices[9]), (WIDGET *)(&choices[21]), - (WIDGET *)(&buttons[1]) }; + (WIDGET *)(&choices[22]), + (WIDGET *)(&buttons[1]), + NULL }; static WIDGET *engine_widgets[] = { (WIDGET *)(&choices[4]), @@ -145,7 +141,8 @@ static WIDGET *engine_widgets[] = { (WIDGET *)(&choices[13]), (WIDGET *)(&choices[11]), (WIDGET *)(&choices[17]), - (WIDGET *)(&buttons[1]) }; + (WIDGET *)(&buttons[1]), + NULL }; static WIDGET *advanced_widgets[] = { #ifdef HAVE_OPENGL @@ -154,14 +151,16 @@ static WIDGET *advanced_widgets[] = { (WIDGET *)(&choices[12]), (WIDGET *)(&choices[15]), (WIDGET *)(&choices[16]), - (WIDGET *)(&buttons[1]) }; + (WIDGET *)(&buttons[1]), + NULL }; static WIDGET *keyconfig_widgets[] = { (WIDGET *)(&choices[18]), (WIDGET *)(&choices[19]), (WIDGET *)(&labels[1]), (WIDGET *)(&buttons[8]), - (WIDGET *)(&buttons[1]) }; + (WIDGET *)(&buttons[1]), + NULL }; static WIDGET *editkeys_widgets[] = { (WIDGET *)(&choices[20]), @@ -174,15 +173,43 @@ static WIDGET *editkeys_widgets[] = { (WIDGET *)(&controlentries[4]), (WIDGET *)(&controlentries[5]), (WIDGET *)(&controlentries[6]), - (WIDGET *)(&buttons[9]) }; + (WIDGET *)(&buttons[9]), + NULL }; static WIDGET *incomplete_widgets[] = { (WIDGET *)(&labels[0]), - (WIDGET *)(&buttons[1]) }; + (WIDGET *)(&buttons[1]), + NULL }; + +static const struct +{ + WIDGET **widgets; + int bgIndex; +} +menu_defs[] = +{ + {main_widgets, 0}, + {graphics_widgets, 1}, + {audio_widgets, 1}, + {engine_widgets, 2}, + {incomplete_widgets, 3}, + {keyconfig_widgets, 1}, + {advanced_widgets, 2}, + {editkeys_widgets, 1}, + {NULL, 0} +}; + +// Start with reasonable gamma bounds. These will get updated +// as we find out the actual bounds. +static float minGamma = 0.4f; +static float maxGamma = 2.5f; +// The gamma slider uses an exponential curve +// We use y = e^(2.1972*(x-1)) curve to give us a nice spread of +// gamma values 0.11 < g < 9.0 centered at g=1.0 +#define GAMMA_CURVE_B 2.1972f +static float minGammaX; +static float maxGammaX; -static WIDGET **menu_widgets[MENU_COUNT] = { - main_widgets, graphics_widgets, audio_widgets, engine_widgets, - incomplete_widgets, keyconfig_widgets, advanced_widgets, editkeys_widgets }; static int number_res_options (void) @@ -301,18 +328,18 @@ do_advanced (WIDGET *self, int event) } static void -populate_editkeys (int template) +populate_editkeys (int templat) { int i, j; - strncpy (textentries[0].value, input_templates[template].name, textentries[0].maxlen); + strncpy (textentries[0].value, input_templates[templat].name, textentries[0].maxlen); textentries[0].value[textentries[0].maxlen-1] = 0; for (i = 0; i < NUM_KEYS; i++) { for (j = 0; j < 2; j++) { - InterrogateInputState (template, i, j, controlentries[i].controlname[j], WIDGET_CONTROLENTRY_WIDTH); + InterrogateInputState (templat, i, j, controlentries[i].controlname[j], WIDGET_CONTROLENTRY_WIDTH); } } } @@ -394,10 +421,13 @@ SetDefaults (void) choices[19].selected = opts.player2; choices[20].selected = 0; choices[21].selected = opts.musicremix; + choices[22].selected = opts.speech; + choices[23].selected = opts.keepaspect; sliders[0].value = opts.musicvol; sliders[1].value = opts.sfxvol; sliders[2].value = opts.speechvol; + sliders[3].value = opts.gamma; } static void @@ -425,10 +455,13 @@ PropagateResults (void) opts.player1 = choices[18].selected; opts.player2 = choices[19].selected; opts.musicremix = choices[21].selected; + opts.speech = choices[22].selected; + opts.keepaspect = choices[23].selected; opts.musicvol = sliders[0].value; opts.sfxvol = sliders[1].value; opts.speechvol = sliders[2].value; + opts.gamma = sliders[3].value; SetGlobalOptions (&opts); } @@ -585,31 +618,170 @@ OnTextEntryEvent (WIDGET_TEXTENTRY *widget) return TRUE; // event handled } +static inline float +gammaCurve (float x) +{ + // The slider uses an exponential curve + return exp ((x - 1) * GAMMA_CURVE_B); +} + +static inline float +solveGammaCurve (float y) +{ + return log (y) / GAMMA_CURVE_B + 1; +} + +static int +gammaToSlider (float gamma) +{ + const float x = solveGammaCurve (gamma); + const float step = (maxGammaX - minGammaX) / 100; + return (int) ((x - minGammaX) / step + 0.5); +} + +static float +sliderToGamma (int value) +{ + const float step = (maxGammaX - minGammaX) / 100; + const float x = minGammaX + step * value; + const float g = gammaCurve (x); + // report any value that is close enough as 1.0 + return (fabs (g - 1.0f) < 0.001f) ? 1.0f : g; +} + +static void +updateGammaBounds (bool useUpper) +{ + float g, x; + int slider; + + // The slider uses an exponential curve. + // Calculate where on the curve the min and max gamma values are + minGammaX = solveGammaCurve (minGamma); + maxGammaX = solveGammaCurve (maxGamma); + + // We have 100 discrete steps through the range, so the slider may + // skip over a 1.0 gamma. We need to ensure that there always is + // a 1.0 on the slider by tweaking the range (expanding/contracting). + slider = gammaToSlider (1.0f); + g = sliderToGamma (slider); + if (g == 1.0f) + return; // no adjustment needed + + x = solveGammaCurve (g); + if (useUpper) + { // Move the upper bound up or down to land on 1.0 + const float d = (x - 1.0f) * 100 / slider; + maxGammaX -= d; + maxGamma = gammaCurve (maxGammaX); + } + else + { // Move the lower bound up or down to land on 1.0 + const float d = (x - 1.0f) * 100 / (100 - slider); + minGammaX -= d; + minGamma = gammaCurve (minGammaX); + } +} + +static int +gamma_HandleEventSlider (WIDGET *_self, int event) +{ + WIDGET_SLIDER *self = (WIDGET_SLIDER *)_self; + int prevValue = self->value; + float gamma; + bool set; + + switch (event) + { + case WIDGET_EVENT_LEFT: + self->value -= self->step; + break; + case WIDGET_EVENT_RIGHT: + self->value += self->step; + break; + default: + return FALSE; + } + + // Limit the slider to values accepted by gfx subsys + gamma = sliderToGamma (self->value); + set = TFB_SetGamma (gamma); + if (!set) + { // revert + self->value = prevValue; + gamma = sliderToGamma (self->value); + } + + // Grow or shrink the range based on accepted values + if (gamma < minGamma || (!set && event == WIDGET_EVENT_LEFT)) + { + minGamma = gamma; + updateGammaBounds (true); + // at the lowest end + self->value = 0; + } + else if (gamma > maxGamma || (!set && event == WIDGET_EVENT_RIGHT)) + { + maxGamma = gamma; + updateGammaBounds (false); + // at the highest end + self->value = 100; + } + return TRUE; +} + +static void +gamma_DrawValue (WIDGET_SLIDER *self, int x, int y) +{ + TEXT t; + char buf[16]; + float gamma = sliderToGamma (self->value); + snprintf (buf, sizeof buf, "%.4f", gamma); + + t.baseline.x = x; + t.baseline.y = y; + t.align = ALIGN_CENTER; + t.CharCount = ~0; + t.pStr = buf; + + font_DrawText (&t); +} + static void rebind_control (WIDGET_CONTROLENTRY *widget) { - int template = choices[20].selected; + int templat = choices[20].selected; int control = widget->controlindex; int index = widget->highlighted; FlushInput (); DrawLabelAsWindow (&labels[3], NULL); - RebindInputState (template, control, index); - populate_editkeys (template); + RebindInputState (templat, control, index); + populate_editkeys (templat); FlushInput (); } static void clear_control (WIDGET_CONTROLENTRY *widget) { - int template = choices[20].selected; + int templat = choices[20].selected; int control = widget->controlindex; int index = widget->highlighted; - RemoveInputState (template, control, index); - populate_editkeys (template); + RemoveInputState (templat, control, index); + populate_editkeys (templat); } +static int +count_widgets (WIDGET **widgets) +{ + int count; + + for (count = 0; *widgets != NULL; ++widgets, ++count) + ; + return count; +} + static stringbank *bank = NULL; static FRAME setup_frame = NULL; @@ -659,11 +831,15 @@ init_widgets (void) menus[i].subtitle = buffer[i]; menus[i].bgStamp.origin.x = 0; menus[i].bgStamp.origin.y = 0; - menus[i].bgStamp.frame = SetAbsFrameIndex (setup_frame, menu_bgs[i]); - menus[i].num_children = menu_sizes[i]; - menus[i].child = menu_widgets[i]; + menus[i].bgStamp.frame = SetAbsFrameIndex (setup_frame, menu_defs[i].bgIndex); + menus[i].num_children = count_widgets (menu_defs[i].widgets); + menus[i].child = menu_defs[i].widgets; menus[i].highlighted = 0; } + if (menu_defs[i].widgets != NULL) + { + log_add (log_Error, "Menu definition array has more items!"); + } /* Options */ if (SplitString (GetStringAddress (SetAbsStringTableIndex (SetupTab, 2)), '\n', 100, buffer, bank) != CHOICE_COUNT) @@ -781,6 +957,10 @@ init_widgets (void) sliders[i].tooltip[1] = ""; sliders[i].tooltip[2] = ""; } + // gamma is a special case + sliders[3].step = 1; + sliders[3].handleEvent = gamma_HandleEventSlider; + sliders[3].draw_value = gamma_DrawValue; for (i = 0; i < SLIDER_COUNT; i++) { @@ -1057,6 +1237,8 @@ SetupMenu (void) void GetGlobalOptions (GLOBALOPTS *opts) { + bool whichBound; + if (GfxFlags & TFB_GFXFLAGS_SCALE_BILINEAR) { opts->scaler = OPTVAL_BILINEAR_SCALE; @@ -1100,6 +1282,8 @@ GetGlobalOptions (GLOBALOPTS *opts) /* These values are read in, but won't change during a run. */ opts->music3do = opt3doMusic ? OPTVAL_ENABLED : OPTVAL_DISABLED; opts->musicremix = optRemixMusic ? OPTVAL_ENABLED : OPTVAL_DISABLED; + opts->speech = optSpeech ? OPTVAL_ENABLED : OPTVAL_DISABLED; + opts->keepaspect = optKeepAspectRatio ? OPTVAL_ENABLED : OPTVAL_DISABLED; switch (snddriver) { case audio_DRIVER_OPENAL: opts->adriver = OPTVAL_OPENAL; @@ -1212,13 +1396,22 @@ GetGlobalOptions (GLOBALOPTS *opts) } } + whichBound = (optGamma < maxGamma); + // The option supplied by the user may be beyond our starting range + // but valid nonetheless. We need to account for that. + if (optGamma <= minGamma) + minGamma = optGamma - 0.03f; + else if (optGamma >= maxGamma) + maxGamma = optGamma + 0.3f; + updateGammaBounds (whichBound); + opts->gamma = gammaToSlider (optGamma); + opts->player1 = PlayerControls[0]; opts->player2 = PlayerControls[1]; opts->musicvol = (((int)(musicVolumeScale * 100.0f) + 2) / 5) * 5; opts->sfxvol = (((int)(sfxVolumeScale * 100.0f) + 2) / 5) * 5; opts->speechvol = (((int)(speechVolumeScale * 100.0f) + 2) / 5) * 5; - } void @@ -1326,15 +1519,27 @@ SetGlobalOptions (GLOBALOPTS *opts) FlushGraphics (); InitVideoPlayer (TRUE); } + + // Avoid setting gamma when it is not necessary + if (optGamma != 1.0f || sliderToGamma (opts->gamma) != 1.0f) + { + optGamma = sliderToGamma (opts->gamma); + setGammaCorrection (optGamma); + } + optSubtitles = (opts->subtitles == OPTVAL_ENABLED) ? TRUE : FALSE; - // optWhichMusic = (opts->music == OPTVAL_3DO) ? OPT_3DO : OPT_PC; optWhichMenu = (opts->menu == OPTVAL_3DO) ? OPT_3DO : OPT_PC; optWhichFonts = (opts->text == OPTVAL_3DO) ? OPT_3DO : OPT_PC; optWhichCoarseScan = (opts->cscan == OPTVAL_3DO) ? OPT_3DO : OPT_PC; optSmoothScroll = (opts->scroll == OPTVAL_3DO) ? OPT_3DO : OPT_PC; optWhichShield = (opts->shield == OPTVAL_3DO) ? OPT_3DO : OPT_PC; optMeleeScale = (opts->meleezoom == OPTVAL_3DO) ? TFB_SCALE_TRILINEAR : TFB_SCALE_STEP; + opt3doMusic = (opts->music3do == OPTVAL_ENABLED); + optRemixMusic = (opts->musicremix == OPTVAL_ENABLED); + optSpeech = (opts->speech == OPTVAL_ENABLED); optWhichIntro = (opts->intro == OPTVAL_3DO) ? OPT_3DO : OPT_PC; + optStereoSFX = (opts->stereo == OPTVAL_ENABLED); + optKeepAspectRatio = (opts->keepaspect == OPTVAL_ENABLED); PlayerControls[0] = opts->player1; PlayerControls[1] = opts->player2; @@ -1346,11 +1551,14 @@ SetGlobalOptions (GLOBALOPTS *opts) res_PutBoolean ("config.3domusic", opts->music3do == OPTVAL_ENABLED); res_PutBoolean ("config.remixmusic", opts->musicremix == OPTVAL_ENABLED); + res_PutBoolean ("config.speech", opts->speech == OPTVAL_ENABLED); res_PutBoolean ("config.3domovies", opts->intro == OPTVAL_3DO); res_PutBoolean ("config.showfps", opts->fps == OPTVAL_ENABLED); res_PutBoolean ("config.smoothmelee", opts->meleezoom == OPTVAL_3DO); res_PutBoolean ("config.positionalsfx", opts->stereo == OPTVAL_ENABLED); res_PutBoolean ("config.pulseshield", opts->shield == OPTVAL_3DO); + res_PutBoolean ("config.keepaspectratio", opts->keepaspect == OPTVAL_ENABLED); + res_PutInteger ("config.gamma", (int) (optGamma * GAMMA_SCALE + 0.5)); res_PutInteger ("config.player1control", opts->player1); res_PutInteger ("config.player2control", opts->player2); diff --git a/sc2/src/uqm/setupmenu.h b/sc2/src/uqm/setupmenu.h index 9b0a48eba..4dc74c04b 100644 --- a/sc2/src/uqm/setupmenu.h +++ b/sc2/src/uqm/setupmenu.h @@ -21,6 +21,10 @@ #include "controls.h" +#if defined(__cplusplus) +extern "C" { +#endif + typedef enum { OPTVAL_DISABLED, OPTVAL_ENABLED @@ -75,10 +79,13 @@ typedef struct globalopts_struct { OPT_DRIVERTYPE driver; OPT_ADRIVERTYPE adriver; OPT_AQUALITYTYPE aquality; - OPT_ENABLABLE fullscreen, subtitles, scanlines, fps, stereo, music3do, musicremix; + OPT_ENABLABLE fullscreen, subtitles, scanlines, fps, stereo; + OPT_ENABLABLE music3do, musicremix, speech; + OPT_ENABLABLE keepaspect; OPT_CONSOLETYPE menu, text, cscan, scroll, intro, meleezoom, shield; CONTROL_TEMPLATE player1, player2; int speechvol, musicvol, sfxvol; + int gamma; } GLOBALOPTS; void SetupMenu (void); @@ -86,4 +93,8 @@ void SetupMenu (void); void GetGlobalOptions (GLOBALOPTS *opts); void SetGlobalOptions (GLOBALOPTS *opts); +#if defined(__cplusplus) +} +#endif + #endif // UQM_SETUPMENU_H_ diff --git a/sc2/src/uqm/ship.c b/sc2/src/uqm/ship.c index 13480fccf..747c92991 100644 --- a/sc2/src/uqm/ship.c +++ b/sc2/src/uqm/ship.c @@ -193,6 +193,9 @@ ship_preprocess (ELEMENT *ElementPtr) if (RDPtr->preprocess_func) (*RDPtr->preprocess_func) (ElementPtr); + // XXX: Hack: Pkunk sets hTarget!=0 when it reincarnates. In that + // case there is no ship_transition() but a Phoenix transition + // instead. if (ElementPtr->hTarget == 0) { ship_transition (ElementPtr); @@ -451,7 +454,7 @@ spawn_ship (STARSHIP *StarShipPtr) else { StarShipPtr->ShipFacing = NORMALIZE_FACING (TFB_Random ()); - if (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE) + if (inHQSpace ()) { // Only one ship is ever spawned in HyperSpace -- flagship COUNT facing = GLOBAL (ShipFacing); // XXX: Solar system reentry test depends on ShipFacing != 0 diff --git a/sc2/src/uqm/ship.h b/sc2/src/uqm/ship.h index 5cfc31889..8f0c72c62 100644 --- a/sc2/src/uqm/ship.h +++ b/sc2/src/uqm/ship.h @@ -21,6 +21,10 @@ #include "races.h" #include "element.h" +#if defined(__cplusplus) +extern "C" { +#endif + extern BOOLEAN GetNextStarShip (STARSHIP *LastStarShipPtr, COUNT which_side); extern BOOLEAN GetInitialStarShips (void); @@ -32,4 +36,8 @@ extern void collision (ELEMENT *ElementPtr0, POINT *pPt0, extern STATUS_FLAGS inertial_thrust (ELEMENT *ElementPtr); +#if defined(__cplusplus) +} +#endif + #endif /* UQM_SHIP_H_INCL_ */ diff --git a/sc2/src/uqm/shipcont.h b/sc2/src/uqm/shipcont.h index a127fbad1..e265e7d7e 100644 --- a/sc2/src/uqm/shipcont.h +++ b/sc2/src/uqm/shipcont.h @@ -21,6 +21,10 @@ #include "menustat.h" +#if defined(__cplusplus) +extern "C" { +#endif + #define FIELD_WIDTH (STATUS_WIDTH - 5) extern void CargoMenu (void); @@ -33,5 +37,8 @@ extern void ShowRemainingCapacity (void); extern SIZE InventoryDevices (BYTE *pDeviceMap, COUNT Size); -#endif /* UQM_SHIPCONT_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_SHIPCONT_H_ */ diff --git a/sc2/src/uqm/ships/Makeinfo b/sc2/src/uqm/ships/Makeinfo index 70a36adda..e77d2db11 100644 --- a/sc2/src/uqm/ships/Makeinfo +++ b/sc2/src/uqm/ships/Makeinfo @@ -2,3 +2,4 @@ uqm_SUBDIRS="androsyn arilou blackurq chenjesu chmmr druuge human ilwrath lastbat melnorme mmrnmhrm mycon orz pkunk probe shofixti sis_ship slylandr spathi supox syreen thradd umgah urquan utwig vux yehat zoqfot" +uqm_HFILES="ship.h" diff --git a/sc2/src/uqm/ships/androsyn/Makeinfo b/sc2/src/uqm/ships/androsyn/Makeinfo index 4819125a4..2f2f51177 100644 --- a/sc2/src/uqm/ships/androsyn/Makeinfo +++ b/sc2/src/uqm/ships/androsyn/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="androsyn.c" +uqm_HFILES="androsyn.h icode.h resinst.h" diff --git a/sc2/src/uqm/ships/androsyn/androsyn.c b/sc2/src/uqm/ships/androsyn/androsyn.c index ac03f7a57..2625b3f80 100644 --- a/sc2/src/uqm/ships/androsyn/androsyn.c +++ b/sc2/src/uqm/ships/androsyn/androsyn.c @@ -110,6 +110,46 @@ static RACE_DESC androsynth_desc = 0, /* CodeRef */ }; + +// Private per-instance ship data +typedef struct +{ + ElementCollisionFunc* collision_func; +} ANDROSYNTH_DATA; + +// Local typedef +typedef ANDROSYNTH_DATA CustomShipData_t; + +// Retrieve race-specific ship data from a race desc +static CustomShipData_t * +GetCustomShipData (RACE_DESC *pRaceDesc) +{ + return pRaceDesc->data; +} + +// Set the race-specific data in a race desc +// (Re)Allocates its own storage for the data. +static void +SetCustomShipData (RACE_DESC *pRaceDesc, const CustomShipData_t *data) +{ + if (pRaceDesc->data == data) + return; // no-op + + if (pRaceDesc->data) // Out with the old + { + HFree (pRaceDesc->data); + pRaceDesc->data = NULL; + } + + if (data) // In with the new + { + CustomShipData_t* newData = HMalloc (sizeof (*data)); + *newData = *data; + pRaceDesc->data = newData; + } +} + + #define BLAZER_DAMAGE 3 #define BLAZER_MASS 1 @@ -355,11 +395,14 @@ androsynth_postprocess (ELEMENT *ElementPtr) ElementPtr->mass_points = BLAZER_MASS; StarShipPtr->RaceDescPtr->characteristics.turn_wait = BLAZER_TURN_WAIT; + /* Save the current collision func because we were not the * ones who set it */ - StarShipPtr->RaceDescPtr->data = (intptr_t) - ElementPtr->collision_func; - ElementPtr->collision_func = blazer_collision; + { + const ANDROSYNTH_DATA shipData = { ElementPtr->collision_func }; + SetCustomShipData (StarShipPtr->RaceDescPtr, &shipData); + ElementPtr->collision_func = blazer_collision; + } } } @@ -426,8 +469,8 @@ androsynth_preprocess (ELEMENT *ElementPtr) StarShipPtr->RaceDescPtr->characteristics.special_wait; StarShipPtr->RaceDescPtr->characteristics.energy_regeneration = ENERGY_REGENERATION; ElementPtr->mass_points = SHIP_MASS; - ElementPtr->collision_func = (CollisionFunc *) - StarShipPtr->RaceDescPtr->data; + ElementPtr->collision_func = + GetCustomShipData (StarShipPtr->RaceDescPtr)->collision_func; ElementPtr->next.image.farray = StarShipPtr->RaceDescPtr->ship_data.ship; ElementPtr->next.image.frame = @@ -463,11 +506,19 @@ androsynth_preprocess (ELEMENT *ElementPtr) StarShipPtr->cur_status_flags = cur_status_flags; } +static void +uninit_androsynth (RACE_DESC *pRaceDesc) +{ + SetCustomShipData (pRaceDesc, NULL); +} + + RACE_DESC* init_androsynth (void) { RACE_DESC *RaceDescPtr; + androsynth_desc.uninit_func = uninit_androsynth; androsynth_desc.preprocess_func = androsynth_preprocess; androsynth_desc.postprocess_func = androsynth_postprocess; androsynth_desc.init_weapon_func = initialize_bubble; diff --git a/sc2/src/uqm/ships/androsyn/androsyn.h b/sc2/src/uqm/ships/androsyn/androsyn.h index 4e891e3db..43fe88d5b 100644 --- a/sc2/src/uqm/ships/androsyn/androsyn.h +++ b/sc2/src/uqm/ships/androsyn/androsyn.h @@ -17,7 +17,15 @@ #ifndef ANDROSYN_H #define ANDROSYN_H +#if defined(__cplusplus) +extern "C" { +#endif + RACE_DESC *init_androsynth (void); +#if defined(__cplusplus) +} +#endif + #endif /* ANDROSYN_H */ diff --git a/sc2/src/uqm/ships/androsyn/icode.h b/sc2/src/uqm/ships/androsyn/icode.h index 86af2df1d..67f053a15 100644 --- a/sc2/src/uqm/ships/androsyn/icode.h +++ b/sc2/src/uqm/ships/androsyn/icode.h @@ -1 +1,5 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define ANDROSYNTH_CODE "ship.androsynth.code" diff --git a/sc2/src/uqm/ships/androsyn/resinst.h b/sc2/src/uqm/ships/androsyn/resinst.h index b8b0cd400..94b4a3f86 100644 --- a/sc2/src/uqm/ships/androsyn/resinst.h +++ b/sc2/src/uqm/ships/androsyn/resinst.h @@ -1,17 +1,19 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define ANDROSYNTH_BIG_MASK_PMAP_ANIM "ship.androsynth.graphics.guardian.large" #define ANDROSYNTH_CAPT_MASK_PMAP_ANIM "ship.androsynth.graphics.captain" #define ANDROSYNTH_ICON_MASK_PMAP_ANIM "ship.androsynth.icons" #define ANDROSYNTH_MED_MASK_PMAP_ANIM "ship.androsynth.graphics.guardian.medium" #define ANDROSYNTH_MICON_MASK_PMAP_ANIM "ship.androsynth.meleeicons" +#define ANDROSYNTH_RACE_STRINGS "ship.androsynth.text" +#define ANDROSYNTH_SHIP_SOUNDS "ship.androsynth.sounds" #define ANDROSYNTH_SML_MASK_PMAP_ANIM "ship.androsynth.graphics.guardian.small" +#define ANDROSYNTH_VICTORY_SONG "ship.androsynth.ditty" #define BLAZER_BIG_MASK_PMAP_ANIM "ship.androsynth.graphics.blazer.large" #define BLAZER_MED_MASK_PMAP_ANIM "ship.androsynth.graphics.blazer.medium" #define BLAZER_SML_MASK_PMAP_ANIM "ship.androsynth.graphics.blazer.small" #define BUBBLE_BIG_MASK_PMAP_ANIM "ship.androsynth.graphics.bubble.large" #define BUBBLE_MED_MASK_PMAP_ANIM "ship.androsynth.graphics.bubble.medium" #define BUBBLE_SML_MASK_PMAP_ANIM "ship.androsynth.graphics.bubble.small" -#define ANDROSYNTH_RACE_STRINGS "ship.androsynth.text" -#define ANDROSYNTH_SHIP_SOUNDS "ship.androsynth.sounds" -#define ANDROSYNTH_VICTORY_SONG "ship.androsynth.ditty" - -#include "icode.h" diff --git a/sc2/src/uqm/ships/arilou/Makeinfo b/sc2/src/uqm/ships/arilou/Makeinfo index bc616cbfb..f132bdd0d 100644 --- a/sc2/src/uqm/ships/arilou/Makeinfo +++ b/sc2/src/uqm/ships/arilou/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="arilou.c" +uqm_HFILES="arilou.h icode.h resinst.h" diff --git a/sc2/src/uqm/ships/arilou/arilou.h b/sc2/src/uqm/ships/arilou/arilou.h index 606dd9608..8e65d5892 100644 --- a/sc2/src/uqm/ships/arilou/arilou.h +++ b/sc2/src/uqm/ships/arilou/arilou.h @@ -17,7 +17,15 @@ #ifndef ARILOU_H #define ARILOU_H +#if defined(__cplusplus) +extern "C" { +#endif + RACE_DESC *init_arilou (void); +#if defined(__cplusplus) +} +#endif + #endif /* ARILOU_H */ diff --git a/sc2/src/uqm/ships/arilou/icode.h b/sc2/src/uqm/ships/arilou/icode.h index b845d29bb..81d4fff2c 100644 --- a/sc2/src/uqm/ships/arilou/icode.h +++ b/sc2/src/uqm/ships/arilou/icode.h @@ -1 +1,5 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define ARILOU_CODE "ship.arilou.code" diff --git a/sc2/src/uqm/ships/arilou/resinst.h b/sc2/src/uqm/ships/arilou/resinst.h index f723b93f0..173e2227f 100644 --- a/sc2/src/uqm/ships/arilou/resinst.h +++ b/sc2/src/uqm/ships/arilou/resinst.h @@ -1,14 +1,16 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define ARILOU_BIG_MASK_PMAP_ANIM "ship.arilou.graphics.skiff.large" #define ARILOU_CAPTAIN_MASK_PMAP_ANIM "ship.arilou.graphics.captain" #define ARILOU_ICON_MASK_PMAP_ANIM "ship.arilou.icons" #define ARILOU_MED_MASK_PMAP_ANIM "ship.arilou.graphics.skiff.medium" #define ARILOU_MICON_MASK_PMAP_ANIM "ship.arilou.meleeicons" +#define ARILOU_RACE_STRINGS "ship.arilou.text" +#define ARILOU_SHIP_SOUNDS "ship.arilou.sounds" #define ARILOU_SML_MASK_PMAP_ANIM "ship.arilou.graphics.skiff.small" +#define ARILOU_VICTORY_SONG "ship.arilou.ditty" #define WARP_BIG_MASK_PMAP_ANIM "ship.arilou.graphics.warp.large" #define WARP_MED_MASK_PMAP_ANIM "ship.arilou.graphics.warp.medium" #define WARP_SML_MASK_PMAP_ANIM "ship.arilou.graphics.warp.small" -#define ARILOU_RACE_STRINGS "ship.arilou.text" -#define ARILOU_SHIP_SOUNDS "ship.arilou.sounds" -#define ARILOU_VICTORY_SONG "ship.arilou.ditty" - -#include "icode.h" diff --git a/sc2/src/uqm/ships/blackurq/Makeinfo b/sc2/src/uqm/ships/blackurq/Makeinfo index 1110b6363..62ca12ee2 100644 --- a/sc2/src/uqm/ships/blackurq/Makeinfo +++ b/sc2/src/uqm/ships/blackurq/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="blackurq.c" +uqm_HFILES="blackurq.h icode.h resinst.h" diff --git a/sc2/src/uqm/ships/blackurq/blackurq.h b/sc2/src/uqm/ships/blackurq/blackurq.h index 3a1b9404b..4b2b5d987 100644 --- a/sc2/src/uqm/ships/blackurq/blackurq.h +++ b/sc2/src/uqm/ships/blackurq/blackurq.h @@ -17,7 +17,15 @@ #ifndef BLACKURQ_H #define BLACKURQ_H +#if defined(__cplusplus) +extern "C" { +#endif + RACE_DESC *init_black_urquan (void); +#if defined(__cplusplus) +} +#endif + #endif /* BLACKURQ_H */ diff --git a/sc2/src/uqm/ships/blackurq/icode.h b/sc2/src/uqm/ships/blackurq/icode.h index afa7c16c5..99c0ca227 100644 --- a/sc2/src/uqm/ships/blackurq/icode.h +++ b/sc2/src/uqm/ships/blackurq/icode.h @@ -1 +1,5 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define KOHR_AH_CODE "ship.kohrah.code" diff --git a/sc2/src/uqm/ships/blackurq/resinst.h b/sc2/src/uqm/ships/blackurq/resinst.h index c185a50ca..840f519d1 100644 --- a/sc2/src/uqm/ships/blackurq/resinst.h +++ b/sc2/src/uqm/ships/blackurq/resinst.h @@ -1,3 +1,7 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define BUZZSAW_BIG_MASK_PMAP_ANIM "ship.kohrah.graphics.buzzsaw.large" #define BUZZSAW_MED_MASK_PMAP_ANIM "ship.kohrah.graphics.buzzsaw.medium" #define BUZZSAW_SML_MASK_PMAP_ANIM "ship.kohrah.graphics.buzzsaw.small" @@ -9,9 +13,7 @@ #define KOHR_AH_ICON_MASK_PMAP_ANIM "ship.kohrah.icons" #define KOHR_AH_MED_MASK_PMAP_ANIM "ship.kohrah.graphics.marauder.medium" #define KOHR_AH_MICON_MASK_PMAP_ANIM "ship.kohrah.meleeicons" -#define KOHR_AH_SML_MASK_PMAP_ANIM "ship.kohrah.graphics.marauder.small" #define KOHR_AH_RACE_STRINGS "ship.kohrah.text" #define KOHR_AH_SHIP_SOUNDS "ship.kohrah.sounds" +#define KOHR_AH_SML_MASK_PMAP_ANIM "ship.kohrah.graphics.marauder.small" #define KOHR_AH_VICTORY_SONG "ship.kohrah.ditty" - -#include "icode.h" diff --git a/sc2/src/uqm/ships/chenjesu/Makeinfo b/sc2/src/uqm/ships/chenjesu/Makeinfo index d310e2566..3f10d6a19 100644 --- a/sc2/src/uqm/ships/chenjesu/Makeinfo +++ b/sc2/src/uqm/ships/chenjesu/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="chenjesu.c" +uqm_HFILES="chenjesu.h icode.h resinst.h" diff --git a/sc2/src/uqm/ships/chenjesu/chenjesu.h b/sc2/src/uqm/ships/chenjesu/chenjesu.h index 8cd17a515..37ac9d68a 100644 --- a/sc2/src/uqm/ships/chenjesu/chenjesu.h +++ b/sc2/src/uqm/ships/chenjesu/chenjesu.h @@ -17,7 +17,15 @@ #ifndef CHENJESU_H #define CHENJESU_H +#if defined(__cplusplus) +extern "C" { +#endif + RACE_DESC *init_chenjesu (void); +#if defined(__cplusplus) +} +#endif + #endif /* CHENJESU_H */ diff --git a/sc2/src/uqm/ships/chenjesu/icode.h b/sc2/src/uqm/ships/chenjesu/icode.h index 1f01274bf..1f4b693ef 100644 --- a/sc2/src/uqm/ships/chenjesu/icode.h +++ b/sc2/src/uqm/ships/chenjesu/icode.h @@ -1 +1,5 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define CHENJESU_CODE "ship.chenjesu.code" diff --git a/sc2/src/uqm/ships/chenjesu/resinst.h b/sc2/src/uqm/ships/chenjesu/resinst.h index 646f2b0ef..966029a53 100644 --- a/sc2/src/uqm/ships/chenjesu/resinst.h +++ b/sc2/src/uqm/ships/chenjesu/resinst.h @@ -1,17 +1,19 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define CHENJESU_BIG_MASK_PMAP_ANIM "ship.chenjesu.graphics.broodhome.large" #define CHENJESU_CAPTAIN_MASK_PMAP_ANIM "ship.chenjesu.graphics.captain" #define CHENJESU_ICON_MASK_PMAP_ANIM "ship.chenjesu.icons" #define CHENJESU_MED_MASK_PMAP_ANIM "ship.chenjesu.graphics.broodhome.medium" #define CHENJESU_MICON_MASK_PMAP_ANIM "ship.chenjesu.meleeicons" +#define CHENJESU_RACE_STRINGS "ship.chenjesu.text" +#define CHENJESU_SHIP_SOUNDS "ship.chenjesu.sounds" #define CHENJESU_SML_MASK_PMAP_ANIM "ship.chenjesu.graphics.broodhome.small" +#define CHENJESU_VICTORY_SONG "ship.chenjesu.ditty" #define DOGGY_BIG_MASK_PMAP_ANIM "ship.chenjesu.graphics.doggy.large" #define DOGGY_MED_MASK_PMAP_ANIM "ship.chenjesu.graphics.doggy.medium" #define DOGGY_SML_MASK_PMAP_ANIM "ship.chenjesu.graphics.doggy.small" #define SPARK_BIG_MASK_PMAP_ANIM "ship.chenjesu.graphics.spark.large" #define SPARK_MED_MASK_PMAP_ANIM "ship.chenjesu.graphics.spark.medium" #define SPARK_SML_MASK_PMAP_ANIM "ship.chenjesu.graphics.spark.small" -#define CHENJESU_RACE_STRINGS "ship.chenjesu.text" -#define CHENJESU_SHIP_SOUNDS "ship.chenjesu.sounds" -#define CHENJESU_VICTORY_SONG "ship.chenjesu.ditty" - -#include "icode.h" diff --git a/sc2/src/uqm/ships/chmmr/Makeinfo b/sc2/src/uqm/ships/chmmr/Makeinfo index c402731b9..70b8bc6f3 100644 --- a/sc2/src/uqm/ships/chmmr/Makeinfo +++ b/sc2/src/uqm/ships/chmmr/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="chmmr.c" +uqm_HFILES="chmmr.h icode.h resinst.h" diff --git a/sc2/src/uqm/ships/chmmr/chmmr.h b/sc2/src/uqm/ships/chmmr/chmmr.h index 5499fe797..88dd9b852 100644 --- a/sc2/src/uqm/ships/chmmr/chmmr.h +++ b/sc2/src/uqm/ships/chmmr/chmmr.h @@ -17,7 +17,15 @@ #ifndef CHMMR_H #define CHMMR_H +#if defined(__cplusplus) +extern "C" { +#endif + RACE_DESC *init_chmmr (void); +#if defined(__cplusplus) +} +#endif + #endif /* CHMMR_H */ diff --git a/sc2/src/uqm/ships/chmmr/icode.h b/sc2/src/uqm/ships/chmmr/icode.h index a2344eef1..0873a155d 100644 --- a/sc2/src/uqm/ships/chmmr/icode.h +++ b/sc2/src/uqm/ships/chmmr/icode.h @@ -1 +1,5 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define CHMMR_CODE "ship.chmmr.code" diff --git a/sc2/src/uqm/ships/chmmr/resinst.h b/sc2/src/uqm/ships/chmmr/resinst.h index 37566d569..a83027370 100644 --- a/sc2/src/uqm/ships/chmmr/resinst.h +++ b/sc2/src/uqm/ships/chmmr/resinst.h @@ -1,17 +1,19 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define CHMMR_BIG_MASK_PMAP_ANIM "ship.chmmr.graphics.avatar.large" #define CHMMR_CAPTAIN_MASK_PMAP_ANIM "ship.chmmr.graphics.captain" #define CHMMR_ICON_MASK_PMAP_ANIM "ship.chmmr.icons" #define CHMMR_MED_MASK_PMAP_ANIM "ship.chmmr.graphics.avatar.medium" #define CHMMR_MICON_MASK_PMAP_ANIM "ship.chmmr.meleeicons" +#define CHMMR_RACE_STRINGS "ship.chmmr.text" +#define CHMMR_SHIP_SOUNDS "ship.chmmr.sounds" #define CHMMR_SML_MASK_PMAP_ANIM "ship.chmmr.graphics.avatar.small" +#define CHMMR_VICTORY_SONG "ship.chmmr.ditty" #define MUZZLE_BIG_MASK_PMAP_ANIM "ship.chmmr.graphics.muzzle.large" #define MUZZLE_MED_MASK_PMAP_ANIM "ship.chmmr.graphics.muzzle.medium" #define MUZZLE_SML_MASK_PMAP_ANIM "ship.chmmr.graphics.muzzle.small" #define SATELLITE_BIG_MASK_PMAP_ANIM "ship.chmmr.graphics.satellite.large" #define SATELLITE_MED_MASK_PMAP_ANIM "ship.chmmr.graphics.satellite.medium" #define SATELLITE_SML_MASK_PMAP_ANIM "ship.chmmr.graphics.satellite.small" -#define CHMMR_RACE_STRINGS "ship.chmmr.text" -#define CHMMR_SHIP_SOUNDS "ship.chmmr.sounds" -#define CHMMR_VICTORY_SONG "ship.chmmr.ditty" - -#include "icode.h" diff --git a/sc2/src/uqm/ships/druuge/Makeinfo b/sc2/src/uqm/ships/druuge/Makeinfo index 67cb3dfd4..6687b5648 100644 --- a/sc2/src/uqm/ships/druuge/Makeinfo +++ b/sc2/src/uqm/ships/druuge/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="druuge.c" +uqm_HFILES="druuge.h icode.h resinst.h" diff --git a/sc2/src/uqm/ships/druuge/druuge.h b/sc2/src/uqm/ships/druuge/druuge.h index ec25d7752..f332bc328 100644 --- a/sc2/src/uqm/ships/druuge/druuge.h +++ b/sc2/src/uqm/ships/druuge/druuge.h @@ -17,7 +17,15 @@ #ifndef DRUUGE_H #define DRUUGE_H +#if defined(__cplusplus) +extern "C" { +#endif + RACE_DESC *init_druuge (void); +#if defined(__cplusplus) +} +#endif + #endif /* DRUUGE_H */ diff --git a/sc2/src/uqm/ships/druuge/icode.h b/sc2/src/uqm/ships/druuge/icode.h index b173fe0fe..859949011 100644 --- a/sc2/src/uqm/ships/druuge/icode.h +++ b/sc2/src/uqm/ships/druuge/icode.h @@ -1 +1,5 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define DRUUGE_CODE "ship.druuge.code" diff --git a/sc2/src/uqm/ships/druuge/resinst.h b/sc2/src/uqm/ships/druuge/resinst.h index 51960103d..2213ad9d8 100644 --- a/sc2/src/uqm/ships/druuge/resinst.h +++ b/sc2/src/uqm/ships/druuge/resinst.h @@ -1,3 +1,7 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define DRUUGE_BIG_MASK_PMAP_ANIM "ship.druuge.graphics.mauler.large" #define DRUUGE_CANNON_BIG_MASK_PMAP_ANIM "ship.druuge.graphics.cannon.large" #define DRUUGE_CANNON_MED_MASK_PMAP_ANIM "ship.druuge.graphics.cannon.medium" @@ -6,9 +10,7 @@ #define DRUUGE_ICON_MASK_PMAP_ANIM "ship.druuge.icons" #define DRUUGE_MED_MASK_PMAP_ANIM "ship.druuge.graphics.mauler.medium" #define DRUUGE_MICON_MASK_PMAP_ANIM "ship.druuge.meleeicons" -#define DRUUGE_SML_MASK_PMAP_ANIM "ship.druuge.graphics.mauler.small" #define DRUUGE_RACE_STRINGS "ship.druuge.text" #define DRUUGE_SHIP_SOUNDS "ship.druuge.sounds" +#define DRUUGE_SML_MASK_PMAP_ANIM "ship.druuge.graphics.mauler.small" #define DRUUGE_VICTORY_SONG "ship.druuge.ditty" - -#include "icode.h" diff --git a/sc2/src/uqm/ships/human/Makeinfo b/sc2/src/uqm/ships/human/Makeinfo index 912df63f1..f80f814fc 100644 --- a/sc2/src/uqm/ships/human/Makeinfo +++ b/sc2/src/uqm/ships/human/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="human.c" +uqm_HFILES="human.h icode.h resinst.h" diff --git a/sc2/src/uqm/ships/human/human.h b/sc2/src/uqm/ships/human/human.h index 7a1f18c85..6f7314d20 100644 --- a/sc2/src/uqm/ships/human/human.h +++ b/sc2/src/uqm/ships/human/human.h @@ -17,7 +17,15 @@ #ifndef HUMAN_H #define HUMAN_H +#if defined(__cplusplus) +extern "C" { +#endif + RACE_DESC *init_human (void); +#if defined(__cplusplus) +} +#endif + #endif /* HUMAN_H */ diff --git a/sc2/src/uqm/ships/human/icode.h b/sc2/src/uqm/ships/human/icode.h index 0700876fa..acfd62ec3 100644 --- a/sc2/src/uqm/ships/human/icode.h +++ b/sc2/src/uqm/ships/human/icode.h @@ -1 +1,5 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define HUMAN_CODE "ship.earthling.code" diff --git a/sc2/src/uqm/ships/human/resinst.h b/sc2/src/uqm/ships/human/resinst.h index b43c29953..3d4022ec1 100644 --- a/sc2/src/uqm/ships/human/resinst.h +++ b/sc2/src/uqm/ships/human/resinst.h @@ -1,14 +1,16 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define HUMAN_BIG_MASK_PMAP_ANIM "ship.earthling.graphics.human.large" #define HUMAN_CAPTAIN_MASK_PMAP_ANIM "ship.earthling.graphics.captain" #define HUMAN_ICON_MASK_PMAP_ANIM "ship.earthling.icons" #define HUMAN_MED_MASK_PMAP_ANIM "ship.earthling.graphics.human.medium" #define HUMAN_MICON_MASK_PMAP_ANIM "ship.earthling.meleeicons" +#define HUMAN_RACE_STRINGS "ship.earthling.text" +#define HUMAN_SHIP_SOUNDS "ship.earthling.sounds" #define HUMAN_SML_MASK_PMAP_ANIM "ship.earthling.graphics.human.small" +#define HUMAN_VICTORY_SONG "ship.earthling.ditty" #define SATURN_BIG_MASK_PMAP_ANIM "ship.earthling.graphics.saturn.large" #define SATURN_MED_MASK_PMAP_ANIM "ship.earthling.graphics.saturn.medium" #define SATURN_SML_MASK_PMAP_ANIM "ship.earthling.graphics.saturn.small" -#define HUMAN_RACE_STRINGS "ship.earthling.text" -#define HUMAN_SHIP_SOUNDS "ship.earthling.sounds" -#define HUMAN_VICTORY_SONG "ship.earthling.ditty" - -#include "icode.h" diff --git a/sc2/src/uqm/ships/ilwrath/Makeinfo b/sc2/src/uqm/ships/ilwrath/Makeinfo index e9f752f8a..cbc8f695e 100644 --- a/sc2/src/uqm/ships/ilwrath/Makeinfo +++ b/sc2/src/uqm/ships/ilwrath/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="ilwrath.c" +uqm_HFILES="icode.h ilwrath.h resinst.h" diff --git a/sc2/src/uqm/ships/ilwrath/icode.h b/sc2/src/uqm/ships/ilwrath/icode.h index 275cd9e77..fa78adc05 100644 --- a/sc2/src/uqm/ships/ilwrath/icode.h +++ b/sc2/src/uqm/ships/ilwrath/icode.h @@ -1 +1,5 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define ILWRATH_CODE "ship.ilwrath.code" diff --git a/sc2/src/uqm/ships/ilwrath/ilwrath.h b/sc2/src/uqm/ships/ilwrath/ilwrath.h index e5914767d..a442b9d5c 100644 --- a/sc2/src/uqm/ships/ilwrath/ilwrath.h +++ b/sc2/src/uqm/ships/ilwrath/ilwrath.h @@ -17,7 +17,15 @@ #ifndef ILWRATH_H #define ILWRATH_H +#if defined(__cplusplus) +extern "C" { +#endif + RACE_DESC *init_ilwrath (void); +#if defined(__cplusplus) +} +#endif + #endif /* ILWRATH_H */ diff --git a/sc2/src/uqm/ships/ilwrath/resinst.h b/sc2/src/uqm/ships/ilwrath/resinst.h index ae9f8f8b0..46cb53a1d 100644 --- a/sc2/src/uqm/ships/ilwrath/resinst.h +++ b/sc2/src/uqm/ships/ilwrath/resinst.h @@ -1,3 +1,7 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define FIRE_BIG_MASK_PMAP_ANIM "ship.ilwrath.graphics.fire.large" #define FIRE_MED_MASK_PMAP_ANIM "ship.ilwrath.graphics.fire.medium" #define FIRE_SML_MASK_PMAP_ANIM "ship.ilwrath.graphics.fire.small" @@ -6,9 +10,7 @@ #define ILWRATH_ICON_MASK_PMAP_ANIM "ship.ilwrath.icons" #define ILWRATH_MED_MASK_PMAP_ANIM "ship.ilwrath.graphics.avenger.medium" #define ILWRATH_MICON_MASK_PMAP_ANIM "ship.ilwrath.meleeicons" -#define ILWRATH_SML_MASK_PMAP_ANIM "ship.ilwrath.graphics.avenger.small" #define ILWRATH_RACE_STRINGS "ship.ilwrath.text" #define ILWRATH_SHIP_SOUNDS "ship.ilwrath.sounds" +#define ILWRATH_SML_MASK_PMAP_ANIM "ship.ilwrath.graphics.avenger.small" #define ILWRATH_VICTORY_SONG "ship.ilwrath.ditty" - -#include "icode.h" diff --git a/sc2/src/uqm/ships/lastbat/Makeinfo b/sc2/src/uqm/ships/lastbat/Makeinfo index 5a04249ed..589d8d09c 100644 --- a/sc2/src/uqm/ships/lastbat/Makeinfo +++ b/sc2/src/uqm/ships/lastbat/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="lastbat.c" +uqm_HFILES="icode.h lastbat.h resinst.h" diff --git a/sc2/src/uqm/ships/lastbat/icode.h b/sc2/src/uqm/ships/lastbat/icode.h index d0b2e5c6c..087c891b6 100644 --- a/sc2/src/uqm/ships/lastbat/icode.h +++ b/sc2/src/uqm/ships/lastbat/icode.h @@ -1 +1,5 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define SAMATRA_CODE "ship.samatra.code" diff --git a/sc2/src/uqm/ships/lastbat/lastbat.h b/sc2/src/uqm/ships/lastbat/lastbat.h index abd7658e8..ccda7f164 100644 --- a/sc2/src/uqm/ships/lastbat/lastbat.h +++ b/sc2/src/uqm/ships/lastbat/lastbat.h @@ -17,7 +17,15 @@ #ifndef LASTBAT_H #define LASTBAT_H +#if defined(__cplusplus) +extern "C" { +#endif + RACE_DESC *init_samatra (void); +#if defined(__cplusplus) +} +#endif + #endif /* LASTBAT_H */ diff --git a/sc2/src/uqm/ships/lastbat/resinst.h b/sc2/src/uqm/ships/lastbat/resinst.h index 389c637f4..779c00a04 100644 --- a/sc2/src/uqm/ships/lastbat/resinst.h +++ b/sc2/src/uqm/ships/lastbat/resinst.h @@ -1,14 +1,16 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define GENERATOR_BIG_MASK_ANIM "ship.samatra.graphics.generator.large" #define GENERATOR_MED_MASK_PMAP_ANIM "ship.samatra.graphics.generator.medium" #define GENERATOR_SML_MASK_PMAP_ANIM "ship.samatra.graphics.generator.small" #define SAMATRA_BIG_MASK_ANIM "ship.samatra.graphics.samatra.large" #define SAMATRA_CAPTAIN_MASK_PMAP_ANIM "ship.samatra.graphics.captain" #define SAMATRA_MED_MASK_PMAP_ANIM "ship.samatra.graphics.samatra.medium" +#define SAMATRA_SHIP_SOUNDS "ship.samatra.sounds" #define SAMATRA_SML_MASK_PMAP_ANIM "ship.samatra.graphics.samatra.small" +#define SAMATRA_VICTORY_SONG "ship.samatra.ditty" #define SENTINEL_BIG_MASK_ANIM "ship.samatra.graphics.sentinel.large" #define SENTINEL_MED_MASK_PMAP_ANIM "ship.samatra.graphics.sentinel.medium" #define SENTINEL_SML_MASK_PMAP_ANIM "ship.samatra.graphics.sentinel.small" -#define SAMATRA_SHIP_SOUNDS "ship.samatra.sounds" -#define SAMATRA_VICTORY_SONG "ship.samatra.ditty" - -#include "icode.h" diff --git a/sc2/src/uqm/ships/melnorme/Makeinfo b/sc2/src/uqm/ships/melnorme/Makeinfo index 8fed3db18..f5bb991c2 100644 --- a/sc2/src/uqm/ships/melnorme/Makeinfo +++ b/sc2/src/uqm/ships/melnorme/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="melnorme.c" +uqm_HFILES="icode.h melnorme.h resinst.h" diff --git a/sc2/src/uqm/ships/melnorme/icode.h b/sc2/src/uqm/ships/melnorme/icode.h index 53b39c09a..d9dd355f5 100644 --- a/sc2/src/uqm/ships/melnorme/icode.h +++ b/sc2/src/uqm/ships/melnorme/icode.h @@ -1 +1,5 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define MELNORME_CODE "ship.melnorme.code" diff --git a/sc2/src/uqm/ships/melnorme/melnorme.h b/sc2/src/uqm/ships/melnorme/melnorme.h index 4fb6254bc..287ec76d1 100644 --- a/sc2/src/uqm/ships/melnorme/melnorme.h +++ b/sc2/src/uqm/ships/melnorme/melnorme.h @@ -17,7 +17,15 @@ #ifndef MELNORME_H #define MELNORME_H +#if defined(__cplusplus) +extern "C" { +#endif + RACE_DESC *init_melnorme (void); +#if defined(__cplusplus) +} +#endif + #endif /* MELNORME_H */ diff --git a/sc2/src/uqm/ships/melnorme/resinst.h b/sc2/src/uqm/ships/melnorme/resinst.h index a42872f4c..01b93df64 100644 --- a/sc2/src/uqm/ships/melnorme/resinst.h +++ b/sc2/src/uqm/ships/melnorme/resinst.h @@ -1,3 +1,7 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define CONFUSE_BIG_MASK_PMAP_ANIM "ship.melnorme.graphics.confuse.large" #define CONFUSE_MED_MASK_PMAP_ANIM "ship.melnorme.graphics.confuse.medium" #define CONFUSE_SML_MASK_PMAP_ANIM "ship.melnorme.graphics.confuse.small" @@ -6,12 +10,10 @@ #define MELNORME_ICON_MASK_PMAP_ANIM "ship.melnorme.icons" #define MELNORME_MED_MASK_PMAP_ANIM "ship.melnorme.graphics.trader.medium" #define MELNORME_MICON_MASK_PMAP_ANIM "ship.melnorme.meleeicons" +#define MELNORME_RACE_STRINGS "ship.melnorme.text" +#define MELNORME_SHIP_SOUNDS "ship.melnorme.sounds" #define MELNORME_SML_MASK_PMAP_ANIM "ship.melnorme.graphics.trader.small" +#define MELNORME_VICTORY_SONG "ship.melnorme.ditty" #define PUMPUP_BIG_MASK_PMAP_ANIM "ship.melnorme.graphics.pumpup.large" #define PUMPUP_MED_MASK_PMAP_ANIM "ship.melnorme.graphics.pumpup.medium" #define PUMPUP_SML_MASK_PMAP_ANIM "ship.melnorme.graphics.pumpup.small" -#define MELNORME_RACE_STRINGS "ship.melnorme.text" -#define MELNORME_SHIP_SOUNDS "ship.melnorme.sounds" -#define MELNORME_VICTORY_SONG "ship.melnorme.ditty" - -#include "icode.h" diff --git a/sc2/src/uqm/ships/mmrnmhrm/Makeinfo b/sc2/src/uqm/ships/mmrnmhrm/Makeinfo index 4176e4754..0c8663754 100644 --- a/sc2/src/uqm/ships/mmrnmhrm/Makeinfo +++ b/sc2/src/uqm/ships/mmrnmhrm/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="mmrnmhrm.c" +uqm_HFILES="icode.h mmrnmhrm.h resinst.h" diff --git a/sc2/src/uqm/ships/mmrnmhrm/icode.h b/sc2/src/uqm/ships/mmrnmhrm/icode.h index 7a9457c9a..ba3f593b5 100644 --- a/sc2/src/uqm/ships/mmrnmhrm/icode.h +++ b/sc2/src/uqm/ships/mmrnmhrm/icode.h @@ -1 +1,5 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define MMRNMHRM_CODE "ship.mmrnmhrm.code" diff --git a/sc2/src/uqm/ships/mmrnmhrm/mmrnmhrm.c b/sc2/src/uqm/ships/mmrnmhrm/mmrnmhrm.c index e6886129e..bc5ed0d60 100644 --- a/sc2/src/uqm/ships/mmrnmhrm/mmrnmhrm.c +++ b/sc2/src/uqm/ships/mmrnmhrm/mmrnmhrm.c @@ -124,6 +124,41 @@ static RACE_DESC mmrnmhrm_desc = #define MISSILE_SPEED DISPLAY_TO_WORLD (20) #define TRACK_WAIT 5 +// Private per-instance ship data +typedef CHARACTERISTIC_STUFF MMRNMHRM_DATA; + +// Local typedef +typedef MMRNMHRM_DATA CustomShipData_t; + +// Retrieve race-specific ship data from a race desc +static CustomShipData_t * +GetCustomShipData (RACE_DESC *pRaceDesc) +{ + return pRaceDesc->data; +} + +// Set the race-specific data in a race desc +// (Re)Allocates its own storage for the data. +static void +SetCustomShipData (RACE_DESC *pRaceDesc, const CustomShipData_t *data) +{ + if (pRaceDesc->data == data) + return; // no-op + + if (pRaceDesc->data) // Out with the old + { + HFree (pRaceDesc->data); + pRaceDesc->data = NULL; + } + + if (data) // In with the new + { + CustomShipData_t* newData = HMalloc (sizeof (*data)); + *newData = *data; + pRaceDesc->data = newData; + } +} + static void missile_preprocess (ELEMENT *ElementPtr) { @@ -363,8 +398,8 @@ mmrnmhrm_postprocess (ELEMENT *ElementPtr) /* take care of transform effect */ if (ElementPtr->next.image.farray != ElementPtr->current.image.farray) { - CHARACTERISTIC_STUFF t; - CHARACTERISTIC_STUFF *otherwing_desc; + MMRNMHRM_DATA tempShipData; + MMRNMHRM_DATA *otherwing_desc; ProcessSound (SetAbsSoundIndex ( /* TRANSFORM */ @@ -373,11 +408,13 @@ mmrnmhrm_postprocess (ELEMENT *ElementPtr) StarShipPtr->weapon_counter = 0; /* Swap characteristics descriptors around */ - otherwing_desc = (CHARACTERISTIC_STUFF *) - StarShipPtr->RaceDescPtr->data; - t = *otherwing_desc; - *otherwing_desc = StarShipPtr->RaceDescPtr->characteristics; - StarShipPtr->RaceDescPtr->characteristics = t; + otherwing_desc = GetCustomShipData (StarShipPtr->RaceDescPtr); + if (!otherwing_desc) + return; // No ship data (?!) + + tempShipData = *otherwing_desc; + SetCustomShipData (StarShipPtr->RaceDescPtr, &StarShipPtr->RaceDescPtr->characteristics); + StarShipPtr->RaceDescPtr->characteristics = tempShipData; StarShipPtr->RaceDescPtr->cyborg_control.ManeuverabilityIndex = 0; if (ElementPtr->next.image.farray == StarShipPtr->RaceDescPtr->ship_data.special) @@ -444,17 +481,16 @@ mmrnmhrm_preprocess (ELEMENT *ElementPtr) static void uninit_mmrnmhrm (RACE_DESC *pRaceDesc) { - HFree ((void *)pRaceDesc->data); - pRaceDesc->data = 0; + SetCustomShipData (pRaceDesc, NULL); } RACE_DESC* init_mmrnmhrm (void) { RACE_DESC *RaceDescPtr; - + // The caller of this func will copy the struct static RACE_DESC new_mmrnmhrm_desc; - CHARACTERISTIC_STUFF *otherwing_desc; + MMRNMHRM_DATA otherwing_desc; mmrnmhrm_desc.uninit_func = uninit_mmrnmhrm; mmrnmhrm_desc.preprocess_func = mmrnmhrm_preprocess; @@ -464,20 +500,19 @@ init_mmrnmhrm (void) new_mmrnmhrm_desc = mmrnmhrm_desc; - otherwing_desc = HMalloc (sizeof (*otherwing_desc)); - otherwing_desc->max_thrust = YWING_MAX_THRUST; - otherwing_desc->thrust_increment = YWING_THRUST_INCREMENT; - otherwing_desc->energy_regeneration = YWING_ENERGY_REGENERATION; - otherwing_desc->weapon_energy_cost = YWING_WEAPON_ENERGY_COST; - otherwing_desc->special_energy_cost = YWING_SPECIAL_ENERGY_COST; - otherwing_desc->energy_wait = YWING_ENERGY_WAIT; - otherwing_desc->turn_wait = YWING_TURN_WAIT; - otherwing_desc->thrust_wait = YWING_THRUST_WAIT; - otherwing_desc->weapon_wait = YWING_WEAPON_WAIT; - otherwing_desc->special_wait = YWING_SPECIAL_WAIT; - otherwing_desc->ship_mass = SHIP_MASS; + otherwing_desc.max_thrust = YWING_MAX_THRUST; + otherwing_desc.thrust_increment = YWING_THRUST_INCREMENT; + otherwing_desc.energy_regeneration = YWING_ENERGY_REGENERATION; + otherwing_desc.weapon_energy_cost = YWING_WEAPON_ENERGY_COST; + otherwing_desc.special_energy_cost = YWING_SPECIAL_ENERGY_COST; + otherwing_desc.energy_wait = YWING_ENERGY_WAIT; + otherwing_desc.turn_wait = YWING_TURN_WAIT; + otherwing_desc.thrust_wait = YWING_THRUST_WAIT; + otherwing_desc.weapon_wait = YWING_WEAPON_WAIT; + otherwing_desc.special_wait = YWING_SPECIAL_WAIT; + otherwing_desc.ship_mass = SHIP_MASS; - new_mmrnmhrm_desc.data = (intptr_t) otherwing_desc; + SetCustomShipData (&new_mmrnmhrm_desc, &otherwing_desc); RaceDescPtr = &new_mmrnmhrm_desc; diff --git a/sc2/src/uqm/ships/mmrnmhrm/mmrnmhrm.h b/sc2/src/uqm/ships/mmrnmhrm/mmrnmhrm.h index a942f9ac4..c2c851267 100644 --- a/sc2/src/uqm/ships/mmrnmhrm/mmrnmhrm.h +++ b/sc2/src/uqm/ships/mmrnmhrm/mmrnmhrm.h @@ -17,7 +17,15 @@ #ifndef MMRNMHRM_H #define MMRNMHRM_H +#if defined(__cplusplus) +extern "C" { +#endif + RACE_DESC *init_mmrnmhrm (void); +#if defined(__cplusplus) +} +#endif + #endif /* MMRNMHRM_H */ diff --git a/sc2/src/uqm/ships/mmrnmhrm/resinst.h b/sc2/src/uqm/ships/mmrnmhrm/resinst.h index 154535b09..f44285f64 100644 --- a/sc2/src/uqm/ships/mmrnmhrm/resinst.h +++ b/sc2/src/uqm/ships/mmrnmhrm/resinst.h @@ -1,17 +1,19 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define MMRNMHRM_BIG_MASK_PMAP_ANIM "ship.mmrnmhrm.graphics.xform.large" #define MMRNMHRM_CAPTAIN_MASK_PMAP_ANIM "ship.mmrnmhrm.graphics.captain" #define MMRNMHRM_ICON_MASK_PMAP_ANIM "ship.mmrnmhrm.icons" #define MMRNMHRM_MED_MASK_PMAP_ANIM "ship.mmrnmhrm.graphics.xform.medium" #define MMRNMHRM_MICON_MASK_PMAP_ANIM "ship.mmrnmhrm.meleeicons" +#define MMRNMHRM_RACE_STRINGS "ship.mmrnmhrm.text" +#define MMRNMHRM_SHIP_SOUNDS "ship.mmrnmhrm.sounds" #define MMRNMHRM_SML_MASK_PMAP_ANIM "ship.mmrnmhrm.graphics.xform.small" +#define MMRNMHRM_VICTORY_SONG "ship.mmrnmhrm.ditty" #define TORP_BIG_MASK_PMAP_ANIM "ship.mmrnmhrm.graphics.torpedo.large" #define TORP_MED_MASK_PMAP_ANIM "ship.mmrnmhrm.graphics.torpedo.medium" #define TORP_SML_MASK_PMAP_ANIM "ship.mmrnmhrm.graphics.torpedo.small" #define YWING_BIG_MASK_PMAP_ANIM "ship.mmrnmhrm.graphics.ywing.large" #define YWING_MED_MASK_PMAP_ANIM "ship.mmrnmhrm.graphics.ywing.medium" #define YWING_SML_MASK_PMAP_ANIM "ship.mmrnmhrm.graphics.ywing.small" -#define MMRNMHRM_RACE_STRINGS "ship.mmrnmhrm.text" -#define MMRNMHRM_SHIP_SOUNDS "ship.mmrnmhrm.sounds" -#define MMRNMHRM_VICTORY_SONG "ship.mmrnmhrm.ditty" - -#include "icode.h" diff --git a/sc2/src/uqm/ships/mycon/Makeinfo b/sc2/src/uqm/ships/mycon/Makeinfo index 860f6ba4a..0ba898807 100644 --- a/sc2/src/uqm/ships/mycon/Makeinfo +++ b/sc2/src/uqm/ships/mycon/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="mycon.c" +uqm_HFILES="icode.h mycon.h resinst.h" diff --git a/sc2/src/uqm/ships/mycon/icode.h b/sc2/src/uqm/ships/mycon/icode.h index 067afbc03..b3caa5819 100644 --- a/sc2/src/uqm/ships/mycon/icode.h +++ b/sc2/src/uqm/ships/mycon/icode.h @@ -1 +1,5 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define MYCON_CODE "ship.mycon.code" diff --git a/sc2/src/uqm/ships/mycon/mycon.h b/sc2/src/uqm/ships/mycon/mycon.h index f536532af..8051b7ccc 100644 --- a/sc2/src/uqm/ships/mycon/mycon.h +++ b/sc2/src/uqm/ships/mycon/mycon.h @@ -17,7 +17,15 @@ #ifndef MYCON_H #define MYCON_H +#if defined(__cplusplus) +extern "C" { +#endif + RACE_DESC *init_mycon (void); +#if defined(__cplusplus) +} +#endif + #endif /* MYCON_H */ diff --git a/sc2/src/uqm/ships/mycon/resinst.h b/sc2/src/uqm/ships/mycon/resinst.h index 4a74e4449..38908a2ba 100644 --- a/sc2/src/uqm/ships/mycon/resinst.h +++ b/sc2/src/uqm/ships/mycon/resinst.h @@ -1,14 +1,16 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define MYCON_BIG_MASK_PMAP_ANIM "ship.mycon.graphics.podship.large" #define MYCON_CAPTAIN_MASK_PMAP_ANIM "ship.mycon.graphics.captain" #define MYCON_ICON_MASK_PMAP_ANIM "ship.mycon.icons" #define MYCON_MED_MASK_PMAP_ANIM "ship.mycon.graphics.podship.medium" #define MYCON_MICON_MASK_PMAP_ANIM "ship.mycon.meleeicons" +#define MYCON_RACE_STRINGS "ship.mycon.text" +#define MYCON_SHIP_SOUNDS "ship.mycon.sounds" #define MYCON_SML_MASK_PMAP_ANIM "ship.mycon.graphics.podship.small" +#define MYCON_VICTORY_SONG "ship.mycon.ditty" #define PLASMA_BIG_MASK_PMAP_ANIM "ship.mycon.graphics.plasma.large" #define PLASMA_MED_MASK_PMAP_ANIM "ship.mycon.graphics.plasma.medium" #define PLASMA_SML_MASK_PMAP_ANIM "ship.mycon.graphics.plasma.small" -#define MYCON_RACE_STRINGS "ship.mycon.text" -#define MYCON_SHIP_SOUNDS "ship.mycon.sounds" -#define MYCON_VICTORY_SONG "ship.mycon.ditty" - -#include "icode.h" diff --git a/sc2/src/uqm/ships/orz/Makeinfo b/sc2/src/uqm/ships/orz/Makeinfo index 89cbbfb63..0c4961df2 100644 --- a/sc2/src/uqm/ships/orz/Makeinfo +++ b/sc2/src/uqm/ships/orz/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="orz.c" +uqm_HFILES="icode.h orz.h resinst.h" diff --git a/sc2/src/uqm/ships/orz/icode.h b/sc2/src/uqm/ships/orz/icode.h index 0d3349081..bb45c4e35 100644 --- a/sc2/src/uqm/ships/orz/icode.h +++ b/sc2/src/uqm/ships/orz/icode.h @@ -1 +1,5 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define ORZ_CODE "ship.orz.code" diff --git a/sc2/src/uqm/ships/orz/orz.h b/sc2/src/uqm/ships/orz/orz.h index 28693a9a4..a62caacef 100644 --- a/sc2/src/uqm/ships/orz/orz.h +++ b/sc2/src/uqm/ships/orz/orz.h @@ -17,11 +17,19 @@ #ifndef ORZ_H #define ORZ_H +#if defined(__cplusplus) +extern "C" { +#endif + RACE_DESC *init_orz (void); void intruder_preprocess (ELEMENT *ElementPtr); void marine_collision (ELEMENT *ElementPtr0, POINT *pPt0, ELEMENT *ElementPtr1, POINT *pPt1); +#if defined(__cplusplus) +} +#endif + #endif /* ORZ_H */ diff --git a/sc2/src/uqm/ships/orz/resinst.h b/sc2/src/uqm/ships/orz/resinst.h index 4a43a858d..4af5264dc 100644 --- a/sc2/src/uqm/ships/orz/resinst.h +++ b/sc2/src/uqm/ships/orz/resinst.h @@ -1,3 +1,7 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define HOWITZER_BIG_MASK_PMAP_ANIM "ship.orz.graphics.howitzer.large" #define HOWITZER_MED_MASK_PMAP_ANIM "ship.orz.graphics.howitzer.medium" #define HOWITZER_SML_MASK_PMAP_ANIM "ship.orz.graphics.howitzer.small" @@ -6,12 +10,10 @@ #define ORZ_ICON_MASK_PMAP_ANIM "ship.orz.icons" #define ORZ_MED_MASK_PMAP_ANIM "ship.orz.graphics.nemesis.medium" #define ORZ_MICON_MASK_PMAP_ANIM "ship.orz.meleeicons" +#define ORZ_RACE_STRINGS "ship.orz.text" +#define ORZ_SHIP_SOUNDS "ship.orz.sounds" #define ORZ_SML_MASK_PMAP_ANIM "ship.orz.graphics.nemesis.small" +#define ORZ_VICTORY_SONG "ship.orz.ditty" #define TURRET_BIG_MASK_PMAP_ANIM "ship.orz.graphics.turret.large" #define TURRET_MED_MASK_PMAP_ANIM "ship.orz.graphics.turret.medium" #define TURRET_SML_MASK_PMAP_ANIM "ship.orz.graphics.turret.small" -#define ORZ_RACE_STRINGS "ship.orz.text" -#define ORZ_SHIP_SOUNDS "ship.orz.sounds" -#define ORZ_VICTORY_SONG "ship.orz.ditty" - -#include "icode.h" diff --git a/sc2/src/uqm/ships/pkunk/Makeinfo b/sc2/src/uqm/ships/pkunk/Makeinfo index ce5fcd3ea..54d92b0c9 100644 --- a/sc2/src/uqm/ships/pkunk/Makeinfo +++ b/sc2/src/uqm/ships/pkunk/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="pkunk.c" +uqm_HFILES="icode.h pkunk.h resinst.h" diff --git a/sc2/src/uqm/ships/pkunk/icode.h b/sc2/src/uqm/ships/pkunk/icode.h index 2893b749b..4d0d4e51f 100644 --- a/sc2/src/uqm/ships/pkunk/icode.h +++ b/sc2/src/uqm/ships/pkunk/icode.h @@ -1 +1,5 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define PKUNK_CODE "ship.pkunk.code" diff --git a/sc2/src/uqm/ships/pkunk/pkunk.c b/sc2/src/uqm/ships/pkunk/pkunk.c index b1a7af85e..6e8902e07 100644 --- a/sc2/src/uqm/ships/pkunk/pkunk.c +++ b/sc2/src/uqm/ships/pkunk/pkunk.c @@ -21,6 +21,7 @@ #include "resinst.h" #include "uqm/globdata.h" +#include "uqm/tactrans.h" #include "libs/mathlib.h" @@ -112,6 +113,48 @@ static RACE_DESC pkunk_desc = 0, /* CodeRef */ }; +// Private per-instance ship data +typedef struct +{ + HELEMENT hPhoenix; + ElementProcessFunc *saved_preprocess_func; + ElementProcessFunc *saved_postprocess_func; + ElementProcessFunc *saved_death_func; + +} PKUNK_DATA; + +// Local typedef +typedef PKUNK_DATA CustomShipData_t; + +// Retrieve race-specific ship data from a race desc +static CustomShipData_t * +GetCustomShipData (RACE_DESC *pRaceDesc) +{ + return pRaceDesc->data; +} + +// Set the race-specific data in a race desc +// (Re)Allocates its own storage for the data. +static void +SetCustomShipData (RACE_DESC *pRaceDesc, const CustomShipData_t *data) +{ + if (pRaceDesc->data == data) + return; // no-op + + if (pRaceDesc->data) // Out with the old + { + HFree (pRaceDesc->data); + pRaceDesc->data = NULL; + } + + if (data) // In with the new + { + CustomShipData_t* newData = HMalloc (sizeof (*data)); + *newData = *data; + pRaceDesc->data = newData; + } +} + static void animate (ELEMENT *ElementPtr) { @@ -186,15 +229,15 @@ pkunk_intelligence (ELEMENT *ShipPtr, EVALUATE_DESC *ObjectsOfConcern, COUNT ConcernCounter) { STARSHIP *StarShipPtr; - HELEMENT hPhoenix; + PKUNK_DATA *PkunkData; GetElementStarShip (ShipPtr, &StarShipPtr); - hPhoenix = (HELEMENT) StarShipPtr->RaceDescPtr->data; - if (hPhoenix && (StarShipPtr->control & STANDARD_RATING)) + PkunkData = GetCustomShipData (StarShipPtr->RaceDescPtr); + if (PkunkData->hPhoenix && (StarShipPtr->control & STANDARD_RATING)) { - RemoveElement (hPhoenix); - FreeElement (hPhoenix); - StarShipPtr->RaceDescPtr->data = 0; + RemoveElement (PkunkData->hPhoenix); + FreeElement (PkunkData->hPhoenix); + PkunkData->hPhoenix = 0; } if (StarShipPtr->RaceDescPtr->ship_info.energy_level < @@ -208,108 +251,116 @@ pkunk_intelligence (ELEMENT *ShipPtr, EVALUATE_DESC *ObjectsOfConcern, } static void pkunk_preprocess (ELEMENT *ElementPtr); -static void pkunk_postprocess (ELEMENT *ElementPtr); static void new_pkunk (ELEMENT *ElementPtr) { STARSHIP *StarShipPtr; + PKUNK_DATA *PkunkData; GetElementStarShip (ElementPtr, &StarShipPtr); - if (!(ElementPtr->state_flags & PLAYER_SHIP)) + PkunkData = GetCustomShipData (StarShipPtr->RaceDescPtr); + + ElementPtr->state_flags = APPEARING | PLAYER_SHIP | IGNORE_SIMILAR; + ElementPtr->mass_points = SHIP_MASS; + // Restore the element processing callbacks after the explosion. + // The callbacks were changed for the explosion sequence + ElementPtr->preprocess_func = PkunkData->saved_preprocess_func; + ElementPtr->postprocess_func = PkunkData->saved_postprocess_func; + ElementPtr->death_func = PkunkData->saved_death_func; + // preprocess_func() is called during the phoenix transition and + // then cleared, so we need to restore it + StarShipPtr->RaceDescPtr->preprocess_func = pkunk_preprocess; + StarShipPtr->RaceDescPtr->ship_info.crew_level = MAX_CREW; + StarShipPtr->RaceDescPtr->ship_info.energy_level = MAX_ENERGY; + /* fix vux impairment */ + StarShipPtr->RaceDescPtr->characteristics.max_thrust = MAX_THRUST; + StarShipPtr->RaceDescPtr->characteristics.thrust_increment = THRUST_INCREMENT; + StarShipPtr->RaceDescPtr->characteristics.turn_wait = TURN_WAIT; + StarShipPtr->RaceDescPtr->characteristics.thrust_wait = THRUST_WAIT; + StarShipPtr->RaceDescPtr->characteristics.special_wait = 0; + + StarShipPtr->ship_input_state = 0; + // Pkunk wins in a simultaneous destruction if it reincarnates + StarShipPtr->cur_status_flags &= PLAY_VICTORY_DITTY; + StarShipPtr->old_status_flags = 0; + StarShipPtr->energy_counter = 0; + StarShipPtr->weapon_counter = 0; + StarShipPtr->special_counter = 0; + ElementPtr->crew_level = 0; + ElementPtr->turn_wait = 0; + ElementPtr->thrust_wait = 0; + ElementPtr->life_span = NORMAL_LIFE; + + StarShipPtr->ShipFacing = NORMALIZE_FACING (TFB_Random ()); + ElementPtr->current.image.farray = StarShipPtr->RaceDescPtr->ship_data.ship; + ElementPtr->current.image.frame = SetAbsFrameIndex ( + StarShipPtr->RaceDescPtr->ship_data.ship[0], + StarShipPtr->ShipFacing); + SetPrimType (&(GLOBAL (DisplayArray))[ElementPtr->PrimIndex], STAMP_PRIM); + + do { - ELEMENT *ShipPtr; + ElementPtr->current.location.x = + WRAP_X (DISPLAY_ALIGN_X (TFB_Random ())); + ElementPtr->current.location.y = + WRAP_Y (DISPLAY_ALIGN_Y (TFB_Random ())); + } while (CalculateGravity (ElementPtr) + || TimeSpaceMatterConflict (ElementPtr)); - LockElement (StarShipPtr->hShip, &ShipPtr); - ShipPtr->death_func = new_pkunk; - UnlockElement (StarShipPtr->hShip); - } - else - { - ElementPtr->state_flags = APPEARING | PLAYER_SHIP | IGNORE_SIMILAR; - ElementPtr->mass_points = SHIP_MASS; - ElementPtr->preprocess_func = StarShipPtr->RaceDescPtr->preprocess_func; - ElementPtr->postprocess_func = StarShipPtr->RaceDescPtr->postprocess_func; - ElementPtr->death_func = - (void (*) (ELEMENT *ElementPtr)) - StarShipPtr->RaceDescPtr->init_weapon_func; - StarShipPtr->RaceDescPtr->preprocess_func = pkunk_preprocess; - StarShipPtr->RaceDescPtr->postprocess_func = pkunk_postprocess; - StarShipPtr->RaceDescPtr->init_weapon_func = initialize_bug_missile; - StarShipPtr->RaceDescPtr->ship_info.crew_level = MAX_CREW; - StarShipPtr->RaceDescPtr->ship_info.energy_level = MAX_ENERGY; - /* fix vux impairment */ - StarShipPtr->RaceDescPtr->characteristics.max_thrust = MAX_THRUST; - StarShipPtr->RaceDescPtr->characteristics.thrust_increment = THRUST_INCREMENT; - StarShipPtr->RaceDescPtr->characteristics.turn_wait = TURN_WAIT; - StarShipPtr->RaceDescPtr->characteristics.thrust_wait = THRUST_WAIT; - StarShipPtr->RaceDescPtr->characteristics.special_wait = 0; + // XXX: Hack: Set hTarget!=0 so that ship_preprocess() does not + // call ship_transition() for us. + ElementPtr->hTarget = StarShipPtr->hShip; +} - StarShipPtr->ship_input_state = 0; - StarShipPtr->cur_status_flags = 0; - StarShipPtr->old_status_flags = 0; - StarShipPtr->energy_counter = 0; - StarShipPtr->weapon_counter = 0; - StarShipPtr->special_counter = 0; - ElementPtr->crew_level = 0; - ElementPtr->turn_wait = 0; - ElementPtr->thrust_wait = 0; - ElementPtr->life_span = NORMAL_LIFE; - - StarShipPtr->ShipFacing = NORMALIZE_FACING (TFB_Random ()); - ElementPtr->current.image.farray = StarShipPtr->RaceDescPtr->ship_data.ship; - ElementPtr->current.image.frame = - SetAbsFrameIndex (StarShipPtr->RaceDescPtr->ship_data.ship[0], - StarShipPtr->ShipFacing); - SetPrimType (&(GLOBAL (DisplayArray))[ - ElementPtr->PrimIndex - ], STAMP_PRIM); - - do - { - ElementPtr->current.location.x = - WRAP_X (DISPLAY_ALIGN_X (TFB_Random ())); - ElementPtr->current.location.y = - WRAP_Y (DISPLAY_ALIGN_Y (TFB_Random ())); - } while (CalculateGravity (ElementPtr) - || TimeSpaceMatterConflict (ElementPtr)); - - ElementPtr->hTarget = StarShipPtr->hShip; - } +// This function is called when the ship dies but reincarnates. +// The generic ship_death() function is not called for the ship in this case. +static void +pkunk_reincarnation_death (ELEMENT *ShipPtr) +{ + // Simulate ship death + StopAllBattleMusic (); + StartShipExplosion (ShipPtr, true); + // Once the explosion ends, we will get a brand new ship + ShipPtr->death_func = new_pkunk; } static void intercept_pkunk_death (ELEMENT *ElementPtr) { STARSHIP *StarShipPtr; - - ElementPtr->state_flags &= ~DISAPPEARING; - ElementPtr->life_span = 1; + PKUNK_DATA *PkunkData; + ELEMENT *ShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); - if (StarShipPtr->RaceDescPtr->ship_info.crew_level == 0) - { - ELEMENT *ShipPtr; - - LockElement (StarShipPtr->hShip, &ShipPtr); - if (GRAVITY_MASS (ShipPtr->mass_points + 1)) - { - ElementPtr->state_flags |= DISAPPEARING; - ElementPtr->life_span = 0; - } - else - { - ShipPtr->mass_points = MAX_SHIP_MASS + 1; - StarShipPtr->RaceDescPtr->preprocess_func = ShipPtr->preprocess_func; - StarShipPtr->RaceDescPtr->postprocess_func = ShipPtr->postprocess_func; - StarShipPtr->RaceDescPtr->init_weapon_func = - (COUNT (*) (ELEMENT *ElementPtr, HELEMENT Weapon[])) - ShipPtr->death_func; - - ElementPtr->death_func = new_pkunk; - } - UnlockElement (StarShipPtr->hShip); + PkunkData = GetCustomShipData (StarShipPtr->RaceDescPtr); + + if (StarShipPtr->RaceDescPtr->ship_info.crew_level != 0) + { // Ship not dead yet. + // Keep the Phoenix element alive. + ElementPtr->state_flags &= ~DISAPPEARING; + ElementPtr->life_span = 1; + return; } + + LockElement (StarShipPtr->hShip, &ShipPtr); + // GRAVITY_MASS() indicates a warp-out here. If Pkunk dies while warping + // out, there is no reincarnation. + if (!GRAVITY_MASS (ShipPtr->mass_points + 1)) + { + // XXX: Hack: Set mass_points to indicate a reincarnation to + // FindAliveStarShip() + ShipPtr->mass_points = MAX_SHIP_MASS + 1; + // Save the various element processing callbacks before the + // explosion happens, because we were not the ones who set + // these callbacks and they are about to be changed. + PkunkData->saved_preprocess_func = ShipPtr->preprocess_func; + PkunkData->saved_postprocess_func = ShipPtr->postprocess_func; + PkunkData->saved_death_func = ShipPtr->death_func; + + ShipPtr->death_func = pkunk_reincarnation_death; + } + UnlockElement (StarShipPtr->hShip); } #define START_PHOENIX_COLOR BUILD_COLOR (MAKE_RGB15 (0x1F, 0x15, 0x00), 0x7A) @@ -425,15 +476,22 @@ static void pkunk_preprocess (ELEMENT *ElementPtr) { STARSHIP *StarShipPtr; + PKUNK_DATA *PkunkData; GetElementStarShip (ElementPtr, &StarShipPtr); + PkunkData = GetCustomShipData (StarShipPtr->RaceDescPtr); if (ElementPtr->state_flags & APPEARING) { HELEMENT hPhoenix = 0; - if ((BYTE)TFB_Random () & 1) + if (TFB_Random () & 1) hPhoenix = AllocElement (); + // The hPhoenix element is created and placed at the head of the + // queue so that it is preprocessed before any of the ships' elements + // are, and so before death_func() is called for the dead Pkunk. + // hPhoenix detects when the Pkunk ship dies and tweaks the ship, + // starting the death + reincarnation sequence. if (hPhoenix) { ELEMENT *PhoenixPtr; @@ -450,12 +508,17 @@ pkunk_preprocess (ELEMENT *ElementPtr) UnlockElement (hPhoenix); InsertElement (hPhoenix, GetHeadElement ()); } - StarShipPtr->RaceDescPtr->data = (intptr_t) hPhoenix; + PkunkData->hPhoenix = hPhoenix; + // XXX: Hack: new_pkunk() sets hTarget!=0 which indicates a + // reincarnation to us. if (ElementPtr->hTarget == 0) - StarShipPtr->RaceDescPtr->preprocess_func = 0; - else { + // A brand new ship is preprocessed only once + StarShipPtr->RaceDescPtr->preprocess_func = 0; + } + else + { // Start the reincarnation sequence COUNT angle, facing; ProcessSound (SetAbsSoundIndex ( @@ -538,17 +601,32 @@ pkunk_postprocess (ELEMENT *ElementPtr) } } +static void +uninit_pkunk (RACE_DESC *pRaceDesc) +{ + SetCustomShipData (pRaceDesc, NULL); +} + RACE_DESC* init_pkunk (void) { RACE_DESC *RaceDescPtr; + // The caller of this func will copy the struct + static RACE_DESC new_pkunk_desc; + PKUNK_DATA empty_data; + memset (&empty_data, 0, sizeof (empty_data)); + pkunk_desc.uninit_func = uninit_pkunk; pkunk_desc.preprocess_func = pkunk_preprocess; pkunk_desc.postprocess_func = pkunk_postprocess; pkunk_desc.init_weapon_func = initialize_bug_missile; pkunk_desc.cyborg_control.intelligence_func = pkunk_intelligence; - RaceDescPtr = &pkunk_desc; + /* copy initial ship settings to the new descriptor */ + new_pkunk_desc = pkunk_desc; + SetCustomShipData (&new_pkunk_desc, &empty_data); + + RaceDescPtr = &new_pkunk_desc; LastSound = 0; // We need to reinitialise it at least each battle, to ensure @@ -557,4 +635,3 @@ init_pkunk (void) return (RaceDescPtr); } - diff --git a/sc2/src/uqm/ships/pkunk/pkunk.h b/sc2/src/uqm/ships/pkunk/pkunk.h index aa1dd7104..91681b863 100644 --- a/sc2/src/uqm/ships/pkunk/pkunk.h +++ b/sc2/src/uqm/ships/pkunk/pkunk.h @@ -17,7 +17,15 @@ #ifndef PKUNK_H #define PKUNK_H +#if defined(__cplusplus) +extern "C" { +#endif + RACE_DESC *init_pkunk (void); +#if defined(__cplusplus) +} +#endif + #endif /* PKUNK_H */ diff --git a/sc2/src/uqm/ships/pkunk/resinst.h b/sc2/src/uqm/ships/pkunk/resinst.h index 5b1384254..9c1168e19 100644 --- a/sc2/src/uqm/ships/pkunk/resinst.h +++ b/sc2/src/uqm/ships/pkunk/resinst.h @@ -1,3 +1,7 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define BUG_BIG_MASK_PMAP_ANIM "ship.pkunk.graphics.bug.large" #define BUG_MED_MASK_PMAP_ANIM "ship.pkunk.graphics.bug.medium" #define BUG_SML_MASK_PMAP_ANIM "ship.pkunk.graphics.bug.small" @@ -6,9 +10,7 @@ #define PKUNK_ICON_MASK_PMAP_ANIM "ship.pkunk.icons" #define PKUNK_MED_MASK_PMAP_ANIM "ship.pkunk.graphics.fury.medium" #define PKUNK_MICON_MASK_PMAP_ANIM "ship.pkunk.meleeicons" -#define PKUNK_SML_MASK_PMAP_ANIM "ship.pkunk.graphics.fury.small" #define PKUNK_RACE_STRINGS "ship.pkunk.text" #define PKUNK_SHIP_SOUNDS "ship.pkunk.sounds" +#define PKUNK_SML_MASK_PMAP_ANIM "ship.pkunk.graphics.fury.small" #define PKUNK_VICTORY_SONG "ship.pkunk.ditty" - -#include "icode.h" diff --git a/sc2/src/uqm/ships/probe/Makeinfo b/sc2/src/uqm/ships/probe/Makeinfo index 4f5b4bbf7..27e5093fb 100644 --- a/sc2/src/uqm/ships/probe/Makeinfo +++ b/sc2/src/uqm/ships/probe/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="probe.c" +uqm_HFILES="icode.h probe.h resinst.h" diff --git a/sc2/src/uqm/ships/probe/icode.h b/sc2/src/uqm/ships/probe/icode.h index 7d03794d8..badab2a2e 100644 --- a/sc2/src/uqm/ships/probe/icode.h +++ b/sc2/src/uqm/ships/probe/icode.h @@ -1 +1,5 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define URQUAN_DRONE_CODE "ship.drone.code" diff --git a/sc2/src/uqm/ships/probe/probe.h b/sc2/src/uqm/ships/probe/probe.h index 4af7e9826..c5889700b 100644 --- a/sc2/src/uqm/ships/probe/probe.h +++ b/sc2/src/uqm/ships/probe/probe.h @@ -17,7 +17,15 @@ #ifndef PROBE_H #define PROBE_H +#if defined(__cplusplus) +extern "C" { +#endif + RACE_DESC *init_probe (void); +#if defined(__cplusplus) +} +#endif + #endif /* PROBE_H */ diff --git a/sc2/src/uqm/ships/probe/resinst.h b/sc2/src/uqm/ships/probe/resinst.h index 4e2620f2b..5365c6d56 100644 --- a/sc2/src/uqm/ships/probe/resinst.h +++ b/sc2/src/uqm/ships/probe/resinst.h @@ -1,3 +1,5 @@ -#define URQUAN_DRONE_MICON_MASK_PMAP_ANIM "ship.drone.meleeicons" +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ -#include "icode.h" +#define URQUAN_DRONE_MICON_MASK_PMAP_ANIM "ship.drone.meleeicons" diff --git a/sc2/src/uqm/ships/shofixti/Makeinfo b/sc2/src/uqm/ships/shofixti/Makeinfo index a39285dc6..52d912157 100644 --- a/sc2/src/uqm/ships/shofixti/Makeinfo +++ b/sc2/src/uqm/ships/shofixti/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="shofixti.c" +uqm_HFILES="icode.h resinst.h shofixti.h" diff --git a/sc2/src/uqm/ships/shofixti/icode.h b/sc2/src/uqm/ships/shofixti/icode.h index 8741de9c4..4afe8d350 100644 --- a/sc2/src/uqm/ships/shofixti/icode.h +++ b/sc2/src/uqm/ships/shofixti/icode.h @@ -1 +1,5 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define SHOFIXTI_CODE "ship.shofixti.code" diff --git a/sc2/src/uqm/ships/shofixti/resinst.h b/sc2/src/uqm/ships/shofixti/resinst.h index 5b8e5bc86..bd95cb25c 100644 --- a/sc2/src/uqm/ships/shofixti/resinst.h +++ b/sc2/src/uqm/ships/shofixti/resinst.h @@ -1,3 +1,7 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define DART_BIG_MASK_PMAP_ANIM "ship.shofixti.graphics.missile.large" #define DART_MED_MASK_PMAP_ANIM "ship.shofixti.graphics.missile.medium" #define DART_SML_MASK_PMAP_ANIM "ship.shofixti.graphics.missile.small" @@ -13,9 +17,7 @@ #define SHOFIXTI_ICON_MASK_PMAP_ANIM "ship.shofixti.icons" #define SHOFIXTI_MED_MASK_PMAP_ANIM "ship.shofixti.graphics.scout.medium" #define SHOFIXTI_MICON_MASK_PMAP_ANIM "ship.shofixti.meleeicons" -#define SHOFIXTI_SML_MASK_PMAP_ANIM "ship.shofixti.graphics.scout.small" #define SHOFIXTI_RACE_STRINGS "ship.shofixti.text" #define SHOFIXTI_SHIP_SOUNDS "ship.shofixti.sounds" +#define SHOFIXTI_SML_MASK_PMAP_ANIM "ship.shofixti.graphics.scout.small" #define SHOFIXTI_VICTORY_SONG "ship.shofixti.ditty" - -#include "icode.h" diff --git a/sc2/src/uqm/ships/shofixti/shofixti.c b/sc2/src/uqm/ships/shofixti/shofixti.c index 7c5cc67ea..454a29c7a 100644 --- a/sc2/src/uqm/ships/shofixti/shofixti.c +++ b/sc2/src/uqm/ships/shofixti/shofixti.c @@ -21,6 +21,7 @@ #include "resinst.h" #include "uqm/globdata.h" +#include "uqm/tactrans.h" #include "libs/mathlib.h" @@ -212,10 +213,10 @@ destruct_preprocess (ELEMENT *ElementPtr) PutElement (hDestruct); LockElement (hDestruct, &DestructPtr); SetElementStarShip (DestructPtr, StarShipPtr); - DestructPtr->hit_points = DestructPtr->mass_points = 0; + DestructPtr->hit_points = 0; + DestructPtr->mass_points = 0; DestructPtr->playerNr = NEUTRAL_PLAYER_NUM; DestructPtr->state_flags = APPEARING | FINITE_LIFE | NONSOLID; - DestructPtr->life_span = (NUM_EXPLOSION_FRAMES - 3) - 1; SetPrimType (&(GLOBAL (DisplayArray))[DestructPtr->PrimIndex], STAMPFILL_PRIM); SetPrimColor (&(GLOBAL (DisplayArray))[DestructPtr->PrimIndex], @@ -224,6 +225,8 @@ destruct_preprocess (ELEMENT *ElementPtr) StarShipPtr->RaceDescPtr->ship_data.special; DestructPtr->current.image.frame = StarShipPtr->RaceDescPtr->ship_data.special[0]; + DestructPtr->life_span = GetFrameCount ( + DestructPtr->current.image.frame); DestructPtr->current.location = ElementPtr->current.location; DestructPtr->preprocess_func = destruct_preprocess; DestructPtr->postprocess_func = NULL; @@ -240,110 +243,147 @@ destruct_preprocess (ELEMENT *ElementPtr) #define ORZ_MARINE(ptr) (ptr->preprocess_func == intruder_preprocess && \ ptr->collision_func == marine_collision) -// XXX: This function should be split into two +static void +self_destruct_kill_objects (ELEMENT *ElementPtr) +{ + // This is called during PostProcessQueue(), close to or at the end, + // for the temporary destruct element to apply the effects of glory + // explosion. The effects are not seen until the next frame. + HELEMENT hElement, hNextElement; + + for (hElement = GetHeadElement (); hElement != 0; hElement = hNextElement) + { + ELEMENT *ObjPtr; + SIZE delta_x, delta_y; + DWORD dist; + + LockElement (hElement, &ObjPtr); + hNextElement = GetSuccElement (ObjPtr); + + if (!CollidingElement (ObjPtr) && !ORZ_MARINE (ObjPtr)) + { + UnlockElement (hElement); + continue; + } + +#define DESTRUCT_RANGE 180 + delta_x = ObjPtr->next.location.x - ElementPtr->next.location.x; + if (delta_x < 0) + delta_x = -delta_x; + delta_y = ObjPtr->next.location.y - ElementPtr->next.location.y; + if (delta_y < 0) + delta_y = -delta_y; + delta_x = WORLD_TO_DISPLAY (delta_x); + delta_y = WORLD_TO_DISPLAY (delta_y); + dist = delta_x * delta_x + delta_y * delta_y; + if (delta_x <= DESTRUCT_RANGE && delta_y <= DESTRUCT_RANGE + && dist <= DESTRUCT_RANGE * DESTRUCT_RANGE) + { +#define MAX_DESTRUCTION (DESTRUCT_RANGE / 10) + int destruction = 1 + MAX_DESTRUCTION * + (DESTRUCT_RANGE - square_root (dist)) / DESTRUCT_RANGE; + + // XXX: Why not simply call do_damage()? + if (ObjPtr->state_flags & PLAYER_SHIP) + { + if (!DeltaCrew (ObjPtr, -destruction)) + ObjPtr->life_span = 0; + } + else if (!GRAVITY_MASS (ObjPtr->mass_points)) + { + if (destruction < ObjPtr->hit_points) + ObjPtr->hit_points -= destruction; + else + { + ObjPtr->hit_points = 0; + ObjPtr->life_span = 0; + } + } + } + + UnlockElement (hElement); + } +} + +// This function is called when the ship dies via Glory Device. +// The generic ship_death() function is not called for the ship in this case. +static void +shofixti_destruct_death (ELEMENT *ShipPtr) +{ + STARSHIP *StarShip; + STARSHIP *winner; + + GetElementStarShip (ShipPtr, &StarShip); + + StopAllBattleMusic (); + + StartShipExplosion (ShipPtr, false); + // We process the explosion ourselves because it is different + ShipPtr->preprocess_func = destruct_preprocess; + + PlaySound (SetAbsSoundIndex (StarShip->RaceDescPtr->ship_data.ship_sounds, + 1), CalcSoundPosition (ShipPtr), ShipPtr, GAME_SOUND_PRIORITY + 1); + + winner = GetWinnerStarShip (); + if (winner == NULL) + { // No winner determined yet + winner = FindAliveStarShip (ShipPtr); + if (winner == NULL) + { // No ships left alive after the Glory Device thus Shofixti wins + winner = StarShip; + } + SetWinnerStarShip (winner); + } + else if (winner == StarShip) + { // This ship is the winner + // It may have self-destructed before the ditty started playing, + // and in that case, there should be no ditty + StarShip->cur_status_flags &= ~PLAY_VICTORY_DITTY; + } + RecordShipDeath (ShipPtr); +} + static void self_destruct (ELEMENT *ElementPtr) { STARSHIP *StarShipPtr; + HELEMENT hDestruct; GetElementStarShip (ElementPtr, &StarShipPtr); - if (ElementPtr->state_flags & PLAYER_SHIP) - { - HELEMENT hDestruct; - // Spawn a temporary element, which dies in this same frame, in order - // to defer the effects of the glory explosion. - // It will be the last element (or one of the last) for which the - // death_func will be called from PostProcessQueue() in this frame. - hDestruct = AllocElement (); - if (hDestruct) - { - ELEMENT *DestructPtr; - - LockElement (hDestruct, &DestructPtr); - DestructPtr->playerNr = ElementPtr->playerNr; - DestructPtr->state_flags = APPEARING | NONSOLID | FINITE_LIFE; - DestructPtr->next.location = ElementPtr->next.location; - DestructPtr->life_span = 0; - DestructPtr->pParent = ElementPtr->pParent; - DestructPtr->hTarget = 0; - - DestructPtr->death_func = self_destruct; - - UnlockElement (hDestruct); - - PutElement (hDestruct); - } - - ElementPtr->state_flags |= NONSOLID; - // The ship is now dead. It's death_func, i.e. ship_death(), will be - // called the next frame. - ElementPtr->life_span = 0; - - ElementPtr->preprocess_func = destruct_preprocess; - } - else + // Spawn a temporary element, which dies in this same frame, in order + // to defer the effects of the glory explosion. + // It will be the last element (or one of the last) for which the + // death_func() will be called from PostProcessQueue() in this frame. + // XXX: Why at the end? Why not just do it now? + hDestruct = AllocElement (); + if (hDestruct) { - // This is called during PostProcessQueue(), close to or at the end, - // for the temporary destruct element to apply the effects of glory - // explosion. The effects are not seen until the next frame. - HELEMENT hElement, hNextElement; + ELEMENT *DestructPtr; - for (hElement = GetHeadElement (); - hElement != 0; hElement = hNextElement) - { - ELEMENT *ObjPtr; + LockElement (hDestruct, &DestructPtr); + DestructPtr->playerNr = ElementPtr->playerNr; + DestructPtr->state_flags = APPEARING | NONSOLID | FINITE_LIFE; + DestructPtr->next.location = ElementPtr->next.location; + DestructPtr->life_span = 0; + DestructPtr->pParent = ElementPtr->pParent; + DestructPtr->hTarget = 0; - LockElement (hElement, &ObjPtr); - hNextElement = GetSuccElement (ObjPtr); + DestructPtr->death_func = self_destruct_kill_objects; - if (CollidingElement (ObjPtr) || ORZ_MARINE (ObjPtr)) - { -#define DESTRUCT_RANGE 180 - SIZE delta_x, delta_y; - DWORD dist; + UnlockElement (hDestruct); - if ((delta_x = ObjPtr->next.location.x - - ElementPtr->next.location.x) < 0) - delta_x = -delta_x; - if ((delta_y = ObjPtr->next.location.y - - ElementPtr->next.location.y) < 0) - delta_y = -delta_y; - delta_x = WORLD_TO_DISPLAY (delta_x); - delta_y = WORLD_TO_DISPLAY (delta_y); - if (delta_x <= DESTRUCT_RANGE && delta_y <= DESTRUCT_RANGE - && (dist = (DWORD)(delta_x * delta_x) - + (DWORD)(delta_y * delta_y)) <= - (DWORD)(DESTRUCT_RANGE * DESTRUCT_RANGE)) - { -#define MAX_DESTRUCTION (DESTRUCT_RANGE / 10) - SIZE destruction; - - destruction = ((MAX_DESTRUCTION - * (DESTRUCT_RANGE - square_root (dist))) - / DESTRUCT_RANGE) + 1; - - if (ObjPtr->state_flags & PLAYER_SHIP) - { - if (!DeltaCrew (ObjPtr, -destruction)) - ObjPtr->life_span = 0; - } - else if (!GRAVITY_MASS (ObjPtr->mass_points)) - { - if ((BYTE)destruction < ObjPtr->hit_points) - ObjPtr->hit_points -= (BYTE)destruction; - else - { - ObjPtr->hit_points = 0; - ObjPtr->life_span = 0; - } - } - } - } - - UnlockElement (hElement); - } + PutElement (hDestruct); } + + // Must kill off the remaining crew ourselves + DeltaCrew (ElementPtr, -(int)ElementPtr->crew_level); + + ElementPtr->state_flags |= NONSOLID; + ElementPtr->life_span = 0; + // The ship is now dead. It's death_func, i.e. shofixti_destruct_death(), + // will be called the next frame. + ElementPtr->death_func = shofixti_destruct_death; } static void @@ -410,7 +450,7 @@ RACE_DESC* init_shofixti (void) { RACE_DESC *RaceDescPtr; - + // The caller of this func will copy the struct static RACE_DESC new_shofixti_desc; shofixti_desc.postprocess_func = shofixti_postprocess; diff --git a/sc2/src/uqm/ships/shofixti/shofixti.h b/sc2/src/uqm/ships/shofixti/shofixti.h index 1151ea4af..e4fdd0c83 100644 --- a/sc2/src/uqm/ships/shofixti/shofixti.h +++ b/sc2/src/uqm/ships/shofixti/shofixti.h @@ -17,7 +17,15 @@ #ifndef SHOFIXTI_H #define SHOFIXTI_H +#if defined(__cplusplus) +extern "C" { +#endif + RACE_DESC *init_shofixti (void); +#if defined(__cplusplus) +} +#endif + #endif /* SHOFIXTI_H */ diff --git a/sc2/src/uqm/ships/sis_ship/Makeinfo b/sc2/src/uqm/ships/sis_ship/Makeinfo index 022e91ffc..540e3a6e7 100644 --- a/sc2/src/uqm/ships/sis_ship/Makeinfo +++ b/sc2/src/uqm/ships/sis_ship/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="sis_ship.c" +uqm_HFILES="icode.h resinst.h sis_ship.h" diff --git a/sc2/src/uqm/ships/sis_ship/icode.h b/sc2/src/uqm/ships/sis_ship/icode.h index 8c2426283..3d5744955 100644 --- a/sc2/src/uqm/ships/sis_ship/icode.h +++ b/sc2/src/uqm/ships/sis_ship/icode.h @@ -1 +1,5 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define SIS_CODE "ship.flagship.code" diff --git a/sc2/src/uqm/ships/sis_ship/resinst.h b/sc2/src/uqm/ships/sis_ship/resinst.h index ac97bfe4c..cf8d074ec 100644 --- a/sc2/src/uqm/ships/sis_ship/resinst.h +++ b/sc2/src/uqm/ships/sis_ship/resinst.h @@ -1,3 +1,7 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define BLASTER_BIG_MASK_PMAP_ANIM "ship.flagship.graphics.blaster.large" #define BLASTER_MED_MASK_PMAP_ANIM "ship.flagship.graphics.blaster.medium" #define BLASTER_SML_MASK_PMAP_ANIM "ship.flagship.graphics.blaster.small" @@ -6,8 +10,6 @@ #define SIS_HYPER_MASK_PMAP_ANIM "ship.flagship.graphics.hyperspace" #define SIS_ICON_MASK_PMAP_ANIM "ship.flagship.icons" #define SIS_MED_MASK_PMAP_ANIM "ship.flagship.graphics.flagship.medium" -#define SIS_SML_MASK_PMAP_ANIM "ship.flagship.graphics.flagship.small" #define SIS_SHIP_SOUNDS "ship.flagship.sounds" +#define SIS_SML_MASK_PMAP_ANIM "ship.flagship.graphics.flagship.small" #define SIS_VICTORY_SONG "ship.flagship.ditty" - -#include "icode.h" diff --git a/sc2/src/uqm/ships/sis_ship/sis_ship.c b/sc2/src/uqm/ships/sis_ship/sis_ship.c index 7ed9d56aa..0553ef3e5 100644 --- a/sc2/src/uqm/ships/sis_ship/sis_ship.c +++ b/sc2/src/uqm/ships/sis_ship/sis_ship.c @@ -136,9 +136,41 @@ static void InitDriveSlots (RACE_DESC *RaceDescPtr, const BYTE *DriveSlots); static void InitJetSlots (RACE_DESC *RaceDescPtr, const BYTE *JetSlots); -void uninit_sis (RACE_DESC *pRaceDesc); +static void uninit_sis (RACE_DESC *pRaceDesc); +// Local typedef +typedef SIS_DATA CustomShipData_t; + +// Retrieve race-specific ship data from a race desc +static CustomShipData_t * +GetCustomShipData (RACE_DESC *pRaceDesc) +{ + return pRaceDesc->data; +} + +// Set the race-specific data in a race desc +// (Re)Allocates its own storage for the data. +static void +SetCustomShipData (RACE_DESC *pRaceDesc, const CustomShipData_t *data) +{ + if (pRaceDesc->data == data) + return; // no-op + + if (pRaceDesc->data) // Out with the old + { + HFree (pRaceDesc->data); + pRaceDesc->data = NULL; + } + + if (data) // In with the new + { + CustomShipData_t* newData = HMalloc (sizeof (*data)); + *newData = *data; + pRaceDesc->data = newData; + } +} + static void sis_hyper_preprocess (ELEMENT *ElementPtr) { @@ -566,7 +598,7 @@ initialize_blasters (ELEMENT *ShipPtr, HELEMENT BlasterArray[]) SIS_DATA *SisData; GetElementStarShip (ShipPtr, &StarShipPtr); - SisData = (SIS_DATA *) StarShipPtr->RaceDescPtr->data; + SisData = GetCustomShipData (StarShipPtr->RaceDescPtr); nt = (BYTE)((4 - SisData->num_trackers) & 3); @@ -606,7 +638,7 @@ sis_intelligence (ELEMENT *ShipPtr, EVALUATE_DESC *ObjectsOfConcern, SIS_DATA *SisData; GetElementStarShip (ShipPtr, &StarShipPtr); - SisData = (SIS_DATA *) StarShipPtr->RaceDescPtr->data; + SisData = GetCustomShipData (StarShipPtr->RaceDescPtr); lpEvalDesc = &ObjectsOfConcern[ENEMY_WEAPON_INDEX]; if (lpEvalDesc->ObjectPtr) @@ -680,7 +712,7 @@ InitWeaponSlots (RACE_DESC *RaceDescPtr, const BYTE *ModuleSlots) #define BLASTER_HITS 2 #define BLASTER_OFFSET 8 COUNT i; - SIS_DATA *SisData = (SIS_DATA *) RaceDescPtr->data; + SIS_DATA *SisData = GetCustomShipData (RaceDescPtr); MISSILE_BLOCK *lpMB = SisData->MissileBlock; SisData->num_blasters = 0; @@ -760,7 +792,7 @@ InitModuleSlots (RACE_DESC *RaceDescPtr, const BYTE *ModuleSlots) { COUNT i; COUNT num_trackers; - SIS_DATA *SisData = (SIS_DATA *) RaceDescPtr->data; + SIS_DATA *SisData = GetCustomShipData (RaceDescPtr); RaceDescPtr->ship_info.max_crew = 0; num_trackers = 0; @@ -848,16 +880,18 @@ RACE_DESC* init_sis (void) { RACE_DESC *RaceDescPtr; - COUNT i; + // The caller of this func will copy the struct static RACE_DESC new_sis_desc; + SIS_DATA empty_data; + memset (&empty_data, 0, sizeof (empty_data)); /* copy initial ship settings to new_sis_desc */ new_sis_desc = sis_desc; new_sis_desc.uninit_func = uninit_sis; - if (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE) + if (inHQSpace ()) { for (i = 0; i < NUM_VIEWS; ++i) { @@ -888,7 +922,7 @@ init_sis (void) SET_GAME_STATE (BOMB_CARRIER, 1); } - new_sis_desc.data = (intptr_t) HCalloc (sizeof (SIS_DATA)); + SetCustomShipData (&new_sis_desc, &empty_data); InitModuleSlots (&new_sis_desc, GLOBAL_SIS (ModuleSlots)); InitWeaponSlots (&new_sis_desc, GLOBAL_SIS (ModuleSlots)); InitDriveSlots (&new_sis_desc, GLOBAL_SIS (DriveSlots)); @@ -913,18 +947,17 @@ init_sis (void) return (RaceDescPtr); } -void +static void uninit_sis (RACE_DESC *pRaceDesc) { - if (LOBYTE (GLOBAL (CurrentActivity)) != IN_HYPERSPACE) + if (!inHQSpace ()) { GLOBAL_SIS (CrewEnlisted) = pRaceDesc->ship_info.crew_level; if (pRaceDesc->ship_info.ship_flags & PLAYER_CAPTAIN) GLOBAL_SIS (CrewEnlisted)--; } - HFree ((void *)pRaceDesc->data); - pRaceDesc->data = 0; + SetCustomShipData (pRaceDesc, NULL); } diff --git a/sc2/src/uqm/ships/sis_ship/sis_ship.h b/sc2/src/uqm/ships/sis_ship/sis_ship.h index 79dda24e3..ffe077692 100644 --- a/sc2/src/uqm/ships/sis_ship/sis_ship.h +++ b/sc2/src/uqm/ships/sis_ship/sis_ship.h @@ -17,7 +17,15 @@ #ifndef SIS_SHIP_H #define SIS_SHIP_H +#if defined(__cplusplus) +extern "C" { +#endif + RACE_DESC *init_sis (void); +#if defined(__cplusplus) +} +#endif + #endif /* SIS_SHIP_H */ diff --git a/sc2/src/uqm/ships/slylandr/Makeinfo b/sc2/src/uqm/ships/slylandr/Makeinfo index 284586798..309b1d4a1 100644 --- a/sc2/src/uqm/ships/slylandr/Makeinfo +++ b/sc2/src/uqm/ships/slylandr/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="slylandr.c" +uqm_HFILES="icode.h resinst.h slylandr.h" diff --git a/sc2/src/uqm/ships/slylandr/icode.h b/sc2/src/uqm/ships/slylandr/icode.h index 9465d3481..9897234b5 100644 --- a/sc2/src/uqm/ships/slylandr/icode.h +++ b/sc2/src/uqm/ships/slylandr/icode.h @@ -1 +1,5 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define SLYLANDRO_CODE "ship.slylandro.code" diff --git a/sc2/src/uqm/ships/slylandr/resinst.h b/sc2/src/uqm/ships/slylandr/resinst.h index d7861c925..00df8338b 100644 --- a/sc2/src/uqm/ships/slylandr/resinst.h +++ b/sc2/src/uqm/ships/slylandr/resinst.h @@ -1,11 +1,13 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define SLYLANDRO_BIG_MASK_PMAP_ANIM "ship.slylandro.graphics.probe.large" #define SLYLANDRO_CAPTAIN_MASK_PMAP_ANIM "ship.slylandro.graphics.captain" #define SLYLANDRO_ICON_MASK_PMAP_ANIM "ship.slylandro.icons" #define SLYLANDRO_MED_MASK_PMAP_ANIM "ship.slylandro.graphics.probe.medium" #define SLYLANDRO_MICON_MASK_PMAP_ANIM "ship.slylandro.meleeicons" -#define SLYLANDRO_SML_MASK_PMAP_ANIM "ship.slylandro.graphics.probe.small" #define SLYLANDRO_RACE_STRINGS "ship.slylandro.text" #define SLYLANDRO_SHIP_SOUNDS "ship.slylandro.sounds" +#define SLYLANDRO_SML_MASK_PMAP_ANIM "ship.slylandro.graphics.probe.small" #define SLYLANDRO_VICTORY_SONG "ship.slylandro.ditty" - -#include "icode.h" diff --git a/sc2/src/uqm/ships/slylandr/slylandr.h b/sc2/src/uqm/ships/slylandr/slylandr.h index 72843395d..a55362d2d 100644 --- a/sc2/src/uqm/ships/slylandr/slylandr.h +++ b/sc2/src/uqm/ships/slylandr/slylandr.h @@ -17,7 +17,15 @@ #ifndef SLYLANDR_H #define SLYLANDR_H +#if defined(__cplusplus) +extern "C" { +#endif + RACE_DESC *init_slylandro (void); +#if defined(__cplusplus) +} +#endif + #endif /* SLYLANDR_H */ diff --git a/sc2/src/uqm/ships/spathi/Makeinfo b/sc2/src/uqm/ships/spathi/Makeinfo index 21ed75024..48dc3f9f0 100644 --- a/sc2/src/uqm/ships/spathi/Makeinfo +++ b/sc2/src/uqm/ships/spathi/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="spathi.c" +uqm_HFILES="icode.h resinst.h spathi.h" diff --git a/sc2/src/uqm/ships/spathi/icode.h b/sc2/src/uqm/ships/spathi/icode.h index f34800f90..aa5f6ef27 100644 --- a/sc2/src/uqm/ships/spathi/icode.h +++ b/sc2/src/uqm/ships/spathi/icode.h @@ -1 +1,5 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define SPATHI_CODE "ship.spathi.code" diff --git a/sc2/src/uqm/ships/spathi/resinst.h b/sc2/src/uqm/ships/spathi/resinst.h index 5a6bbb42a..1d4ecf6ee 100644 --- a/sc2/src/uqm/ships/spathi/resinst.h +++ b/sc2/src/uqm/ships/spathi/resinst.h @@ -1,3 +1,7 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define DISCRIM_BIG_MASK_PMAP_ANIM "ship.spathi.graphics.butt.large" #define DISCRIM_MED_MASK_PMAP_ANIM "ship.spathi.graphics.butt.medium" #define DISCRIM_SML_MASK_PMAP_ANIM "ship.spathi.graphics.butt.small" @@ -9,9 +13,7 @@ #define SPATHI_ICON_MASK_PMAP_ANIM "ship.spathi.icons" #define SPATHI_MED_MASK_PMAP_ANIM "ship.spathi.graphics.eluder.medium" #define SPATHI_MICON_MASK_PMAP_ANIM "ship.spathi.meleeicons" -#define SPATHI_SML_MASK_PMAP_ANIM "ship.spathi.graphics.eluder.small" #define SPATHI_RACE_STRINGS "ship.spathi.text" #define SPATHI_SHIP_SOUNDS "ship.spathi.sounds" +#define SPATHI_SML_MASK_PMAP_ANIM "ship.spathi.graphics.eluder.small" #define SPATHI_VICTORY_SONG "ship.spathi.ditty" - -#include "icode.h" diff --git a/sc2/src/uqm/ships/spathi/spathi.h b/sc2/src/uqm/ships/spathi/spathi.h index 4a4d58cb4..900d05cd2 100644 --- a/sc2/src/uqm/ships/spathi/spathi.h +++ b/sc2/src/uqm/ships/spathi/spathi.h @@ -17,7 +17,15 @@ #ifndef SPATHI_H #define SPATHI_H +#if defined(__cplusplus) +extern "C" { +#endif + RACE_DESC *init_spathi (void); +#if defined(__cplusplus) +} +#endif + #endif /* SPATHI_H */ diff --git a/sc2/src/uqm/ships/supox/Makeinfo b/sc2/src/uqm/ships/supox/Makeinfo index 46e22f952..9105cf6cb 100644 --- a/sc2/src/uqm/ships/supox/Makeinfo +++ b/sc2/src/uqm/ships/supox/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="supox.c" +uqm_HFILES="icode.h resinst.h supox.h" diff --git a/sc2/src/uqm/ships/supox/icode.h b/sc2/src/uqm/ships/supox/icode.h index cd87276b2..d2f82f95f 100644 --- a/sc2/src/uqm/ships/supox/icode.h +++ b/sc2/src/uqm/ships/supox/icode.h @@ -1 +1,5 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define SUPOX_CODE "ship.supox.code" diff --git a/sc2/src/uqm/ships/supox/resinst.h b/sc2/src/uqm/ships/supox/resinst.h index e8e00a719..8984c6c91 100644 --- a/sc2/src/uqm/ships/supox/resinst.h +++ b/sc2/src/uqm/ships/supox/resinst.h @@ -1,3 +1,7 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define GOB_BIG_MASK_PMAP_ANIM "ship.supox.graphics.glob.large" #define GOB_MED_MASK_PMAP_ANIM "ship.supox.graphics.glob.medium" #define GOB_SML_MASK_PMAP_ANIM "ship.supox.graphics.glob.small" @@ -6,9 +10,7 @@ #define SUPOX_ICON_MASK_PMAP_ANIM "ship.supox.icons" #define SUPOX_MED_MASK_PMAP_ANIM "ship.supox.graphics.blade.medium" #define SUPOX_MICON_MASK_PMAP_ANIM "ship.supox.meleeicons" -#define SUPOX_SML_MASK_PMAP_ANIM "ship.supox.graphics.blade.small" #define SUPOX_RACE_STRINGS "ship.supox.text" #define SUPOX_SHIP_SOUNDS "ship.supox.sounds" +#define SUPOX_SML_MASK_PMAP_ANIM "ship.supox.graphics.blade.small" #define SUPOX_VICTORY_SONG "ship.supox.ditty" - -#include "icode.h" diff --git a/sc2/src/uqm/ships/supox/supox.h b/sc2/src/uqm/ships/supox/supox.h index ce3721379..b06632034 100644 --- a/sc2/src/uqm/ships/supox/supox.h +++ b/sc2/src/uqm/ships/supox/supox.h @@ -17,7 +17,15 @@ #ifndef SUPOX_H #define SUPOX_H +#if defined(__cplusplus) +extern "C" { +#endif + RACE_DESC *init_supox (void); +#if defined(__cplusplus) +} +#endif + #endif /* SUPOX_H */ diff --git a/sc2/src/uqm/ships/syreen/Makeinfo b/sc2/src/uqm/ships/syreen/Makeinfo index c13b4b54d..9485c7822 100644 --- a/sc2/src/uqm/ships/syreen/Makeinfo +++ b/sc2/src/uqm/ships/syreen/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="syreen.c" +uqm_HFILES="icode.h resinst.h syreen.h" diff --git a/sc2/src/uqm/ships/syreen/icode.h b/sc2/src/uqm/ships/syreen/icode.h index ce0635a58..66f3ca4c8 100644 --- a/sc2/src/uqm/ships/syreen/icode.h +++ b/sc2/src/uqm/ships/syreen/icode.h @@ -1 +1,5 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define SYREEN_CODE "ship.syreen.code" diff --git a/sc2/src/uqm/ships/syreen/resinst.h b/sc2/src/uqm/ships/syreen/resinst.h index dba48d7d6..7a7cc2430 100644 --- a/sc2/src/uqm/ships/syreen/resinst.h +++ b/sc2/src/uqm/ships/syreen/resinst.h @@ -1,3 +1,7 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define DAGGER_BIG_MASK_PMAP_ANIM "ship.syreen.graphics.dagger.large" #define DAGGER_MED_MASK_PMAP_ANIM "ship.syreen.graphics.dagger.medium" #define DAGGER_SML_MASK_PMAP_ANIM "ship.syreen.graphics.dagger.small" @@ -6,9 +10,7 @@ #define SYREEN_ICON_MASK_PMAP_ANIM "ship.syreen.icons" #define SYREEN_MED_MASK_PMAP_ANIM "ship.syreen.graphics.penetrator.medium" #define SYREEN_MICON_MASK_PMAP_ANIM "ship.syreen.meleeicons" -#define SYREEN_SML_MASK_PMAP_ANIM "ship.syreen.graphics.penetrator.small" #define SYREEN_RACE_STRINGS "ship.syreen.text" #define SYREEN_SHIP_SOUNDS "ship.syreen.sounds" +#define SYREEN_SML_MASK_PMAP_ANIM "ship.syreen.graphics.penetrator.small" #define SYREEN_VICTORY_SONG "ship.syreen.ditty" - -#include "icode.h" diff --git a/sc2/src/uqm/ships/syreen/syreen.h b/sc2/src/uqm/ships/syreen/syreen.h index 713f87f09..1930a1a66 100644 --- a/sc2/src/uqm/ships/syreen/syreen.h +++ b/sc2/src/uqm/ships/syreen/syreen.h @@ -17,7 +17,15 @@ #ifndef SYREEN_H #define SYREEN_H +#if defined(__cplusplus) +extern "C" { +#endif + RACE_DESC *init_syreen (void); +#if defined(__cplusplus) +} +#endif + #endif /* SYREEN_H */ diff --git a/sc2/src/uqm/ships/thradd/Makeinfo b/sc2/src/uqm/ships/thradd/Makeinfo index 600fd13c4..f55550954 100644 --- a/sc2/src/uqm/ships/thradd/Makeinfo +++ b/sc2/src/uqm/ships/thradd/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="thradd.c" +uqm_HFILES="icode.h resinst.h thradd.h" diff --git a/sc2/src/uqm/ships/thradd/icode.h b/sc2/src/uqm/ships/thradd/icode.h index 32046157d..070353a48 100644 --- a/sc2/src/uqm/ships/thradd/icode.h +++ b/sc2/src/uqm/ships/thradd/icode.h @@ -1 +1,5 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define THRADDASH_CODE "ship.thraddash.code" diff --git a/sc2/src/uqm/ships/thradd/resinst.h b/sc2/src/uqm/ships/thradd/resinst.h index ef49cd8e0..191d263ec 100644 --- a/sc2/src/uqm/ships/thradd/resinst.h +++ b/sc2/src/uqm/ships/thradd/resinst.h @@ -1,3 +1,7 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define HORN_BIG_MASK_PMAP_ANIM "ship.thraddash.graphics.horn.large" #define HORN_MED_MASK_PMAP_ANIM "ship.thraddash.graphics.horn.medium" #define HORN_SML_MASK_PMAP_ANIM "ship.thraddash.graphics.horn.small" @@ -9,9 +13,7 @@ #define THRADDASH_ICON_MASK_PMAP_ANIM "ship.thraddash.icons" #define THRADDASH_MED_MASK_PMAP_ANIM "ship.thraddash.graphics.torch.medium" #define THRADDASH_MICON_MASK_PMAP_ANIM "ship.thraddash.meleeicons" -#define THRADDASH_SML_MASK_PMAP_ANIM "ship.thraddash.graphics.torch.small" #define THRADDASH_RACE_STRINGS "ship.thraddash.text" #define THRADDASH_SHIP_SOUNDS "ship.thraddash.sounds" +#define THRADDASH_SML_MASK_PMAP_ANIM "ship.thraddash.graphics.torch.small" #define THRADDASH_VICTORY_SONG "ship.thraddash.ditty" - -#include "icode.h" diff --git a/sc2/src/uqm/ships/thradd/thradd.h b/sc2/src/uqm/ships/thradd/thradd.h index 193248cd1..fb2a54203 100644 --- a/sc2/src/uqm/ships/thradd/thradd.h +++ b/sc2/src/uqm/ships/thradd/thradd.h @@ -17,7 +17,15 @@ #ifndef THRADD_H #define THRADD_H +#if defined(__cplusplus) +extern "C" { +#endif + RACE_DESC *init_thraddash (void); +#if defined(__cplusplus) +} +#endif + #endif /* THRADD_H */ diff --git a/sc2/src/uqm/ships/umgah/Makeinfo b/sc2/src/uqm/ships/umgah/Makeinfo index a60037014..a66b4cee9 100644 --- a/sc2/src/uqm/ships/umgah/Makeinfo +++ b/sc2/src/uqm/ships/umgah/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="umgah.c" +uqm_HFILES="icode.h resinst.h umgah.h" diff --git a/sc2/src/uqm/ships/umgah/icode.h b/sc2/src/uqm/ships/umgah/icode.h index c1dce3a7f..103f5d28f 100644 --- a/sc2/src/uqm/ships/umgah/icode.h +++ b/sc2/src/uqm/ships/umgah/icode.h @@ -1 +1,5 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define UMGAH_CODE "ship.umgah.code" diff --git a/sc2/src/uqm/ships/umgah/resinst.h b/sc2/src/uqm/ships/umgah/resinst.h index 333ffc0fa..4df4b07d0 100644 --- a/sc2/src/uqm/ships/umgah/resinst.h +++ b/sc2/src/uqm/ships/umgah/resinst.h @@ -1,3 +1,7 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define CONE_BIG_MASK_ANIM "ship.umgah.graphics.cone.large" #define CONE_MED_MASK_ANIM "ship.umgah.graphics.cone.medium" #define CONE_SML_MASK_ANIM "ship.umgah.graphics.cone.small" @@ -7,9 +11,7 @@ #define UMGAH_ICON_MASK_PMAP_ANIM "ship.umgah.icons" #define UMGAH_MED_MASK_PMAP_ANIM "ship.umgah.graphics.drone.medium" #define UMGAH_MICON_MASK_PMAP_ANIM "ship.umgah.meleeicons" -#define UMGAH_SML_MASK_PMAP_ANIM "ship.umgah.graphics.drone.small" #define UMGAH_RACE_STRINGS "ship.umgah.text" #define UMGAH_SHIP_SOUNDS "ship.umgah.sounds" +#define UMGAH_SML_MASK_PMAP_ANIM "ship.umgah.graphics.drone.small" #define UMGAH_VICTORY_SONG "ship.umgah.ditty" - -#include "icode.h" diff --git a/sc2/src/uqm/ships/umgah/umgah.c b/sc2/src/uqm/ships/umgah/umgah.c index bbb23e85e..054cdfa9a 100644 --- a/sc2/src/uqm/ships/umgah/umgah.c +++ b/sc2/src/uqm/ships/umgah/umgah.c @@ -110,6 +110,46 @@ static RACE_DESC umgah_desc = 0, /* CodeRef */ }; + +// Private per-instance ship data +typedef struct +{ + UWORD prevFacing; +} UMGAH_DATA; + +// Local typedef +typedef UMGAH_DATA CustomShipData_t; + +// Retrieve race-specific ship data from a race desc +static CustomShipData_t * +GetCustomShipData (RACE_DESC *pRaceDesc) +{ + return pRaceDesc->data; +} + +// Set the race-specific data in a race desc +// (Re)Allocates its own storage for the data. +static void +SetCustomShipData (RACE_DESC *pRaceDesc, const CustomShipData_t *data) +{ + if (pRaceDesc->data == data) + return; // no-op + + if (pRaceDesc->data) // Out with the old + { + HFree (pRaceDesc->data); + pRaceDesc->data = NULL; + } + + if (data) // In with the new + { + CustomShipData_t* newData = HMalloc (sizeof (*data)); + *newData = *data; + pRaceDesc->data = newData; + } +} + + static void cone_preprocess (ELEMENT *ElementPtr) { @@ -266,6 +306,7 @@ initialize_cone (ELEMENT *ShipPtr, HELEMENT ConeArray[]) #define MISSILE_LIFE 1 #define MISSILE_OFFSET 0 STARSHIP *StarShipPtr; + UMGAH_DATA* UmgahData; MISSILE_BLOCK MissileBlock; GetElementStarShip (ShipPtr, &StarShipPtr); @@ -285,15 +326,17 @@ initialize_cone (ELEMENT *ShipPtr, HELEMENT ConeArray[]) // This func is called every frame while the player is holding down WEAPON // Don't reset the cone FRAME to the first image every time - if (ShipPtr->next.image.frame != (FRAME) StarShipPtr->RaceDescPtr->data) + UmgahData = GetCustomShipData (StarShipPtr->RaceDescPtr); + if (!UmgahData || StarShipPtr->ShipFacing != UmgahData->prevFacing) { - StarShipPtr->RaceDescPtr->data = (intptr_t) ShipPtr->next.image.frame; + const UMGAH_DATA shipData = {StarShipPtr->ShipFacing}; + + SetCustomShipData (StarShipPtr->RaceDescPtr, &shipData); StarShipPtr->RaceDescPtr->ship_data.special[0] = SetAbsFrameIndex ( StarShipPtr->RaceDescPtr->ship_data.special[0], - StarShipPtr->ShipFacing - ); + StarShipPtr->ShipFacing); } MissileBlock.index = GetFrameIndex (StarShipPtr->RaceDescPtr->ship_data.special[0]); @@ -341,7 +384,7 @@ umgah_preprocess (ELEMENT *ElementPtr) if (ElementPtr->state_flags & APPEARING) { // Reset the value just in case - StarShipPtr->RaceDescPtr->data = 0; + SetCustomShipData (StarShipPtr->RaceDescPtr, NULL); } else { @@ -366,11 +409,18 @@ umgah_preprocess (ELEMENT *ElementPtr) } } +static void +uninit_umgah (RACE_DESC *pRaceDesc) +{ + SetCustomShipData (pRaceDesc, NULL); +} + RACE_DESC* init_umgah (void) { RACE_DESC *RaceDescPtr; + umgah_desc.uninit_func = uninit_umgah; umgah_desc.preprocess_func = umgah_preprocess; umgah_desc.postprocess_func = umgah_postprocess; umgah_desc.init_weapon_func = initialize_cone; diff --git a/sc2/src/uqm/ships/umgah/umgah.h b/sc2/src/uqm/ships/umgah/umgah.h index 5da749230..8c706bba0 100644 --- a/sc2/src/uqm/ships/umgah/umgah.h +++ b/sc2/src/uqm/ships/umgah/umgah.h @@ -17,7 +17,15 @@ #ifndef UMGAH_H #define UMGAH_H +#if defined(__cplusplus) +extern "C" { +#endif + RACE_DESC *init_umgah (void); +#if defined(__cplusplus) +} +#endif + #endif /* UMGAH_H */ diff --git a/sc2/src/uqm/ships/urquan/Makeinfo b/sc2/src/uqm/ships/urquan/Makeinfo index 84bbff281..a1d130dc3 100644 --- a/sc2/src/uqm/ships/urquan/Makeinfo +++ b/sc2/src/uqm/ships/urquan/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="urquan.c" +uqm_HFILES="icode.h resinst.h urquan.h" diff --git a/sc2/src/uqm/ships/urquan/icode.h b/sc2/src/uqm/ships/urquan/icode.h index 7a17467b5..b26e84a09 100644 --- a/sc2/src/uqm/ships/urquan/icode.h +++ b/sc2/src/uqm/ships/urquan/icode.h @@ -1 +1,5 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define URQUAN_CODE "ship.urquan.code" diff --git a/sc2/src/uqm/ships/urquan/resinst.h b/sc2/src/uqm/ships/urquan/resinst.h index 1c9b36d42..a7b9ecdbb 100644 --- a/sc2/src/uqm/ships/urquan/resinst.h +++ b/sc2/src/uqm/ships/urquan/resinst.h @@ -1,3 +1,7 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define FIGHTER_BIG_MASK_PMAP_ANIM "ship.urquan.graphics.fighter.large" #define FIGHTER_MED_MASK_PMAP_ANIM "ship.urquan.graphics.fighter.medium" #define FIGHTER_SML_MASK_PMAP_ANIM "ship.urquan.graphics.fighter.small" @@ -9,9 +13,7 @@ #define URQUAN_ICON_MASK_PMAP_ANIM "ship.urquan.icons" #define URQUAN_MED_MASK_PMAP_ANIM "ship.urquan.graphics.dreadnought.medium" #define URQUAN_MICON_MASK_PMAP_ANIM "ship.urquan.meleeicons" -#define URQUAN_SML_MASK_PMAP_ANIM "ship.urquan.graphics.dreadnought.small" #define URQUAN_RACE_STRINGS "ship.urquan.text" #define URQUAN_SHIP_SOUNDS "ship.urquan.sounds" +#define URQUAN_SML_MASK_PMAP_ANIM "ship.urquan.graphics.dreadnought.small" #define URQUAN_VICTORY_SONG "ship.urquan.ditty" - -#include "icode.h" diff --git a/sc2/src/uqm/ships/urquan/urquan.h b/sc2/src/uqm/ships/urquan/urquan.h index d1a4161df..937d93ffa 100644 --- a/sc2/src/uqm/ships/urquan/urquan.h +++ b/sc2/src/uqm/ships/urquan/urquan.h @@ -17,7 +17,15 @@ #ifndef URQUAN_H #define URQUAN_H +#if defined(__cplusplus) +extern "C" { +#endif + RACE_DESC *init_urquan (void); +#if defined(__cplusplus) +} +#endif + #endif /* URQUAN_H */ diff --git a/sc2/src/uqm/ships/utwig/Makeinfo b/sc2/src/uqm/ships/utwig/Makeinfo index 5e08eabc4..84b1d8c13 100644 --- a/sc2/src/uqm/ships/utwig/Makeinfo +++ b/sc2/src/uqm/ships/utwig/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="utwig.c" +uqm_HFILES="icode.h resinst.h utwig.h" diff --git a/sc2/src/uqm/ships/utwig/icode.h b/sc2/src/uqm/ships/utwig/icode.h index 4d46c551b..4762b8905 100644 --- a/sc2/src/uqm/ships/utwig/icode.h +++ b/sc2/src/uqm/ships/utwig/icode.h @@ -1 +1,5 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define UTWIG_CODE "ship.utwig.code" diff --git a/sc2/src/uqm/ships/utwig/resinst.h b/sc2/src/uqm/ships/utwig/resinst.h index 1fbd4451b..384862ec1 100644 --- a/sc2/src/uqm/ships/utwig/resinst.h +++ b/sc2/src/uqm/ships/utwig/resinst.h @@ -1,3 +1,7 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define LANCE_BIG_MASK_PMAP_ANIM "ship.utwig.graphics.lance.large" #define LANCE_MED_MASK_PMAP_ANIM "ship.utwig.graphics.lance.medium" #define LANCE_SML_MASK_PMAP_ANIM "ship.utwig.graphics.lance.small" @@ -6,9 +10,7 @@ #define UTWIG_ICON_MASK_PMAP_ANIM "ship.utwig.icons" #define UTWIG_MED_MASK_PMAP_ANIM "ship.utwig.graphics.jugger.medium" #define UTWIG_MICON_MASK_PMAP_ANIM "ship.utwig.meleeicons" -#define UTWIG_SML_MASK_PMAP_ANIM "ship.utwig.graphics.jugger.small" #define UTWIG_RACE_STRINGS "ship.utwig.text" #define UTWIG_SHIP_SOUNDS "ship.utwig.sounds" +#define UTWIG_SML_MASK_PMAP_ANIM "ship.utwig.graphics.jugger.small" #define UTWIG_VICTORY_SONG "ship.utwig.ditty" - -#include "icode.h" diff --git a/sc2/src/uqm/ships/utwig/utwig.h b/sc2/src/uqm/ships/utwig/utwig.h index 903625a45..83ab97e47 100644 --- a/sc2/src/uqm/ships/utwig/utwig.h +++ b/sc2/src/uqm/ships/utwig/utwig.h @@ -17,7 +17,15 @@ #ifndef UTWIG_H #define UTWIG_H +#if defined(__cplusplus) +extern "C" { +#endif + RACE_DESC *init_utwig (void); +#if defined(__cplusplus) +} +#endif + #endif /* UTWIG_H */ diff --git a/sc2/src/uqm/ships/vux/Makeinfo b/sc2/src/uqm/ships/vux/Makeinfo index 555c7fb81..13c926431 100644 --- a/sc2/src/uqm/ships/vux/Makeinfo +++ b/sc2/src/uqm/ships/vux/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="vux.c" +uqm_HFILES="icode.h resinst.h vux.h" diff --git a/sc2/src/uqm/ships/vux/icode.h b/sc2/src/uqm/ships/vux/icode.h index 78f42e1b5..0bd37d7d8 100644 --- a/sc2/src/uqm/ships/vux/icode.h +++ b/sc2/src/uqm/ships/vux/icode.h @@ -1 +1,5 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define VUX_CODE "ship.vux.code" diff --git a/sc2/src/uqm/ships/vux/resinst.h b/sc2/src/uqm/ships/vux/resinst.h index f4d718081..c3e04bf08 100644 --- a/sc2/src/uqm/ships/vux/resinst.h +++ b/sc2/src/uqm/ships/vux/resinst.h @@ -1,3 +1,7 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define LIMPETS_BIG_MASK_PMAP_ANIM "ship.vux.graphics.limpets.large" #define LIMPETS_MED_MASK_PMAP_ANIM "ship.vux.graphics.limpets.medium" #define LIMPETS_SML_MASK_PMAP_ANIM "ship.vux.graphics.limpets.small" @@ -7,9 +11,7 @@ #define VUX_ICON_MASK_PMAP_ANIM "ship.vux.icons" #define VUX_MED_MASK_PMAP_ANIM "ship.vux.graphics.intruder.medium" #define VUX_MICON_MASK_PMAP_ANIM "ship.vux.meleeicons" -#define VUX_SML_MASK_PMAP_ANIM "ship.vux.graphics.intruder.small" #define VUX_RACE_STRINGS "ship.vux.text" #define VUX_SHIP_SOUNDS "ship.vux.sounds" +#define VUX_SML_MASK_PMAP_ANIM "ship.vux.graphics.intruder.small" #define VUX_VICTORY_SONG "ship.vux.ditty" - -#include "icode.h" diff --git a/sc2/src/uqm/ships/vux/vux.h b/sc2/src/uqm/ships/vux/vux.h index e1a6ee2a1..3fa2f3f64 100644 --- a/sc2/src/uqm/ships/vux/vux.h +++ b/sc2/src/uqm/ships/vux/vux.h @@ -17,7 +17,15 @@ #ifndef VUX_H #define VUX_H +#if defined(__cplusplus) +extern "C" { +#endif + RACE_DESC *init_vux (void); +#if defined(__cplusplus) +} +#endif + #endif /* VUX_H */ diff --git a/sc2/src/uqm/ships/yehat/Makeinfo b/sc2/src/uqm/ships/yehat/Makeinfo index 7dd1c37ac..73d70c374 100644 --- a/sc2/src/uqm/ships/yehat/Makeinfo +++ b/sc2/src/uqm/ships/yehat/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="yehat.c" +uqm_HFILES="icode.h resinst.h yehat.h" diff --git a/sc2/src/uqm/ships/yehat/icode.h b/sc2/src/uqm/ships/yehat/icode.h index 26a732dab..81cac0eb5 100644 --- a/sc2/src/uqm/ships/yehat/icode.h +++ b/sc2/src/uqm/ships/yehat/icode.h @@ -1 +1,5 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define YEHAT_CODE "ship.yehat.code" diff --git a/sc2/src/uqm/ships/yehat/resinst.h b/sc2/src/uqm/ships/yehat/resinst.h index 742bb7ef3..ad325a559 100644 --- a/sc2/src/uqm/ships/yehat/resinst.h +++ b/sc2/src/uqm/ships/yehat/resinst.h @@ -1,3 +1,7 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define SHIELD_BIG_MASK_ANIM "ship.yehat.graphics.shield.large" #define SHIELD_MED_MASK_ANIM "ship.yehat.graphics.shield.medium" #define SHIELD_SML_MASK_ANIM "ship.yehat.graphics.shield.small" @@ -9,9 +13,7 @@ #define YEHAT_ICON_MASK_PMAP_ANIM "ship.yehat.icons" #define YEHAT_MED_MASK_PMAP_ANIM "ship.yehat.graphics.terminator.medium" #define YEHAT_MICON_MASK_PMAP_ANIM "ship.yehat.meleeicons" -#define YEHAT_SML_MASK_PMAP_ANIM "ship.yehat.graphics.terminator.small" #define YEHAT_RACE_STRINGS "ship.yehat.text" #define YEHAT_SHIP_SOUNDS "ship.yehat.sounds" +#define YEHAT_SML_MASK_PMAP_ANIM "ship.yehat.graphics.terminator.small" #define YEHAT_VICTORY_SONG "ship.yehat.ditty" - -#include "icode.h" diff --git a/sc2/src/uqm/ships/yehat/yehat.h b/sc2/src/uqm/ships/yehat/yehat.h index ae8a0bb55..8b3dd5a48 100644 --- a/sc2/src/uqm/ships/yehat/yehat.h +++ b/sc2/src/uqm/ships/yehat/yehat.h @@ -17,7 +17,15 @@ #ifndef YEHAT_H #define YEHAT_H +#if defined(__cplusplus) +extern "C" { +#endif + RACE_DESC *init_yehat (void); +#if defined(__cplusplus) +} +#endif + #endif /* YEHAT_H */ diff --git a/sc2/src/uqm/ships/zoqfot/Makeinfo b/sc2/src/uqm/ships/zoqfot/Makeinfo index bbb5f48f5..e795e78eb 100644 --- a/sc2/src/uqm/ships/zoqfot/Makeinfo +++ b/sc2/src/uqm/ships/zoqfot/Makeinfo @@ -1 +1,2 @@ uqm_CFILES="zoqfot.c" +uqm_HFILES="icode.h resinst.h zoqfot.h" diff --git a/sc2/src/uqm/ships/zoqfot/icode.h b/sc2/src/uqm/ships/zoqfot/icode.h index 58379feac..0fe635fe0 100644 --- a/sc2/src/uqm/ships/zoqfot/icode.h +++ b/sc2/src/uqm/ships/zoqfot/icode.h @@ -1 +1,5 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define ZOQFOTPIK_CODE "ship.zoqfotpik.code" diff --git a/sc2/src/uqm/ships/zoqfot/resinst.h b/sc2/src/uqm/ships/zoqfot/resinst.h index 76d022789..5939142ac 100644 --- a/sc2/src/uqm/ships/zoqfot/resinst.h +++ b/sc2/src/uqm/ships/zoqfot/resinst.h @@ -1,3 +1,7 @@ +/* This file was auto-generated by the gen_resfiles utility and + should not be edited directly. Modify the master resource list + instead and regenerate. */ + #define SPIT_BIG_MASK_PMAP_ANIM "ship.zoqfotpik.graphics.spit.large" #define SPIT_MED_MASK_PMAP_ANIM "ship.zoqfotpik.graphics.spit.medium" #define SPIT_SML_MASK_PMAP_ANIM "ship.zoqfotpik.graphics.spit.small" @@ -9,9 +13,7 @@ #define ZOQFOTPIK_ICON_MASK_PMAP_ANIM "ship.zoqfotpik.icons" #define ZOQFOTPIK_MED_MASK_PMAP_ANIM "ship.zoqfotpik.graphics.stinger.medium" #define ZOQFOTPIK_MICON_MASK_PMAP_ANIM "ship.zoqfotpik.meleeicons" -#define ZOQFOTPIK_SML_MASK_PMAP_ANIM "ship.zoqfotpik.graphics.stinger.small" #define ZOQFOTPIK_RACE_STRINGS "ship.zoqfotpik.text" #define ZOQFOTPIK_SHIP_SOUNDS "ship.zoqfotpik.sounds" +#define ZOQFOTPIK_SML_MASK_PMAP_ANIM "ship.zoqfotpik.graphics.stinger.small" #define ZOQFOTPIK_VICTORY_SONG "ship.zoqfotpik.ditty" - -#include "icode.h" diff --git a/sc2/src/uqm/ships/zoqfot/zoqfot.h b/sc2/src/uqm/ships/zoqfot/zoqfot.h index 83a16f67c..1bdcc8589 100644 --- a/sc2/src/uqm/ships/zoqfot/zoqfot.h +++ b/sc2/src/uqm/ships/zoqfot/zoqfot.h @@ -17,7 +17,15 @@ #ifndef ZOQFOT_H #define ZOQFOT_H +#if defined(__cplusplus) +extern "C" { +#endif + RACE_DESC *init_zoqfotpik (void); +#if defined(__cplusplus) +} +#endif + #endif /* ZOQFOT_H */ diff --git a/sc2/src/uqm/shipyard.c b/sc2/src/uqm/shipyard.c index df4e521bc..f317ba338 100644 --- a/sc2/src/uqm/shipyard.c +++ b/sc2/src/uqm/shipyard.c @@ -73,6 +73,20 @@ enum SHIPYARD_EXIT }; +// Editing mode for DoModifyShips() +typedef enum { + DMS_Mode_navigate, // Navigating the ship slots. + DMS_Mode_addEscort, // Selecting a ship to add to an empty slot. + DMS_Mode_editCrew, // Hiring or dismissing crew. + DMS_Mode_exit, // Leaving DoModifyShips() mode. +} DMS_Mode; + +static COUNT ShipCost[] = +{ + RACE_SHIP_COST +}; + + static void animatePowerLines (MENU_STATE *pMS) { @@ -105,11 +119,9 @@ on_input_frame (void) { CONTEXT oldContext; - LockMutex (GraphicsLock); oldContext = SetContext (SpaceContext); animatePowerLines (NULL); SetContext (oldContext); - UnlockMutex (GraphicsLock); } #ifdef WANT_SHIP_SPINS @@ -125,9 +137,7 @@ SpinStarShip (MENU_STATE *pMS, HFLEETINFO hStarShip) if (Index >= 0 && Index < NUM_MELEE_SHIPS) { - UnlockMutex (GraphicsLock); DoShipSpin (Index, pMS->hMusic); - LockMutex (GraphicsLock); } } #endif @@ -187,7 +197,6 @@ DrawRaceStrings (MENU_STATE *pMS, BYTE NewRaceItem) STAMP s; CONTEXT OldContext; - LockMutex (GraphicsLock); OldContext = SetContext (StatusContext); GetContextClipRect (&r); @@ -205,8 +214,7 @@ DrawRaceStrings (MENU_STATE *pMS, BYTE NewRaceItem) r.corner = s.origin; r.extent.width = RADAR_WIDTH; r.extent.height = RADAR_HEIGHT; - SetContextForeGroundColor ( - BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x00), 0x00)); + SetContextForeGroundColor (BLACK_COLOR); DrawFilledRectangle (&r); if (NewRaceItem != (BYTE)~0) { @@ -214,25 +222,26 @@ DrawRaceStrings (MENU_STATE *pMS, BYTE NewRaceItem) HFLEETINFO hStarShip; FLEET_INFO *FleetPtr; UNICODE buf[30]; - COUNT ShipCost[] = - { - RACE_SHIP_COST - }; hStarShip = GetAvailableRaceFromIndex (NewRaceItem); NewRaceItem = GetIndexFromStarShip (&GLOBAL (avail_race_q), hStarShip); + + // Draw the ship name, above the ship image. s.frame = SetAbsFrameIndex (pMS->ModuleFrame, 3 + NewRaceItem); DrawStamp (&s); + + // Draw the ship image. FleetPtr = LockFleetInfo (&GLOBAL (avail_race_q), hStarShip); s.frame = FleetPtr->melee_icon; UnlockFleetInfo (&GLOBAL (avail_race_q), hStarShip); - t.baseline.x = s.origin.x + RADAR_WIDTH - 2; t.baseline.y = s.origin.y + RADAR_HEIGHT - 2; s.origin.x += (RADAR_WIDTH >> 1); s.origin.y += (RADAR_HEIGHT >> 1); DrawStamp (&s); + + // Print the ship cost. t.align = ALIGN_RIGHT; t.CharCount = (COUNT)~0; t.pStr = buf; @@ -245,37 +254,39 @@ DrawRaceStrings (MENU_STATE *pMS, BYTE NewRaceItem) UnbatchGraphics (); SetContext (OldContext); - // Flash the ship purchase menu even when optMenu == OPT_PC - SetFlashRect (SFR_MENU_ANY); - UnlockMutex (GraphicsLock); } #define SHIP_WIN_WIDTH 34 #define SHIP_WIN_HEIGHT (SHIP_WIN_WIDTH + 6) #define SHIP_WIN_FRAMES ((SHIP_WIN_WIDTH >> 1) + 1) +// Print the crew count of an escort ship on top of its (already drawn) +// image, either as '30' (full), '28/30' (partially full), or 'SCRAP' +// (empty). +// pRect is the rectangle of the ship image. static void -ShowShipCrew (SHIP_FRAGMENT *StarShipPtr, RECT *pRect) +ShowShipCrew (SHIP_FRAGMENT *StarShipPtr, const RECT *pRect) { RECT r; TEXT t; UNICODE buf[80]; HFLEETINFO hTemplate; FLEET_INFO *TemplatePtr; + COUNT maxCrewLevel; hTemplate = GetStarShipFromIndex (&GLOBAL (avail_race_q), StarShipPtr->race_id); TemplatePtr = LockFleetInfo (&GLOBAL (avail_race_q), hTemplate); - if (StarShipPtr->crew_level >= TemplatePtr->crew_level) + maxCrewLevel = TemplatePtr->crew_level; + UnlockFleetInfo (&GLOBAL (avail_race_q), hTemplate); + + if (StarShipPtr->crew_level >= maxCrewLevel) sprintf (buf, "%u", StarShipPtr->crew_level); else if (StarShipPtr->crew_level == 0) // XXX: "SCRAP" needs to be moved to starcon.txt utf8StringCopy (buf, sizeof (buf), "SCRAP"); else - sprintf (buf, "%u/%u", - StarShipPtr->crew_level, - TemplatePtr->crew_level); - UnlockFleetInfo (&GLOBAL (avail_race_q), hTemplate); + sprintf (buf, "%u/%u", StarShipPtr->crew_level, maxCrewLevel); r = *pRect; t.baseline.x = r.corner.x + (r.extent.width >> 1); @@ -301,14 +312,17 @@ static void ShowCombatShip (MENU_STATE *pMS, COUNT which_window, SHIP_FRAGMENT *YankedStarShipPtr) { - COUNT i, num_ships; + COUNT i; + COUNT num_ships; HSHIPFRAG hStarShip, hNextShip; SHIP_FRAGMENT *StarShipPtr; struct { SHIP_FRAGMENT *StarShipPtr; POINT finished_s; - STAMP ship_s, lfdoor_s, rtdoor_s; + STAMP ship_s; + STAMP lfdoor_s; + STAMP rtdoor_s; } ship_win_info[MAX_BUILT_SHIPS], *pship_win_info; num_ships = 1; @@ -376,6 +390,10 @@ ShowCombatShip (MENU_STATE *pMS, COUNT which_window, hNextShip = _GetSuccLink (StarShipPtr); pship_win_info->StarShipPtr = StarShipPtr; + // XXX BUG: this looks wrong according to the original + // semantics of LockShipFrag(): StarShipPtr is not valid + // anymore after UnlockShipFrag() is called, but it is + // used thereafter. pship_win_info->lfdoor_s.origin.x = -1; pship_win_info->rtdoor_s.origin.x = 1; @@ -431,7 +449,6 @@ ShowCombatShip (MENU_STATE *pMS, COUNT which_window, AllDoorsFinished = TRUE; } - LockMutex (GraphicsLock); OldContext = SetContext (SpaceContext); GetContextClipRect (&OldClipRect); SetContextBackGroundColor (BLACK_COLOR); @@ -479,7 +496,6 @@ ShowCombatShip (MENU_STATE *pMS, COUNT which_window, #endif UnbatchGraphics (); SetContext (OldContext); - UnlockMutex (GraphicsLock); } } } @@ -507,10 +523,7 @@ CrewTransaction (SIZE crew_delta) && crew_bought - crew_delta < CREW_EXPENSE_THRESHOLD) { GLOBAL (CrewCost) += 2; - - UnlockMutex (GraphicsLock); DrawMenuStateStrings (PM_CREW, SHIPYARD_CREW); - LockMutex (GraphicsLock); } } else @@ -519,13 +532,10 @@ CrewTransaction (SIZE crew_delta) && crew_bought - crew_delta >= CREW_EXPENSE_THRESHOLD) { GLOBAL (CrewCost) -= 2; - - UnlockMutex (GraphicsLock); DrawMenuStateStrings (PM_CREW, SHIPYARD_CREW); - LockMutex (GraphicsLock); } } - if (ActivateStarShip (SHOFIXTI_SHIP, CHECK_ALLIANCE) != GOOD_GUY) + if (CheckAlliance (SHOFIXTI_SHIP) != GOOD_GUY) { SET_GAME_STATE (CREW_PURCHASED0, LOBYTE (crew_bought)); SET_GAME_STATE (CREW_PURCHASED1, HIBYTE (crew_bought)); @@ -533,7 +543,660 @@ CrewTransaction (SIZE crew_delta) } } -/* in this routine, the least significant byte of pMS->CurState is used +static void +DMS_FlashFlagShip (void) +{ + RECT r; + r.corner.x = 0; + r.corner.y = 0; + r.extent.width = SIS_SCREEN_WIDTH; + r.extent.height = 61; + SetFlashRect (&r); +} + +static void +DMS_GetEscortShipRect (RECT *rOut, BYTE slotNr) +{ + BYTE row = slotNr / HANGAR_SHIPS_ROW; + BYTE col = slotNr % HANGAR_SHIPS_ROW; + + rOut->corner.x = hangar_x_coords[col]; + rOut->corner.y = HANGAR_Y + (HANGAR_DY * row); + rOut->extent.width = SHIP_WIN_WIDTH; + rOut->extent.height = SHIP_WIN_HEIGHT; +} + +static void +DMS_FlashEscortShip (BYTE slotNr) +{ + RECT r; + DMS_GetEscortShipRect (&r, slotNr); + SetFlashRect (&r); +} + +static void +DMS_FlashFlagShipCrewCount (void) +{ + RECT r; + SetContext (StatusContext); + GetGaugeRect (&r, TRUE); + SetFlashRect (&r); + SetContext (SpaceContext); +} + +static void +DMS_FlashEscortShipCrewCount (BYTE slotNr) +{ + RECT r; + BYTE row = slotNr / HANGAR_SHIPS_ROW; + BYTE col = slotNr % HANGAR_SHIPS_ROW; + + r.corner.x = hangar_x_coords[col]; + r.corner.y = (HANGAR_Y + (HANGAR_DY * row)) + (SHIP_WIN_HEIGHT - 6); + r.extent.width = SHIP_WIN_WIDTH; + r.extent.height = 5; + + SetContext (SpaceContext); + SetFlashRect (&r); +} + +// Helper function for DoModifyShips(). Called to change the flash +// rectangle to the currently selected ship (flagship or escort ship). +static void +DMS_FlashActiveShip (MENU_STATE *pMS) +{ + if (HINIBBLE (pMS->CurState)) + { + // Flash the flag ship. + DMS_FlashFlagShip (); + } + else + { + // Flash the current escort ship slot. + DMS_FlashEscortShip (pMS->CurState); + } +} + +// Helper function for DoModifyShips(). Called to switch between +// the various edit modes. +// XXX: right now, this only switches the sound and flash rectangle. +// Perhaps we should move more of the code to modify other aspects +// here too. +static void +DMS_SetMode (MENU_STATE *pMS, DMS_Mode mode) +{ + switch (mode) { + case DMS_Mode_navigate: + SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT); + DMS_FlashActiveShip (pMS); + break; + case DMS_Mode_addEscort: + SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT); + SetFlashRect (SFR_MENU_ANY); + break; + case DMS_Mode_editCrew: + SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, + MENU_SOUND_SELECT | MENU_SOUND_CANCEL); + if (HINIBBLE (pMS->CurState)) + { + // Enter crew editing mode for the flagship. + DMS_FlashFlagShipCrewCount (); + } + else + { + // Enter crew editing mode for an escort ship. + DMS_FlashEscortShipCrewCount (pMS->CurState); + } + break; + case DMS_Mode_exit: + SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT); + SetFlashRect (SFR_MENU_3DO); + break; + } +} + +#define MODIFY_CREW_FLAG (1 << 8) +#ifdef WANT_SHIP_SPINS +// Helper function for DoModifyShips(), called when the player presses the +// special button. +// It works both when the cursor is over an escort ship, while not editing +// the crew, and when a new ship is added. +// hStarShip is the ship in the slot under the cursor (or 0 if no such ship). +static BOOLEAN +DMS_SpinShip (MENU_STATE *pMS, HSHIPFRAG hStarShip) +{ + HFLEETINFO hSpinShip = 0; + CONTEXT OldContext; + RECT OldClipRect; + + // No spinning the flagship. + if (HINIBBLE (pMS->CurState) != 0) + return FALSE; + + // We must either be hovering over a used ship slot, or adding a new + // ship to the fleet. + if ((hStarShip == 0) == !(pMS->delta_item & MODIFY_CREW_FLAG)) + return FALSE; + + if (!hStarShip) + { + // Selecting a ship to build. + hSpinShip = GetAvailableRaceFromIndex (LOBYTE (pMS->delta_item)); + if (!hSpinShip) + return FALSE; + } + else + { + // Hovering over an escort ship. + SHIP_FRAGMENT *FragPtr = LockShipFrag ( + &GLOBAL (built_ship_q), hStarShip); + hSpinShip = GetStarShipFromIndex ( + &GLOBAL (avail_race_q), FragPtr->race_id); + UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); + } + + SetFlashRect (NULL); + + OldContext = SetContext (ScreenContext); + GetContextClipRect (&OldClipRect); + + SpinStarShip (pMS, hSpinShip); + + SetContextClipRect (&OldClipRect); + SetContext (OldContext); + + return TRUE; +} +#endif /* WANT_SHIP_SPINS */ + +// Helper function for DoModifyShips(), called when the player presses the +// up button when modifying the crew of the flagship. +// Buy crew for the flagship. +// Returns the change in crew (1 on success, 0 on failure). +static SIZE +DMS_HireFlagShipCrew (void) +{ + RECT r; + + if (GetCPodCapacity (&r.corner) <= GetCrewCount ()) + { + // At capacity. + return 0; + } + + if (GLOBAL_SIS (ResUnits) < (DWORD)GLOBAL (CrewCost)) + { + // Not enough RUs. + return 0; + } + + // Draw a crew member. + DrawPoint (&r.corner); + + // Update the crew counter and RU. Note that the crew counter is + // flashing. + PreUpdateFlashRect (); + DeltaSISGauges (1, 0, -GLOBAL (CrewCost)); + PostUpdateFlashRect (); + + return 1; +} + +// Helper function for DoModifyShips(), called when the player presses the +// down button when modifying the crew of the flagship. +// Dismiss crew from the flagship. +// Returns the change in crew (-1 on success, 0 on failure). +static SIZE +DMS_DismissFlagShipCrew (void) +{ + SIZE crew_bought; + RECT r; + + if (GetCrewCount () == 0) + { + // No crew to dismiss. + return 0; + } + + crew_bought = (SIZE)MAKE_WORD ( + GET_GAME_STATE (CREW_PURCHASED0), + GET_GAME_STATE (CREW_PURCHASED1)); + + // Update the crew counter and RU. Note that the crew counter is + // flashing. + PreUpdateFlashRect (); + DeltaSISGauges (-1, 0, GLOBAL (CrewCost) - + (crew_bought == CREW_EXPENSE_THRESHOLD ? 2 : 0)); + PostUpdateFlashRect (); + + // Remove the pixel representing the crew member. + GetCPodCapacity (&r.corner); + SetContextForeGroundColor (BLACK_COLOR); + DrawPoint (&r.corner); + + return -1; +} + +// Helper function for DoModifyShips(), called when the player presses the +// up button when modifying the crew of an escort ship. +// Buy crew for an escort ship +// Returns the change in crew (1 on success, 0 on failure). +static SIZE +DMS_HireEscortShipCrew (SHIP_FRAGMENT *StarShipPtr) +{ + COUNT templateMaxCrew; + RECT r; + + { + // XXX Split this off into a separate function? + HFLEETINFO hTemplate = GetStarShipFromIndex (&GLOBAL (avail_race_q), + StarShipPtr->race_id); + FLEET_INFO *TemplatePtr = + LockFleetInfo (&GLOBAL (avail_race_q), hTemplate); + templateMaxCrew = TemplatePtr->crew_level; + UnlockFleetInfo (&GLOBAL (avail_race_q), hTemplate); + } + + if (GLOBAL_SIS (ResUnits) < (DWORD)GLOBAL (CrewCost)) + { + // Not enough money to hire a crew member. + return 0; + } + + if (StarShipPtr->crew_level >= StarShipPtr->max_crew) + { + // This ship cannot handle more crew. + return 0; + } + + if (StarShipPtr->crew_level >= templateMaxCrew) + { + // A ship of this type cannot handle more crew. + return 0; + } + + if (StarShipPtr->crew_level > 0) + { + DeltaSISGauges (0, 0, -GLOBAL (CrewCost)); + } + else + { + // Buy a ship. + DeltaSISGauges (0, 0, -(COUNT)ShipCost[StarShipPtr->race_id]); + } + + ++StarShipPtr->crew_level; + + PreUpdateFlashRect (); + DMS_GetEscortShipRect (&r, StarShipPtr->index); + ShowShipCrew (StarShipPtr, &r); + PostUpdateFlashRect (); + + return 1; +} + +// Helper function for DoModifyShips(), called when the player presses the +// down button when modifying the crew of an escort ship. +// Dismiss crew from an escort ship +// Returns the change in crew (-1 on success, 0 on failure). +static SIZE +DMS_DismissEscortShipCrew (SHIP_FRAGMENT *StarShipPtr) +{ + SIZE crew_delta = 0; + RECT r; + + if (StarShipPtr->crew_level > 0) + { + if (StarShipPtr->crew_level > 1) + { + // The ship was not at 'scrap'. + // Give one crew member worth of RU. + SIZE crew_bought = (SIZE)MAKE_WORD ( + GET_GAME_STATE (CREW_PURCHASED0), + GET_GAME_STATE (CREW_PURCHASED1)); + + DeltaSISGauges (0, 0, GLOBAL (CrewCost) + - (crew_bought == CREW_EXPENSE_THRESHOLD ? 2 : 0)); + } + else + { + // With the last crew member, the ship will be scrapped. + // Give RU for the ship. + DeltaSISGauges (0, 0, (COUNT)ShipCost[StarShipPtr->race_id]); + } + crew_delta = -1; + --StarShipPtr->crew_level; + } + else + { // no crew to dismiss + PlayMenuSound (MENU_SOUND_FAILURE); + } + + PreUpdateFlashRect (); + DMS_GetEscortShipRect (&r, StarShipPtr->index); + ShowShipCrew (StarShipPtr, &r); + PostUpdateFlashRect (); + + return crew_delta; +} + +// Helper function for DoModifyShips(), called when the player presses the +// up or down button when modifying the crew of the flagship or of an escort +// ship. +// 'hStarShip' is the currently escort ship, or 0 if no ship is +// selected. +// 'dy' is -1 if the 'up' button was pressed, or '1' if the down button was +// pressed. +static void +DMS_ModifyCrew (MENU_STATE *pMS, HSHIPFRAG hStarShip, SBYTE dy) +{ + SIZE crew_delta = 0; + SHIP_FRAGMENT *StarShipPtr = NULL; + + if (hStarShip) + StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip); + + if (hStarShip == 0) + { + // Add/Dismiss crew for the flagship. + if (dy < 0) + { + // Add crew for the flagship. + crew_delta = DMS_HireFlagShipCrew (); + } + else + { + // Dismiss crew from the flagship. + crew_delta = DMS_DismissFlagShipCrew (); + } + + if (crew_delta != 0) + DMS_FlashFlagShipCrewCount (); + } + else + { + // Add/Dismiss crew for an escort ship. + if (dy < 0) + { + // Add crew for an escort ship. + crew_delta = DMS_HireEscortShipCrew (StarShipPtr); + } + else + { + // Dismiss crew from an escort ship. + crew_delta = DMS_DismissEscortShipCrew (StarShipPtr); + } + + if (crew_delta != 0) + DMS_FlashEscortShipCrewCount (StarShipPtr->index); + } + + if (crew_delta == 0) + PlayMenuSound (MENU_SOUND_FAILURE); + + if (hStarShip) + { + UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); + + // Clear out the bought ship index so that flash rects work + // correctly. + pMS->delta_item &= MODIFY_CREW_FLAG; + } + + CrewTransaction (crew_delta); +} + +// Helper function for DoModifyShips(), called when the player presses the +// select button when the cursor is over an empty escort ship slot. +// Try to add the currently selected ship as an escort ship. +static void +DMS_TryAddEscortShip (MENU_STATE *pMS) +{ + HFLEETINFO shipInfo = GetAvailableRaceFromIndex ( + LOBYTE (pMS->delta_item)); + COUNT Index = GetIndexFromStarShip (&GLOBAL (avail_race_q), shipInfo); + + if (GLOBAL_SIS (ResUnits) >= (DWORD)ShipCost[Index] + && CloneShipFragment (Index, &GLOBAL (built_ship_q), 1)) + { + ShowCombatShip (pMS, pMS->CurState, NULL); + // Reset flash rectangle + DrawMenuStateStrings (PM_CREW, SHIPYARD_CREW); + + DeltaSISGauges (UNDEFINED_DELTA, UNDEFINED_DELTA, + -((int)ShipCost[Index])); + DMS_SetMode (pMS, DMS_Mode_editCrew); + } + else + { + // not enough RUs to build, or cloning the ship failed. + PlayMenuSound (MENU_SOUND_FAILURE); + } +} + +// Helper function for DoModifyShips(), called when the player is in the +// mode to add a new escort ship to the fleet (after pressing select on an +// empty slot). +// LOBYTE (pMS->delta_item) is used to store the currently highlighted ship. +// Returns FALSE if the flash rectangle needs to be updated. +static void +DMS_AddEscortShip (MENU_STATE *pMS, BOOLEAN special, BOOLEAN select, + BOOLEAN cancel, SBYTE dx, SBYTE dy) +{ + assert (pMS->delta_item & MODIFY_CREW_FLAG); + +#ifdef WANT_SHIP_SPINS + if (special) + { + HSHIPFRAG hStarShip = GetEscortByStarShipIndex (pMS->delta_item); + if (DMS_SpinShip (pMS, hStarShip)) + DMS_SetMode (pMS, DMS_Mode_addEscort); + return; + } +#else + (void) special; // Satisfying compiler. +#endif /* WANT_SHIP_SPINS */ + + if (cancel) + { + // Cancel selecting an escort ship. + pMS->delta_item &= ~MODIFY_CREW_FLAG; + SetFlashRect (NULL); + DrawMenuStateStrings (PM_CREW, SHIPYARD_CREW); + DMS_SetMode (pMS, DMS_Mode_navigate); + } + else if (select) + { + // Selected a ship to be inserted in an empty escort + // ship slot. + DMS_TryAddEscortShip (pMS); + } + else if (dx || dy) + { + // Motion key pressed while selecting a ship to be + // inserted in an empty escort ship slot. + COUNT availableCount = GetAvailableRaceCount (); + BYTE currentShip = LOBYTE (pMS->delta_item); + if (dx < 0 || dy < 0) + { + if (currentShip-- == 0) + currentShip = availableCount - 1; + } + else if (dx > 0 || dy > 0) + { + if (++currentShip == availableCount) + currentShip = 0; + } + + if (currentShip != LOBYTE (pMS->delta_item)) + { + PreUpdateFlashRect (); + DrawRaceStrings (pMS, currentShip); + PostUpdateFlashRect (); + pMS->delta_item = currentShip | MODIFY_CREW_FLAG; + } + } +} + +// Helper function for DoModifyShips(), called when the player presses +// 'select' or 'cancel' after selling all the crew. +static void +DMS_ScrapEscortShip (MENU_STATE *pMS, HSHIPFRAG hStarShip) +{ + SHIP_FRAGMENT *StarShipPtr = + LockShipFrag (&GLOBAL (built_ship_q), hStarShip); + BYTE slotNr; + + SetFlashRect (NULL); + ShowCombatShip (pMS, pMS->CurState, StarShipPtr); + + slotNr = StarShipPtr->index; + UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); + + RemoveQueue (&GLOBAL (built_ship_q), hStarShip); + FreeShipFrag (&GLOBAL (built_ship_q), hStarShip); + // refresh SIS display + DeltaSISGauges (UNDEFINED_DELTA, UNDEFINED_DELTA, UNDEFINED_DELTA); + + SetContext (SpaceContext); + DMS_SetMode (pMS, DMS_Mode_navigate); +} + +// Helper function for DoModifyShips(), called when the player presses +// one of the motion keys when not in crew modification mode. +static BYTE +DMS_MoveCursor (BYTE curState, SBYTE dx, SBYTE dy) +{ + BYTE row = LONIBBLE(curState) / HANGAR_SHIPS_ROW; + BYTE col = LONIBBLE(curState) % HANGAR_SHIPS_ROW; + BOOLEAN isFlagShipSelected = (HINIBBLE(curState) != 0); + + if (dy) + { + // Vertical motion. + + // We consider the flagship an extra row (on the bottom), + // to ease operations. + if (isFlagShipSelected) + row = HANGAR_ROWS; + + // Move up/down, wrapping around: + row = (row + (HANGAR_ROWS + 1) + dy) % (HANGAR_ROWS + 1); + + // If we moved to the 'extra row', this means the flag ship. + isFlagShipSelected = (row == HANGAR_ROWS); + if (isFlagShipSelected) + row = 0; + } + else if (dx) + { + // Horizontal motion. + if (!isFlagShipSelected) + { + // Moving horizontally through the escort ship slots, + // wrapping around if necessary. + col = (col + HANGAR_SHIPS_ROW + dx) % HANGAR_SHIPS_ROW; + } + } + + return MAKE_BYTE(row * HANGAR_SHIPS_ROW + col, + isFlagShipSelected ? 0xf : 0); +} + +// Helper function for DoModifyShips(), called every time DoModifyShip() is +// called when we are in crew editing mode. +static void +DMS_EditCrewMode (MENU_STATE *pMS, HSHIPFRAG hStarShip, + BOOLEAN select, BOOLEAN cancel, SBYTE dy) +{ + if (select || cancel) + { + // Leave crew editing mode. + if (hStarShip != 0) + { + // Exiting crew editing mode for an escort ship. + SHIP_FRAGMENT *StarShipPtr = LockShipFrag ( + &GLOBAL (built_ship_q), hStarShip); + COUNT crew_level = StarShipPtr->crew_level; + UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); + + if (crew_level == 0) + { + // Scrapping the escort ship before exiting crew edit + // mode. + DMS_ScrapEscortShip (pMS, hStarShip); + } + } + + pMS->delta_item &= ~MODIFY_CREW_FLAG; + DMS_SetMode (pMS, DMS_Mode_navigate); + } + else if (dy) + { + // Hire or dismiss crew for the flagship or an escort + // ship. + DMS_ModifyCrew (pMS, hStarShip, dy); + } +} + +// Helper function for DoModifyShips(), called every time DoModifyShip() is +// called when we are in the mode where you can select a ship or empty slot. +static void +DMS_NavigateShipSlots (MENU_STATE *pMS, BOOLEAN special, BOOLEAN select, + BOOLEAN cancel, SBYTE dx, SBYTE dy) +{ + HSHIPFRAG hStarShip = GetEscortByStarShipIndex (pMS->CurState); + + if (dx || dy) + { + // Moving through the ship slots. + BYTE NewState = DMS_MoveCursor (pMS->CurState, dx, dy); + if (NewState != pMS->CurState) + { + pMS->CurState = NewState; + DMS_FlashActiveShip(pMS); + } + } + +#ifndef WANT_SHIP_SPINS + (void) special; // Satisfying compiler. +#else + if (special) + { + if (DMS_SpinShip (pMS, hStarShip)) + DMS_SetMode (pMS, DMS_Mode_navigate); + } + else +#endif /* WANT_SHIP_SPINS */ + if (select) + { + if (hStarShip == 0 && HINIBBLE (pMS->CurState) == 0) + { + // Select button was pressed over an empty escort + // ship slot. Switch to 'add escort ship' mode. + pMS->delta_item = MODIFY_CREW_FLAG; + DrawRaceStrings (pMS, 0); + DMS_SetMode (pMS, DMS_Mode_addEscort); + } + else + { + // Select button was pressed over an escort ship or + // the flagship. Entering crew editing mode + pMS->delta_item |= MODIFY_CREW_FLAG; + DMS_SetMode (pMS, DMS_Mode_editCrew); + } + } + else if (cancel) + { + // Leave escort ship editor. + pMS->InputFunc = DoShipyard; + pMS->CurState = SHIPYARD_CREW; + DrawMenuStateStrings (PM_CREW, pMS->CurState); + DMS_SetMode (pMS, DMS_Mode_exit); + } +} + +/* In this routine, the least significant byte of pMS->CurState is used * to store the current selected ship index * a special case for the row is hi-nibble == -1 (0xf), which specifies * SIS as the selected ship @@ -543,16 +1206,6 @@ CrewTransaction (SIZE crew_delta) static BOOLEAN DoModifyShips (MENU_STATE *pMS) { -#define MODIFY_CREW_FLAG (1 << 8) - BOOLEAN select, cancel; -#ifdef WANT_SHIP_SPINS - BOOLEAN special; - - special = PulsedInputState.menu[KEY_MENU_SPECIAL]; -#endif /* WANT_SHIP_SPINS */ - select = PulsedInputState.menu[KEY_MENU_SELECT]; - cancel = PulsedInputState.menu[KEY_MENU_CANCEL]; - if (GLOBAL (CurrentActivity) & CHECK_ABORT) { pMS->InputFunc = DoShipyard; @@ -566,477 +1219,50 @@ DoModifyShips (MENU_STATE *pMS) pMS->CurState = MAKE_BYTE (0, 0xF); pMS->delta_item = 0; - LockMutex (GraphicsLock); SetContext (SpaceContext); - goto ChangeFlashRect; + DMS_SetMode (pMS, DMS_Mode_navigate); } else { + BOOLEAN special = (PulsedInputState.menu[KEY_MENU_SPECIAL] != 0); + BOOLEAN select = (PulsedInputState.menu[KEY_MENU_SELECT] != 0); + BOOLEAN cancel = (PulsedInputState.menu[KEY_MENU_CANCEL] != 0); SBYTE dx = 0; SBYTE dy = 0; - BYTE NewState; + + if (PulsedInputState.menu[KEY_MENU_RIGHT]) + dx = 1; + if (PulsedInputState.menu[KEY_MENU_LEFT]) + dx = -1; + if (PulsedInputState.menu[KEY_MENU_UP]) + dy = -1; + if (PulsedInputState.menu[KEY_MENU_DOWN]) + dy = 1; + if (!(pMS->delta_item & MODIFY_CREW_FLAG)) { - SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT); + // Navigating through the ship slots. + DMS_NavigateShipSlots (pMS, special, select, cancel, dx, dy); } - - if (PulsedInputState.menu[KEY_MENU_RIGHT]) dx = 1; - if (PulsedInputState.menu[KEY_MENU_LEFT]) dx = -1; - if (PulsedInputState.menu[KEY_MENU_UP]) dy = -1; - if (PulsedInputState.menu[KEY_MENU_DOWN]) dy = 1; - NewState = pMS->CurState; - if (pMS->delta_item & MODIFY_CREW_FLAG) + else { - } - else if (dy) - { - if (HINIBBLE (NewState)) - NewState = pMS->CurState % HANGAR_SHIPS_ROW; - else - NewState = (unsigned char)(pMS->CurState + HANGAR_SHIPS_ROW); + // Add an escort ship or edit the crew of a ship. + HSHIPFRAG hStarShip = GetEscortByStarShipIndex (pMS->CurState); - NewState += dy * HANGAR_SHIPS_ROW; - if (NewState / HANGAR_SHIPS_ROW > 0 - && NewState / HANGAR_SHIPS_ROW <= HANGAR_ROWS) - NewState -= HANGAR_SHIPS_ROW; - else if (NewState / HANGAR_SHIPS_ROW > HANGAR_ROWS + 1) - /* negative number - select last row */ - NewState = pMS->CurState % HANGAR_SHIPS_ROW - + HANGAR_SHIPS_ROW * (HANGAR_ROWS - 1); + if (hStarShip == 0 && HINIBBLE (pMS->CurState) == 0) + { + // Cursor is over an empty escort ship slot, while we're + // in 'add escort ship' mode. + DMS_AddEscortShip (pMS, special, select, cancel, dx, dy); + } else - // select SIS - NewState = MAKE_BYTE (pMS->CurState, 0xF); - } - else if (dx && !HINIBBLE (NewState)) - { - NewState = NewState % HANGAR_SHIPS_ROW; - if ((dx += NewState) < 0) - NewState = (BYTE)(pMS->CurState + (HANGAR_SHIPS_ROW - 1)); - else if (dx > HANGAR_SHIPS_ROW - 1) - NewState = (BYTE)(pMS->CurState - (HANGAR_SHIPS_ROW - 1)); - else - NewState = (BYTE)(pMS->CurState - NewState + dx); + { + // Crew editing mode. + DMS_EditCrewMode (pMS, hStarShip, select, cancel, dy); + } } - if (select || cancel -#ifdef WANT_SHIP_SPINS - || special -#endif - || NewState != pMS->CurState - || ((pMS->delta_item & MODIFY_CREW_FLAG) && (dx || dy))) - { - HSHIPFRAG hStarShip, hNextShip; - SHIP_FRAGMENT *StarShipPtr; - RECT r; - - for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q)); - hStarShip; hStarShip = hNextShip) - { - StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip); - - if (StarShipPtr->index == pMS->CurState) - { - UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); - break; - } - - hNextShip = _GetSuccLink (StarShipPtr); - UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); - } - if ((pMS->delta_item & MODIFY_CREW_FLAG) && (hStarShip)) - { - SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, - MENU_SOUND_SELECT | MENU_SOUND_CANCEL); - } - else - { - SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT); - } - - LockMutex (GraphicsLock); - -#ifdef WANT_SHIP_SPINS - if (special) - { - HFLEETINFO hSpinShip = 0; - - if ((special && (((hStarShip == 0 - && HINIBBLE (pMS->CurState) == 0) - && (pMS->delta_item & MODIFY_CREW_FLAG)) - || ((hStarShip != 0 && - HINIBBLE (pMS->CurState) == 0) - && !(pMS->delta_item & MODIFY_CREW_FLAG)))) - && (hStarShip - || (HINIBBLE (pMS->CurState) == 0 - && (hSpinShip = GetAvailableRaceFromIndex ( - LOBYTE (pMS->delta_item)))))) - { - CONTEXT OldContext; - RECT OldClipRect; - - if (!hSpinShip) - { /* Get fleet info from selected escort */ - SHIP_FRAGMENT *FragPtr = LockShipFrag ( - &GLOBAL (built_ship_q), hStarShip); - hSpinShip = GetStarShipFromIndex ( - &GLOBAL (avail_race_q), FragPtr->race_id); - UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); - } - - SetFlashRect (NULL); - - OldContext = SetContext (ScreenContext); - GetContextClipRect (&OldClipRect); - - SpinStarShip (pMS, hSpinShip); - - SetContextClipRect (&OldClipRect); - SetContext (OldContext); - - if (hStarShip) - goto ChangeFlashRect; - - SetFlashRect (SFR_MENU_3DO); - } - } - else -#endif - if (select || ((pMS->delta_item & MODIFY_CREW_FLAG) - && (dx || dy || cancel))) - { - COUNT ShipCost[] = - { - RACE_SHIP_COST - }; - - if (hStarShip == 0 && HINIBBLE (pMS->CurState) == 0) - { - COUNT Index; - -// SetFlashRect (NULL); - UnlockMutex (GraphicsLock); - if (!(pMS->delta_item & MODIFY_CREW_FLAG)) - { - pMS->delta_item = MODIFY_CREW_FLAG; - DrawRaceStrings (pMS, 0); - return TRUE; - } - else if (cancel) - { - pMS->delta_item ^= MODIFY_CREW_FLAG; - LockMutex (GraphicsLock); - SetFlashRect (SFR_MENU_3DO); - UnlockMutex (GraphicsLock); - DrawMenuStateStrings (PM_CREW, SHIPYARD_CREW); - SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT); - } - else if (select) - { - Index = GetIndexFromStarShip (&GLOBAL (avail_race_q), - GetAvailableRaceFromIndex ( - LOBYTE (pMS->delta_item))); - - if (GLOBAL_SIS (ResUnits) >= (DWORD)ShipCost[Index] - && CloneShipFragment (Index, - &GLOBAL (built_ship_q), 1)) - { - ShowCombatShip (pMS, pMS->CurState, NULL); - //Reset flash rectangle - LockMutex (GraphicsLock); - SetFlashRect (SFR_MENU_3DO); - UnlockMutex (GraphicsLock); - DrawMenuStateStrings (PM_CREW, SHIPYARD_CREW); - - LockMutex (GraphicsLock); - DeltaSISGauges (UNDEFINED_DELTA, UNDEFINED_DELTA, - -((int)ShipCost[Index])); - r.corner.x = pMS->flash_rect0.corner.x; - r.corner.y = pMS->flash_rect0.corner.y - + pMS->flash_rect0.extent.height - 6; - r.extent.width = SHIP_WIN_WIDTH; - r.extent.height = 5; - SetContext (SpaceContext); - SetFlashRect (&r); - UnlockMutex (GraphicsLock); - } - else - { // not enough RUs to build - PlayMenuSound (MENU_SOUND_FAILURE); - } - SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, - MENU_SOUND_SELECT | MENU_SOUND_CANCEL); - - return TRUE; - } - else - { - Index = GetAvailableRaceCount (); - NewState = LOBYTE (pMS->delta_item); - if (dx < 0 || dy < 0) - { - if (NewState-- == 0) - NewState = Index - 1; - } - else if (dx > 0 || dy > 0) - { - if (++NewState == Index) - NewState = 0; - } - - if (NewState != LOBYTE (pMS->delta_item)) - { - DrawRaceStrings (pMS, NewState); - pMS->delta_item = NewState | MODIFY_CREW_FLAG; - } - - return TRUE; - } - LockMutex (GraphicsLock); - goto ChangeFlashRect; - } - else if (select || cancel) - { - if ((pMS->delta_item & MODIFY_CREW_FLAG) - && hStarShip != 0) - { - StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), - hStarShip); - if (StarShipPtr->crew_level == 0) - { - SetFlashRect (NULL); - UnlockMutex (GraphicsLock); - ShowCombatShip (pMS, pMS->CurState, StarShipPtr); - LockMutex (GraphicsLock); - UnlockShipFrag (&GLOBAL (built_ship_q), - hStarShip); - RemoveQueue (&GLOBAL (built_ship_q), hStarShip); - FreeShipFrag (&GLOBAL (built_ship_q), hStarShip); - // refresh SIS display - DeltaSISGauges (UNDEFINED_DELTA, UNDEFINED_DELTA, - UNDEFINED_DELTA); - r.corner.x = pMS->flash_rect0.corner.x; - r.corner.y = pMS->flash_rect0.corner.y; - r.extent.width = SHIP_WIN_WIDTH; - r.extent.height = SHIP_WIN_HEIGHT; - SetContext (SpaceContext); - SetFlashRect (&r); - } - else - { - UnlockShipFrag (&GLOBAL (built_ship_q), - hStarShip); - } - } - - if (!(pMS->delta_item ^= MODIFY_CREW_FLAG)) - { - goto ChangeFlashRect; - } - else if (hStarShip == 0) - { - SetContext (StatusContext); - GetGaugeRect (&r, TRUE); - SetFlashRect (&r); - SetContext (SpaceContext); - SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, - MENU_SOUND_SELECT | MENU_SOUND_CANCEL); - } - else - { - r.corner.x = pMS->flash_rect0.corner.x; - r.corner.y = pMS->flash_rect0.corner.y - + pMS->flash_rect0.extent.height - 6; - r.extent.width = SHIP_WIN_WIDTH; - r.extent.height = 5; - SetContext (SpaceContext); - SetFlashRect (&r); - SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, - MENU_SOUND_SELECT | MENU_SOUND_CANCEL); - } - } - else if (pMS->delta_item & MODIFY_CREW_FLAG) - { - SIZE crew_delta, crew_bought; - - if (hStarShip) - StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), - hStarShip); - else - StarShipPtr = NULL; // Keeping compiler quiet. - - SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, - MENU_SOUND_SELECT | MENU_SOUND_CANCEL); - crew_delta = 0; - if (dy < 0) - { - if (hStarShip == 0) - { - if (GetCPodCapacity (&r.corner) > GetCrewCount () - && GLOBAL_SIS (ResUnits) >= - (DWORD)GLOBAL (CrewCost)) - { - DrawPoint (&r.corner); - DeltaSISGauges (1, 0, -GLOBAL (CrewCost)); - crew_delta = 1; - - SetContext (StatusContext); - GetGaugeRect (&r, TRUE); - SetFlashRect (&r); - SetContext (SpaceContext); - } - else - { // at capacity or not enough RUs - PlayMenuSound (MENU_SOUND_FAILURE); - } - } - else - { - HFLEETINFO hTemplate; - FLEET_INFO *TemplatePtr; - - hTemplate = GetStarShipFromIndex ( - &GLOBAL (avail_race_q), - StarShipPtr->race_id); - TemplatePtr = LockFleetInfo ( - &GLOBAL (avail_race_q), hTemplate); - if (GLOBAL_SIS (ResUnits) >= - (DWORD)GLOBAL (CrewCost) - && StarShipPtr->crew_level < - StarShipPtr->max_crew && - StarShipPtr->crew_level < - TemplatePtr->crew_level) - { - if (StarShipPtr->crew_level > 0) - DeltaSISGauges (0, 0, -GLOBAL (CrewCost)); - else - DeltaSISGauges (0, 0, -(COUNT)ShipCost[ - StarShipPtr->race_id]); - ++StarShipPtr->crew_level; - crew_delta = 1; - ShowShipCrew (StarShipPtr, &pMS->flash_rect0); - r.corner.x = pMS->flash_rect0.corner.x; - r.corner.y = pMS->flash_rect0.corner.y - + pMS->flash_rect0.extent.height - 6; - r.extent.width = SHIP_WIN_WIDTH; - r.extent.height = 5; - SetContext (SpaceContext); - SetFlashRect (&r); - } - else - { // at capacity or not enough RUs - PlayMenuSound (MENU_SOUND_FAILURE); - } - UnlockFleetInfo (&GLOBAL (avail_race_q), - hTemplate); - } - } - else if (dy > 0) - { - crew_bought = (SIZE)MAKE_WORD ( - GET_GAME_STATE (CREW_PURCHASED0), - GET_GAME_STATE (CREW_PURCHASED1)); - if (hStarShip == 0) - { - if (GetCrewCount ()) - { - DeltaSISGauges (-1, 0, GLOBAL (CrewCost) - - (crew_bought == - CREW_EXPENSE_THRESHOLD ? 2 : 0)); - crew_delta = -1; - - GetCPodCapacity (&r.corner); - SetContextForeGroundColor (BLACK_COLOR); - DrawPoint (&r.corner); - - SetContext (StatusContext); - GetGaugeRect (&r, TRUE); - SetFlashRect (&r); - SetContext (SpaceContext); - } - else - { // no crew to dismiss - PlayMenuSound (MENU_SOUND_FAILURE); - } - } - else - { - if (StarShipPtr->crew_level > 0) - { - if (StarShipPtr->crew_level > 1) - DeltaSISGauges (0, 0, GLOBAL (CrewCost) - - (crew_bought == - CREW_EXPENSE_THRESHOLD ? 2 : 0)); - else - DeltaSISGauges (0, 0, (COUNT)ShipCost[ - StarShipPtr->race_id]); - crew_delta = -1; - --StarShipPtr->crew_level; - } - else - { // no crew to dismiss - PlayMenuSound (MENU_SOUND_FAILURE); - } - ShowShipCrew (StarShipPtr, &pMS->flash_rect0); - r.corner.x = pMS->flash_rect0.corner.x; - r.corner.y = pMS->flash_rect0.corner.y - + pMS->flash_rect0.extent.height - 6; - r.extent.width = SHIP_WIN_WIDTH; - r.extent.height = 5; - SetContext (SpaceContext); - SetFlashRect (&r); - } - } - - if (hStarShip) - { - UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); - - // clear out the bought ship index - // so that flash rects work correctly - pMS->delta_item &= MODIFY_CREW_FLAG; - } - CrewTransaction (crew_delta); - } - } - else if (cancel) - { - UnlockMutex (GraphicsLock); - - pMS->InputFunc = DoShipyard; - pMS->CurState = SHIPYARD_CREW; - DrawMenuStateStrings (PM_CREW, pMS->CurState); - LockMutex (GraphicsLock); - SetFlashRect (SFR_MENU_3DO); - UnlockMutex (GraphicsLock); - - return TRUE; - } - else - { - pMS->CurState = NewState; - -ChangeFlashRect: - if (HINIBBLE (pMS->CurState)) - { - pMS->flash_rect0.corner.x = - pMS->flash_rect0.corner.y = 0; - pMS->flash_rect0.extent.width = SIS_SCREEN_WIDTH; - pMS->flash_rect0.extent.height = 61; - } - else - { - pMS->flash_rect0.corner.x = hangar_x_coords[ - pMS->CurState % HANGAR_SHIPS_ROW]; - pMS->flash_rect0.corner.y = HANGAR_Y + (HANGAR_DY * - (pMS->CurState / HANGAR_SHIPS_ROW)); - pMS->flash_rect0.extent.width = SHIP_WIN_WIDTH; - pMS->flash_rect0.extent.height = SHIP_WIN_HEIGHT; - } - SetFlashRect (&pMS->flash_rect0); - } - UnlockMutex (GraphicsLock); - } } SleepThread (ONE_SECOND / 30); @@ -1184,7 +1410,6 @@ DoShipyard (MENU_STATE *pMS) pMS->hMusic = LoadMusic (SHIPYARD_MUSIC); - LockMutex (GraphicsLock); SetTransitionSource (NULL); BatchGraphics (); DrawSISFrame (); @@ -1192,12 +1417,10 @@ DoShipyard (MENU_STATE *pMS) DrawSISTitle (GAME_STRING (STARBASE_STRING_BASE)); SetContext (SpaceContext); DrawBluePrint (pMS); - UnlockMutex (GraphicsLock); pMS->CurState = SHIPYARD_CREW; DrawMenuStateStrings (PM_CREW, pMS->CurState); - LockMutex (GraphicsLock); SetContext (SpaceContext); s.origin.x = 0; s.origin.y = 0; @@ -1222,7 +1445,6 @@ DoShipyard (MENU_STATE *pMS) ScreenTransition (3, NULL); UnbatchGraphics (); - UnlockMutex (GraphicsLock); PlayMusic (pMS->hMusic, TRUE, 1); @@ -1230,9 +1452,7 @@ DoShipyard (MENU_STATE *pMS) SetInputCallback (on_input_frame); - LockMutex (GraphicsLock); SetFlashRect (SFR_MENU_3DO); - UnlockMutex (GraphicsLock); } pMS->Initialized = TRUE; @@ -1242,12 +1462,10 @@ DoShipyard (MENU_STATE *pMS) ExitShipyard: SetInputCallback (NULL); - LockMutex (GraphicsLock); DestroyDrawable (ReleaseDrawable (pMS->ModuleFrame)); pMS->ModuleFrame = 0; DestroyColorMap (ReleaseColorMap (pMS->CurString)); pMS->CurString = 0; - UnlockMutex (GraphicsLock); return FALSE; } @@ -1264,9 +1482,7 @@ ExitShipyard: if (!GameOptions ()) goto ExitShipyard; DrawMenuStateStrings (PM_CREW, pMS->CurState); - LockMutex (GraphicsLock); SetFlashRect (SFR_MENU_3DO); - UnlockMutex (GraphicsLock); } } else diff --git a/sc2/src/uqm/sis.c b/sc2/src/uqm/sis.c index cf35c2fe0..9f50d1d02 100644 --- a/sc2/src/uqm/sis.c +++ b/sc2/src/uqm/sis.c @@ -20,8 +20,7 @@ #include "colors.h" #include "races.h" -// XXX: including encount.h for stuff that does not belong there -#include "encount.h" +#include "starmap.h" #include "units.h" #include "menustat.h" // for DrawMenuStateStrings() @@ -32,8 +31,10 @@ #include "element.h" #include "setup.h" #include "state.h" +#include "flash.h" #include "libs/graphics/gfx_common.h" #include "libs/tasklib.h" +#include "libs/alarm.h" #include "libs/log.h" #include @@ -99,9 +100,7 @@ ClearSISRect (BYTE ClearFlags) if (ClearFlags & CLEAR_SIS_RADAR) { - UnlockMutex (GraphicsLock); DrawMenuStateStrings ((BYTE)~0, 1); - LockMutex (GraphicsLock); #ifdef NEVER r.corner.x = RADAR_X - 1; r.corner.y = RADAR_Y - 1; @@ -215,7 +214,7 @@ DrawSISMessageEx (const UNICODE *pStr, SIZE CurPos, SIZE ExPos, COUNT flags) pStr = buf; break; case IN_HYPERSPACE: - if (GET_GAME_STATE (ARILOU_SPACE_SIDE) <= 1) + if (inHyperSpace ()) { pStr = GAME_STRING (NAVIGATION_STRING_BASE); // "HyperSpace" @@ -950,7 +949,6 @@ DrawModules (void) } } -// Pre: GraphicsLock is unlocked static void DrawSupportShips (void) { @@ -974,9 +972,7 @@ DrawSupportShips (void) s.origin = *pship_pos; s.frame = StarShipPtr->icons; - LockMutex (GraphicsLock); DrawStamp (&s); - UnlockMutex (GraphicsLock); UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); } @@ -1141,9 +1137,7 @@ DeltaSISGauges (SIZE crew_delta, SIZE fuel_delta, int resunit_delta) DrawTurningJets (); DrawModules (); - UnlockMutex (GraphicsLock); DrawSupportShips (); - LockMutex (GraphicsLock); } SetContextFont (TinyFont); @@ -1590,248 +1584,158 @@ DrawAutoPilotMessage (BOOLEAN Reset) } -Task flash_task = 0; -RECT flash_rect; -static FRAME flash_screen_frame = 0; - // The original contents of the flash rectangle. -static int flash_changed; -Mutex flash_mutex = 0; +static FlashContext *flashContext = NULL; +static RECT flash_rect; +static Alarm *flashAlarm = NULL; +static BOOLEAN flashPaused = FALSE; -static int -flash_rect_func (void *data) +static void scheduleFlashAlarm (void); + +static void +updateFlashRect (void *arg) { -#define NORMAL_STRENGTH 4 -#define NORMAL_F_STRENGTH 0 -#define CACHE_SIZE 10 - DWORD TimeIn; - const DWORD WaitTime = ONE_SECOND / 16; - SIZE strength; - RECT cached_rect = {{0, 0}, {0, 0}}; - FRAME cached_screen_frame = 0; - Task task = (Task)data; - bool cached[CACHE_SIZE]; - STAMP cached_stamp[CACHE_SIZE]; - int i; + if (flashContext == NULL) + return; - // Init cache - for (i = 0; i < CACHE_SIZE; i++) - { - cached[i] = false; - cached_stamp[i].frame = 0; - } + Flash_process (flashContext); + scheduleFlashAlarm (); + (void) arg; +} - strength = NORMAL_STRENGTH; - TimeIn = GetTimeCounter (); - while (!Task_ReadState(task, TASK_EXIT)) - { - CONTEXT OldContext; - - LockMutex (flash_mutex); - if (flash_changed) - { - cached_rect = flash_rect; - if (cached_screen_frame) - DestroyDrawable (ReleaseDrawable (cached_screen_frame)); - flash_changed = 0; - // Wait for the flash_screen_frame to get initialized - FlushGraphics (); - cached_screen_frame = CaptureDrawable ( - CloneFrame (flash_screen_frame)); - UnlockMutex (flash_mutex); - - // Clear the cache. - for (i = 0; i < CACHE_SIZE; i++) - { - cached[i] = false; - if (cached_stamp[i].frame) - DestroyDrawable (ReleaseDrawable (cached_stamp[i].frame)); - cached_stamp[i].frame = 0; - } - } - else - UnlockMutex (flash_mutex); - - if (cached_rect.extent.width) - { - STAMP *pStamp; - -#define MIN_STRENGTH 4 -#define MAX_STRENGTH 6 - strength += 2; - if (strength > MAX_STRENGTH) - strength = MIN_STRENGTH; - if (cached[strength - MIN_STRENGTH]) - pStamp = &cached_stamp[strength - MIN_STRENGTH]; - else - { - pStamp = &cached_stamp[strength - MIN_STRENGTH]; - cached[strength - MIN_STRENGTH] = true; - pStamp->frame = CaptureDrawable ( - CloneFrame (cached_screen_frame)); - pStamp->origin.x = 0; - pStamp->origin.y = 0; - - if (strength != 4) - { // brighten the frame with an additive - DrawMode oldMode; - STAMP s; - int factor; - - s.origin.x = 0; - s.origin.y = 0; - s.frame = cached_screen_frame; - - factor = (strength - MIN_STRENGTH) * DRAW_FACTOR_1 / 4; - - LockMutex (GraphicsLock); - OldContext = SetContext (OffScreenContext); - SetContextFGFrame (pStamp->frame); - SetContextClipRect (NULL); - oldMode = SetContextDrawMode (MAKE_DRAW_MODE ( - DRAW_ADDITIVE, factor)); - DrawStamp (&s); - SetContextDrawMode (oldMode); - SetContext (OldContext); - UnlockMutex (GraphicsLock); - } - } - - LockMutex (GraphicsLock); - OldContext = SetContext (ScreenContext); - SetContextClipRect (&cached_rect); - // flash changed_can't be modified while GraphicSem is held - if (!flash_changed) - DrawStamp (pStamp); - // XXX: Shouldn't we save and restore the original cliprect? - SetContextClipRect (NULL); - SetContext (OldContext); - UnlockMutex (GraphicsLock); - } - FlushGraphics (); - SleepThreadUntil (TimeIn + WaitTime); - TimeIn = GetTimeCounter (); - } - - // Clear cache - { - if (cached_screen_frame) - DestroyDrawable (ReleaseDrawable (cached_screen_frame)); - - for (i = 0; i < CACHE_SIZE; i++) - { - if(cached_stamp[i].frame) - DestroyDrawable (ReleaseDrawable (cached_stamp[i].frame)); - } - } - LockMutex (flash_mutex); - flash_task = 0; - UnlockMutex (flash_mutex); - - FinishTask (task); - return 0; +static void +scheduleFlashAlarm (void) +{ + TimeCount nextTime = Flash_nextTime (flashContext); + DWORD nextTimeMs = (nextTime / ONE_SECOND) * 1000 + + ((nextTime % ONE_SECOND) * 1000 / ONE_SECOND); + // Overflow-safe conversion. + flashAlarm = Alarm_addAbsoluteMs (nextTimeMs, updateFlashRect, NULL); } void -SetFlashRect (RECT *pRect) +SetFlashRect (const RECT *pRect) { RECT clip_r = {{0, 0}, {0, 0}}; - RECT temp_r, flash_rect1, old_r; - CONTEXT OldContext; - int create_flash = 0; - - if (!flash_mutex) - flash_mutex = CreateMutex ("FlashRect Lock", - SYNC_CLASS_TOPLEVEL | SYNC_CLASS_VIDEO); - - old_r = flash_rect; - flash_rect1 = flash_rect; - + RECT temp_r; + if (pRect != SFR_MENU_3DO && pRect != SFR_MENU_ANY) { + // The caller specified their own flash area, or NULL (stop flashing). GetContextClipRect (&clip_r); - OldContext = SetContext (ScreenContext); } else { - //Don't flash when using the PC menu if (optWhichMenu == OPT_PC && pRect != SFR_MENU_ANY) { - OldContext = SetContext (ScreenContext); + // The player wants PC menus and this flash is not used + // for a PC menu. + // Don't flash. pRect = 0; } else { - OldContext = SetContext (StatusContext); + // The player wants 3DO menus, or the flash is used in both + // 3DO and PC mode. + CONTEXT OldContext = SetContext (StatusContext); GetContextClipRect (&clip_r); pRect = &temp_r; temp_r.corner.x = RADAR_X - clip_r.corner.x; temp_r.corner.y = RADAR_Y - clip_r.corner.y; temp_r.extent.width = RADAR_WIDTH; temp_r.extent.height = RADAR_HEIGHT; - SetContext (ScreenContext); + SetContext (OldContext); } } - if (pRect == 0 || pRect->extent.width == 0) + if (pRect != 0 && pRect->extent.width != 0) { - // End the flashing. - flash_rect1.extent.width = 0; - if (flash_task) + // Flash rectangle is not empty, start or continue flashing. + flash_rect = *pRect; + flash_rect.corner.x += clip_r.corner.x; + flash_rect.corner.y += clip_r.corner.y; + + if (flashContext == NULL) { - UnlockMutex (GraphicsLock); - ConcludeTask (flash_task); - LockMutex (GraphicsLock); + // Create a new flash context. + flashContext = Flash_createHighlight (ScreenContext, &flash_rect); + Flash_setMergeFactors(flashContext, 3, 2, 2); + Flash_setSpeed (flashContext, 0, ONE_SECOND / 16, 0, ONE_SECOND / 16); + Flash_setFrameTime (flashContext, ONE_SECOND / 16); + Flash_start (flashContext); + scheduleFlashAlarm (); + } + else + { + // Reuse an existing flash context + Flash_setRect (flashContext, &flash_rect); } } else { - flash_rect1 = *pRect; - flash_rect1.corner.x += clip_r.corner.x; - flash_rect1.corner.y += clip_r.corner.y; - create_flash = 1; - } - - LockMutex (flash_mutex); - flash_rect = flash_rect1; - - if (old_r.extent.width && !rectsEqual (old_r, flash_rect)) - { - // We had a flash rectangle, and now a different one is set. - if (flash_screen_frame) + // Flash rectangle is empty. Stop flashing. + if (flashContext != NULL) { - // The screen contents may have changed; we grab a new copy. - STAMP old_s; - old_s.origin.x = old_r.corner.x; - old_s.origin.y = old_r.corner.y; - old_s.frame = flash_screen_frame; - DrawStamp (&old_s); - DestroyDrawable (ReleaseDrawable (flash_screen_frame)); - flash_screen_frame = 0; + Alarm_remove(flashAlarm); + flashAlarm = 0; + + Flash_terminate (flashContext); + flashContext = NULL; } - else - log_add (log_Debug, "Couldn't locate flash_screen_rect"); } - - if (flash_rect.extent.width) - { - // A new flash rectangle is set. - // Copy the original contents of the rectangle from the screen. - if (flash_screen_frame) - DestroyDrawable (ReleaseDrawable (flash_screen_frame)); - flash_screen_frame = - CaptureDrawable (LoadDisplayPixmap (&flash_rect, (FRAME)0)); - } - flash_changed = 1; - UnlockMutex (flash_mutex); - // we create the thread after the LoadDisplayPixmap() - // so there is no race between the FlushGraphics in flash_task - // and the Enqueue in LoadDisplayPixmap() - if (create_flash && flash_task == 0) - { - flash_task = AssignTask (flash_rect_func, 2048, - "flash rectangle"); - } - - SetContext (OldContext); } +COUNT updateFlashRectRecursion = 0; +// XXX This is necessary at least because DMS_AddEscortShip() calls +// DrawRaceStrings() in an UpdateFlashRect block, which calls +// ClearSISRect(), which calls DrawMenuStateStrings(), which starts its own +// UpdateFlashRect block. This should probably be cleaned up. + +void +PreUpdateFlashRect (void) +{ + if (flashAlarm) + { + updateFlashRectRecursion++; + if (updateFlashRectRecursion > 1) + return; + Flash_preUpdate (flashContext); + } +} + +void +PostUpdateFlashRect (void) +{ + if (flashAlarm) + { + updateFlashRectRecursion--; + if (updateFlashRectRecursion > 0) + return; + + Flash_postUpdate (flashContext); + } +} + +// Stop flashing if flashing is active. +void +PauseFlash (void) +{ + if (flashContext != NULL) + { + Alarm_remove(flashAlarm); + flashAlarm = 0; + flashPaused = TRUE; + } +} + +// Continue flashing after PauseFlash (), if flashing was active. +void +ContinueFlash (void) +{ + if (flashPaused) + { + scheduleFlashAlarm (); + flashPaused = FALSE; + } +} + + diff --git a/sc2/src/uqm/sis.h b/sc2/src/uqm/sis.h index b717b5b6d..06dea4265 100644 --- a/sc2/src/uqm/sis.h +++ b/sc2/src/uqm/sis.h @@ -22,6 +22,10 @@ #include "planets/elemdata.h" // for NUM_ELEMENT_CATEGORIES +#if defined(__cplusplus) +extern "C" { +#endif + #define CLEAR_SIS_RADAR (1 << 2) #define DRAW_SIS_DISPLAY (1 << 3) @@ -177,7 +181,12 @@ extern void RepairSISBorder (void); extern void InitSISContexts (void); extern void DrawSISFrame (void); extern void ClearSISRect (BYTE ClearFlags); -extern void SetFlashRect (RECT *pRect); +extern void SetFlashRect (const RECT *pRect); +extern void PreUpdateFlashRect (void); +extern void PostUpdateFlashRect (void); +extern void PauseFlash (void); +extern void ContinueFlash (void); + #define SFR_MENU_3DO ((RECT*)~0L) #define SFR_MENU_ANY ((RECT*)~1L) extern void DrawHyperCoords (POINT puniverse); @@ -244,5 +253,9 @@ extern COUNT CountSISPieces (BYTE piece_type); extern void DrawFlagshipName (BOOLEAN InStatusArea); extern void DrawCaptainsName (void); +#if defined(__cplusplus) +} +#endif + #endif /* SIS_H_INCL__ */ diff --git a/sc2/src/uqm/sounds.h b/sc2/src/uqm/sounds.h index 7917ae9c2..622b3bafb 100644 --- a/sc2/src/uqm/sounds.h +++ b/sc2/src/uqm/sounds.h @@ -23,6 +23,10 @@ #include "libs/compiler.h" #include "libs/sndlib.h" +#if defined(__cplusplus) +extern "C" { +#endif + typedef enum { GRAB_CREW = 0, @@ -74,6 +78,8 @@ extern void UpdateSoundPositions (void); extern void FlushSounds (void); extern void RemoveSoundsForObject (ELEMENT *PosObj); +#if defined(__cplusplus) +} +#endif + #endif /* UQM_SOUNDS_H_ */ - - diff --git a/sc2/src/uqm/starbase.c b/sc2/src/uqm/starbase.c index 2f48cd38c..be12f06c7 100644 --- a/sc2/src/uqm/starbase.c +++ b/sc2/src/uqm/starbase.c @@ -19,8 +19,7 @@ #include "build.h" #include "colors.h" #include "controls.h" -// XXX: for CurStarDescPtr -#include "encount.h" +#include "starmap.h" #include "comm.h" #include "gamestr.h" #include "load.h" @@ -308,7 +307,6 @@ DoStarBase (MENU_STATE *pMS) LastActivity &= ~CHECK_LOAD; pMS->InputFunc = DoStarBase; - LockMutex (GraphicsLock); SetFlashRect (NULL); if (pMS->hMusic) @@ -319,12 +317,10 @@ DoStarBase (MENU_STATE *pMS) } pMS->Initialized = TRUE; - UnlockMutex (GraphicsLock); pMS->CurFrame = CaptureDrawable (LoadGraphic (STARBASE_ANIM)); pMS->hMusic = LoadMusic (STARBASE_MUSIC); - LockMutex (GraphicsLock); SetContext (ScreenContext); SetTransitionSource (NULL); BatchGraphics (); @@ -335,7 +331,6 @@ DoStarBase (MENU_STATE *pMS) ScreenTransition (3, NULL); PlayMusic (pMS->hMusic, TRUE, 1); UnbatchGraphics (); - UnlockMutex (GraphicsLock); } else if (PulsedInputState.menu[KEY_MENU_SELECT]) { @@ -405,7 +400,6 @@ ExitStarBase: NewState = TALK_COMMANDER; } - LockMutex (GraphicsLock); BatchGraphics (); SetContext (ScreenContext); @@ -418,7 +412,6 @@ ExitStarBase: rotateStarbase (pMS, NULL); UnbatchGraphics (); - UnlockMutex (GraphicsLock); SleepThread (ONE_SECOND / 30); } @@ -431,9 +424,7 @@ DoTimePassage (void) { #define LOST_DAYS 14 SleepThreadUntil (FadeScreen (FadeAllToBlack, ONE_SECOND * 2)); - LockMutex (GraphicsLock); MoveGameClockDays (LOST_DAYS); - UnlockMutex (GraphicsLock); } void @@ -542,12 +533,10 @@ InstallBombAtEarth (void) { DoTimePassage (); - LockMutex (GraphicsLock); SetContext (ScreenContext); SetTransitionSource (NULL); SetContextBackGroundColor (BLACK_COLOR); ClearDrawable (); - UnlockMutex (GraphicsLock); SleepThreadUntil (FadeScreen (FadeAllToColor, 0)); diff --git a/sc2/src/uqm/starbase.h b/sc2/src/uqm/starbase.h index 8802fad78..0bf5558ce 100644 --- a/sc2/src/uqm/starbase.h +++ b/sc2/src/uqm/starbase.h @@ -21,6 +21,10 @@ #include "menustat.h" +#if defined(__cplusplus) +extern "C" { +#endif + enum { TALK_COMMANDER = 0, @@ -44,5 +48,8 @@ extern COUNT WrapText (const UNICODE *pStr, COUNT len, TEXT *tarray, SIZE field_width); // XXX: Doesn't really belong in this file. -#endif /* UQM_STARBASE_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_STARBASE_H_ */ diff --git a/sc2/src/uqm/starcon.c b/sc2/src/uqm/starcon.c index 969ecf75c..cf9d6724f 100644 --- a/sc2/src/uqm/starcon.c +++ b/sc2/src/uqm/starcon.c @@ -50,6 +50,10 @@ #include "options.h" volatile int MainExited = FALSE; +#ifdef DEBUG_SLEEP +uint32 mainThreadId; +extern uint32 SDL_ThreadID(void); +#endif // Open or close the periodically occuring QuasiSpace portal. // It changes the appearant portal size when necessary. @@ -73,7 +77,6 @@ checkArilouGate (void) } // Battle frame callback function. -// Called with GraphicsLock held static void on_battle_frame (void) { @@ -101,6 +104,7 @@ BackgroundInitKernel (DWORD TimeOut) } } +// Executes on the main() thread void SignalStopMainThread (void) { @@ -109,6 +113,7 @@ SignalStopMainThread (void) TaskSwitch (); } +// Executes on the main() thread void ProcessUtilityKeys (void) { @@ -128,11 +133,17 @@ ProcessUtilityKeys (void) } #if defined(DEBUG) || defined(USE_DEBUG_KEY) - if (ImmediateInputState.menu[KEY_DEBUG]) - { - // clear ImmediateInputState so we don't repeat this next frame - FlushInput (); - debugKeyPressed (); + { // Only call the debug func on the rising edge of + // ImmediateInputState[KEY_DEBUG] so it does not execute repeatedly. + // This duplicates the PulsedInputState somewhat, but we cannot + // use PulsedInputState here because it is meant for another thread. + static int debugKeyState; + + if (ImmediateInputState.menu[KEY_DEBUG] && debugKeyState == 0) + { + debugKeyPressed (); + } + debugKeyState = ImmediateInputState.menu[KEY_DEBUG]; } #endif /* DEBUG */ } @@ -143,6 +154,10 @@ extern int snddriver, soundflags; int Starcon2Main (void *threadArg) { +#ifdef DEBUG_SLEEP + mainThreadId = SDL_ThreadID(); +#endif + #if CREATE_JOURNAL { int ac = argc; @@ -270,9 +285,7 @@ while (--ac > 0) Battle (&on_battle_frame); } - LockMutex (GraphicsLock); SetFlashRect (NULL); - UnlockMutex (GraphicsLock); LastActivity = GLOBAL (CurrentActivity); diff --git a/sc2/src/uqm/starcon.h b/sc2/src/uqm/starcon.h index cefdb5ec7..a8f652861 100644 --- a/sc2/src/uqm/starcon.h +++ b/sc2/src/uqm/starcon.h @@ -17,6 +17,10 @@ #ifndef UQM_STARCON_H_ #define UQM_STARCON_H_ +#if defined(__cplusplus) +extern "C" { +#endif + extern volatile int MainExited; extern void SignalStopMainThread (void); extern void ProcessUtilityKeys (void); @@ -24,5 +28,8 @@ extern void ProcessUtilityKeys (void); extern int Starcon2Main (void *threadArg); extern void FreeGameData (void); -#endif /* UQM_STARCON_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_STARCON_H_ */ diff --git a/sc2/src/uqm/starmap.c b/sc2/src/uqm/starmap.c index f372d2295..a209917bd 100644 --- a/sc2/src/uqm/starmap.c +++ b/sc2/src/uqm/starmap.c @@ -16,10 +16,9 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "encount.h" +#include "starmap.h" #include "gamestr.h" #include "globdata.h" -#include "libs/compiler.h" #include "libs/gfxlib.h" diff --git a/sc2/src/uqm/starmap.h b/sc2/src/uqm/starmap.h new file mode 100644 index 000000000..016183025 --- /dev/null +++ b/sc2/src/uqm/starmap.h @@ -0,0 +1,42 @@ +/* + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef STARMAP_H_INCL_ +#define STARMAP_H_INCL_ + +#include "libs/compiler.h" +#include "planets/planets.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +extern STAR_DESC *CurStarDescPtr; +extern STAR_DESC *star_array; + +#define NUM_SOLAR_SYSTEMS 502 + +extern STAR_DESC* FindStar (STAR_DESC *pLastStar, POINT *puniverse, + SIZE xbounds, SIZE ybounds); + +extern void GetClusterName (const STAR_DESC *pSD, UNICODE buf[]); + +#if defined(__cplusplus) +} +#endif + +#endif /* STARMAP_H_INCL_ */ + diff --git a/sc2/src/uqm/state.c b/sc2/src/uqm/state.c index 61d6be648..3358b3249 100644 --- a/sc2/src/uqm/state.c +++ b/sc2/src/uqm/state.c @@ -18,12 +18,13 @@ #include "state.h" -#include "encount.h" +#include "starmap.h" #include "libs/memlib.h" #include "libs/log.h" #ifdef HAVE_UNISTD_H #include #endif +#include // in-memory file i/o struct GAME_STATE_FILE @@ -123,6 +124,8 @@ DeleteStateFile (int stateFile) fp->used = 0; fp->ptr = 0; + HFree (fp->data); + fp->data = 0; } DWORD @@ -238,7 +241,7 @@ UninitPlanetInfo (void) void GetPlanetInfo (void) { - void *fp; + GAME_STATE_FILE *fp; pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask[BIOLOGICAL_SCAN] = 0; pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask[MINERAL_SCAN] = 0; @@ -286,7 +289,7 @@ GetPlanetInfo (void) void PutPlanetInfo (void) { - void *fp; + GAME_STATE_FILE *fp; fp = OpenStateFile (STARINFO_FILE, "r+b"); if (fp) diff --git a/sc2/src/uqm/state.h b/sc2/src/uqm/state.h index 7bd51ca7e..e469cba04 100644 --- a/sc2/src/uqm/state.h +++ b/sc2/src/uqm/state.h @@ -23,6 +23,10 @@ #include "libs/compiler.h" #include +#if defined(__cplusplus) +extern "C" { +#endif + extern void InitPlanetInfo (void); extern void UninitPlanetInfo (void); extern void GetPlanetInfo (void); @@ -75,7 +79,7 @@ int WriteStateFile (const void *lpBuf, COUNT size, COUNT count, GAME_STATE_FILE int SeekStateFile (GAME_STATE_FILE *fp, long offset, int whence); static inline COUNT -sread_8 (void *fp, BYTE *v) +sread_8 (GAME_STATE_FILE *fp, BYTE *v) { BYTE t; if (!v) /* read value ignored */ @@ -84,7 +88,7 @@ sread_8 (void *fp, BYTE *v) } static inline COUNT -sread_16 (void *fp, UWORD *v) +sread_16 (GAME_STATE_FILE *fp, UWORD *v) { UWORD t; if (!v) /* read value ignored */ @@ -93,7 +97,7 @@ sread_16 (void *fp, UWORD *v) } static inline COUNT -sread_16s (void *fp, SWORD *v) +sread_16s (GAME_STATE_FILE *fp, SWORD *v) { UWORD t; COUNT ret; @@ -105,7 +109,7 @@ sread_16s (void *fp, SWORD *v) } static inline COUNT -sread_32 (void *fp, DWORD *v) +sread_32 (GAME_STATE_FILE *fp, DWORD *v) { DWORD t; if (!v) /* read value ignored */ @@ -114,7 +118,7 @@ sread_32 (void *fp, DWORD *v) } static inline COUNT -sread_a32 (void *fp, DWORD *ar, COUNT count) +sread_a32 (GAME_STATE_FILE *fp, DWORD *ar, COUNT count) { assert (ar != NULL); @@ -127,25 +131,25 @@ sread_a32 (void *fp, DWORD *ar, COUNT count) } static inline COUNT -swrite_8 (void *fp, BYTE v) +swrite_8 (GAME_STATE_FILE *fp, BYTE v) { return WriteStateFile (&v, 1, 1, fp); } static inline COUNT -swrite_16 (void *fp, UWORD v) +swrite_16 (GAME_STATE_FILE *fp, UWORD v) { return WriteStateFile (&v, 2, 1, fp); } static inline COUNT -swrite_32 (void *fp, DWORD v) +swrite_32 (GAME_STATE_FILE *fp, DWORD v) { return WriteStateFile (&v, 4, 1, fp); } static inline COUNT -swrite_a32 (void *fp, const DWORD *ar, COUNT count) +swrite_a32 (GAME_STATE_FILE *fp, const DWORD *ar, COUNT count) { for ( ; count > 0; --count, ++ar) { @@ -155,5 +159,8 @@ swrite_a32 (void *fp, const DWORD *ar, COUNT count) return 1; } -#endif /* UQM_STATE_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_STATE_H_ */ diff --git a/sc2/src/uqm/status.h b/sc2/src/uqm/status.h index b119d48a3..f27965ee8 100644 --- a/sc2/src/uqm/status.h +++ b/sc2/src/uqm/status.h @@ -22,6 +22,10 @@ #include "races.h" #include "libs/compiler.h" +#if defined(__cplusplus) +extern "C" { +#endif + #define CREW_XOFFS 4 #define ENERGY_XOFFS 52 #define GAUGE_YOFFS (SHIP_INFO_HEIGHT - 10) @@ -64,4 +68,8 @@ extern BOOLEAN DeltaCrew (ELEMENT *ElementPtr, SIZE crew_delta); extern void PreProcessStatus (ELEMENT *ShipPtr); extern void PostProcessStatus (ELEMENT *ShipPtr); +#if defined(__cplusplus) +} +#endif + #endif /* UQM_STATUS_H_INCL_ */ diff --git a/sc2/src/uqm/supermelee/Makeinfo b/sc2/src/uqm/supermelee/Makeinfo index 980b93b60..897a1fe56 100644 --- a/sc2/src/uqm/supermelee/Makeinfo +++ b/sc2/src/uqm/supermelee/Makeinfo @@ -1,4 +1,5 @@ uqm_CFILES="buildpick.c loadmele.c melee.c meleesetup.c pickmele.c" +uqm_HFILES="buildpick.h loadmele.h melee.h meleesetup.h meleeship.h pickmele.h" if [ -n "$uqm_NETPLAY" ]; then uqm_SUBDIRS="$uqm_SUBDIRS netplay" fi diff --git a/sc2/src/uqm/supermelee/buildpick.c b/sc2/src/uqm/supermelee/buildpick.c index 14ef2731b..3f4731bc3 100644 --- a/sc2/src/uqm/supermelee/buildpick.c +++ b/sc2/src/uqm/supermelee/buildpick.c @@ -86,7 +86,6 @@ DrawPickIcon (MeleeShip ship, bool DrawErase) } } -// Pre: the called holds the GraphicsLock void DrawPickFrame (MELEE_STATE *pMS) { @@ -187,11 +186,9 @@ DoPickShip (MELEE_STATE *pMS) if (newSelectedShip != pMS->currentShip) { // A new ship has been selected. - LockMutex (GraphicsLock); DrawPickIcon (pMS->currentShip, true); pMS->currentShip = newSelectedShip; DrawMeleeShipStrings (pMS, newSelectedShip); - UnlockMutex (GraphicsLock); } } @@ -214,9 +211,7 @@ BuildPickShip (MELEE_STATE *pMS) if (pMS->currentShip == MELEE_NONE) pMS->currentShip = 0; - LockMutex (GraphicsLock); DrawPickFrame (pMS); - UnlockMutex (GraphicsLock); pMS->InputFunc = DoPickShip; DoInput (pMS, FALSE); diff --git a/sc2/src/uqm/supermelee/buildpick.h b/sc2/src/uqm/supermelee/buildpick.h index dc609c627..43608e725 100644 --- a/sc2/src/uqm/supermelee/buildpick.h +++ b/sc2/src/uqm/supermelee/buildpick.h @@ -4,6 +4,10 @@ #include "types.h" #include "melee.h" +#if defined(__cplusplus) +extern "C" { +#endif + void BuildBuildPickFrame (void); void DestroyBuildPickFrame (void); bool BuildPickShip (MELEE_STATE *pMS); @@ -13,5 +17,9 @@ void DrawPickFrame (MELEE_STATE *pMS); void DrawPickIcon (MeleeShip ship, bool DrawErase); +#if defined(__cplusplus) +} +#endif + #endif /* BUILDPICK_H */ diff --git a/sc2/src/uqm/supermelee/loadmele.c b/sc2/src/uqm/supermelee/loadmele.c index b3559507e..d5917c3d9 100644 --- a/sc2/src/uqm/supermelee/loadmele.c +++ b/sc2/src/uqm/supermelee/loadmele.c @@ -311,11 +311,9 @@ flashSelectedTeam (MELEE_STATE *pMS) NextTime = Now + FLASH_RATE; hilite ^= 1; - LockMutex (GraphicsLock); OldContext = SetContext (SpaceContext); SelectFileString (pMS, hilite); SetContext (OldContext); - UnlockMutex (GraphicsLock); } } @@ -335,12 +333,10 @@ DoLoadTeam (MELEE_STATE *pMS) if (!pMS->Initialized) { - LockMutex (GraphicsLock); DrawFileStrings (pMS); SelectFileString (pMS, true); pMS->Initialized = TRUE; pMS->InputFunc = DoLoadTeam; - UnlockMutex (GraphicsLock); return TRUE; } @@ -360,9 +356,7 @@ DoLoadTeam (MELEE_STATE *pMS) RECT r; GetFrameRect (SetAbsFrameIndex (MeleeFrame, 28), &r); - LockMutex (GraphicsLock); RepairMeleeFrame (&r); - UnlockMutex (GraphicsLock); } return TRUE; } @@ -418,7 +412,6 @@ DoLoadTeam (MELEE_STATE *pMS) if (newIndex != pMS->load.cur) { // The cursor has been moved. - LockMutex (GraphicsLock); if (newTop == pMS->load.top) { // The view itself hasn't changed. @@ -431,7 +424,6 @@ DoLoadTeam (MELEE_STATE *pMS) DrawFileStrings (pMS); } pMS->load.cur = newIndex; - UnlockMutex (GraphicsLock); } } @@ -482,11 +474,9 @@ DoSaveTeam (MELEE_STATE *pMS) snprintf (file, sizeof file, "%s.mle", MeleeSetup_getTeamName (pMS->meleeSetup, pMS->side)); - LockMutex (GraphicsLock); OldContext = SetContext (ScreenContext); ConfirmSaveLoad (&MsgStamp); // Show the "Saving . . ." message. - UnlockMutex (GraphicsLock); stream = uio_fopen (meleeDir, file, "wb"); if (stream != NULL) @@ -503,11 +493,9 @@ DoSaveTeam (MELEE_STATE *pMS) pMS->load.cur = 0; // Undo the screen damage done by the "Saving . . ." message. - LockMutex (GraphicsLock); DrawStamp (&MsgStamp); DestroyDrawable (ReleaseDrawable (MsgStamp.frame)); SetContext (OldContext); - UnlockMutex (GraphicsLock); if (!saveOk) SaveProblem (); diff --git a/sc2/src/uqm/supermelee/loadmele.h b/sc2/src/uqm/supermelee/loadmele.h index 30a0477c7..529ef66d2 100644 --- a/sc2/src/uqm/supermelee/loadmele.h +++ b/sc2/src/uqm/supermelee/loadmele.h @@ -26,6 +26,10 @@ struct melee_load_state; #include "melee.h" #include "meleesetup.h" +#if defined(__cplusplus) +extern "C" { +#endif + struct melee_load_state { MeleeTeam **preBuiltList; @@ -56,6 +60,8 @@ bool ReadTeamImage (MeleeTeam *pTI, uio_Stream *load_fp); int WriteTeamImage (const MeleeTeam *pTI, uio_Stream *save_fp); void LoadTeamList (MELEE_STATE *pMS); +#if defined(__cplusplus) +} +#endif + #endif /* UQM_SUPERMELEE_LOADMELE_H_ */ - - diff --git a/sc2/src/uqm/supermelee/melee.c b/sc2/src/uqm/supermelee/melee.c index c04c92093..70f3acbaf 100644 --- a/sc2/src/uqm/supermelee/melee.c +++ b/sc2/src/uqm/supermelee/melee.c @@ -250,7 +250,6 @@ GetShipBox (RECT *pRect, COUNT side, COUNT row, COUNT col) pRect->extent.height = MELEE_BOX_HEIGHT; } -// The caller must hold the GraphicsLock. static void DrawShipBox (COUNT side, FleetShipIndex index, MeleeShip ship, BOOLEAN HiLite) { @@ -286,7 +285,6 @@ DrawShipBox (COUNT side, FleetShipIndex index, MeleeShip ship, BOOLEAN HiLite) UnbatchGraphics (); } -// The caller must hold the GraphicsLock. static void ClearShipBox (COUNT side, FleetShipIndex index) { @@ -570,7 +568,6 @@ DrawTeamString (MELEE_STATE *pMS, COUNT side, COUNT HiLiteState, #ifdef NETPLAY // This function is generic. It should probably be moved to elsewhere. -// The caller should hold the GraphicsLock. static void multiLineDrawText (TEXT *textIn, RECT *clipRect) { RECT oldRect; @@ -617,7 +614,6 @@ DrawMeleeStatusMessage (const char *message) CONTEXT oldContext; RECT r; - LockMutex (GraphicsLock); oldContext = SetContext (SpaceContext); r.corner.x = MELEE_STATUS_X_OFFS; @@ -643,7 +639,6 @@ DrawMeleeStatusMessage (const char *message) } SetContext (oldContext); - UnlockMutex (GraphicsLock); } static void @@ -697,7 +692,6 @@ UpdateMeleeStatusMessage (ssize_t player) #endif /* NETPLAY */ // XXX: this function is called when the current selection is blinking off. -// The caller should hold the GraphicsLock. static void Deselect (BYTE opt) { @@ -760,7 +754,6 @@ Deselect (BYTE opt) } // XXX: this function is called when the current selection is blinking off. -// The caller should hold the GraphicsLock. static void Select (BYTE opt) { @@ -837,14 +830,12 @@ Melee_flashSelection (MELEE_STATE *pMS) NextTime = Now + FLASH_RATE; select = !select; - LockMutex (GraphicsLock); OldContext = SetContext (SpaceContext); if (select) Select (pMS->MeleeOption); else Deselect (pMS->MeleeOption); SetContext (OldContext); - UnlockMutex (GraphicsLock); } } @@ -870,7 +861,6 @@ InitMelee (MELEE_STATE *pMS) (void) pMS; } -// Pre: The caller holds the GraphicsLock. void DrawMeleeShipStrings (MELEE_STATE *pMS, MeleeShip NewStarShip) { @@ -957,9 +947,7 @@ UpdateCurrentShip (MELEE_STATE *pMS) MeleeSetup_getShip (pMS->meleeSetup, pMS->side, slotNr); } - LockMutex (GraphicsLock); DrawMeleeShipStrings (pMS, pMS->currentShip); - UnlockMutex (GraphicsLock); } // returns (COUNT) ~0 for an invalid ship. @@ -1025,9 +1013,7 @@ OnTeamNameChange (TEXTENTRY_STATE *pTES) if (pTES->JoystickMode) hl |= DTSHS_BLOCKCUR; - LockMutex (GraphicsLock); ret = DrawTeamString (pMS, pMS->side, hl, pTES->BaseStr); - UnlockMutex (GraphicsLock); return ret; } @@ -1074,9 +1060,7 @@ BuildPickShipPopup (MELEE_STATE *pMS) RECT r; GetBuildPickFrameRect (&r); - LockMutex (GraphicsLock); RepairMeleeFrame (&r); - UnlockMutex (GraphicsLock); } UpdateCurrentShip (pMS); @@ -1113,12 +1097,10 @@ DoEdit (MELEE_STATE *pMS) || pMS->row == NUM_MELEE_ROWS)))) { // Done editing the teams. - LockMutex (GraphicsLock); Deselect (EDIT_MELEE); pMS->currentShip = MELEE_NONE; pMS->MeleeOption = START_MELEE; pMS->InputFunc = DoMelee; - UnlockMutex (GraphicsLock); pMS->LastInputTime = GetTimeCounter (); } else if (pMS->row < NUM_MELEE_ROWS @@ -1132,13 +1114,11 @@ DoEdit (MELEE_STATE *pMS) && PulsedInputState.menu[KEY_MENU_SPECIAL]) { // TODO: this is a stub; Should we display a ship spin? - LockMutex (GraphicsLock); Deselect (EDIT_MELEE); if (pMS->currentShip != MELEE_NONE) { // Do something with pMS->currentShip here } - UnlockMutex (GraphicsLock); } else if (pMS->row < NUM_MELEE_ROWS && PulsedInputState.menu[KEY_MENU_DELETE]) @@ -1165,9 +1145,7 @@ DoEdit (MELEE_STATE *pMS) // going to enter text pMS->CurIndex = 0; - LockMutex (GraphicsLock); DrawTeamString (pMS, pMS->side, DTSHS_EDIT, NULL); - UnlockMutex (GraphicsLock); strncpy (buf, MeleeSetup_getTeamName ( pMS->meleeSetup, pMS->side), MAX_TEAM_CHARS); @@ -1238,12 +1216,10 @@ DoEdit (MELEE_STATE *pMS) if (col != pMS->col || row != pMS->row || side != pMS->side) { - LockMutex (GraphicsLock); Deselect (EDIT_MELEE); pMS->side = side; pMS->row = row; pMS->col = col; - UnlockMutex (GraphicsLock); UpdateCurrentShip (pMS); } @@ -1488,9 +1464,7 @@ StartMelee (MELEE_STATE *pMS) { if (!SetPlayerInputAll ()) break; - LockMutex (GraphicsLock); BuildAndDrawShipList (pMS); - UnlockMutex (GraphicsLock); WaitForSoundEnd (TFBSOUND_WAIT_ALL); @@ -1638,7 +1612,6 @@ DoConnectingDialog (MELEE_STATE *pMS) pMS->InputFunc = DoConnectingDialog; /* Draw the dialog box here */ - LockMutex (GraphicsLock); oldfont = SetContextFont (StarConFont); oldcolor = SetContextForeGroundColor (BLACK_COLOR); BatchGraphics (); @@ -1674,7 +1647,6 @@ DoConnectingDialog (MELEE_STATE *pMS) SetContextFont (oldfont); SetContextForeGroundColor (oldcolor); UnbatchGraphics (); - UnlockMutex (GraphicsLock); } netInput (); @@ -1882,9 +1854,7 @@ DoMelee (MELEE_STATE *pMS) pMS->MeleeOption = START_MELEE; PlayMusic (pMS->hMusic, TRUE, 1); - LockMutex (GraphicsLock); InitMelee (pMS); - UnlockMutex (GraphicsLock); FadeScreen (FadeAllToColor, ONE_SECOND / 2); pMS->LastInputTime = GetTimeCounter (); @@ -1899,10 +1869,8 @@ DoMelee (MELEE_STATE *pMS) PulsedInputState.menu[KEY_MENU_LEFT]) { // Start editing the teams. - LockMutex (GraphicsLock); pMS->LastInputTime = GetTimeCounter (); Deselect (pMS->MeleeOption); - UnlockMutex (GraphicsLock); pMS->MeleeOption = EDIT_MELEE; pMS->Initialized = FALSE; if (PulsedInputState.menu[KEY_MENU_CANCEL]) @@ -1949,11 +1917,9 @@ DoMelee (MELEE_STATE *pMS) pMS->MeleeOption == CONTROLS_BOT) UpdateMeleeStatusMessage (-1); #endif - LockMutex (GraphicsLock); Deselect (pMS->MeleeOption); pMS->MeleeOption = NewMeleeOption; Select (pMS->MeleeOption); - UnlockMutex (GraphicsLock); #ifdef NETPLAY if (NewMeleeOption == CONTROLS_TOP || NewMeleeOption == CONTROLS_BOT) @@ -2148,14 +2114,12 @@ updateRandomSeed (MELEE_STATE *pMS, COUNT side, DWORD seed) void confirmationCancelled (MELEE_STATE *pMS, COUNT side) { - LockMutex (GraphicsLock); if (side == 0) DrawMeleeStatusMessage (GAME_STRING (NETMELEE_STRING_BASE + 16)); // "Bottom player changed something -- need to reconfirm." else DrawMeleeStatusMessage (GAME_STRING (NETMELEE_STRING_BASE + 17)); // "Top player changed something -- need to reconfirm." - UnlockMutex (GraphicsLock); if (pMS->InputFunc == DoConfirmSettings) pMS->InputFunc = DoMelee; @@ -2168,9 +2132,7 @@ connectionFeedback (NetConnection *conn, const char *str, bool forcePopup) { if (bs == NULL && !forcePopup) { // bs == NULL means the game has not started yet. - LockMutex (GraphicsLock); DrawMeleeStatusMessage (str); - UnlockMutex (GraphicsLock); } else { @@ -2314,10 +2276,8 @@ Melee_UpdateView_fleetValue (MELEE_STATE *pMS, COUNT side) if (pMS->meleeStarted) return; - LockMutex (GraphicsLock); DrawFleetValue (pMS, side, DTSHS_REPAIR); // BUG: The fleet value is always drawn as deselected. - UnlockMutex (GraphicsLock); } static void @@ -2330,7 +2290,6 @@ Melee_UpdateView_ship (MELEE_STATE *pMS, COUNT side, FleetShipIndex index) ship = MeleeSetup_getShip (pMS->meleeSetup, side, index); - LockMutex (GraphicsLock); if (ship == MELEE_NONE) { ClearShipBox (side, index); @@ -2339,7 +2298,6 @@ Melee_UpdateView_ship (MELEE_STATE *pMS, COUNT side, FleetShipIndex index) { DrawShipBox (side, index, ship, FALSE); } - UnlockMutex (GraphicsLock); } static void @@ -2348,9 +2306,7 @@ Melee_UpdateView_teamName (MELEE_STATE *pMS, COUNT side) if (pMS->meleeStarted) return; - LockMutex (GraphicsLock); DrawTeamString (pMS, side, DTSHS_REPAIR, NULL); - UnlockMutex (GraphicsLock); } /////////////////////////////////////////////////////////////////////////// @@ -2378,9 +2334,7 @@ Melee_Change_ship (MELEE_STATE *pMS, COUNT side, FleetShipIndex index, if (isShipSlotSelected (pMS, side, index)) { pMS->currentShip = ship; - LockMutex (GraphicsLock); DrawMeleeShipStrings (pMS, ship); - UnlockMutex (GraphicsLock); } return true; diff --git a/sc2/src/uqm/supermelee/melee.h b/sc2/src/uqm/supermelee/melee.h index 94b600221..e6026a39f 100644 --- a/sc2/src/uqm/supermelee/melee.h +++ b/sc2/src/uqm/supermelee/melee.h @@ -28,6 +28,10 @@ #include "netplay/packet.h" // for NetplayAbortReason and NetplayResetReason. +#if defined(__cplusplus) +extern "C" { +#endif + typedef struct melee_state MELEE_STATE; #define NUM_MELEE_ROWS 2 @@ -50,10 +54,18 @@ extern FRAME PickMeleeFrame; typedef BYTE MELEE_OPTIONS; +#if defined(__cplusplus) +} +#endif + #include "loadmele.h" #include "meleesetup.h" #include "meleeship.h" +#if defined(__cplusplus) +extern "C" { +#endif + struct melee_state { BOOLEAN (*InputFunc) (struct melee_state *pInputState); @@ -125,5 +137,8 @@ void Melee_RemoteChange_ship (MELEE_STATE *pMS, NetConnection *conn, void Melee_RemoteChange_teamName (MELEE_STATE *pMS, NetConnection *conn, COUNT side, const char *name); -#endif /* UQM_SUPERMELEE_MELEE_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_MELEE_H_ */ diff --git a/sc2/src/uqm/supermelee/meleesetup.h b/sc2/src/uqm/supermelee/meleesetup.h index d6ff9eda9..0097d920b 100644 --- a/sc2/src/uqm/supermelee/meleesetup.h +++ b/sc2/src/uqm/supermelee/meleesetup.h @@ -32,6 +32,10 @@ typedef COUNT FleetShipIndex; #include "melee.h" #include "meleeship.h" +#if defined(__cplusplus) +extern "C" { +#endif + #ifdef MELEETEAM_INTERNAL struct MeleeTeam { @@ -131,5 +135,9 @@ void MeleeState_setTeamName (MELEE_STATE *pMS, size_t teamNr, void MeleeState_setTeam (MELEE_STATE *pMS, size_t teamNr, const MeleeTeam *team); +#if defined(__cplusplus) +} +#endif + #endif /* MELEESETUP_H */ diff --git a/sc2/src/uqm/supermelee/meleeship.h b/sc2/src/uqm/supermelee/meleeship.h index b58c5b26c..e917b7561 100644 --- a/sc2/src/uqm/supermelee/meleeship.h +++ b/sc2/src/uqm/supermelee/meleeship.h @@ -3,6 +3,10 @@ #include "types.h" +#if defined(__cplusplus) +extern "C" { +#endif + typedef enum MeleeShip { MELEE_ANDROSYNTH, MELEE_ARILOU, @@ -43,5 +47,9 @@ MeleeShip_valid (MeleeShip ship) return (ship < NUM_MELEE_SHIPS) || (ship == MELEE_NONE); } +#if defined(__cplusplus) +} +#endif + #endif /* MELEESHIP_H */ diff --git a/sc2/src/uqm/supermelee/netplay/Makeinfo b/sc2/src/uqm/supermelee/netplay/Makeinfo index 48a2f6d0f..ff3101145 100644 --- a/sc2/src/uqm/supermelee/netplay/Makeinfo +++ b/sc2/src/uqm/supermelee/netplay/Makeinfo @@ -1,3 +1,4 @@ uqm_SUBDIRS="proto" uqm_CFILES="checkbuf.c checksum.c crc.c netconnection.c netinput.c netmelee.c netmisc.c netoptions.c netrcv.c netsend.c netstate.c notify.c notifyall.c packet.c packethandlers.c packetsenders.c packetq.c" +uqm_HFILES="checkbuf.h checksum.h crc.h netconnection.h netinput.h netmelee.h netmisc.h netoptions.h netplay.h netrcv.h netsend.h netstate.h notifyall.h notify.h packet.h packethandlers.h packetq.h packetsenders.h" diff --git a/sc2/src/uqm/supermelee/netplay/checkbuf.h b/sc2/src/uqm/supermelee/netplay/checkbuf.h index 71159a742..f6094489e 100644 --- a/sc2/src/uqm/supermelee/netplay/checkbuf.h +++ b/sc2/src/uqm/supermelee/netplay/checkbuf.h @@ -19,13 +19,25 @@ #ifndef UQM_SUPERMELEE_NETPLAY_CHECKBUF_H_ #define UQM_SUPERMELEE_NETPLAY_CHECKBUF_H_ +#if defined(__cplusplus) +extern "C" { +#endif + typedef struct ChecksumEntry ChecksumEntry; typedef struct ChecksumBuffer ChecksumBuffer; +#if defined(__cplusplus) +} +#endif + #include "../../battle.h" // for BattleFrameCounter #include "checksum.h" +#if defined(__cplusplus) +extern "C" { +#endif + struct ChecksumEntry { #ifdef NETPLAY_DEBUG @@ -58,5 +70,8 @@ bool ChecksumBuffer_addChecksum(ChecksumBuffer *cb, bool ChecksumBuffer_getChecksum(ChecksumBuffer *cb, BattleFrameCounter frameNr, Checksum *result); -#endif /* UQM_SUPERMELEE_NETPLAY_CHECKBUF_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_SUPERMELEE_NETPLAY_CHECKBUF_H_ */ diff --git a/sc2/src/uqm/supermelee/netplay/checksum.h b/sc2/src/uqm/supermelee/netplay/checksum.h index 539de5dd1..cfb48d623 100644 --- a/sc2/src/uqm/supermelee/netplay/checksum.h +++ b/sc2/src/uqm/supermelee/netplay/checksum.h @@ -33,6 +33,10 @@ typedef uint32 Checksum; #include "netconnection.h" +#if defined(__cplusplus) +extern "C" { +#endif + static inline void crc_processELEMENT_FLAGS(crc_State *state, ELEMENT_FLAGS val) { @@ -88,6 +92,8 @@ void addRemoteChecksum(NetConnection *conn, BattleFrameCounter frameNr, Checksum checksum); bool verifyChecksums(BattleFrameCounter frameNr); +#if defined(__cplusplus) +} +#endif + #endif /* UQM_SUPERMELEE_NETPLAY_CHECKSUM_H_ */ - - diff --git a/sc2/src/uqm/supermelee/netplay/crc.h b/sc2/src/uqm/supermelee/netplay/crc.h index 01aa6e5c1..1744d112c 100644 --- a/sc2/src/uqm/supermelee/netplay/crc.h +++ b/sc2/src/uqm/supermelee/netplay/crc.h @@ -25,6 +25,10 @@ typedef struct crc_State crc_State; #include +#if defined(__cplusplus) +extern "C" { +#endif + struct crc_State { uint32 crc; }; @@ -36,6 +40,9 @@ void crc_processUint16(crc_State *state, uint16 val); void crc_processUint32(crc_State *state, uint32 val); uint32 crc_finish(const crc_State *state); +#if defined(__cplusplus) +} +#endif #ifdef DUMP_CRC_OPS #include "netconnection.h" diff --git a/sc2/src/uqm/supermelee/netplay/netconnection.h b/sc2/src/uqm/supermelee/netplay/netconnection.h index e3f18ecd0..485d3c4d7 100644 --- a/sc2/src/uqm/supermelee/netplay/netconnection.h +++ b/sc2/src/uqm/supermelee/netplay/netconnection.h @@ -22,6 +22,10 @@ #include "netplay.h" // for NETPLAY_STATISTICS +#if defined(__cplusplus) +extern "C" { +#endif + typedef struct NetConnection NetConnection; typedef struct NetConnectionError NetConnectionError; typedef struct ConnectStateData ConnectStateData; @@ -38,6 +42,10 @@ typedef void (*NetConnection_DeleteCallback)(NetConnection *nd); typedef void (*NetConnection_ReadyCallback)(NetConnection *conn, void *arg); typedef void (*NetConnection_ResetCallback)(NetConnection *conn, void *arg); +#if defined(__cplusplus) +} +#endif + #include "netstate.h" #include "netoptions.h" #ifdef NETPLAY_CHECKSUM @@ -50,6 +58,10 @@ typedef void (*NetConnection_ResetCallback)(NetConnection *conn, void *arg); # include "libs/uio.h" #endif +#if defined(__cplusplus) +extern "C" { +#endif + struct NetConnectionError { NetState state; int err; @@ -68,11 +80,18 @@ struct NetStatistics { }; #endif +#if defined(__cplusplus) +} +#endif #ifdef NETCONNECTION_INTERNAL #include "libs/net.h" #include "packetq.h" +#if defined(__cplusplus) +extern "C" { +#endif + typedef struct { // For actions that require agreement by both parties. bool localOk : 1; /* Action confirmed by us */ @@ -232,6 +251,9 @@ void *NetConnection_getResetCallbackArg(const NetConnection *conn); extern uio_Stream *netplayDebugFile; #endif +#if defined(__cplusplus) +} +#endif #endif /* UQM_SUPERMELEE_NETPLAY_NETCONNECTION_H_ */ diff --git a/sc2/src/uqm/supermelee/netplay/netinput.h b/sc2/src/uqm/supermelee/netplay/netinput.h index 8eccbed9a..2afdf0291 100644 --- a/sc2/src/uqm/supermelee/netplay/netinput.h +++ b/sc2/src/uqm/supermelee/netplay/netinput.h @@ -22,6 +22,10 @@ #include "../../controls.h" // for BATTLE_INPUT_STATE #include "../../init.h" + +#if defined(__cplusplus) +extern "C" { +#endif // for NUM_PLAYERS typedef struct BattleInputBuffer { @@ -46,5 +50,8 @@ bool BattleInputBuffer_pop(BattleInputBuffer *bib, BattleInputBuffer *getBattleInputBuffer(size_t player); -#endif /* UQM_SUPERMELEE_NETPLAY_NETINPUT_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_SUPERMELEE_NETPLAY_NETINPUT_H_ */ diff --git a/sc2/src/uqm/supermelee/netplay/netmelee.c b/sc2/src/uqm/supermelee/netplay/netmelee.c index a784d8582..e9368fdfd 100644 --- a/sc2/src/uqm/supermelee/netplay/netmelee.c +++ b/sc2/src/uqm/supermelee/netplay/netmelee.c @@ -19,7 +19,7 @@ #define PORT_WANT_ERRNO #include "port.h" #include "netmelee.h" -#include "libs/alarm.h" +#include "libs/async.h" #include "libs/callback.h" #include "libs/log.h" #include "libs/net.h" @@ -148,8 +148,7 @@ netInputAux(uint32 timeoutMs) { NetManager_process(&timeoutMs); // This may cause more packets to be queued, hence the // flushPacketQueues(). - Alarm_process(); - Callback_process(); + Async_process(); flushPacketQueues(); // During the flush, a disconnect may be noticed, which triggers // another callback. It must be handled immediately, before @@ -168,11 +167,11 @@ netInput(void) { void netInputBlocking(uint32 timeoutMs) { - uint32 nextAlarmMs; + uint32 nextAsyncMs; - nextAlarmMs = Alarm_timeBeforeNextMs(); - if (nextAlarmMs < timeoutMs) - timeoutMs = nextAlarmMs; + nextAsyncMs = Async_timeBeforeNextMs(); + if (nextAsyncMs < timeoutMs) + timeoutMs = nextAsyncMs; netInputAux(timeoutMs); } diff --git a/sc2/src/uqm/supermelee/netplay/netmelee.h b/sc2/src/uqm/supermelee/netplay/netmelee.h index a9b1e1e17..83f3562c8 100644 --- a/sc2/src/uqm/supermelee/netplay/netmelee.h +++ b/sc2/src/uqm/supermelee/netplay/netmelee.h @@ -31,6 +31,9 @@ #include "../../races.h" // for STARSHIP +#if defined(__cplusplus) +extern "C" { +#endif extern struct NetConnection *netConnections[]; @@ -80,6 +83,8 @@ bool waitReady(NetConnection *conn); bool waitReset(NetConnection *conn, NetState nextState); bool waitResetConnections(NetState nextState); +#if defined(__cplusplus) +} +#endif + #endif /* UQM_SUPERMELEE_NETPLAY_NETMELEE_H_ */ - - diff --git a/sc2/src/uqm/supermelee/netplay/netmisc.h b/sc2/src/uqm/supermelee/netplay/netmisc.h index b86d5c334..ea1492177 100644 --- a/sc2/src/uqm/supermelee/netplay/netmisc.h +++ b/sc2/src/uqm/supermelee/netplay/netmisc.h @@ -28,6 +28,10 @@ typedef struct BattleStateData BattleStateData; #include "../../battle.h" // for BattleFrameCounter, BATTLE_FRAME_RATE +#if defined(__cplusplus) +extern "C" { +#endif + struct BattleStateData { NETCONNECTION_STATE_DATA_COMMON @@ -66,6 +70,8 @@ readyFlagsMeaningful(NetState state) { } +#if defined(__cplusplus) +} +#endif + #endif /* UQM_SUPERMELEE_NETPLAY_NETMISC_H_ */ - - diff --git a/sc2/src/uqm/supermelee/netplay/netoptions.h b/sc2/src/uqm/supermelee/netplay/netoptions.h index f777f2e78..77b16375e 100644 --- a/sc2/src/uqm/supermelee/netplay/netoptions.h +++ b/sc2/src/uqm/supermelee/netplay/netoptions.h @@ -23,6 +23,10 @@ #include +#if defined(__cplusplus) +extern "C" { +#endif + #define NETPLAY_NUM_PLAYERS 2 // Not using NUM_PLAYERS because that would mean we'd have // to include init.h, and all that comes with it. @@ -45,7 +49,8 @@ typedef struct { extern NetplayOptions netplayOptions; +#if defined(__cplusplus) +} +#endif + #endif /* UQM_SUPERMELEE_NETPLAY_NETOPTIONS_H_ */ - - - diff --git a/sc2/src/uqm/supermelee/netplay/netrcv.h b/sc2/src/uqm/supermelee/netplay/netrcv.h index 8ea7c3a37..a7577d99b 100644 --- a/sc2/src/uqm/supermelee/netplay/netrcv.h +++ b/sc2/src/uqm/supermelee/netplay/netrcv.h @@ -21,7 +21,14 @@ #include "libs/net.h" +#if defined(__cplusplus) +extern "C" { +#endif + void dataReadyCallback(NetDescriptor *nd); -#endif /* UQM_SUPERMELEE_NETPLAY_NETRCV_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_SUPERMELEE_NETPLAY_NETRCV_H_ */ diff --git a/sc2/src/uqm/supermelee/netplay/netsend.h b/sc2/src/uqm/supermelee/netplay/netsend.h index 3cd3bf20c..e005d03fb 100644 --- a/sc2/src/uqm/supermelee/netplay/netsend.h +++ b/sc2/src/uqm/supermelee/netplay/netsend.h @@ -21,8 +21,15 @@ #include "packet.h" +#if defined(__cplusplus) +extern "C" { +#endif + int sendPacket(NetConnection *conn, Packet *packet); -#endif /* UQM_SUPERMELEE_NETPLAY_NETSEND_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_SUPERMELEE_NETPLAY_NETSEND_H_ */ diff --git a/sc2/src/uqm/supermelee/netplay/netstate.h b/sc2/src/uqm/supermelee/netplay/netstate.h index 07af2c765..1d46d49e6 100644 --- a/sc2/src/uqm/supermelee/netplay/netstate.h +++ b/sc2/src/uqm/supermelee/netplay/netstate.h @@ -21,6 +21,9 @@ #include "port.h" +#if defined(__cplusplus) +extern "C" { +#endif typedef struct NetConnectionStateData NetConnectionStateData; @@ -38,8 +41,16 @@ typedef enum { NetState_endingBattle2, /* Waiting for the final synchronisation */ } NetState; +#if defined(__cplusplus) +} +#endif + #include "types.h" +#if defined(__cplusplus) +extern "C" { +#endif + typedef struct { const char *name; } NetStateData; @@ -65,5 +76,8 @@ NetState_battleActive(NetState state) { } -#endif /* UQM_SUPERMELEE_NETPLAY_NETSTATE_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_SUPERMELEE_NETPLAY_NETSTATE_H_ */ diff --git a/sc2/src/uqm/supermelee/netplay/notify.h b/sc2/src/uqm/supermelee/netplay/notify.h index 3398f8d3f..60a127ddc 100644 --- a/sc2/src/uqm/supermelee/netplay/notify.h +++ b/sc2/src/uqm/supermelee/netplay/notify.h @@ -32,6 +32,10 @@ #include "../meleesetup.h" // for FleetShipIndex +#if defined(__cplusplus) +extern "C" { +#endif + void Netplay_Notify_shipSelected(NetConnection *conn, FleetShipIndex index); void Netplay_Notify_battleInput(NetConnection *conn, BATTLE_INPUT_STATE input); @@ -51,5 +55,8 @@ void Netplay_Notify_checksum(NetConnection *conn, #endif -#endif /* UQM_SUPERMELEE_NETPLAY_NOTIFY_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_SUPERMELEE_NETPLAY_NOTIFY_H_ */ diff --git a/sc2/src/uqm/supermelee/netplay/notifyall.h b/sc2/src/uqm/supermelee/netplay/notifyall.h index 55f413f07..d20ca8117 100644 --- a/sc2/src/uqm/supermelee/netplay/notifyall.h +++ b/sc2/src/uqm/supermelee/netplay/notifyall.h @@ -24,6 +24,10 @@ # include "checksum.h" #endif /* NETPLAY_CHECKSUM */ +#if defined(__cplusplus) +extern "C" { +#endif + void Netplay_NotifyAll_setTeamName (MELEE_STATE *pMS, size_t playerNr); void Netplay_NotifyAll_setFleet (MELEE_STATE *pMS, size_t playerNr); void Netplay_NotifyAll_setShip (MELEE_STATE *pMS, size_t playerNr, @@ -37,5 +41,9 @@ void Netplay_NotifyAll_checksum(BattleFrameCounter frameNr, void Netplay_NotifyAll_battleInput(BATTLE_INPUT_STATE input); +#if defined(__cplusplus) +} +#endif + #endif /* NOTIFYALL_H */ diff --git a/sc2/src/uqm/supermelee/netplay/packet.h b/sc2/src/uqm/supermelee/netplay/packet.h index 508ccb1e3..f8c968209 100644 --- a/sc2/src/uqm/supermelee/netplay/packet.h +++ b/sc2/src/uqm/supermelee/netplay/packet.h @@ -19,6 +19,10 @@ #ifndef UQM_SUPERMELEE_NETPLAY_PACKET_H_ #define UQM_SUPERMELEE_NETPLAY_PACKET_H_ +#if defined(__cplusplus) +extern "C" { +#endif + typedef struct Packet Packet; typedef enum PacketType { @@ -60,12 +64,19 @@ typedef enum NetplayResetReason { ResetReason_manualReset, } NetplayResetReason; +#if defined(__cplusplus) +} +#endif + #ifndef PACKET_H_STANDALONE #include "netconnection.h" #include "types.h" #include "libs/network/bytesex.h" +#if defined(__cplusplus) +extern "C" { +#endif /* NB: These handlers are expected not to modify the state if an * error occurs. @@ -81,8 +92,16 @@ typedef struct { } PacketTypeData; extern PacketTypeData packetTypeData[]; + +#if defined(__cplusplus) +} #endif +#endif + +#if defined(__cplusplus) +extern "C" { +#endif // When adding new packets, be sure to have all the fields properly aligned, // and that the size of a packet is a multiple of 4 bytes in length. @@ -272,6 +291,9 @@ Packet_Abort *Packet_Abort_create(uint16 reason); Packet_Reset *Packet_Reset_create(uint16 reason); #endif +#if defined(__cplusplus) +} +#endif #endif /* UQM_SUPERMELEE_NETPLAY_PACKET_H_ */ diff --git a/sc2/src/uqm/supermelee/netplay/packethandlers.h b/sc2/src/uqm/supermelee/netplay/packethandlers.h index 0416a104b..7bd686e67 100644 --- a/sc2/src/uqm/supermelee/netplay/packethandlers.h +++ b/sc2/src/uqm/supermelee/netplay/packethandlers.h @@ -21,9 +21,13 @@ #include "packet.h" +#if defined(__cplusplus) +extern "C" { +#endif + #define DECLARE_PACKETHANDLER(type) \ int PacketHandler_##type(NetConnection *conn, \ - const Packet_##type *packet); + const Packet_##type *packet) DECLARE_PACKETHANDLER(Init); DECLARE_PACKETHANDLER(Ping); @@ -45,4 +49,8 @@ DECLARE_PACKETHANDLER(Abort); DECLARE_PACKETHANDLER(Reset); +#if defined(__cplusplus) +} +#endif + #endif /* UQM_SUPERMELEE_NETPLAY_PACKETHANDLERS_H_ */ diff --git a/sc2/src/uqm/supermelee/netplay/packetq.h b/sc2/src/uqm/supermelee/netplay/packetq.h index 999bb44fe..71f234750 100644 --- a/sc2/src/uqm/supermelee/netplay/packetq.h +++ b/sc2/src/uqm/supermelee/netplay/packetq.h @@ -26,6 +26,10 @@ typedef struct PacketQueue PacketQueue; #include +#if defined(__cplusplus) +extern "C" { +#endif + typedef struct PacketQueueLink PacketQueueLink; struct PacketQueueLink { PacketQueueLink *next; @@ -47,5 +51,9 @@ void queuePacket(NetConnection *conn, Packet *packet); int flushPacketQueue(NetConnection *conn); +#if defined(__cplusplus) +} +#endif + #endif diff --git a/sc2/src/uqm/supermelee/netplay/packetsenders.h b/sc2/src/uqm/supermelee/netplay/packetsenders.h index 4051339a5..de0bc6d79 100644 --- a/sc2/src/uqm/supermelee/netplay/packetsenders.h +++ b/sc2/src/uqm/supermelee/netplay/packetsenders.h @@ -31,6 +31,10 @@ #include "../meleesetup.h" // for FleetShipIndex +#if defined(__cplusplus) +extern "C" { +#endif + void sendInit(NetConnection *conn); void sendPing(NetConnection *conn, uint32 id); void sendAck(NetConnection *conn, uint32 id); @@ -56,6 +60,8 @@ void sendAbort(NetConnection *conn, NetplayAbortReason reason); void sendReset(NetConnection *conn, NetplayResetReason reason); +#if defined(__cplusplus) +} +#endif + #endif /* UQM_SUPERMELEE_NETPLAY_PACKETSENDERS_H_ */ - - diff --git a/sc2/src/uqm/supermelee/netplay/proto/Makeinfo b/sc2/src/uqm/supermelee/netplay/proto/Makeinfo index 624ae1ccc..1d9739cd9 100644 --- a/sc2/src/uqm/supermelee/netplay/proto/Makeinfo +++ b/sc2/src/uqm/supermelee/netplay/proto/Makeinfo @@ -1,2 +1,2 @@ uqm_CFILES="npconfirm.c ready.c reset.c" - +uqm_HFILES="npconfirm.h ready.h reset.h" diff --git a/sc2/src/uqm/supermelee/netplay/proto/npconfirm.h b/sc2/src/uqm/supermelee/netplay/proto/npconfirm.h index 73e5becb3..1ae58f528 100644 --- a/sc2/src/uqm/supermelee/netplay/proto/npconfirm.h +++ b/sc2/src/uqm/supermelee/netplay/proto/npconfirm.h @@ -22,9 +22,15 @@ #include "../netplay.h" #include "../netconnection.h" +#if defined(__cplusplus) +extern "C" { +#endif + int Netplay_confirm(NetConnection *conn); int Netplay_cancelConfirmation(NetConnection *conn); +#if defined(__cplusplus) +} +#endif + #endif /* UQM_SUPERMELEE_NETPLAY_PROTO_NPCONFIRM_H_ */ - - diff --git a/sc2/src/uqm/supermelee/netplay/proto/ready.h b/sc2/src/uqm/supermelee/netplay/proto/ready.h index fd58dc002..352155795 100644 --- a/sc2/src/uqm/supermelee/netplay/proto/ready.h +++ b/sc2/src/uqm/supermelee/netplay/proto/ready.h @@ -21,11 +21,18 @@ #include "../netconnection.h" +#if defined(__cplusplus) +extern "C" { +#endif + bool Netplay_localReady(NetConnection *conn, NetConnection_ReadyCallback callback, void *arg, bool notifyRemote); bool Netplay_remoteReady(NetConnection *conn); bool Netplay_isLocalReady(const NetConnection *conn); bool Netplay_isRemoteReady(const NetConnection *conn); -#endif /* UQM_SUPERMELEE_NETPLAY_PROTO_READY_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_SUPERMELEE_NETPLAY_PROTO_READY_H_ */ diff --git a/sc2/src/uqm/supermelee/netplay/proto/reset.h b/sc2/src/uqm/supermelee/netplay/proto/reset.h index f25d910d7..e16b1d16c 100644 --- a/sc2/src/uqm/supermelee/netplay/proto/reset.h +++ b/sc2/src/uqm/supermelee/netplay/proto/reset.h @@ -22,6 +22,10 @@ #include "../netconnection.h" #include "../packet.h" +#if defined(__cplusplus) +extern "C" { +#endif + void Netplay_setResetCallback(NetConnection *conn, NetConnection_ResetCallback callback, void *resetArg); void Netplay_localReset(NetConnection *conn, NetplayResetReason reason); @@ -29,6 +33,9 @@ void Netplay_remoteReset(NetConnection *conn, NetplayResetReason reason); bool Netplay_isLocalReset(const NetConnection *conn); bool Netplay_isRemoteReset(const NetConnection *conn); +#if defined(__cplusplus) +} +#endif #endif /* UQM_SUPERMELEE_NETPLAY_PROTO_RESET_H_ */ diff --git a/sc2/src/uqm/supermelee/pickmele.c b/sc2/src/uqm/supermelee/pickmele.c index ea600a789..0ce648970 100644 --- a/sc2/src/uqm/supermelee/pickmele.c +++ b/sc2/src/uqm/supermelee/pickmele.c @@ -37,6 +37,7 @@ #include "../races.h" #include "../setup.h" #include "../sounds.h" +#include "libs/async.h" #include "libs/log.h" #include "libs/mathlib.h" @@ -655,7 +656,6 @@ MeleeGameOver (void) for (playerI = 0; playerI < NUM_PLAYERS; playerI++) DrawPickMeleeFrame (playerI); - UnlockMutex (GraphicsLock); #ifdef NETPLAY negotiateReadyConnections(true, NetState_inSetup); @@ -676,12 +676,12 @@ MeleeGameOver (void) ButtonState = FALSE; } + Async_process (); TaskSwitch (); } while (!(GLOBAL (CurrentActivity) & CHECK_ABORT) && (!ButtonState && (!(PlayerControl[0] & PlayerControl[1] & PSYTRON_CONTROL) || GetTimeCounter () < TimeOut))); - LockMutex (GraphicsLock); } void @@ -794,12 +794,10 @@ GetMeleeStarShips (COUNT playerMask, HSTARSHIP *ships) SetContext (OffScreenContext); - UnlockMutex (GraphicsLock); DoInput (&gmstate, FALSE); WaitForSoundEnd (0); - LockMutex (GraphicsLock); for (playerI = 0; playerI < NUM_PLAYERS; playerI++) { diff --git a/sc2/src/uqm/supermelee/pickmele.h b/sc2/src/uqm/supermelee/pickmele.h index 674c0366d..3588063fa 100644 --- a/sc2/src/uqm/supermelee/pickmele.h +++ b/sc2/src/uqm/supermelee/pickmele.h @@ -24,6 +24,10 @@ typedef struct getmelee_struct GETMELEE_STATE; #include "meleesetup.h" #include "libs/compiler.h" +#if defined(__cplusplus) +extern "C" { +#endif + void MeleeShipDeath (STARSHIP *); void BuildPickMeleeFrame (void); void DestroyPickMeleeFrame (void); @@ -41,12 +45,20 @@ BOOLEAN selectShipComputer (ComputerInputContext *context, BOOLEAN selectShipNetwork (NetworkInputContext *context, GETMELEE_STATE *gms); #endif /* NETPLAY */ +#if defined(__cplusplus) +} +#endif + #ifdef PICKMELE_INTERNAL #include "../flash.h" #include "libs/timelib.h" #include "../init.h" +#if defined(__cplusplus) +extern "C" { +#endif + struct getmelee_struct { BOOLEAN (*InputFunc) (struct getmelee_struct *pInputState); @@ -80,6 +92,10 @@ struct getmelee_struct { bool setShipSelected(GETMELEE_STATE *gms, COUNT playerI, COUNT choice, bool reportNetwork); +#if defined(__cplusplus) +} +#endif + #endif /* PICKMELE_INTERNAL */ #endif /* UQM_SUPERMELEE_PICKMELE_H_ */ diff --git a/sc2/src/uqm/tactrans.c b/sc2/src/uqm/tactrans.c index 6a964f8d3..4e2b8964c 100644 --- a/sc2/src/uqm/tactrans.c +++ b/sc2/src/uqm/tactrans.c @@ -47,6 +47,8 @@ static void cleanup_dead_ship (ELEMENT *ElementPtr); static BOOLEAN dittyIsPlaying; static STARSHIP *winnerStarShip; + // Indicates which ship is the winner of the current battle. + // The winner will be last to pick the next ship. BOOLEAN @@ -471,9 +473,6 @@ new_ship (ELEMENT *DeadShipPtr) SetElementStarShip (DeadShipPtr, 0); RestartMusic = OpponentAlive (DeadStarShipPtr); - if (DeadStarShipPtr->RaceDescPtr->uninit_func != NULL) - (*DeadStarShipPtr->RaceDescPtr->uninit_func) ( - DeadStarShipPtr->RaceDescPtr); free_ship (DeadStarShipPtr->RaceDescPtr, TRUE, TRUE); DeadStarShipPtr->RaceDescPtr = 0; @@ -617,38 +616,37 @@ explosion_preprocess (ELEMENT *ShipPtr) } void -ship_death (ELEMENT *ShipPtr) +StopAllBattleMusic (void) { - STARSHIP *StarShipPtr; - STARSHIP *VictoriousStarShipPtr; - HELEMENT hElement, hNextElement; - ELEMENT *ElementPtr; - StopDitty (); StopMusic (); +} - GetElementStarShip (ShipPtr, &StarShipPtr); +STARSHIP * +FindAliveStarShip (ELEMENT *deadShip) +{ + STARSHIP *aliveShip = NULL; + HELEMENT hElement, hNextElement; - if (ShipPtr->mass_points <= MAX_SHIP_MASS) - { // Not running away and not reincarnating (Pkunk) - // When a ship tries to run away, it is (dis)counted in DoRunAway(), - // so when it dies while running away, we will not count it again - assert (StarShipPtr->playerNr >= 0); - battle_counter[StarShipPtr->playerNr]--; - } - - VictoriousStarShipPtr = NULL; + // Find the remaining ship, if any, and see if it is still alive. for (hElement = GetHeadElement (); hElement; hElement = hNextElement) { + ELEMENT *ElementPtr; + LockElement (hElement, &ElementPtr); if ((ElementPtr->state_flags & PLAYER_SHIP) - && ElementPtr != ShipPtr + && ElementPtr != deadShip /* and not running away */ - && ElementPtr->mass_points <= MAX_SHIP_MASS) + && ElementPtr->mass_points <= MAX_SHIP_MASS + 1) { - GetElementStarShip (ElementPtr, &VictoriousStarShipPtr); - if (VictoriousStarShipPtr->RaceDescPtr->ship_info.crew_level == 0) - VictoriousStarShipPtr = NULL; + GetElementStarShip (ElementPtr, &aliveShip); + assert (aliveShip != NULL); + if (aliveShip->RaceDescPtr->ship_info.crew_level == 0 + /* reincarnating Pkunk is not actually dead */ + && ElementPtr->mass_points != MAX_SHIP_MASS + 1) + { + aliveShip = NULL; + } UnlockElement (hElement); break; @@ -656,8 +654,59 @@ ship_death (ELEMENT *ShipPtr) hNextElement = GetSuccElement (ElementPtr); UnlockElement (hElement); } + + return aliveShip; +} - StarShipPtr->cur_status_flags &= ~PLAY_VICTORY_DITTY; +STARSHIP * +GetWinnerStarShip (void) +{ + return winnerStarShip; +} + +void +SetWinnerStarShip (STARSHIP *winner) +{ + if (winner == NULL) + return; // nothing to do + + winner->cur_status_flags |= PLAY_VICTORY_DITTY; + + // The winner is set once per battle. If both ships die, this function is + // called twice, once for each ship. We need to preserve the winner + // determined on the first call. + if (winnerStarShip == NULL) + winnerStarShip = winner; +} + +void +RecordShipDeath (ELEMENT *deadShip) +{ + STARSHIP *deadStarShip; + + GetElementStarShip (deadShip, &deadStarShip); + assert (deadStarShip != NULL); + + if (deadShip->mass_points <= MAX_SHIP_MASS) + { // Not running away. + // When a ship tries to run away, it is (dis)counted in DoRunAway(), + // so when it dies while running away, we will not count it again + assert (deadStarShip->playerNr >= 0); + battle_counter[deadStarShip->playerNr]--; + } + + if (LOBYTE (GLOBAL (CurrentActivity)) == SUPER_MELEE) + MeleeShipDeath (deadStarShip); +} + +void +StartShipExplosion (ELEMENT *ShipPtr, bool playSound) +{ + STARSHIP *StarShipPtr; + + GetElementStarShip (ShipPtr, &StarShipPtr); + + ZeroVelocityComponents (&ShipPtr->velocity); DeltaEnergy (ShipPtr, -(SIZE)StarShipPtr->RaceDescPtr->ship_info.energy_level); @@ -665,43 +714,38 @@ ship_death (ELEMENT *ShipPtr) ShipPtr->life_span = NUM_EXPLOSION_FRAMES * 3; ShipPtr->state_flags &= ~DISAPPEARING; ShipPtr->state_flags |= FINITE_LIFE | NONSOLID; + ShipPtr->preprocess_func = explosion_preprocess; ShipPtr->postprocess_func = PostProcessStatus; ShipPtr->death_func = cleanup_dead_ship; ShipPtr->hTarget = 0; - ZeroVelocityComponents (&ShipPtr->velocity); - if (ShipPtr->crew_level) /* only happens for shofixti self-destruct */ - { - PlaySound (SetAbsSoundIndex ( - StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), - CalcSoundPosition (ShipPtr), ShipPtr, - GAME_SOUND_PRIORITY + 1); - DeltaCrew (ShipPtr, -(SIZE)ShipPtr->crew_level); - if (VictoriousStarShipPtr == NULL) - { // No ships left alive after a Shofixti Glory device, - // thus Shofixti wins - VictoriousStarShipPtr = StarShipPtr; - } - } - else + if (playSound) { - ShipPtr->preprocess_func = explosion_preprocess; - PlaySound (SetAbsSoundIndex (GameSounds, SHIP_EXPLODES), CalcSoundPosition (ShipPtr), ShipPtr, GAME_SOUND_PRIORITY + 1); } +} - if (VictoriousStarShipPtr != NULL) - VictoriousStarShipPtr->cur_status_flags |= PLAY_VICTORY_DITTY; +void +ship_death (ELEMENT *ShipPtr) +{ + STARSHIP *StarShipPtr; + STARSHIP *winner; - // The winner is set once per battle. If both ships die, this function is - // called twice, once for each ship. We need to preserve the winner - // determined on the first call. - if (winnerStarShip == NULL) - winnerStarShip = VictoriousStarShipPtr; + GetElementStarShip (ShipPtr, &StarShipPtr); - if (LOBYTE (GLOBAL (CurrentActivity)) == SUPER_MELEE) - MeleeShipDeath (StarShipPtr); + StopAllBattleMusic (); + + // If the winning ship dies before the ditty starts, do not play it. + // e.g. a ship can die after the opponent begins exploding but + // before the explosion is over. + StarShipPtr->cur_status_flags &= ~PLAY_VICTORY_DITTY; + + StartShipExplosion (ShipPtr, true); + + winner = FindAliveStarShip (ShipPtr); + SetWinnerStarShip (winner); + RecordShipDeath (ShipPtr); } #define START_ION_COLOR BUILD_COLOR (MAKE_RGB15 (0x1F, 0x15, 0x00), 0x7A) diff --git a/sc2/src/uqm/tactrans.h b/sc2/src/uqm/tactrans.h index d21fa2c0d..c0f847910 100644 --- a/sc2/src/uqm/tactrans.h +++ b/sc2/src/uqm/tactrans.h @@ -24,6 +24,10 @@ #include "element.h" #include "battlecontrols.h" +#if defined(__cplusplus) +extern "C" { +#endif + bool battleEndReadyHuman (HumanInputContext *context); bool battleEndReadyComputer (ComputerInputContext *context); #ifdef NETPLAY @@ -39,6 +43,16 @@ extern void flee_preprocess (ELEMENT *ElementPtr); extern void StopDitty (void); extern void ResetWinnerStarShip (void); +extern void StopAllBattleMusic (void); +extern STARSHIP* FindAliveStarShip (ELEMENT *deadShip); +extern STARSHIP* GetWinnerStarShip (void); +extern void SetWinnerStarShip (STARSHIP *winner); +extern void RecordShipDeath (ELEMENT *deadShip); +extern void StartShipExplosion (ELEMENT *ShipPtr, bool playSound); + +#if defined(__cplusplus) +} +#endif #endif /* UQM_TACTRANS_H_ */ diff --git a/sc2/src/uqm/units.h b/sc2/src/uqm/units.h index 6c9677319..93d903c47 100644 --- a/sc2/src/uqm/units.h +++ b/sc2/src/uqm/units.h @@ -21,6 +21,10 @@ #include "libs/gfxlib.h" +#if defined(__cplusplus) +extern "C" { +#endif + extern int ScreenWidth; extern int ScreenHeight; @@ -216,5 +220,8 @@ extern COUNT ARCTAN (SIZE delta_x, SIZE delta_y); #define WRAP_DELTA_Y(dy) ((dy)<0 ? \ ((-(dy)<=LOG_SPACE_HEIGHT>>1)?(dy):(LOG_SPACE_HEIGHT+(dy))) : \ (((dy)<=LOG_SPACE_HEIGHT>>1)?(dy):((dy)-LOG_SPACE_HEIGHT))) -#endif /* UQM_UNITS_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_UNITS_H_ */ diff --git a/sc2/src/uqm/uqmdebug.c b/sc2/src/uqm/uqmdebug.c index c21ea50ae..4113a5d82 100644 --- a/sc2/src/uqm/uqmdebug.c +++ b/sc2/src/uqm/uqmdebug.c @@ -22,7 +22,7 @@ #include "colors.h" #include "controls.h" #include "clock.h" -#include "encount.h" +#include "starmap.h" #include "element.h" #include "sis.h" #include "status.h" @@ -72,11 +72,12 @@ static void dumpPlanetTypeCallback (int index, const PlanetFrame *planet, BOOLEAN instantMove = FALSE; BOOLEAN disableInteractivity = FALSE; void (* volatile debugHook) (void) = NULL; -void (* volatile doInputDebugHook) (void) = NULL; +// Must be called on the Starcon2Main thread. +// This function is called synchronously wrt the game logic thread. void -debugKeyPressed (void) +debugKeyPressedSynchronous (void) { // State modifying: equipShip (); @@ -85,18 +86,18 @@ debugKeyPressed (void) // Give the player the ships you can't ally with under normal // conditions. clearEscorts (); - ActivateStarShip (ARILOU_SHIP, 1); - ActivateStarShip (PKUNK_SHIP, 1); - ActivateStarShip (VUX_SHIP, 1); - ActivateStarShip (YEHAT_SHIP, 1); - ActivateStarShip (MELNORME_SHIP, 1); - ActivateStarShip (DRUUGE_SHIP, 1); - ActivateStarShip (ILWRATH_SHIP, 1); - ActivateStarShip (MYCON_SHIP, 1); - ActivateStarShip (SLYLANDRO_SHIP, 1); - ActivateStarShip (UMGAH_SHIP, 1); - ActivateStarShip (URQUAN_SHIP, 1); - ActivateStarShip (BLACK_URQUAN_SHIP, 1); + AddEscortShips (ARILOU_SHIP, 1); + AddEscortShips (PKUNK_SHIP, 1); + AddEscortShips (VUX_SHIP, 1); + AddEscortShips (YEHAT_SHIP, 1); + AddEscortShips (MELNORME_SHIP, 1); + AddEscortShips (DRUUGE_SHIP, 1); + AddEscortShips (ILWRATH_SHIP, 1); + AddEscortShips (MYCON_SHIP, 1); + AddEscortShips (SLYLANDRO_SHIP, 1); + AddEscortShips (UMGAH_SHIP, 1); + AddEscortShips (URQUAN_SHIP, 1); + AddEscortShips (BLACK_URQUAN_SHIP, 1); resetCrewBattle (); resetEnergyBattle (); @@ -107,28 +108,36 @@ debugKeyPressed (void) // SET_GAME_STATE (MELNORME_CREDIT1, 100); // GLOBAL_SIS (ResUnits) = 100000; + // Informational: +// dumpEvents (stderr); + + // Graphical and textual: +// debugContexts(); +} + +// Can be called on any thread, but usually on main() +// This function is called asynchronously wrt the game logic thread, +// which means locking applies. Use carefully. +// TODO: Once game logic thread is purged of graphics and clock locks, +// this function may not call graphics and game clock functions at all. +void +debugKeyPressed (void) +{ // Tests // Scale_PerfTest (); // Informational: // dumpStrings (stdout); -// dumpEvents (stderr); // dumpPlanetTypes(stderr); // debugHook = dumpUniverseToFile; // This will cause dumpUniverseToFile to be called from the - // main loop. Calling it from here would give threading + // Starcon2Main loop. Calling it from here would give threading // problems. // debugHook = tallyResourcesToFile; // This will cause tallyResourcesToFile to be called from the - // main loop. Calling it from here would give threading + // Starcon2Main loop. Calling it from here would give threading // problems. - // Graphical and textual: - //doInputDebugHook = debugContexts; - // This will cause debugContexts to be called from the - // Starcon2Main thread, from DoInput(). Calling it from here - // would give threading problems. - // Interactive: // uio_debugInteractive(stdin, stdout, stderr); } @@ -137,6 +146,9 @@ debugKeyPressed (void) // Fast forwards to the next event. // If skipHEE is set, HYPERSPACE_ENCOUNTER_EVENTs are skipped. +// Must be called from the Starcon2Main thread. +// TODO: LockGameClock may be removed since it is only +// supposed to be called synchronously wrt the game logic thread. void forwardToNextEvent (BOOLEAN skipHEE) { @@ -149,9 +161,6 @@ forwardToNextEvent (BOOLEAN skipHEE) if (!GameClockRunning ()) return; - // Must hold GraphicsLock for MoveGameClockDays() - // Must acquire GraphicsLock *before* the game clock lock - LockMutex (GraphicsLock); LockGameClock (); done = !skipHEE; @@ -180,7 +189,6 @@ forwardToNextEvent (BOOLEAN skipHEE) } while (!done); UnlockGameClock (); - UnlockMutex (GraphicsLock); } const char * @@ -361,12 +369,10 @@ equipShip (void) } // Make sure everything is redrawn: - if (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE || + if (inHQSpace () || LOBYTE (GLOBAL (CurrentActivity)) == IN_INTERPLANETARY) { - LockMutex (GraphicsLock); DeltaSISGauges (UNDEFINED_DELTA, UNDEFINED_DELTA, UNDEFINED_DELTA); - UnlockMutex (GraphicsLock); } } @@ -423,9 +429,7 @@ clearEscorts (void) FreeShipFrag (&GLOBAL (built_ship_q), hStarShip); } - LockMutex (GraphicsLock); DeltaSISGauges (UNDEFINED_DELTA, UNDEFINED_DELTA, UNDEFINED_DELTA); - UnlockMutex (GraphicsLock); } //////////////////////////////////////////////////////////////////////////// @@ -596,6 +600,8 @@ forAllMoons (STAR_DESC *star, SOLARSYS_STATE *system, PLANET_DESC *planet, //////////////////////////////////////////////////////////////////////////// +// Must be called from the Starcon2Main thread. +// TODO: LockGameClock may be removed void UniverseRecurse (UniverseRecurseArg *universeRecurseArg) { @@ -627,15 +633,14 @@ starRecurse (STAR_DESC *star, void *arg) SOLARSYS_STATE SolarSysState; SOLARSYS_STATE *oldPSolarSysState = pSolarSysState; - DWORD oldSeed = - TFB_SeedRandom (MAKE_DWORD (star->star_pt.x, star->star_pt.y)); - STAR_DESC *oldStarDescPtr = CurStarDescPtr; CurStarDescPtr = star; + RandomContext_SeedRandom (SysGenRNG, GetRandomSeedForStar (star)); + memset (&SolarSysState, 0, sizeof (SolarSysState)); SolarSysState.SunDesc[0].pPrevDesc = 0; - SolarSysState.SunDesc[0].rand_seed = TFB_Random (); + SolarSysState.SunDesc[0].rand_seed = RandomContext_Random (SysGenRNG); SolarSysState.SunDesc[0].data_index = STAR_TYPE (star->Type); SolarSysState.SunDesc[0].location.x = 0; SolarSysState.SunDesc[0].location.y = 0; @@ -667,7 +672,6 @@ starRecurse (STAR_DESC *star, void *arg) pSolarSysState = oldPSolarSysState; CurStarDescPtr = oldStarDescPtr; - TFB_SeedRandom (oldSeed); } static void @@ -695,14 +699,12 @@ planetRecurse (STAR_DESC *star, SOLARSYS_STATE *system, PLANET_DESC *planet, if (universeRecurseArg->moonFunc != NULL) { - DWORD oldSeed = TFB_SeedRandom (planet->rand_seed); + RandomContext_SeedRandom (SysGenRNG, planet->rand_seed); (*system->genFuncs->generateMoons) (system, planet); forAllMoons (star, system, planet, moonRecurse, (void *) universeRecurseArg); - - TFB_SeedRandom (oldSeed); } if (universeRecurseArg->planetFuncPost != NULL) @@ -732,10 +734,13 @@ moonRecurse (STAR_DESC *star, SOLARSYS_STATE *system, PLANET_DESC *planet, if (universeRecurseArg->moonFunc != NULL) { system->pOrbitalDesc = moon; - DoPlanetaryAnalysis (&system->SysInfo, moon); + if (moon->data_index != HIERARCHY_STARBASE && moon->data_index != SA_MATRA) + { + DoPlanetaryAnalysis (&system->SysInfo, moon); // When GenerateDefaultFunctions is used as genFuncs, // generateOrbital will also call DoPlanetaryAnalysis, // but with other GenerateFunctions this is not guaranteed. + } (*system->genFuncs->generateOrbital) (system, moon); (*universeRecurseArg->moonFunc) ( moon, universeRecurseArg->arg); @@ -749,6 +754,7 @@ typedef struct FILE *out; } DumpUniverseArg; +// Must be called from the Starcon2Main thread. void dumpUniverse (FILE *out) { @@ -767,7 +773,7 @@ dumpUniverse (FILE *out) UniverseRecurse (&universeRecurseArg); } -// Must be called from the main thread. +// Must be called from the Starcon2Main thread. void dumpUniverseToFile (void) { @@ -977,8 +983,7 @@ dumpPlanetCallback (const PLANET_DESC *planet, void *arg) void dumpPlanet (FILE *out, const PLANET_DESC *planet) { - (*pSolarSysState->genFuncs->generateName) ( - pSolarSysState, (PLANET_DESC *) planet); + (*pSolarSysState->genFuncs->generateName) (pSolarSysState, planet); fprintf (out, "- %-37s %s\n", GLOBAL_SIS (PlanetName), planetTypeString (planet->data_index & ~PLANET_SHIELDED)); dumpWorld (out, planet); @@ -1059,16 +1064,16 @@ calculateBioValue (const SOLARSYS_STATE *system, const PLANET_DESC *world) assert (system->pOrbitalDesc == world); - numBio = callGenerateForScanType ((SOLARSYS_STATE *) system, - (PLANET_DESC *) world, ~0, BIOLOGICAL_SCAN); + numBio = callGenerateForScanType (system, world, GENERATE_ALL, + BIOLOGICAL_SCAN, NULL); result = 0; for (i = 0; i < numBio; i++) { - callGenerateForScanType ((SOLARSYS_STATE *) system, - (PLANET_DESC *) world, i, BIOLOGICAL_SCAN); - result += BIO_CREDIT_VALUE * LONIBBLE (CreatureData[ - system->SysInfo.PlanetInfo.CurType].ValueAndHitPoints); + NODE_INFO info; + callGenerateForScanType (system, world, i, BIOLOGICAL_SCAN, &info); + result += BIO_CREDIT_VALUE * + LONIBBLE (CreatureData[info.type].ValueAndHitPoints); } return result; } @@ -1082,17 +1087,17 @@ generateBioIndex(const SOLARSYS_STATE *system, const PLANET_DESC *world, assert (system->pOrbitalDesc == world); - numBio = callGenerateForScanType ((SOLARSYS_STATE *) system, - (PLANET_DESC *) world, ~0, BIOLOGICAL_SCAN); + numBio = callGenerateForScanType (system, world, GENERATE_ALL, + BIOLOGICAL_SCAN, NULL); for (i = 0; i < NUM_CREATURE_TYPES + NUM_SPECIAL_CREATURE_TYPES; i++) bio[i] = 0; for (i = 0; i < numBio; i++) { - callGenerateForScanType ((SOLARSYS_STATE *) system, - (PLANET_DESC *) world, i, BIOLOGICAL_SCAN); - bio[system->SysInfo.PlanetInfo.CurType]++; + NODE_INFO info; + callGenerateForScanType (system, world, i, BIOLOGICAL_SCAN, &info); + bio[info.type]++; } } @@ -1105,17 +1110,16 @@ calculateMineralValue (const SOLARSYS_STATE *system, const PLANET_DESC *world) assert (system->pOrbitalDesc == world); - numDeposits = callGenerateForScanType ((SOLARSYS_STATE *) system, - (PLANET_DESC *) world, ~0, MINERAL_SCAN); + numDeposits = callGenerateForScanType (system, world, GENERATE_ALL, + MINERAL_SCAN, NULL); result = 0; for (i = 0; i < numDeposits; i++) { - callGenerateForScanType ((SOLARSYS_STATE *) system, - (PLANET_DESC *) world, i, MINERAL_SCAN); - result += HIBYTE (system->SysInfo.PlanetInfo.CurDensity) * - GLOBAL (ElementWorth[ElementCategory ( - system->SysInfo.PlanetInfo.CurType)]); + NODE_INFO info; + callGenerateForScanType (system, world, i, MINERAL_SCAN, &info); + result += HIBYTE (info.density) * + GLOBAL (ElementWorth[ElementCategory (info.type)]); } return result; } @@ -1129,18 +1133,17 @@ generateMineralIndex(const SOLARSYS_STATE *system, const PLANET_DESC *world, assert (system->pOrbitalDesc == world); - numDeposits = callGenerateForScanType ((SOLARSYS_STATE *) system, - (PLANET_DESC *) world, ~0, MINERAL_SCAN); + numDeposits = callGenerateForScanType (system, world, GENERATE_ALL, + MINERAL_SCAN, NULL); for (i = 0; i < NUM_ELEMENT_CATEGORIES; i++) minerals[i] = 0; for (i = 0; i < numDeposits; i++) { - callGenerateForScanType ((SOLARSYS_STATE *) system, - (PLANET_DESC *) world, i, MINERAL_SCAN); - minerals[ElementCategory(system->SysInfo.PlanetInfo.CurType)] += - HIBYTE (system->SysInfo.PlanetInfo.CurDensity); + NODE_INFO info; + callGenerateForScanType (system, world, i, MINERAL_SCAN, &info); + minerals[ElementCategory (info.type)] += HIBYTE (info.density); } } @@ -1153,6 +1156,7 @@ struct TallyResourcesArg COUNT bioCount; }; +// Must be called from the Starcon2Main thread. void tallyResources (FILE *out) { @@ -1171,7 +1175,7 @@ tallyResources (FILE *out) UniverseRecurse (&universeRecurseArg); } -// Must be called from the main thread. +// Must be called from the Starcon2Main thread. void tallyResourcesToFile (void) { @@ -1504,7 +1508,7 @@ resetCrewBattle (void) CONTEXT OldContext; if (!(GLOBAL (CurrentActivity) & IN_BATTLE) || - (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE)) + (inHQSpace ())) return; StarShipPtr = findPlayerShip (RPG_PLAYER_NUM); @@ -1527,7 +1531,7 @@ resetEnergyBattle (void) CONTEXT OldContext; if (!(GLOBAL (CurrentActivity) & IN_BATTLE) || - (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE)) + (inHQSpace ())) return; StarShipPtr = findPlayerShip (RPG_PLAYER_NUM); @@ -1853,16 +1857,13 @@ debugContexts (void) return; inDebugContexts = true; - LockMutex (GraphicsLock); contextCount = countVisibleContexts (); if (contextCount == 0) { - UnlockMutex (GraphicsLock); goto out; } savedScreen = getScreen (); - //UnlockMutex (GraphicsLock); FlushGraphics (); // Make sure that the screen has actually been captured, // before we use the frame. @@ -1876,7 +1877,6 @@ debugContexts (void) hueIncrement = 360.0 / contextCount; - //LockMutex (GraphicsLock); visibleContextI = 0; for (context = GetFirstContext (); context != NULL; context = GetNextContext (context)) @@ -1898,7 +1898,6 @@ debugContexts (void) // Blit the final debugging frame to the screen. putScreen (debugDrawFrame); - UnlockMutex (GraphicsLock); // Wait for a key: { @@ -1907,9 +1906,7 @@ debugContexts (void) DoInput(&state, TRUE); } - LockMutex (GraphicsLock); SetContext (orgContext); - UnlockMutex (GraphicsLock); // Destroy the debugging frame and context. DestroyContext (debugDrawContext); @@ -1917,9 +1914,7 @@ debugContexts (void) // SetContextFGFrame(). DestroyDrawable (ReleaseDrawable (debugDrawFrame)); - LockMutex (GraphicsLock); putScreen (savedScreen); - UnlockMutex (GraphicsLock); DestroyDrawable (ReleaseDrawable (savedScreen)); diff --git a/sc2/src/uqm/uqmdebug.h b/sc2/src/uqm/uqmdebug.h index bee8562c3..423841e2b 100644 --- a/sc2/src/uqm/uqmdebug.h +++ b/sc2/src/uqm/uqmdebug.h @@ -33,19 +33,19 @@ extern BOOLEAN disableInteractivity; // Starcon2Main thread, in the main game loop. extern void (* volatile debugHook) (void); -// If a function is assigned to this, it will be called from the -// Starcon2Main thread, in doInput(). -extern void (* volatile doInputDebugHook) (void); - - -// Called when the debug key (symbol 'Debug' in the keys.cfg) is pressed. +// Called on the main() thread when the debug key (symbol 'Debug' in the +// keys.cfg) is pressed void debugKeyPressed (void); +// Called on the Starcon2Main() thread when the debug key (symbol 'Debug' +// in the keys.cfg) is pressed. +void debugKeyPressedSynchronous (void); // Forward time to the next event. If skipHEE is set, the event named // HYPERSPACE_ENCOUNTER_EVENT, which normally occurs every game day, -// is skipped. +// is skipped. Must be called on the Starcon2Main thread. void forwardToNextEvent (BOOLEAN skipHEE); // Generate a list of all events in the event queue. +// Must be called on the Starcon2Main thread. void dumpEvents (FILE *out); // Describe one event. void dumpEvent (FILE *out, const EVENT *eventPtr); @@ -102,11 +102,13 @@ typedef struct // User data. } UniverseRecurseArg; // Recurse through all systems, planets, and moons in the universe. +// Must be called on the Starcon2Main thread. void UniverseRecurse (UniverseRecurseArg *universeRecurseArg); -// Describe the entire universe. +// Describe the entire universe. Must be called on the Starcon2Main thread. void dumpUniverse (FILE *out); // Describe the entire universe, output to a file "./PlanetInfo". +// Must be called on the Starcon2Main thread. void dumpUniverseToFile (void); // Describe one star system. void dumpSystem (FILE *out, const STAR_DESC *star, @@ -137,9 +139,10 @@ void generateBioIndex(const SOLARSYS_STATE *system, const PLANET_DESC *world, COUNT bio[]); // Tally the resources for each star system. +// Must be called on the Starcon2Main thread. void tallyResources (FILE *out); // Tally the resources for each star system, output to a file -// "./ResourceTally". +// "./ResourceTally". Must be called on the Starcon2Main thread. void tallyResourcesToFile (void); @@ -186,7 +189,7 @@ void dumpStrings(FILE *out); // Graphically and textually show all the contexts. -// Should be called from debugHook. +// Must be called on the Starcon2Main thread. void debugContexts (void); diff --git a/sc2/src/uqm/util.c b/sc2/src/uqm/util.c index 8b264069a..aee73a672 100644 --- a/sc2/src/uqm/util.c +++ b/sc2/src/uqm/util.c @@ -152,7 +152,6 @@ PauseGame (void) if (PlayingTrack ()) PauseTrack (); - LockMutex (GraphicsLock); OldContext = SetContext (ScreenContext); oldOrigin = SetContextOrigin (MAKE_POINT (0, 0)); GetContextClipRect (&OldRect); @@ -170,11 +169,7 @@ PauseGame (void) SetSystemRect (&r); DrawStamp (&s); - // It is safer to just not release the lock so any graphics tasks - // would be blocked - //UnlockMutex (GraphicsLock); FlushGraphics (); - //LockMutex (GraphicsLock); while (ImmediateInputState.menu[KEY_PAUSE] && GamePaused) { @@ -209,7 +204,6 @@ PauseGame (void) if (PlayingTrack ()) ResumeTrack (); - UnlockMutex (GraphicsLock); TaskSwitch (); GLOBAL (CurrentActivity) &= ~CHECK_PAUSE; @@ -300,7 +294,6 @@ SleepGame (void) PauseTrack (); PauseMusic (); - LockMutex (GraphicsLock); while (!GameActive && !QuitPosted) SleepThread (ONE_SECOND / 2); @@ -314,7 +307,6 @@ SleepGame (void) if (PlayingTrack ()) ResumeTrack (); - UnlockMutex (GraphicsLock); TaskSwitch (); } diff --git a/sc2/src/uqm/util.h b/sc2/src/uqm/util.h index 2cd49a127..094980901 100644 --- a/sc2/src/uqm/util.h +++ b/sc2/src/uqm/util.h @@ -20,6 +20,10 @@ #include "libs/compiler.h" #include "libs/gfxlib.h" +#if defined(__cplusplus) +extern "C" { +#endif + extern void DrawStarConBox (RECT *pRect, SIZE BorderWidth, Color TopLeftColor, Color BottomRightColor, BOOLEAN FillInterior, Color InteriorColor); @@ -28,5 +32,8 @@ extern DWORD SeedRandomNumbers (void); // saveRect can be NULL to save the entire context frame extern STAMP SaveContextFrame (const RECT *saveRect); -#endif /* UQM_UTIL_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_UTIL_H_ */ diff --git a/sc2/src/uqm/velocity.h b/sc2/src/uqm/velocity.h index cd5d4d241..968e1f790 100644 --- a/sc2/src/uqm/velocity.h +++ b/sc2/src/uqm/velocity.h @@ -22,6 +22,10 @@ #include /* for memset */ #include "libs/gfxlib.h" +#if defined(__cplusplus) +extern "C" { +#endif + typedef struct velocity_desc { COUNT TravelAngle; @@ -45,7 +49,7 @@ extern void SetVelocityComponents (VELOCITY_DESC *velocityptr, SIZE dx, extern void DeltaVelocityComponents (VELOCITY_DESC *velocityptr, SIZE dx, SIZE dy); -static inline BOOLEAN +static inline bool IsVelocityZero (VELOCITY_DESC *vptr) { return vptr->vector.width == 0 && vptr->vector.height == 0 && @@ -65,5 +69,8 @@ VelocitySquared (SIZE dx, SIZE dy) #define VELOCITY_TO_WORLD(v) ((v)>>VELOCITY_SHIFT) #define WORLD_TO_VELOCITY(l) ((l)< +// A wrapper function for weapon_collision that discards the return value. +// This makes its signature match ElementCollisionFunc. +static void +weapon_collision_cb (ELEMENT *WeaponElementPtr, POINT *pWPt, + ELEMENT *HitElementPtr, POINT *pHPt) +{ + weapon_collision (WeaponElementPtr, pWPt, HitElementPtr, pHPt); +} + HELEMENT initialize_laser (LASER_BLOCK *pLaserBlock) @@ -50,7 +59,7 @@ initialize_laser (LASER_BLOCK *pLaserBlock) LaserElementPtr->state_flags = APPEARING | FINITE_LIFE | pLaserBlock->flags; LaserElementPtr->life_span = LASER_LIFE; - LaserElementPtr->collision_func = (CollisionFunc*)weapon_collision; + LaserElementPtr->collision_func = weapon_collision_cb; LaserElementPtr->blast_offset = 1; LaserElementPtr->current.location.x = pLaserBlock->cx @@ -100,7 +109,7 @@ initialize_missile (MISSILE_BLOCK *pMissileBlock) SetAbsFrameIndex (pMissileBlock->farray[0], pMissileBlock->index); MissileElementPtr->preprocess_func = pMissileBlock->preprocess_func; - MissileElementPtr->collision_func = (CollisionFunc*)weapon_collision; + MissileElementPtr->collision_func = weapon_collision_cb; MissileElementPtr->blast_offset = (BYTE)pMissileBlock->blast_offs; angle = FACING_TO_ANGLE (pMissileBlock->face); diff --git a/sc2/src/uqm/weapon.h b/sc2/src/uqm/weapon.h index 77526cd49..128d71ce6 100644 --- a/sc2/src/uqm/weapon.h +++ b/sc2/src/uqm/weapon.h @@ -22,6 +22,10 @@ #include "element.h" #include "libs/gfxlib.h" +#if defined(__cplusplus) +extern "C" { +#endif + typedef struct { COORD cx, cy, ex, ey; @@ -57,5 +61,8 @@ extern void Untarget (ELEMENT *ElementPtr); extern FRAME ModifySilhouette (ELEMENT *ElementPtr, STAMP *modify_stamp, BYTE modify_flags); -#endif /* UQM_WEAPON_H_ */ +#if defined(__cplusplus) +} +#endif +#endif /* UQM_WEAPON_H_ */ diff --git a/sc2/src/uqmversion.h b/sc2/src/uqmversion.h index 48020085b..7eb5576e4 100644 --- a/sc2/src/uqmversion.h +++ b/sc2/src/uqmversion.h @@ -33,6 +33,4 @@ UQM_MAJOR_VERSION_S "." UQM_MINOR_VERSION_S "." UQM_PATCH_VERSION_S \ UQM_EXTRA_VERSION -#define UQM_SVN_REVISION "$Revision$" - #endif diff --git a/tools/map/Makefile b/tools/map/Makefile index ba3f220c4..0f9ea895d 100644 --- a/tools/map/Makefile +++ b/tools/map/Makefile @@ -3,22 +3,27 @@ # # You may need to compile or install libpng and/or zlib before # compiling this. +# When building on Cygwin, do not use Cygwin-supplied libpng. # TARGET = mapgen # These flags are needed to get it to compile with libpngX.dll on CYGWIN #CYGWINFLAGS = -DPNG_USE_DLL -CYGWINFLAGS = -PNGFLAGS = -I. +PNGFLAGS = -I/usr/include/libpng12 SDLFLAGS = $(shell sdl-config --cflags) CC = gcc CFLAGS += -W -Wall -O0 # -g -LIBS = -L/usr/local/lib -lpng -lm -lSDL_ttf -lSDL_image +LIBS = -L/usr/local/lib -lpng12 -lSDL_ttf -lSDL_image LDFLAGS += $(shell sdl-config --libs) +# This is needed for Cygwin; -L. so that we can link with private libpng +#LDFLAGS += -mconsole -L. BINS = $(TARGET) $(TARGET).exe -OBJS = mapgen.o alist.o scriptlib.o stringbank.o unicode.o sdlpngdrv.o SDL_gfxPrimitives.o port.o +OBJS = mapgen.o alist.o scriptlib.o stringbank.o unicode.o port.o +OBJS += SDL_gfxPrimitives.o +OBJS += sdlpngdrv.o +OBJS += sdlsvgdrv.o .SUFFIXES: .c .o @@ -28,7 +33,7 @@ OBJS = mapgen.o alist.o scriptlib.o stringbank.o unicode.o sdlpngdrv.o SDL_gfxPr all: $(TARGET) $(TARGET): $(OBJS) - $(CC) -o $(TARGET) $(OBJS) $(LIBS) $(LDFLAGS) + $(CC) -o $(TARGET) $(OBJS) $(LDFLAGS) $(LIBS) clean: rm -f $(BINS) *.o diff --git a/tools/map/mapgen.c b/tools/map/mapgen.c index b63e635d3..951124ed3 100644 --- a/tools/map/mapgen.c +++ b/tools/map/mapgen.c @@ -30,10 +30,12 @@ #endif extern const mg_driver_t sdlpng_drv; +extern const mg_driver_t sdlsvg_drv; static const mg_driver_t* drvs[] = { &sdlpng_drv, + &sdlsvg_drv, 0 /* term */ }; static const mg_driver_t* drv; @@ -355,7 +357,7 @@ static void usage() static void parseArguments(int argc, char *argv[], options_t *opts) { - char ch; + int ch; opterr = 0; memset(opts, 0, sizeof (options_t)); @@ -395,6 +397,7 @@ static void parseArguments(int argc, char *argv[], options_t *opts) ; } } + // TODO: this does not work with all versions of getopt() optind = 1; // let the driver handle the rest } diff --git a/tools/map/mapgen.dsp b/tools/map/mapgen.dsp index 85018495e..0792f4d4a 100644 --- a/tools/map/mapgen.dsp +++ b/tools/map/mapgen.dsp @@ -25,7 +25,7 @@ CFG=mapgen - Win32 Debug # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" -CPP=xicl6.exe +CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "mapgen - Win32 Release" @@ -42,13 +42,13 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\src\getopt" /I "." /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "PNG_USE_DLL" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\sc2\src\getopt" /I "." /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "PNG_USE_DLL" /YX /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo -LINK32=xilink6.exe +LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 # ADD LINK32 kernel32.lib user32.lib advapi32.lib shell32.lib libpng.lib SDLmain.lib SDL.lib SDL_image.lib SDL_ttf.lib /nologo /subsystem:console /machine:I386 @@ -66,13 +66,13 @@ LINK32=xilink6.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MD /W3 /Gm /GX /ZI /Od /I "..\..\src\getopt" /I "." /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "PNG_USE_DLL" /YX /FD /GZ /c +# ADD CPP /nologo /MD /W3 /Gm /GX /ZI /Od /I "..\..\sc2\src\getopt" /I "." /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "PNG_USE_DLL" /YX /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo -LINK32=xilink6.exe +LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept # ADD LINK32 kernel32.lib user32.lib advapi32.lib shell32.lib libpng.lib SDLmain.lib SDL.lib SDL_image.lib SDL_ttf.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept @@ -99,11 +99,11 @@ SOURCE=.\config.h # End Source File # Begin Source File -SOURCE=..\..\src\getopt\getopt.c +SOURCE=..\..\sc2\src\getopt\getopt.c # End Source File # Begin Source File -SOURCE=..\..\src\getopt\getopt.h +SOURCE=..\..\sc2\src\getopt\getopt.h # End Source File # Begin Source File @@ -143,6 +143,10 @@ SOURCE=.\sdlpngdrv.c # End Source File # Begin Source File +SOURCE=.\sdlsvgdrv.c +# End Source File +# Begin Source File + SOURCE=.\stringbank.c # End Source File # Begin Source File diff --git a/tools/map/port.c b/tools/map/port.c index 1d6439de1..971a34016 100644 --- a/tools/map/port.c +++ b/tools/map/port.c @@ -20,3 +20,25 @@ strupr (char *str) #endif +#ifdef _MSC_VER +// MSVC does not have snprintf() and vsnprintf(). It does have a _snprintf() +// and _vsnprintf(), but these do not terminate a truncated string as +// the C standard prescribes. +#include +#include + +int +snprintf(char *str, size_t size, const char *format, ...) +{ + int result; + va_list args; + + va_start (args, format); + result = _vsnprintf (str, size, format, args); + if (str != NULL && size != 0) + str[size - 1] = '\0'; + va_end (args); + + return result; +} +#endif /* _MSC_VER */ diff --git a/tools/map/port.h b/tools/map/port.h index 2a739f53c..d4f9d6614 100644 --- a/tools/map/port.h +++ b/tools/map/port.h @@ -26,5 +26,10 @@ # define strcasecmp stricmp #endif +#ifdef _MSC_VER +// Defined in port.c +int snprintf(char *str, size_t size, const char *format, ...); +#endif /* _MSC_VER */ + #endif /* _PORT_H */ diff --git a/tools/map/sdlpngdrv.c b/tools/map/sdlpngdrv.c index 9b93de0a4..f34283e35 100644 --- a/tools/map/sdlpngdrv.c +++ b/tools/map/sdlpngdrv.c @@ -126,21 +126,6 @@ static const char* outdev = "starmap.png"; static FILE* fout; static int dpix, dpiy; -static char* strcopy(const char* str) -{ - int l; - char* s; - - if (!str) - return 0; - l = strlen(str); - s = malloc(l + 1); - if (!s) - return 0; - memcpy(s, str, l + 1); - return s; -} - static int drv_init(int argc, char *argv[]) { int ret; @@ -197,7 +182,7 @@ static void drv_usage(void) static int parseArguments(int argc, char* argv[]) { - char ch; + int ch; while (-1 != (ch = getopt(argc, argv, "-f:no:"))) { @@ -401,9 +386,42 @@ static int drv_write(void) return EXIT_SUCCESS; } -static mg_font_t drv_loadFont(const char* name, double size, const char* filename) +static TTF_Font* openFont(const char* filename, int size) { char buf[512]; + char namebuf[128]; + TTF_Font* font; + + strncpy(namebuf, filename, sizeof(namebuf)); + namebuf[sizeof(namebuf) - 1] = '\0'; + + // first try the proper case filename + snprintf(buf, sizeof(buf), "%s/%s", fontdir, namebuf); + font = TTF_OpenFont(buf, size); + if (font) + return font; + + // then try the lowercase filename + strlwr(namebuf); + snprintf(buf, sizeof(buf), "%s/%s", fontdir, namebuf); + font = TTF_OpenFont(buf, size); + if (font) + return font; + + // last try the uppercase filename + strupr(namebuf); + snprintf(buf, sizeof(buf), "%s/%s", fontdir, namebuf); + font = TTF_OpenFont(buf, size); + if (font) + return font; + + mg_verbose(2, "TTF_OpenFont(): %s\n", TTF_GetError()); + + return 0; +} + +static mg_font_t drv_loadFont(const char* name, double size, const char* filename) +{ struct mg_font* fnt; if (!filename) @@ -416,9 +434,8 @@ static mg_font_t drv_loadFont(const char* name, double size, const char* filenam if (!fnt) return 0; fnt->size = inchToPixelsY(size); - fnt->name = strcopy(name ? name : ""); - sprintf(buf, "%s/%s", fontdir, filename); - fnt->font = TTF_OpenFont(buf, fnt->size); + fnt->name = strdup(name ? name : ""); + fnt->font = openFont(filename, fnt->size); if (!fnt->font) { free(fnt); diff --git a/tools/map/sdlsvgdrv.c b/tools/map/sdlsvgdrv.c new file mode 100644 index 000000000..3dfc3edbc --- /dev/null +++ b/tools/map/sdlsvgdrv.c @@ -0,0 +1,499 @@ +/* + * UQM Starmap image generator + * SDL/SVG driver implementation + * + * Uses: SDL, SDL_ttf + * + * + * The GPL applies + * + */ + +#include "mapdrv.h" +#include +#include +#include +#include +#include "SDL_image.h" +#include "SDL.h" +#include "SDL_ttf.h" + +static double width, height; + +struct mg_font +{ + char* name; + TTF_Font* font; + double size; +}; + +struct mg_image +{ + SDL_Surface* img; + char *filename; + double width; + double height; +}; + +static int drv_init(int argc, char *argv[]); +static int drv_term(void); +static void drv_usage(void); +static int drv_begin(double w, double h); +static int drv_write(void); +static int drv_end(void); +static mg_font_t drv_loadFont(const char* name, double size, const char*); +static void drv_freeFont(mg_font_t); +static mg_image_t drv_loadImage(const char*); +static void drv_freeImage(mg_image_t); +static int drv_getImageSize(mg_image_t, mg_rectf_t*); +static int drv_setResolution(int dpi_x, int dpi_y); +static void drv_setClipRect(const mg_rectf_t*); +static void drv_drawPixel(double x, double y, mg_color_t, double weight); +static void drv_drawLine(double x0, double y0, double x1, double y1, mg_color_t, double weight); +static void drv_drawRect(const mg_rectf_t*, mg_color_t color, double weight); +static void drv_drawFilledRect(const mg_rectf_t*, mg_color_t color); +static void drv_drawEllipse(double xc, double yc, double xr, double yr, mg_color_t, double weight); +static void drv_drawFilledEllipse(double xc, double yc, double xr, double yr, mg_color_t); +static void drv_drawImage(double x, double y, mg_image_t); +static void drv_drawText(mg_font_t, double x, double y, const unsigned char* utf8str, mg_color_t); +static void drv_getTextSize(mg_font_t, const unsigned char* utf8str, mg_rectf_t*); + +const mg_driver_t sdlsvg_drv = +{ + "sdlsvg", // name + "SDL/SVG image writer", // description + + // func ptrs + drv_init, + drv_term, + drv_usage, + drv_setResolution, + drv_begin, + drv_write, + drv_end, + drv_loadFont, + drv_freeFont, + drv_loadImage, + drv_freeImage, + drv_getImageSize, + + // draw func ptrs + drv_setClipRect, + drv_drawPixel, + drv_drawLine, + drv_drawRect, + drv_drawFilledRect, + drv_drawEllipse, + drv_drawFilledEllipse, + drv_drawImage, + drv_drawText, + drv_getTextSize, + +}; + +static int parseArguments(int argc, char* argv[]); + +static const char* fontdir = "."; +static const char* outdev = "starmap.svg"; +static FILE* fout; +static int dpix, dpiy; + +static inline int inchToPixelsY(double inch) +{ + int v = (int)(inch * dpiy); + // make sure it's at least 1 pixel wide if present + if (!v && inch) + v = 1; + return v; +} + +static char colbuffer[8]; + +static char *color_string(mg_color_t color) +{ + snprintf(colbuffer, 8, "#%2.2x%2.2x%2.2x", color.r, color.g, color.b); + return colbuffer; +} + +static char alphabuffer[6]; + +static char *alpha_string(mg_color_t color) +{ + snprintf(alphabuffer, 6, "%1.3f", color.a/255.0); + return alphabuffer; +} + +static int drv_init(int argc, char *argv[]) +{ + int ret; + ret = parseArguments(argc, argv); + if (ret) + return ret; + + if (SDL_Init(SDL_INIT_NOPARACHUTE)) + { + mg_verbose(1, "Cannot init SDL\n"); + return EXIT_FAILURE; + } + + if (TTF_Init()) + { + mg_verbose(1, "Cannot init SDL_ttf\n"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +static int drv_term(void) +{ + if (fout) + fclose(fout); + fout = 0; + + TTF_Quit(); + SDL_Quit(); + + return EXIT_SUCCESS; +} + +static void drv_usage(void) +{ + mg_verbose(0, + "sdlsvg driver : [-f ] [-o ]\n" + "Options:\n" + "\t-f dir where font files are located\n" + "\t-o save image as (default is 'starmap.svg')\n" + ); +} + +static int parseArguments(int argc, char* argv[]) +{ + int ch; + + while (-1 != (ch = getopt(argc, argv, "-f:o:"))) + { + switch (ch) + { + case 'f': + fontdir = optarg; + break; + case 'o': + outdev = optarg; + break; + default: + // non-option -- probably an arg to unknown option + ; + } + } + + return EXIT_SUCCESS; +} + +static int drv_setResolution(int dpi_x, int dpi_y) +{ + dpix = dpi_x; + dpiy = dpi_y; + + return EXIT_SUCCESS; +} + +static inline double pixelsToInchX(int pixels) +{ + return (double)pixels / dpix; +} + +static inline double pixelsToInchY(int pixels) +{ + return (double)pixels / dpiy; +} + +static int drv_begin(double w, double h) +{ + width = w; + height = h; + fout = fopen(outdev, "wt"); + if (!fout) + { + mg_verbose(1, "Cannot open file '%s' -- %s\n", outdev, strerror(errno)); + return EXIT_FAILURE; + } + + fprintf(fout, "\n"); + fprintf(fout, "\n"); + fprintf(fout, "\n", w, h); + + return EXIT_SUCCESS; +} + +static int drv_end(void) +{ + if (fout) + { + fprintf(fout, "\n"); + fclose(fout); + + fout = 0; + } + + return EXIT_SUCCESS; +} + +static int drv_write(void) +{ + if (!fout) + return EXIT_FAILURE; + + return EXIT_SUCCESS; +} + +static TTF_Font* openFont(const char* filename, int size) +{ + char buf[512]; + char namebuf[128]; + TTF_Font* font; + + strncpy(namebuf, filename, sizeof(namebuf)); + namebuf[sizeof(namebuf) - 1] = '\0'; + + // first try the proper case filename + snprintf(buf, sizeof(buf), "%s/%s", fontdir, namebuf); + font = TTF_OpenFont(buf, size); + if (font) + return font; + + // then try the lowercase filename + strlwr(namebuf); + snprintf(buf, sizeof(buf), "%s/%s", fontdir, namebuf); + font = TTF_OpenFont(buf, size); + if (font) + return font; + + // last try the uppercase filename + strupr(namebuf); + snprintf(buf, sizeof(buf), "%s/%s", fontdir, namebuf); + font = TTF_OpenFont(buf, size); + if (font) + return font; + + mg_verbose(2, "TTF_OpenFont(): %s\n", TTF_GetError()); + + return 0; +} + +static mg_font_t drv_loadFont(const char* name, double size, const char* filename) +{ + struct mg_font* fnt; + + if (!filename) + { + mg_verbose(1, "sdlsvg: filename not specified for font '%s'\n", name); + return 0; + } + + fnt = calloc(1, sizeof(*fnt)); + if (!fnt) + return 0; + fnt->size = size; + fnt->name = strdup(name ? name : ""); + fnt->font = openFont(filename, inchToPixelsY(fnt->size)); + if (!fnt->font) + { + free(fnt); + return 0; + } + + return fnt; +} + +static void drv_freeFont(mg_font_t fnt) +{ + if (!fnt) + return; + + if (fnt->name) + free(fnt->name); + if (fnt->font) + TTF_CloseFont(fnt->font); + free(fnt); +} + +static mg_image_t drv_loadImage(const char* filename) +{ + struct mg_image* img; + + img = calloc(1, sizeof(*img)); + if (!img) + return 0; + img->img = IMG_Load(filename); + if (!img->img) + { + free(img); + return 0; + } + img->filename = strdup(filename); + if (!img->filename) + { + drv_freeImage(img); + return 0; + } + img->width = pixelsToInchX(img->img->w); + img->height = pixelsToInchY(img->img->h); + + return img; +} + +static void drv_freeImage(mg_image_t img) +{ + if (!img) + return; + + if (img->filename) + free(img->filename); + + if (img->img) + SDL_FreeSurface(img->img); + free(img); +} + +static int drv_getImageSize(mg_image_t img, mg_rectf_t* r) +{ + if (!r) + return EXIT_FAILURE; + + r->x = r->y = 0; + if (img) + { + r->w = img->width; + r->h = img->height; + } + else + { + r->w = 0; + r->h = 0; + } + return EXIT_SUCCESS; +} + +static int clipon = 0; +static int clipcount = 0; + +static void drv_setClipRect(const mg_rectf_t* r) +{ + if (clipon) + fprintf(fout, "\n"); + if (!r) + clipon = 0; + else + { + mg_color_t t; + fprintf(fout, "\n", clipcount); + t.r = t.g = t.b = t.a = 255; + drv_drawFilledRect(r, t); + fprintf(fout, "\n"); + clipon = 1; + fprintf(fout, "\n", clipcount++); + } +} + +static void drv_drawPixel(double xf, double yf, mg_color_t color, double weightf) +{ + drv_drawLine(xf, yf, xf, yf, color, weightf); +} + +static void drv_drawLine(double x0f, double y0f, double x1f, double y1f, mg_color_t color, double weightf) +{ + fprintf(fout, + "\n", + x0f, y0f, x1f, y1f, color_string(color), weightf, alpha_string(color)); +} + +static void drv_drawRect(const mg_rectf_t* r, mg_color_t color, double weightf) +{ + // draw the box + drv_drawLine(r->x, r->y, r->x + r->w, r->y, color, weightf); + drv_drawLine(r->x, r->y + r->h, r->x + r->w, r->y + r->h, color, weightf); + drv_drawLine(r->x, r->y, r->x, r->y + r->h, color, weightf); + drv_drawLine(r->x + r->w, r->y, r->x + r->w, r->y + r->h, color, weightf); +} + +static void drv_drawFilledRect(const mg_rectf_t* r, mg_color_t color) +{ + if (!r) + { + mg_rectf_t t; + t.x = t.y = 0; + t.w = width; + t.h = height; + drv_drawFilledRect(&t, color); + } + else + { + fprintf(fout, + "\n", + r->x, r->y, r->w, r->h, color_string(color), + alpha_string(color)); + + } +} + +static void drv_drawEllipse(double xcf, double ycf, double xrf, double yrf, mg_color_t color, double weight) +{ + fprintf(fout, + "\n", + xcf, ycf, xrf, yrf, color_string(color), alpha_string(color), weight); + +} + +static void drv_drawFilledEllipse(double xcf, double ycf, double xrf, double yrf, mg_color_t color) +{ + fprintf(fout, + "\n", + xcf, ycf, xrf, yrf, color_string(color), alpha_string(color)); + +} + +static void drv_drawImage(double xf, double yf, struct mg_image* img) +{ + fprintf(fout, + "\n", + img->filename, xf, yf, img->width, img->height); +} + +static void drv_drawText(struct mg_font* fnt, double xf, double yf, const unsigned char* utf8str, mg_color_t color) +{ + mg_rectf_t t; + + if (!fnt || !utf8str) + return; + + drv_getTextSize(fnt, utf8str, &t); + + yf += t.h; + + fprintf(fout, + "\n", + xf, yf, fnt->size*96.0, fnt->name, color_string(color), alpha_string(color)); + fprintf(fout, "%s", utf8str); + +} + +static void drv_getTextSize(struct mg_font* fnt, const unsigned char* utf8str, mg_rectf_t* r) +{ + int w = 0; + int h = 0; + + if (!r) + return; + if (!fnt || !utf8str) + { + r->w = 0; + r->h = 0; + return; + } + + TTF_SizeUTF8(fnt->font, (const char*) utf8str, &w, &h); + r->w = (double)w / dpix; + r->h = (double)h / dpiy; +} diff --git a/tools/valgrind/sc2-valgrind.supp b/tools/valgrind/sc2-valgrind.supp new file mode 100644 index 000000000..ce2ffcc00 --- /dev/null +++ b/tools/valgrind/sc2-valgrind.supp @@ -0,0 +1,41 @@ +# Valgrind suppression file. +# Usage: +# valgrind --suppressions=sc2-valgrind.supp --log-file=sc2.vglog ./uqm-debug -l sc2.log +{ + memory leaks in PulseAudio + Memcheck:Leak + ... + obj:*/lib/libpulse* +} +{ + memory leaks in libX11 + Memcheck:Leak + ... + obj:*/lib/libX11* +} +{ + memory leaks in CRT startup + Memcheck:Leak + fun:malloc + ... + fun:_dl_catch_error +} +{ + memory leaks in CRT startup + Memcheck:Leak + fun:calloc + ... + fun:_dl_catch_error +} +{ + memory leaks in SDL_Init + Memcheck:Leak + ... + fun:SDL_Init +} +{ + memory leaks in libmikmod + Memcheck:Leak + ... + obj:*/lib/libmikmod* +}