diff --git a/polymer/eduke32/Makefile b/polymer/eduke32/Makefile index 3499bef82..a2ef3afa1 100644 --- a/polymer/eduke32/Makefile +++ b/polymer/eduke32/Makefile @@ -230,7 +230,7 @@ MAPSTER32_TARGET:=$(MAPSTER32)$(EXESUFFIX) COMMON_OBJS=rev COMMON_EDITOR_OBJS=m32common m32def m32exec m32vars rev -DUKE3D_OBJS=game global actors gamedef gameexec gamevars player premap sector anim animsounds common config demo input menus namesdyn net savegame rts osdfuncs osdcmds grpscan sounds soundsdyn cheats sbar screentext +DUKE3D_OBJS=game global actors gamedef gameexec gamevars player premap sector anim animsounds common config demo input menus namesdyn net savegame rts osdfuncs osdcmds grpscan sounds soundsdyn cheats sbar screentext screens cmdline DUKE3D_EDITOR_OBJS=astub common grpscan sounds_mapster32 ifneq ($(USE_LIBVPX),0) diff --git a/polymer/eduke32/Makefile.deps b/polymer/eduke32/Makefile.deps index e80ad9425..f25fb8774 100644 --- a/polymer/eduke32/Makefile.deps +++ b/polymer/eduke32/Makefile.deps @@ -40,7 +40,8 @@ $(DUKE3D_OBJ)/game.$o: $(DUKE3D_SRC)/game.c $(game_defs_dep) $(MACT_ROOT)/scripl $(DUKE3D_OBJ)/actors.$o: $(DUKE3D_SRC)/actors.c $(duke3d_h) $(DUKE3D_OBJ)/anim.$o: $(DUKE3D_SRC)/anim.c $(duke3d_h) $(DUKE3D_SRC)/input.h $(MACT_ROOT)/animlib.h $(DUKE3D_SRC)/animvpx.h $(DUKE3D_SRC)/animsounds.h $(DUKE3D_OBJ)/animsounds.$o: $(DUKE3D_SRC)/animsounds.c $(DUKE3D_SRC)/animsounds.h -$(DUKE3D_OBJ)/cheats.$o: $(DUKE3D_SRC)/cheats.c +$(DUKE3D_OBJ)/cheats.$o: $(DUKE3D_SRC)/cheats.c $(DUKE3D_SRC)/cheats.h +$(DUKE3D_OBJ)/cmdline.$o: $(DUKE3D_SRC)/cmdline.c $(DUKE3D_SRC)/cmdline.h $(DUKE3D_OBJ)/demo.$o: $(DUKE3D_SRC)/demo.c $(duke3d_h) $(DUKE3D_SRC)/input.h $(DUKE3D_OBJ)/gamedef.$o: $(DUKE3D_SRC)/gamedef.c $(duke3d_h) $(gamedef_h) $(DUKE3D_SRC)/savegame.h $(DUKE3D_OBJ)/gameexec.$o: $(DUKE3D_SRC)/gameexec.c $(DUKE3D_SRC)/gamestructures.c $(duke3d_h) $(gamedef_h) @@ -56,6 +57,7 @@ $(DUKE3D_OBJ)/player.$o: $(DUKE3D_SRC)/player.c $(duke3d_h) $(DUKE3D_OBJ)/premap.$o: $(DUKE3D_SRC)/premap.c $(duke3d_h) $(ENGINE_INC)/osd.h $(DUKE3D_OBJ)/savegame.$o: $(DUKE3D_SRC)/savegame.c $(duke3d_h) $(DUKE3D_SRC)/savegame.h $(DUKE3D_OBJ)/sbar.$o: $(DUKE3D_SRC)/sbar.c $(DUKE3D_SRC)/sbar.h +$(DUKE3D_OBJ)/screens.$o: $(DUKE3D_SRC)/screens.c $(DUKE3D_SRC)/screens.h $(DUKE3D_OBJ)/screentext.$o: $(DUKE3D_SRC)/screentext.c $(DUKE3D_SRC)/screentext.h $(DUKE3D_OBJ)/sector.$o: $(DUKE3D_SRC)/sector.c $(duke3d_h) $(DUKE3D_SRC)/input.h $(DUKE3D_OBJ)/sounds.$o: $(DUKE3D_SRC)/sounds.c $(duke3d_h) diff --git a/polymer/eduke32/Makefile.msvc b/polymer/eduke32/Makefile.msvc index 45545d6d3..542dbe064 100644 --- a/polymer/eduke32/Makefile.msvc +++ b/polymer/eduke32/Makefile.msvc @@ -198,6 +198,8 @@ DUKE3D_OBJS=$(DUKE3D_OBJ)\game.$o \ $(DUKE3D_OBJ)\cheats.$o \ $(DUKE3D_OBJ)\sbar.$o \ $(DUKE3D_OBJ)\screentext.$o \ + $(DUKE3D_OBJ)\screens.$o \ + $(DUKE3D_OBJ)\cmdline.$o \ $(DUKE3D_OBJ)\common.$o \ $(DUKE3D_OBJ)\demo.$o \ $(DUKE3D_OBJ)\gamedef.$o \ diff --git a/polymer/eduke32/eduke32.vcxproj b/polymer/eduke32/eduke32.vcxproj index 9ee08d9b4..ae1c385a7 100644 --- a/polymer/eduke32/eduke32.vcxproj +++ b/polymer/eduke32/eduke32.vcxproj @@ -174,6 +174,7 @@ + @@ -194,6 +195,7 @@ + @@ -308,6 +310,7 @@ + @@ -344,6 +347,7 @@ + diff --git a/polymer/eduke32/eduke32.vcxproj.filters b/polymer/eduke32/eduke32.vcxproj.filters index 4d562c7b3..a2f84872c 100644 --- a/polymer/eduke32/eduke32.vcxproj.filters +++ b/polymer/eduke32/eduke32.vcxproj.filters @@ -519,6 +519,12 @@ eduke32\headers + + eduke32\headers + + + eduke32\headers + @@ -911,6 +917,12 @@ eduke32\source + + eduke32\source + + + eduke32\source + diff --git a/polymer/eduke32/source/cmdline.c b/polymer/eduke32/source/cmdline.c new file mode 100644 index 000000000..843a5639f --- /dev/null +++ b/polymer/eduke32/source/cmdline.c @@ -0,0 +1,840 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 2016 EDuke32 developers and contributors + +This file is part of EDuke32. + +EDuke32 is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 2 +as published by the Free Software Foundation. + +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ +//------------------------------------------------------------------------- + +#include "duke3d.h" +#include "demo.h" +#include "screens.h" + +#ifdef LUNATIC +char const * const * g_argv; +const char **g_elModules; +#endif + +int32_t g_commandSetup = 0; +int32_t g_noSetup = 0; +int32_t g_noAutoLoad = 0; +int32_t g_noSound = 0; +int32_t g_noMusic = 0; +const char *CommandMap = NULL; +const char *CommandName = NULL; +int32_t g_forceWeaponChoice = 0; +int32_t g_fakeMultiMode = 0; + +void G_ShowParameterHelp(void) +{ + const char *s = "Usage: eduke32 [files] [options]\n" + "Example: eduke32 -q4 -a -m -tx -map nukeland.map\n\n" + "Files can be *.grp/zip/con/def/rts\n" + "\n" + "-cfg [file.cfg]\tUse an alternate configuration file\n" +#ifdef HAVE_CLIPSHAPE_FEATURE + "-clipmap [file.map]\tLoad an additional clipping map for use with clipshape\n" +#endif + "-connect [host]\tConnect to a multiplayer game\n" + "-c#\t\tUse MP mode #, 1 = Dukematch, 2 = Coop, 3 = Dukematch(no spawn)\n" + "-d [file.edm or demonum]\tPlay a demo\n" + "-g [file.grp]\tLoad additional game data\n" + "-h [file.def]\tLoad an alternate definitions file\n" + "-j [dir]\t\tAdds a directory to EDuke32's search list\n" + "-l#\t\tWarp to level #, see -v\n" + "-map [file.map]\tLoads a map\n" + "-mh [file.def]\tInclude an additional definitions module\n" + "-mx [file.con]\tInclude an additional CON script module\n" + "-m\t\tDisable monsters\n" + "-nam\t\tRun in NAM compatibility mode\n" + "-napalm\t\tRun in NAPALM compatibility mode\n" + "-rts [file.rts]\tLoad a custom Remote Ridicule sound bank\n" + "-r\t\tRecord demo\n" + "-s#\t\tSet skill level (1-4)\n" + "-server\t\tStart a multiplayer game for other players to join\n" +#ifdef STARTUP_SETUP_WINDOW + "-setup/nosetup\tEnables/disables startup window\n" +#endif + "-t#\t\tSet respawn mode: 1 = Monsters, 2 = Items, 3 = Inventory, x = All\n" + "-usecwd\t\tRead game data and configuration file from working directory\n" + "-u#########\tUser's favorite weapon order (default: 3425689071)\n" + "-v#\t\tWarp to volume #, see -l\n" + "-ww2gi\t\tRun in WWII GI compatibility mode\n" + "-x [game.con]\tLoad custom CON script\n" + "-#\t\tLoad and run a game from slot # (0-9)\n" + // "\n-?/--help\tDisplay this help message and exit\n" + "\nSee eduke32 -debughelp for debug parameters" + ; +#ifdef WM_MSGBOX_WINDOW + Bsnprintf(tempbuf, sizeof(tempbuf), HEAD2 " %s", s_buildRev); + wm_msgbox(tempbuf, "%s", s); +#else + initprintf("%s\n", s); +#endif +} + +void G_ShowDebugHelp(void) +{ + const char *s = "Usage: eduke32 [files] [options]\n" + "\n" + "-a\t\tUse fake player AI (fake multiplayer only)\n" + "-cachesize #\tSets cache size, in Kb\n" + "-game_dir [dir]\tDuke3d_w32 compatibility option, see -j\n" + "-gamegrp \tSelects which file to use as main grp\n" + "-name [name]\tPlayer name in multiplay\n" + "-noautoload\tDisable loading content from autoload dir\n" +#ifdef _WIN32 + "-nodinput\t\tDisable DirectInput (joystick) support\n" +#endif + "-nologo\t\tSkip the logo anim\n" + "-ns/-nm\t\tDisable sound or music\n" + "-rotatesprite-no-widescreen\tpass bit 1024 to all CON rotatesprite calls\n" + "-q#\t\tFake multiplayer with # (2-8) players\n" + "-z#/-condebug\tEnable line-by-line CON compile debugging at level #\n" + "-conversion YYYYMMDD\tSelects CON script version for compatibility with older mods\n" +#ifdef LUNATIC + "-Lopts=,,...\n" + " Pass options to Lunatic, valid ones are:\n" + " diag, nojit, traces, dump, strict\n" +#endif + ; +#ifdef WM_MSGBOX_WINDOW + Bsnprintf(tempbuf, sizeof(tempbuf), HEAD2 " %s", s_buildRev); + wm_msgbox(tempbuf, "%s", s); +#else + initprintf("%s\n", s); +#endif +} + +static void G_AddDemo(const char* param) +{ + Bstrncpy(tempbuf, param, sizeof(tempbuf)); + char * colon = (char *) Bstrchr(tempbuf, ':'); + int32_t framespertic=-1, numrepeats=1; + + if (colon && colon != tempbuf) + { + // -d:[,] + // profiling options + *(colon++) = 0; + Bsscanf(colon, "%u,%u", &framespertic, &numrepeats); + } + + Demo_SetFirst(tempbuf); + + if (framespertic < 0) + { + initprintf("Play demo %s.\n", g_firstDemoFile); + } + else + { + framespertic = clamp(framespertic, 0, 8)+1; + // TODO: repeat count and gathering statistics. + initprintf("Profile demo %s, %d frames/gametic, repeated 1x.\n", g_firstDemoFile, + framespertic-1); + Demo_PlayFirst(framespertic, 1); + g_noLogo = 1; + } +} + +void G_CheckCommandLine(int32_t argc, char const * const * argv) +{ + int16_t i = 1, j; + const char *c, *k; + +#ifdef LUNATIC + g_argv = argv; + g_elModules = (const char **) Xcalloc(argc+1, sizeof(char *)); +#endif + ud.fta_on = 1; + ud.god = 0; + ud.m_respawn_items = 0; + ud.m_respawn_monsters = 0; + ud.m_respawn_inventory = 0; + ud.warp_on = 0; + ud.cashman = 0; + ud.m_player_skill = ud.player_skill = 2; + g_player[0].wchoice[0] = 3; + g_player[0].wchoice[1] = 4; + g_player[0].wchoice[2] = 5; + g_player[0].wchoice[3] = 7; + g_player[0].wchoice[4] = 8; + g_player[0].wchoice[5] = 6; + g_player[0].wchoice[6] = 0; + g_player[0].wchoice[7] = 2; + g_player[0].wchoice[8] = 9; + g_player[0].wchoice[9] = 1; + Bsprintf(ud.wchoice, "3457860291"); + +#ifdef HAVE_CLIPSHAPE_FEATURE + // pre-form the default 10 clipmaps + for (j = '0'; j<='9'; ++j) + { + char clipshape[16] = "_clipshape0.map"; + + clipshape[10] = j; + g_clipMapFiles = (char **) Xrealloc(g_clipMapFiles, (g_clipMapFilesNum+1) * sizeof(char *)); + g_clipMapFiles[g_clipMapFilesNum] = Xstrdup(clipshape); + ++g_clipMapFilesNum; + } +#endif + + if (argc > 1) + { +#ifdef LUNATIC + int32_t numlmods = 0; +#endif + initprintf("Application parameters: "); + while (i < argc) + initprintf("%s ", argv[i++]); + initprintf("\n"); + + i = 1; + do + { + const char *const oc = argv[i]; + int32_t shortopt = 0, ignored_short_opt = 0; + + c = oc; + + if ((*c == '-') +#ifdef _WIN32 + || (*c == '/') +#endif + ) + { + shortopt = 0; + + if (!Bstrcasecmp(c+1, "?") || !Bstrcasecmp(c+1, "help") || !Bstrcasecmp(c+1, "-help")) + { + G_ShowParameterHelp(); + Bexit(0); + } + if (!Bstrcasecmp(c+1, "addon")) + { + if (argc > i+1) + { + g_usingAddon = Batoi(argv[i+1]); + + if (g_usingAddon > ADDON_NONE && g_usingAddon < NUMADDONS) + g_noSetup = 1; + else g_usingAddon = ADDON_NONE; + + i++; + } + i++; + continue; + } + if (!Bstrcasecmp(c+1, "debughelp") || !Bstrcasecmp(c+1, "-debughelp")) + { + G_ShowDebugHelp(); + Bexit(0); + } + if (!Bstrcasecmp(c+1, "grp") || !Bstrcasecmp(c+1, "g")) + { + if (argc > i+1) + { + G_AddGroup(argv[i+1]); + i++; + } + i++; + continue; + } + if (!Bstrcasecmp(c+1, "game_dir")) + { + if (argc > i+1) + { + Bstrncpyz(g_modDir, argv[i+1], sizeof(g_modDir)); + G_AddPath(argv[i+1]); + i++; + } + i++; + continue; + } + if (!Bstrcasecmp(c+1, "cfg")) + { + if (argc > i+1) + { + Bstrcpy(setupfilename, argv[i+1]); + i++; + } + i++; + continue; + } + if (!Bstrcasecmp(c+1, "gamegrp")) + { + if (argc > i+1) + { + clearGrpNamePtr(); + g_grpNamePtr = dup_filename(argv[i+1]); + i++; + } + i++; + continue; + } + if (!Bstrcasecmp(c+1, "nam")) + { + g_gameType = GAMEFLAG_NAM; + i++; + continue; + } + if (!Bstrcasecmp(c+1, "napalm")) + { + g_gameType = GAMEFLAG_NAM|GAMEFLAG_NAPALM; + i++; + continue; + } + if (!Bstrcasecmp(c+1, "ww2gi")) + { + g_gameType = GAMEFLAG_WW2GI; + i++; + continue; + } + if (!Bstrcasecmp(c+1, "setup")) + { + g_commandSetup = TRUE; + i++; + continue; + } + if (!Bstrcasecmp(c+1, "nosetup")) + { + g_noSetup = 1; + g_commandSetup = 0; + i++; + continue; + } +#if defined RENDERTYPEWIN + if (!Bstrcasecmp(c+1, "nodinput")) + { + initprintf("DirectInput (joystick) support disabled\n"); + di_disabled = 1; + i++; + continue; + } +#endif + if (!Bstrcasecmp(c+1, "noautoload")) + { + initprintf("Autoload disabled\n"); + g_noAutoLoad = 1; + i++; + continue; + } + if (!Bstrcasecmp(c+1, "net")) + { + G_GameExit("EDuke32 no longer supports legacy networking.\n\n" + "If using YANG or other launchers that only support legacy netplay, download an older build of EDuke32. " + "Otherwise, run the following:\n\n" + "eduke32 -server\n\n" + "Other clients can then connect by typing \"connect [host]\" in the console.\n\n" + "EDuke32 will now close."); + } + if (!Bstrcasecmp(c+1, "port")) + { + if (argc > i+1) + { + g_netPort = Batoi(argv[i+1]); + i++; + } + i++; + continue; + } + if (!Bstrcasecmp(c+1, "server")) + { + g_networkMode = NET_SERVER; + g_noSetup = g_noLogo = TRUE; + i++; + continue; + } + if (!Bstrcasecmp(c+1, "dedicated")) + { + g_networkMode = NET_DEDICATED_SERVER; + g_noSetup = g_noLogo = TRUE; + i++; + continue; + } + if (!Bstrcasecmp(c+1, "connect")) + { + if (argc > i+1) + { + Net_Connect(argv[i+1]); + g_noSetup = g_noLogo = TRUE; + i++; + } + i++; + continue; + } + if (!Bstrcasecmp(c+1, "password")) + { + if (argc > i+1) + { + Bstrncpyz(g_netPassword, argv[i+1], sizeof(g_netPassword)); + i++; + } + i++; + continue; + } + if (!Bstrcasecmp(c+1, "name")) + { + if (argc > i+1) + { + CommandName = argv[i+1]; + i++; + } + i++; + continue; + } + if (!Bstrcasecmp(c+1, "map")) + { + if (argc > i+1) + { + CommandMap = argv[i+1]; + i++; + } + i++; + continue; + } + if (!Bstrcasecmp(c+1, "rts")) + { + if (argc > i+1) + { + g_rtsNamePtr = argv[i+1]; + Bstrncpyz(ud.rtsname, g_rtsNamePtr, sizeof(ud.rtsname)); + initprintf("Using RTS file \"%s\".\n", ud.rtsname); + i++; + } + i++; + continue; + } + if (!Bstrcasecmp(c+1, "x")) + { + if (argc > i+1) + { + G_AddCon(argv[i+1]); + i++; + } + i++; + continue; + } + if (!Bstrcasecmp(c+1, "mx")) + { + if (argc > i+1) + { + G_AddConModule(argv[i+1]); + i++; + } + i++; + continue; + } + if (!Bstrcasecmp(c+1, "h")) + { + if (argc > i+1) + { + G_AddDef(argv[i+1]); + i++; + } + i++; + continue; + } + if (!Bstrcasecmp(c+1, "mh")) + { + if (argc > i+1) + { + G_AddDefModule(argv[i+1]); + i++; + } + i++; + continue; + } + if (!Bstrcasecmp(c+1, "j")) + { + if (argc > i+1) + { + G_AddPath(argv[i+1]); + i++; + } + i++; + continue; + } + if (!Bstrcasecmp(c+1, "d")) + { + if (argc > i+1) + { + G_AddDemo(argv[i+1]); + i++; + } + i++; + continue; + } +#ifdef HAVE_CLIPSHAPE_FEATURE + if (!Bstrcasecmp(c+1, "clipmap")) + { + if (argc > i+1) + { + G_AddClipMap(argv[i+1]); + i++; + } + i++; + continue; + } +#endif + if (!Bstrcasecmp(c+1, "condebug")) + { + g_scriptDebug = 1; + i++; + continue; + } + if (!Bstrcasecmp(c+1, "nologo")) + { + g_noLogo = 1; + i++; + continue; + } + if (!Bstrcasecmp(c+1, "rotatesprite-no-widescreen")) + { + g_rotatespriteNoWidescreen = 1; + i++; + continue; + } + if (!Bstrcasecmp(c+1, "usecwd")) + { + usecwd = 1; + i++; + continue; + } + if (!Bstrcasecmp(c+1, "cachesize")) + { + if (argc > i+1) + { + uint32_t j = Batol(argv[i+1]); + MAXCACHE1DSIZE = j<<10; + initprintf("Cache size: %dkB\n", j); + i++; + } + i++; + continue; + } + if (!Bstrcasecmp(c+1, "noinstancechecking")) + { + i++; + continue; + } +#if defined(RENDERTYPEWIN) && defined(USE_OPENGL) + if (!Bstrcasecmp(c+1, "forcegl")) + { + forcegl = 1; + i++; + continue; + } +#endif + // the following two dummy entries allow us to serve as a drop-in replacement for NAM on Steam + if (!Bstrcasecmp(c+1, "noconsole")) + { + i++; + continue; + } + if (!Bstrcasecmp(c+1, "conf")) + { + if (argc > i+1) + i++; + i++; + continue; + } + } + + if ((*c == '-') +#ifdef _WIN32 + || (*c == '/') +#endif + ) + { + shortopt = 1; + + c++; + switch (Btolower(*c)) + { + case 'a': + ud.playerai = 1; + initprintf("Other player AI.\n"); + break; + case 'c': + c++; + ud.m_coop = 0; + while ((*c >= '0')&&(*c <= '9')) + { + ud.m_coop *= 10; + ud.m_coop += *c - '0'; + c++; + } + ud.m_coop--; + break; + case 'd': + { + c++; + if (*c) + G_AddDemo(c); + break; + } +#ifdef LUNATIC + case 'f': + break; +#endif + case 'g': + c++; + if (*c) + G_AddGroup(c); + break; + case 'h': + c++; + if (*c) + G_AddDef(c); + break; + case 'j': + c++; + if (*c) + G_AddPath(c); + break; + case 'l': + // NOTE: Overlaid with -Lopts=... options for Lunatic, hence the check. + if (Bisdigit(c[1])) + { + ud.warp_on = 1; + c++; + ud.m_level_number = ud.level_number = ((unsigned) (Batoi(c)-1))%MAXLEVELS; + } + break; + case 'm': + if (*(c+1) != 'a' && *(c+1) != 'A') + { + ud.m_monsters_off = 1; + ud.m_player_skill = ud.player_skill = 0; + initprintf("Monsters off.\n"); + } + break; + case 'n': + c++; + if (*c == 's' || *c == 'S') + { + g_noSound = 2; + initprintf("Sound off.\n"); + } + else if (*c == 'm' || *c == 'M') + { + g_noMusic = 1; + initprintf("Music off.\n"); + } + else + { + G_ShowParameterHelp(); + exit(-1); + } + break; + case 'q': + if (*(++c) == 0) + { + ud.multimode = 1; + initprintf("Fake multiplayer mode: expected number after -q, falling back to 1 player.\n"); + } + else + { + int32_t numpl = Batoi(c); + + if (numpl < 2 || numpl > MAXPLAYERS) + { + initprintf("Fake multiplayer mode: expected 2-%d players, falling back to 1.\n", + MAXPLAYERS); + } + else + { + ud.multimode = numpl; + initprintf("Fake multiplayer mode: %d players.\n", ud.multimode); + + g_fakeMultiMode = numpl; + } + } + + ud.m_coop = ud.coop = 0; + ud.m_marker = ud.marker = 1; + ud.m_respawn_monsters = ud.respawn_monsters = 1; + ud.m_respawn_items = ud.respawn_items = 1; + ud.m_respawn_inventory = ud.respawn_inventory = 1; + break; + case 'r': + ud.m_recstat = 1; + initprintf("Demo record mode on.\n"); + break; + case 's': + c++; + ud.m_player_skill = ud.player_skill = (Batoi(c)%5); + if (ud.m_player_skill == 4) + ud.m_respawn_monsters = ud.respawn_monsters = 1; + break; + case 't': + c++; + if (*c == '1') ud.m_respawn_monsters = 1; + else if (*c == '2') ud.m_respawn_items = 1; + else if (*c == '3') ud.m_respawn_inventory = 1; + else + { + ud.m_respawn_monsters = 1; + ud.m_respawn_items = 1; + ud.m_respawn_inventory = 1; + } + initprintf("Respawn on.\n"); + break; + case 'u': + g_forceWeaponChoice = 1; + c++; + j = 0; + if (*c) + { + initprintf("Using favorite weapon order(s).\n"); + while (*c) + { + g_player[0].wchoice[j] = *c-'0'; + ud.wchoice[j] = *c; + c++; + j++; + } + + while (j < 10) + { + if (j == 9) + { + g_player[0].wchoice[9] = 1; + ud.wchoice[9] = '1'; + } + else + { + g_player[0].wchoice[j] = 2; + ud.wchoice[j] = '2'; + } + + j++; + } + } + else + { + initprintf("Using default weapon orders.\n"); + g_player[0].wchoice[0] = 3; + g_player[0].wchoice[1] = 4; + g_player[0].wchoice[2] = 5; + g_player[0].wchoice[3] = 7; + g_player[0].wchoice[4] = 8; + g_player[0].wchoice[5] = 6; + g_player[0].wchoice[6] = 0; + g_player[0].wchoice[7] = 2; + g_player[0].wchoice[8] = 9; + g_player[0].wchoice[9] = 1; + + Bsprintf(ud.wchoice, "3457860291"); + } + break; + case 'v': + c++; + ud.warp_on = 1; + ud.m_volume_number = ud.volume_number = ((unsigned) (Batoi(c)-1))%MAXVOLUMES; + break; + case 'w': + ud.coords = 1; + break; +#ifdef LUNATIC + case 'W': + break; +#endif + case 'x': + c++; + if (*c) + G_AddCon(c); + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + ud.warp_on = 2 + (*c) - '0'; + break; + case 'z': + c++; + g_scriptDebug = Batoi(c); + if (!g_scriptDebug) + g_scriptDebug = 1; + break; + default: + ignored_short_opt = 1; + break; + } + } + else + { + shortopt = 0; + + k = Bstrrchr(c, '.'); + if (k) + { + if (!Bstrcasecmp(k, ".map")) + { + CommandMap = argv[i++]; + continue; + } + if (!Bstrcasecmp(k, ".grp") || !Bstrcasecmp(k, ".zip") || !Bstrcasecmp(k, ".pk3") || !Bstrcasecmp(k, ".pk4")) + { + G_AddGroup(argv[i++]); + continue; + } + if (!Bstrcasecmp(k, ".con")) + { + clearScriptNamePtr(); + g_scriptNamePtr = dup_filename(argv[i++]); + initprintf("Using CON file \"%s\".\n", g_scriptNamePtr); + continue; + } + if (!Bstrcasecmp(k, ".def")) + { + clearDefNamePtr(); + g_defNamePtr = dup_filename(argv[i++]); + initprintf("Using DEF file \"%s\".\n", g_defNamePtr); + continue; + } + if (!Bstrcasecmp(k, ".rts")) + { + g_rtsNamePtr = argv[i++]; + Bstrncpyz(ud.rtsname, g_rtsNamePtr, sizeof(ud.rtsname)); + initprintf("Using RTS file \"%s\".\n", ud.rtsname); + continue; + } +#ifdef LUNATIC + if (!Bstrcmp(k, ".lua")) // NOTE: case sensitive! + { + g_elModules[numlmods++] = argv[i++]; + continue; + } +#endif + } + } + + if (!shortopt || ignored_short_opt) + initprintf("Warning: ignored application parameter \"%s\".\n", oc); + + i++; + } while (i < argc); + } +} diff --git a/polymer/eduke32/source/cmdline.h b/polymer/eduke32/source/cmdline.h new file mode 100644 index 000000000..14f5896f4 --- /dev/null +++ b/polymer/eduke32/source/cmdline.h @@ -0,0 +1,35 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 2016 EDuke32 developers and contributors + +This file is part of EDuke32. + +EDuke32 is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 2 +as published by the Free Software Foundation. + +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ +//------------------------------------------------------------------------- + +extern void G_CheckCommandLine(int32_t argc, char const * const * argv); +extern void G_ShowParameterHelp(void); +extern void G_ShowDebugHelp(void); + +extern int32_t g_commandSetup; +extern int32_t g_noSetup; +extern int32_t g_noAutoLoad; +extern int32_t g_noSound; +extern int32_t g_noMusic; +extern const char *CommandMap; +extern const char *CommandName; +extern int32_t g_forceWeaponChoice; +extern int32_t g_fakeMultiMode; diff --git a/polymer/eduke32/source/game.c b/polymer/eduke32/source/game.c index 28c882496..cdfe111cb 100644 --- a/polymer/eduke32/source/game.c +++ b/polymer/eduke32/source/game.c @@ -37,6 +37,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "colmatch.h" #include "cheats.h" #include "sbar.h" +#include "screens.h" +#include "cmdline.h" #ifdef __ANDROID__ #include "android.h" @@ -80,17 +82,6 @@ camera_t g_camera; int32_t g_cameraDistance = 0, g_cameraClock = 0; #endif static int32_t g_quickExit; -static int32_t g_commandSetup = 0; -int32_t g_noSetup = 0; -static int32_t g_noAutoLoad = 0; -static int32_t g_noSound = 0; -static int32_t g_noMusic = 0; -static const char *CommandMap = NULL; -static const char *CommandName = NULL; -int32_t g_forceWeaponChoice = 0; -int32_t g_fakeMultiMode = 0; - -double g_moveActorsTime = 0; // in ms, smoothed char boardfilename[BMAX_PATH] = {0}, currentboardfilename[BMAX_PATH] = {0}; @@ -98,8 +89,6 @@ int32_t voting = -1; int32_t vote_map = -1, vote_episode = -1; int32_t g_Debug = 0; -static int32_t g_noLogoAnim = 0; -static int32_t g_noLogo = 0; const char *defaultrtsfilename[GAMECOUNT] = { "DUKE.RTS", "NAM.RTS", "NAPALM.RTS", "WW2GI.RTS" }; @@ -112,9 +101,9 @@ int32_t g_Shareware = 0; // Ideally, we would look at our memory usage on our most cramped platform and figure out // how much of that is needed for the underlying OS and things like SDL instead of guessing #ifndef GEKKO -static int32_t MAXCACHE1DSIZE = (24*1048576); +int32_t MAXCACHE1DSIZE = (24*1048576); #else -static int32_t MAXCACHE1DSIZE = (8*1048576); +int32_t MAXCACHE1DSIZE = (8*1048576); #endif int32_t tempwallptr; @@ -123,11 +112,7 @@ static int32_t nonsharedtimer; int32_t ticrandomseed; -static void G_DrawCameraText(int16_t i); GAME_STATIC GAME_INLINE int32_t G_MoveLoop(void); -static void G_DoOrderScreen(void); - -#define quotepulseshade (sintable[((uint32_t)totalclock<<5)&2047]>>11) int32_t hud_showmapname = 1; @@ -188,19 +173,6 @@ enum gametokens T_GLOBALGAMEFLAGS, }; -void P_SetGamePalette(DukePlayer_t *player, uint32_t palid, int32_t set) -{ - if (palid >= MAXBASEPALS) - palid = 0; - - player->palette = palid; - - if (player != g_player[screenpeek].ps) - return; - - setbrightness(ud.brightness>>2, palid, set); -} - void G_HandleSpecialKeys(void) { // we need CONTROL_GetInput in order to pick up joystick button presses @@ -263,74 +235,6 @@ void G_GameQuit(void) G_GameExit("Timed out."); } -#if !defined DEBUG_ALLOCACHE_AS_MALLOC -extern int32_t cacnum; -extern cactype cac[]; -#endif - -#define COLOR_RED redcol -#define COLOR_WHITE whitecol - -static void G_ShowCacheLocks(void) -{ - int16_t i,k; - - if (offscreenrendering) - return; - - k = 0; -#if !defined DEBUG_ALLOCACHE_AS_MALLOC - for (i=cacnum-1; i>=0; i--) - if ((*cac[i].lock) >= 200) - { - if (k >= ydim-12) - break; - - Bsprintf(tempbuf,"Locked- %d: Leng:%d, Lock:%d",i,cac[i].leng,*cac[i].lock); - printext256(0L,k,COLOR_WHITE,-1,tempbuf,1); - k += 6; - } -#endif - if (k < ydim-12) - k += 6; - - for (i=10; i>=0; i--) - if (rts_lumplockbyte[i] >= 200) - { - if (k >= ydim-12) - break; - - Bsprintf(tempbuf,"RTS Locked %d:",i); - printext256(0,k,COLOR_WHITE,-1,tempbuf,1); - k += 6; - } - - if (k >= ydim-12 && k 0) - { - int32_t j, n=g_sounds[i].num; - - for (j=0; j= ydim-12) - break; - - Bsprintf(tempbuf, "snd #%d inst %d: voice %d, ow %d", i, j, - g_sounds[i].SoundOwner[j].voice, g_sounds[i].SoundOwner[j].ow); - printext256(240,k,COLOR_WHITE,-1,tempbuf,0); - - k += 9; - } - } -} int32_t A_CheckInventorySprite(spritetype *s) { @@ -349,399 +253,6 @@ int32_t A_CheckInventorySprite(spritetype *s) } } -// MYOS* CON commands. -LUNATIC_EXTERN void G_DrawTileGeneric(int32_t x, int32_t y, int32_t zoom, int32_t tilenum, - int32_t shade, int32_t orientation, int32_t p) -{ - int32_t a = 0; - - orientation &= (ROTATESPRITE_MAX-1); - - if (orientation&4) - a = 1024; - - if (!(orientation&ROTATESPRITE_FULL16)) - { - x<<=16; - y<<=16; - } - - rotatesprite_win(x,y,zoom,a,tilenum,shade,p,2|orientation); -} - -#if !defined LUNATIC -void G_DrawTile(int32_t x, int32_t y, int32_t tilenum, int32_t shade, int32_t orientation) -{ - DukePlayer_t *ps = g_player[screenpeek].ps; - int32_t p = ps->cursectnum >= 0 ? sector[ps->cursectnum].floorpal : 0; - - G_DrawTileGeneric(x,y,65536, tilenum,shade,orientation, p); -} - -void G_DrawTilePal(int32_t x, int32_t y, int32_t tilenum, int32_t shade, int32_t orientation, int32_t p) -{ - G_DrawTileGeneric(x,y,65536, tilenum,shade,orientation, p); -} - -void G_DrawTileSmall(int32_t x, int32_t y, int32_t tilenum, int32_t shade, int32_t orientation) -{ - DukePlayer_t *ps = g_player[screenpeek].ps; - int32_t p = ps->cursectnum >= 0 ? sector[ps->cursectnum].floorpal : 0; - - G_DrawTileGeneric(x,y,32768, tilenum,shade,orientation, p); -} - -void G_DrawTilePalSmall(int32_t x, int32_t y, int32_t tilenum, int32_t shade, int32_t orientation, int32_t p) -{ - G_DrawTileGeneric(x,y,32768, tilenum,shade,orientation, p); -} -#endif - -#define LOW_FPS 30 - -#if defined GEKKO -# define FPS_YOFFSET 16 -#else -# define FPS_YOFFSET 0 -#endif - -static void G_PrintFPS(void) -{ - // adapted from ZDoom because I like it better than what we had - // applicable ZDoom code available under GPL from csDoom - static int32_t FrameCount = 0, LastCount = 0, LastSec = 0, LastMS = 0; - static int32_t MinFrames = INT32_MAX, MaxFrames = 0; - - int32_t ms = getticks(); - int32_t howlong = ms - LastMS; - - if (g_player[0].ps->player_par < 2) - { - MinFrames = INT32_MAX; - MaxFrames = 0; - } - - if (howlong >= 0) - { - int32_t thisSec = ms/1000; - int32_t x = (xdim <= 640); - - if (ud.tickrate) - { - int32_t chars = Bsprintf(tempbuf, "%d ms (%3u fps)", howlong, LastCount); - - printext256(windowx2-(chars<<(3-x))+1,windowy1+2+FPS_YOFFSET,0,-1,tempbuf,x); - printext256(windowx2-(chars<<(3-x)),windowy1+1+FPS_YOFFSET, - (LastCount < LOW_FPS) ? COLOR_RED : COLOR_WHITE,-1,tempbuf,x); - - if (ud.tickrate > 1) - { - chars = Bsprintf(tempbuf, "max fps: %3u", MaxFrames); - - printext256(windowx2-(chars<<(3-x))+1, windowy1+10+2+FPS_YOFFSET, 0, -1, tempbuf, x); - printext256(windowx2-(chars<<(3-x)), windowy1+10+FPS_YOFFSET, - (MaxFrames < LOW_FPS) ? COLOR_RED : COLOR_WHITE, -1, tempbuf, x); - - chars = Bsprintf(tempbuf, "min fps: %3u", MinFrames); - - printext256(windowx2-(chars<<(3-x))+1, windowy1+20+2+FPS_YOFFSET, 0, -1, tempbuf, x); - printext256(windowx2-(chars<<(3-x)), windowy1+20+FPS_YOFFSET, - (MinFrames < LOW_FPS) ? COLOR_RED : COLOR_WHITE, -1, tempbuf, x); - } - - // lag meter - if (g_netClientPeer) - { - chars = Bsprintf(tempbuf, "%d +- %d ms", (g_netClientPeer->lastRoundTripTime + g_netClientPeer->roundTripTime)/2, - (g_netClientPeer->lastRoundTripTimeVariance + g_netClientPeer->roundTripTimeVariance)/2); - - printext256(windowx2-(chars<<(3-x))+1,windowy1+30+2+FPS_YOFFSET,0,-1,tempbuf,x); - printext256(windowx2-(chars<<(3-x)),windowy1+30+1+FPS_YOFFSET,g_netClientPeer->lastRoundTripTime > 200 ? COLOR_RED : COLOR_WHITE,-1,tempbuf,x); - } - } - - if (thisSec - LastSec) - { - g_currentFrameRate = LastCount = tabledivide32_noinline(FrameCount, thisSec - LastSec); - LastSec = thisSec; - FrameCount = 0; - - if (!osdshown) - { - if (LastCount > MaxFrames) MaxFrames = LastCount; - if (LastCount < MinFrames) MinFrames = LastCount; - } - } - FrameCount++; - } - LastMS = ms; -} - -// yxaspect and viewingrange just before the 'main' drawrooms call -static int32_t dr_yxaspect, dr_viewingrange; - -#ifdef DEBUGGINGAIDS -static struct { - uint32_t lastgtic; - uint32_t lastnumins, numins; - int32_t numonscreen; -} g_spriteStat; -#endif - -#define printcoordsline(fmt, ...) do { \ - Bsprintf(tempbuf, fmt, ## __VA_ARGS__); \ - printext256(20, y+=9, COLOR_WHITE, -1, tempbuf, 0); \ -} while (0) - -static void G_PrintCoords(int32_t snum) -{ - const int32_t x = 250; - int32_t y = 16; - - const DukePlayer_t *ps = g_player[snum].ps; - const int32_t sectnum = ps->cursectnum; - - if ((GametypeFlags[ud.coop] & GAMETYPE_FRAGBAR)) - { - if (ud.multimode > 4) - y = 32; - else if (g_netServer || ud.multimode > 1) - y = 24; - } - Bsprintf(tempbuf, "XYZ= (%d, %d, %d)", ps->pos.x, ps->pos.y, ps->pos.z); - printext256(x,y,COLOR_WHITE,-1,tempbuf,0); - Bsprintf(tempbuf, "A/H/HO= %d, %d, %d", ps->ang, ps->horiz, ps->horizoff); - printext256(x,y+9,COLOR_WHITE,-1,tempbuf,0); - Bsprintf(tempbuf,"VEL= (%d, %d, %d) + (%d, %d, 0)", - ps->vel.x>>14, ps->vel.y>>14, ps->vel.z, ps->fric.x>>5, ps->fric.y>>5); - printext256(x,y+18,COLOR_WHITE,-1,tempbuf,0); - Bsprintf(tempbuf,"OG= %d SBRIDGE=%d SBS=%d", ps->on_ground, ps->spritebridge, ps->sbs); - printext256(x,y+27,COLOR_WHITE,-1,tempbuf,0); - if (sectnum >= 0) - Bsprintf(tempbuf, "SECT= %d (LO=%d EX=%d)", sectnum, - TrackerCast(sector[sectnum].lotag), TrackerCast(sector[sectnum].extra)); - else - Bsprintf(tempbuf,"SECT= %d", sectnum); - printext256(x,y+36,COLOR_WHITE,-1,tempbuf,0); -// Bsprintf(tempbuf,"SEED= %d",randomseed); -// printext256(x,y+45,COLOR_WHITE,-1,tempbuf,0); - y -= 9; - - y += 7; - Bsprintf(tempbuf,"THOLD= %d", ps->transporter_hold); - printext256(x,y+54,COLOR_WHITE,-1,tempbuf,0); - Bsprintf(tempbuf,"GAMETIC= %d, TOTALCLOCK=%d", g_moveThingsCount, totalclock); - printext256(x,y+63,COLOR_WHITE,-1,tempbuf,0); -#ifdef DEBUGGINGAIDS - Bsprintf(tempbuf,"NUMSPRITES= %d", Numsprites); - printext256(x,y+72,COLOR_WHITE,-1,tempbuf,0); - if (g_moveThingsCount > g_spriteStat.lastgtic + REALGAMETICSPERSEC) - { - g_spriteStat.lastgtic = g_moveThingsCount; - g_spriteStat.lastnumins = g_spriteStat.numins; - g_spriteStat.numins = 0; - } - Bsprintf(tempbuf,"INSERTIONS/s= %u", g_spriteStat.lastnumins); - printext256(x,y+81,COLOR_WHITE,-1,tempbuf,0); - Bsprintf(tempbuf,"ONSCREEN= %d", g_spriteStat.numonscreen); - printext256(x,y+90,COLOR_WHITE,-1,tempbuf,0); - y += 3*9; -#endif - y += 7; - Bsprintf(tempbuf,"VR=%.03f YX=%.03f",(double)dr_viewingrange/65536.0,(double)dr_yxaspect/65536.0); - printext256(x,y+72,COLOR_WHITE,-1,tempbuf,0); - Bsprintf(tempbuf, "MOVEACTORS [ms]= %.3e", g_moveActorsTime); - printext256(x,y+81,COLOR_WHITE,-1,tempbuf,0); - -#ifdef USE_OPENGL - if (ud.coords == 2) - { - y=16; - - printcoordsline("rendmode = %d", getrendermode()); - printcoordsline("r_ambientlight = %.03f", r_ambientlight); - - if (rendmode >= 3) - { - if (rendmode==3) - printcoordsline("r_usenewshading = %d", r_usenewshading); -# ifdef POLYMER - else - printcoordsline("r_pr_artmapping = %d", pr_artmapping); -#endif - printcoordsline("r_usetileshades = %d", r_usetileshades); - } - } -#endif -} - - - - -////////// OFTEN-USED FEW-LINERS ////////// -static void G_HandleEventsWhileNoInput(void) -{ - I_ClearAllInput(); - - while (!I_CheckAllInput()) - G_HandleAsync(); - - I_ClearAllInput(); -} - -static int32_t G_PlaySoundWhileNoInput(int32_t soundnum) -{ - S_PlaySound(soundnum); - I_ClearAllInput(); - while (S_CheckSoundPlaying(-1, soundnum)) - { - G_HandleAsync(); - if (I_CheckAllInput()) - { - I_ClearAllInput(); - return 1; - } - } - - return 0; -} -////////// - -void G_FadePalette(int32_t r,int32_t g,int32_t b,int32_t e) -{ - int32_t tc; - setpalettefade(r,g,b,e); - - nextpage(); - tc = totalclock; - while (totalclock < tc + 4) - G_HandleAsync(); -} - -// START and END limits are always inclusive! -// STEP must evenly divide END-START, i.e. abs(end-start)%step == 0 -void fadepal(int32_t r, int32_t g, int32_t b, int32_t start, int32_t end, int32_t step) -{ - if (getrendermode() >= REND_POLYMOST) - { - G_FadePalette(r, g, b, end); - return; - } - - // (end-start)/step + 1 iterations - do - { - if (KB_KeyPressed(sc_Space)) - { - KB_ClearKeyDown(sc_Space); - setpalettefade(r,g,b,end); // have to set to end fade value if we break! - return; - } - - G_FadePalette(r,g,b,start); - - start += step; - } - while (start != end+step); -} - -// START and END limits are always inclusive! -static void fadepaltile(int32_t r, int32_t g, int32_t b, int32_t start, int32_t end, int32_t step, int32_t tile) -{ - // STEP must evenly divide END-START - Bassert(klabs(end-start)%step == 0); - - clearallviews(0); - - // (end-start)/step + 1 iterations - do - { -#ifdef __ANDROID__ //Needed for N7 2013 to stop corruption while fading video - clearview(0); -#endif - if (KB_KeyPressed(sc_Space)) - { - KB_ClearKeyDown(sc_Space); - setpalettefade(r,g,b,end); // have to set to end fade value if we break! - return; - } - rotatesprite_fs(160<<16,100<<16,65536L,0,tile,0,0,2+8+BGSTRETCH); - G_FadePalette(r,g,b,start); - - start += step; - } - while (start != end+step); -} - -#ifdef LUNATIC -int32_t g_logoFlags = 255; -#endif - -#ifdef __ANDROID__ -int inExtraScreens = 0; -#endif - -static void G_DisplayExtraScreens(void) -{ - int32_t flags = G_GetLogoFlags(); - - S_StopMusic(); - FX_StopAllSounds(); - - if (!DUKEBETA && (!VOLUMEALL || flags & LOGO_SHAREWARESCREENS)) - { -#ifdef __ANDROID__ - inExtraScreens = 1; -#endif - setview(0,0,xdim-1,ydim-1); - flushperms(); - //g_player[myconnectindex].ps->palette = palette; - P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 1); // JBF 20040308 - fadepal(0,0,0, 0,252,28); - I_ClearAllInput(); - rotatesprite_fs(160<<16,100<<16,65536L,0,3291,0,0,2+8+64+BGSTRETCH); - fadepaltile(0,0,0, 252,0,-28, 3291); - while (!I_CheckAllInput()) - G_HandleAsync(); - - fadepaltile(0,0,0, 0,252,28, 3291); - I_ClearAllInput(); - rotatesprite_fs(160<<16,100<<16,65536L,0,3290,0,0,2+8+64+BGSTRETCH); - fadepaltile(0,0,0, 252,0,-28,3290); - while (!I_CheckAllInput()) - G_HandleAsync(); - -#ifdef __ANDROID__ - inExtraScreens = 0; -#endif - } - - if (flags & LOGO_TENSCREEN) - { -#ifdef __ANDROID__ - inExtraScreens = 1; -#endif - setview(0,0,xdim-1,ydim-1); - flushperms(); - //g_player[myconnectindex].ps->palette = palette; - P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 1); // JBF 20040308 - fadepal(0,0,0, 0,252,28); - I_ClearAllInput(); - totalclock = 0; - rotatesprite_fs(160<<16,100<<16,65536L,0,TENSCREEN,0,0,2+8+64+BGSTRETCH); - fadepaltile(0,0,0, 252,0,-28,TENSCREEN); - while (!I_CheckAllInput() && totalclock < 2400) - G_HandleAsync(); - - fadepaltile(0,0,0, 0,252,28, TENSCREEN); - I_ClearAllInput(); -#ifdef __ANDROID__ - inExtraScreens = 0; -#endif - } -} - - extern int32_t g_doQuickSave; void G_GameExit(const char *msg) @@ -792,449 +303,6 @@ void G_GameExit(const char *msg) } -static inline void G_MoveClouds(void) -{ - int32_t i; - - if (totalclock <= cloudtotalclock && totalclock >= (cloudtotalclock-7)) - return; - - cloudtotalclock = totalclock+6; - - cloudx += sintable[(g_player[screenpeek].ps->ang+512)&2047]>>9; - cloudy += sintable[g_player[screenpeek].ps->ang&2047]>>9; - - for (i=g_numClouds-1; i>=0; i--) - { - sector[clouds[i]].ceilingxpanning = cloudx>>6; - sector[clouds[i]].ceilingypanning = cloudy>>6; - } -} - -static void G_DrawOverheadMap(int32_t cposx, int32_t cposy, int32_t czoom, int16_t cang) -{ - int32_t i, j, k, l, x1, y1, x2=0, y2=0, x3, y3, x4, y4, ox, oy, xoff, yoff; - int32_t dax, day, cosang, sinang, xspan, yspan, sprx, spry; - int32_t xrepeat, yrepeat, z1, z2, startwall, endwall, tilenum, daang; - int32_t xvect, yvect, xvect2, yvect2; - int16_t p; - char col; - walltype *wal, *wal2; - spritetype *spr; - - int32_t tmpydim = (xdim*5)/8; - - setaspect(65536, divscale16(tmpydim*320, xdim*200)); - - xvect = sintable[(-cang)&2047] * czoom; - yvect = sintable[(1536-cang)&2047] * czoom; - xvect2 = mulscale16(xvect,yxaspect); - yvect2 = mulscale16(yvect,yxaspect); - - push_nofog(); - - //Draw red lines - for (i=numsectors-1; i>=0; i--) - { - if (!(show2dsector[i>>3]&(1<<(i&7)))) continue; - - startwall = sector[i].wallptr; - endwall = sector[i].wallptr + sector[i].wallnum; - - z1 = sector[i].ceilingz; - z2 = sector[i].floorz; - - for (j=startwall,wal=&wall[startwall]; jnextwall; - if (k < 0) continue; - - if (sector[wal->nextsector].ceilingz == z1) - if (sector[wal->nextsector].floorz == z2) - if (((wal->cstat|wall[wal->nextwall].cstat)&(16+32)) == 0) continue; - - col = 139; //red - if ((wal->cstat|wall[wal->nextwall].cstat)&1) col = 234; //magenta - - if (!(show2dsector[wal->nextsector>>3]&(1<<(wal->nextsector&7)))) - col = 24; - else continue; - - ox = wal->x-cposx; - oy = wal->y-cposy; - x1 = dmulscale16(ox,xvect,-oy,yvect)+(xdim<<11); - y1 = dmulscale16(oy,xvect2,ox,yvect2)+(ydim<<11); - - wal2 = &wall[wal->point2]; - ox = wal2->x-cposx; - oy = wal2->y-cposy; - x2 = dmulscale16(ox,xvect,-oy,yvect)+(xdim<<11); - y2 = dmulscale16(oy,xvect2,ox,yvect2)+(ydim<<11); - - drawline256(x1,y1,x2,y2,col); - } - } - - pop_nofog(); - - //Draw sprites - k = g_player[screenpeek].ps->i; - for (i=numsectors-1; i>=0; i--) - { - if (!(show2dsector[i>>3]&(1<<(i&7)))) continue; - for (j=headspritesect[i]; j>=0; j=nextspritesect[j]) - { - spr = &sprite[j]; - - if (j == k || (spr->cstat&0x8000) || spr->cstat == 257 || spr->xrepeat == 0) continue; - - col = 71; //cyan - if (spr->cstat&1) col = 234; //magenta - - sprx = spr->x; - spry = spr->y; - - if ((spr->cstat&257) != 0) switch (spr->cstat&48) - { - case 0: -// break; - - ox = sprx-cposx; - oy = spry-cposy; - x1 = dmulscale16(ox,xvect,-oy,yvect); - y1 = dmulscale16(oy,xvect2,ox,yvect2); - - ox = (sintable[(spr->ang+512)&2047]>>7); - oy = (sintable[(spr->ang)&2047]>>7); - x2 = dmulscale16(ox,xvect,-oy,yvect); - y2 = dmulscale16(oy,xvect,ox,yvect); - - x3 = mulscale16(x2,yxaspect); - y3 = mulscale16(y2,yxaspect); - - drawline256(x1-x2+(xdim<<11),y1-y3+(ydim<<11), - x1+x2+(xdim<<11),y1+y3+(ydim<<11),col); - drawline256(x1-y2+(xdim<<11),y1+x3+(ydim<<11), - x1+x2+(xdim<<11),y1+y3+(ydim<<11),col); - drawline256(x1+y2+(xdim<<11),y1-x3+(ydim<<11), - x1+x2+(xdim<<11),y1+y3+(ydim<<11),col); - break; - - case 16: - if (spr->picnum == LASERLINE) - { - x1 = sprx; - y1 = spry; - tilenum = spr->picnum; - xoff = picanm[tilenum].xofs + spr->xoffset; - if ((spr->cstat&4) > 0) xoff = -xoff; - k = spr->ang; - l = spr->xrepeat; - dax = sintable[k&2047]*l; - day = sintable[(k+1536)&2047]*l; - l = tilesiz[tilenum].x; - k = (l>>1)+xoff; - x1 -= mulscale16(dax,k); - x2 = x1+mulscale16(dax,l); - y1 -= mulscale16(day,k); - y2 = y1+mulscale16(day,l); - - ox = x1-cposx; - oy = y1-cposy; - x1 = dmulscale16(ox,xvect,-oy,yvect); - y1 = dmulscale16(oy,xvect2,ox,yvect2); - - ox = x2-cposx; - oy = y2-cposy; - x2 = dmulscale16(ox,xvect,-oy,yvect); - y2 = dmulscale16(oy,xvect2,ox,yvect2); - - drawline256(x1+(xdim<<11),y1+(ydim<<11), - x2+(xdim<<11),y2+(ydim<<11),col); - } - - break; - - case 32: - tilenum = spr->picnum; - xoff = picanm[tilenum].xofs + spr->xoffset; - yoff = picanm[tilenum].yofs + spr->yoffset; - if ((spr->cstat&4) > 0) xoff = -xoff; - if ((spr->cstat&8) > 0) yoff = -yoff; - - k = spr->ang; - cosang = sintable[(k+512)&2047]; - sinang = sintable[k&2047]; - xspan = tilesiz[tilenum].x; - xrepeat = spr->xrepeat; - yspan = tilesiz[tilenum].y; - yrepeat = spr->yrepeat; - - dax = ((xspan>>1)+xoff)*xrepeat; - day = ((yspan>>1)+yoff)*yrepeat; - x1 = sprx + dmulscale16(sinang,dax,cosang,day); - y1 = spry + dmulscale16(sinang,day,-cosang,dax); - l = xspan*xrepeat; - x2 = x1 - mulscale16(sinang,l); - y2 = y1 + mulscale16(cosang,l); - l = yspan*yrepeat; - k = -mulscale16(cosang,l); - x3 = x2+k; - x4 = x1+k; - k = -mulscale16(sinang,l); - y3 = y2+k; - y4 = y1+k; - - ox = x1-cposx; - oy = y1-cposy; - x1 = dmulscale16(ox,xvect,-oy,yvect); - y1 = dmulscale16(oy,xvect2,ox,yvect2); - - ox = x2-cposx; - oy = y2-cposy; - x2 = dmulscale16(ox,xvect,-oy,yvect); - y2 = dmulscale16(oy,xvect2,ox,yvect2); - - ox = x3-cposx; - oy = y3-cposy; - x3 = dmulscale16(ox,xvect,-oy,yvect); - y3 = dmulscale16(oy,xvect2,ox,yvect2); - - ox = x4-cposx; - oy = y4-cposy; - x4 = dmulscale16(ox,xvect,-oy,yvect); - y4 = dmulscale16(oy,xvect2,ox,yvect2); - - drawline256(x1+(xdim<<11),y1+(ydim<<11), - x2+(xdim<<11),y2+(ydim<<11),col); - - drawline256(x2+(xdim<<11),y2+(ydim<<11), - x3+(xdim<<11),y3+(ydim<<11),col); - - drawline256(x3+(xdim<<11),y3+(ydim<<11), - x4+(xdim<<11),y4+(ydim<<11),col); - - drawline256(x4+(xdim<<11),y4+(ydim<<11), - x1+(xdim<<11),y1+(ydim<<11),col); - - break; - } - } - } - - push_nofog(); - - //Draw white lines - for (i=numsectors-1; i>=0; i--) - { - if (!(show2dsector[i>>3]&(1<<(i&7)))) continue; - - startwall = sector[i].wallptr; - endwall = sector[i].wallptr + sector[i].wallnum; - - k = -1; - for (j=startwall,wal=&wall[startwall]; jnextwall >= 0) continue; - - if (tilesiz[wal->picnum].x == 0) continue; - if (tilesiz[wal->picnum].y == 0) continue; - - if (j == k) - { - x1 = x2; - y1 = y2; - } - else - { - ox = wal->x-cposx; - oy = wal->y-cposy; - x1 = dmulscale16(ox,xvect,-oy,yvect)+(xdim<<11); - y1 = dmulscale16(oy,xvect2,ox,yvect2)+(ydim<<11); - } - - k = wal->point2; - wal2 = &wall[k]; - ox = wal2->x-cposx; - oy = wal2->y-cposy; - x2 = dmulscale16(ox,xvect,-oy,yvect)+(xdim<<11); - y2 = dmulscale16(oy,xvect2,ox,yvect2)+(ydim<<11); - - drawline256(x1,y1,x2,y2,24); - } - } - - pop_nofog(); - - setaspect_new(); - - for (TRAVERSE_CONNECT(p)) - { - if (ud.scrollmode && p == screenpeek) continue; - - ox = sprite[g_player[p].ps->i].x-cposx; - oy = sprite[g_player[p].ps->i].y-cposy; - daang = (sprite[g_player[p].ps->i].ang-cang)&2047; - if (p == screenpeek) - { - ox = 0; - oy = 0; - daang = 0; - } - x1 = mulscale(ox,xvect,16) - mulscale(oy,yvect,16); - y1 = mulscale(oy,xvect2,16) + mulscale(ox,yvect2,16); - - if (p == screenpeek || GTFLAGS(GAMETYPE_OTHERPLAYERSINMAP)) - { - if (sprite[g_player[p].ps->i].xvel > 16 && g_player[p].ps->on_ground) - i = APLAYERTOP+((totalclock>>4)&3); - else - i = APLAYERTOP; - - j = klabs(g_player[p].ps->truefz-g_player[p].ps->pos.z)>>8; - j = mulscale(czoom*(sprite[g_player[p].ps->i].yrepeat+j),yxaspect,16); - - if (j < 22000) j = 22000; - else if (j > (65536<<1)) j = (65536<<1); - - rotatesprite_win((x1<<4)+(xdim<<15),(y1<<4)+(ydim<<15),j,daang,i,sprite[g_player[p].ps->i].shade, - (g_player[p].ps->cursectnum > -1)?sector[g_player[p].ps->cursectnum].floorpal:0, 0); - } - } -} - - -palette_t CrosshairColors = { 255, 255, 255, 0 }; -palette_t DefaultCrosshairColors = { 0, 0, 0, 0 }; -int32_t g_crosshairSum = 0; - -void G_GetCrosshairColor(void) -{ - // use the brightest color in the original 8-bit tile - int32_t bri = 0, j = 0, i; - int32_t ii; - char *ptr = (char *)waloff[CROSSHAIR]; - - if (DefaultCrosshairColors.f) - return; - - if (waloff[CROSSHAIR] == 0) - { - loadtile(CROSSHAIR); - ptr = (char *)waloff[CROSSHAIR]; - } - - ii = tilesiz[CROSSHAIR].x * tilesiz[CROSSHAIR].y; - - if (ii <= 0) return; - - do - { - if (*ptr != 255) - { - i = curpalette[(int32_t)*ptr].r+curpalette[(int32_t)*ptr].g+curpalette[(int32_t)*ptr].b; - if (i > j) { j = i; bri = *ptr; } - } - ptr++; - } - while (--ii); - - Bmemcpy(&CrosshairColors, &curpalette[bri], sizeof(palette_t)); - Bmemcpy(&DefaultCrosshairColors, &curpalette[bri], sizeof(palette_t)); - DefaultCrosshairColors.f = 1; // this flag signifies that the color has been detected -} - -void G_SetCrosshairColor(int32_t r, int32_t g, int32_t b) -{ - int32_t i, ii; - - if (g_crosshairSum == r+(g<<8)+(b<<16)) return; - - if (!DefaultCrosshairColors.f) - G_GetCrosshairColor(); - - g_crosshairSum = r+(g<<8)+(b<<16); - CrosshairColors.r = r; - CrosshairColors.g = g; - CrosshairColors.b = b; - - char *ptr = (char *) waloff[CROSSHAIR]; - - if (waloff[CROSSHAIR] == 0) - { - loadtile(CROSSHAIR); - ptr = (char *)waloff[CROSSHAIR]; - } - - ii = tilesiz[CROSSHAIR].x * tilesiz[CROSSHAIR].y; - if (ii <= 0) return; - - if (getrendermode() == REND_CLASSIC) - i = getclosestcol(CrosshairColors.r, CrosshairColors.g, CrosshairColors.b); - else i = getclosestcol(255, 255, 255); // use white in GL so we can tint it to the right color - - do - { - if (*ptr != 255) - *ptr = i; - ptr++; - } - while (--ii); - - makepalookup(CROSSHAIR_PAL, NULL, CrosshairColors.r, CrosshairColors.g, CrosshairColors.b,1); - -#ifdef USE_OPENGL - // XXX: this makes us also load all hightile textures tinted with the crosshair color! - Bmemcpy(&hictinting[CROSSHAIR_PAL], &CrosshairColors, sizeof(palette_t)); - hictinting[CROSSHAIR_PAL].f = HICTINT_USEONART | HICTINT_GRAYSCALE; -#endif - invalidatetile(CROSSHAIR, -1, -1); -} - -static inline int G_LastMapInfoIndex(void) -{ - Bassert(ud.last_level >= 1); // NOTE: last_level is 1-based - return ud.volume_number*MAXLEVELS + ud.last_level-1; -} - -#define SCORESHEETOFFSET -20 -static void G_ShowScores(void) -{ - int32_t t, i; - - if (playerswhenstarted > 1 && (GametypeFlags[ud.coop]&GAMETYPE_SCORESHEET)) - { - gametext(160,SCORESHEETOFFSET+58+2,"Multiplayer Totals",0,2+8+16); - gametext(160,SCORESHEETOFFSET+58+10,MapInfo[G_LastMapInfoIndex()].name,0,2+8+16); - - t = 0; - minitext(70,SCORESHEETOFFSET+80,"Name",8,2+8+16+ROTATESPRITE_MAX); - minitext(170,SCORESHEETOFFSET+80,"Frags",8,2+8+16+ROTATESPRITE_MAX); - minitext(200,SCORESHEETOFFSET+80,"Deaths",8,2+8+16+ROTATESPRITE_MAX); - minitext(235,SCORESHEETOFFSET+80,"Ping",8,2+8+16+ROTATESPRITE_MAX); - - for (i=playerswhenstarted-1; i>=0; i--) - { - if (!g_player[i].playerquitflag) - continue; - - minitext(70,SCORESHEETOFFSET+90+t,g_player[i].user_name,g_player[i].ps->palookup,2+8+16+ROTATESPRITE_MAX); - - Bsprintf(tempbuf,"%-4d",g_player[i].ps->frag); - minitext(170,SCORESHEETOFFSET+90+t,tempbuf,2,2+8+16+ROTATESPRITE_MAX); - - Bsprintf(tempbuf,"%-4d", g_player[i].frags[i] + g_player[i].ps->fraggedself); - minitext(200,SCORESHEETOFFSET+90+t,tempbuf,2,2+8+16+ROTATESPRITE_MAX); - - Bsprintf(tempbuf,"%-4d",g_player[i].ping); - minitext(235,SCORESHEETOFFSET+90+t,tempbuf,2,2+8+16+ROTATESPRITE_MAX); - - t += 7; - } - } -} -#undef SCORESHEETOFFSET - #ifdef YAX_DEBUG // ugh... char m32_debugstr[64][128]; @@ -1257,492 +325,6 @@ static void M32_drawdebug(void) #endif -////////// TINT ACCUMULATOR ////////// - -typedef struct { - int32_t r,g,b; - // f: 0-63 scale - int32_t maxf, sumf; -} palaccum_t; - -#define PALACCUM_INITIALIZER { 0, 0, 0, 0, 0 } - -/* For a picture frame F and n tints C_1, C_2, ... C_n weighted a_1, a_2, - * ... a_n (on a 0-1 scale), the faded frame is calculated as - * - * F_new := (1-max_i(a_i))*F + d*sum_i(a_i), where - * - * d := max_i(a_i)/sum_i(a_i). - * - * This means that - * 1) tint application is independent of their order. - * 2) going from n+1 to n tints is continuous when the leaving one has faded. - * - * But note that for more than one tint, the composite tint will in general - * change its hue as the ratio of the weights of the individual ones changes. - */ -static void palaccum_add(palaccum_t *pa, const palette_t *pal, int32_t f) -{ - f = clamp(f, 0, 63); - if (f == 0) - return; - - pa->maxf = max(pa->maxf, f); - pa->sumf += f; - - pa->r += f*clamp(pal->r, 0, 63); - pa->g += f*clamp(pal->g, 0, 63); - pa->b += f*clamp(pal->b, 0, 63); -} - -static void G_FadePalaccum(const palaccum_t *pa) -{ - setpalettefade(tabledivide32_noinline(pa->r, pa->sumf)<<2, - tabledivide32_noinline(pa->g, pa->sumf)<<2, - tabledivide32_noinline(pa->b, pa->sumf)<<2, pa->maxf<<2); -} - - -static int32_t gtextsc(int32_t sc) -{ - return scale(sc, ud.textscale, 400); -} - -////////// DISPLAYREST ////////// - -void G_DisplayRest(int32_t smoothratio) -{ - int32_t i, j; - palaccum_t tint = PALACCUM_INITIALIZER; - - DukePlayer_t *const pp = g_player[screenpeek].ps; -#ifdef SPLITSCREEN_MOD_HACKS - DukePlayer_t *const pp2 = g_fakeMultiMode==2 ? g_player[1].ps : NULL; -#endif - int32_t cposx, cposy, cang; - -#ifdef USE_OPENGL - // this takes care of fullscreen tint for OpenGL - if (getrendermode() >= REND_POLYMOST) - { - if (pp->palette == WATERPAL) - { - static const palette_t wp = { 224, 192, 255, 0 }; - Bmemcpy(&hictinting[MAXPALOOKUPS-1], &wp, sizeof(palette_t)); - } - else if (pp->palette == SLIMEPAL) - { - static const palette_t sp = { 208, 255, 192, 0 }; - Bmemcpy(&hictinting[MAXPALOOKUPS-1], &sp, sizeof(palette_t)); - } - else - { - hictinting[MAXPALOOKUPS-1].r = 255; - hictinting[MAXPALOOKUPS-1].g = 255; - hictinting[MAXPALOOKUPS-1].b = 255; - } - } -#endif // USE_OPENGL - - palaccum_add(&tint, &pp->pals, pp->pals.f); -#ifdef SPLITSCREEN_MOD_HACKS - if (pp2) - palaccum_add(&tint, &pp2->pals, pp2->pals.f); -#endif - { - static const palette_t loogiepal = { 0, 63, 0, 0 }; - - palaccum_add(&tint, &loogiepal, pp->loogcnt>>1); -#ifdef SPLITSCREEN_MOD_HACKS - if (pp2) - palaccum_add(&tint, &loogiepal, pp2->loogcnt>>1); -#endif - } - - if (g_restorePalette) - { - // reset a normal palette - static uint32_t omovethingscnt; - - if (g_restorePalette < 2 || omovethingscnt+1 == g_moveThingsCount) - { - int32_t pal = pp->palette; -#ifdef SPLITSCREEN_MOD_HACKS - const int32_t opal = pal; - - if (pp2) // splitscreen HACK: BASEPAL trumps all, then it's arbitrary. - pal = min(pal, pp2->palette); -#endif - - // g_restorePalette < 0: reset tinting, too (e.g. when loading new game) - P_SetGamePalette(pp, pal, 2 + (g_restorePalette>0)*16); - -#ifdef SPLITSCREEN_MOD_HACKS - if (pp2) // keep first player's pal as its member! - pp->palette = opal; -#endif - - g_restorePalette = 0; - } - else - { - // delay setting the palette by one game tic - omovethingscnt = g_moveThingsCount; - } - } - - if (ud.show_help) - { - switch (ud.show_help) - { - case 1: - rotatesprite_fs(160<<16,100<<16,65536L,0,TEXTSTORY,0,0,10+64); - break; - case 2: - rotatesprite_fs(160<<16,100<<16,65536L,0,F1HELP,0,0,10+64); - break; - } - - if (I_ReturnTrigger()) - { - I_ReturnTriggerClear(); - ud.show_help = 0; - if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2) - { - ready2send = 1; - totalclock = ototalclock; - } - G_UpdateScreenArea(); - } - - return; - } - - i = pp->cursectnum; - if (i > -1) - { - const walltype *wal = &wall[sector[i].wallptr]; - - show2dsector[i>>3] |= (1<<(i&7)); - for (j=sector[i].wallnum; j>0; j--,wal++) - { - i = wal->nextsector; - if (i < 0) continue; - if (wal->cstat&0x0071) continue; - if (wall[wal->nextwall].cstat&0x0071) continue; - if (sector[i].lotag == 32767) continue; - if (sector[i].ceilingz >= sector[i].floorz) continue; - show2dsector[i>>3] |= (1<<(i&7)); - } - } - - if (ud.camerasprite == -1) - { - if (ud.overhead_on != 2) - { - if (pp->newowner >= 0) - G_DrawCameraText(pp->newowner); - else - { - P_DisplayWeapon(); -#ifdef SPLITSCREEN_MOD_HACKS - if (pp2) // HACK - { - const int32_t oscreenpeek = screenpeek; - screenpeek = 1; - P_DisplayWeapon(); - screenpeek = oscreenpeek; - } -#endif - - if (pp->over_shoulder_on == 0) - P_DisplayScuba(); -#ifdef SPLITSCREEN_MOD_HACKS - if (pp2 && pp2->over_shoulder_on == 0) // HACK - { - const int32_t oscreenpeek = screenpeek; - screenpeek = 1; - P_DisplayScuba(); - screenpeek = oscreenpeek; - } -#endif - } - G_MoveClouds(); - } - - if (ud.overhead_on > 0) - { - // smoothratio = min(max(smoothratio,0),65536); - smoothratio = calc_smoothratio(totalclock, ototalclock); - G_DoInterpolations(smoothratio); - - if (ud.scrollmode == 0) - { - if (pp->newowner == -1 && !ud.pause_on) - { - cposx = pp->opos.x + mulscale16(pp->pos.x-pp->opos.x, smoothratio); - cposy = pp->opos.y + mulscale16(pp->pos.y-pp->opos.y, smoothratio); - cang = pp->oang + mulscale16(((pp->ang+1024-pp->oang)&2047)-1024, smoothratio); - } - else - { - cposx = pp->opos.x; - cposy = pp->opos.y; - cang = pp->oang; - } - } - else - { -#ifdef __ANDROID__ - CONTROL_Android_ScrollMap(&ud.fola,& ud.folx,&ud.foly,&pp->zoom); -#else - if (!ud.pause_on) - { - ud.fola += ud.folavel>>3; - ud.folx += (ud.folfvel*sintable[(512+2048-ud.fola)&2047])>>14; - ud.foly += (ud.folfvel*sintable[(512+1024-512-ud.fola)&2047])>>14; - } -#endif - cposx = ud.folx; - cposy = ud.foly; - cang = ud.fola; - } - - if (ud.overhead_on == 2) - { - clearview(0L); - drawmapview(cposx,cposy,pp->zoom,cang); - } - G_DrawOverheadMap(cposx,cposy,pp->zoom,cang); - - G_RestoreInterpolations(); - - if (ud.overhead_on == 2) - { - const int32_t a = (ud.screen_size > 0) ? 147 : 179; - minitext(5,a+6,EpisodeNames[ud.volume_number],0,2+8+16+256); - minitext(5,a+6+6,MapInfo[ud.volume_number*MAXLEVELS + ud.level_number].name,0,2+8+16+256); - } - } - } - - if (pp->invdisptime > 0) G_DrawInventory(pp); - - if (VM_OnEvent(EVENT_DISPLAYSBAR, g_player[screenpeek].ps->i, screenpeek) == 0) - G_DrawStatusBar(screenpeek); - -#ifdef SPLITSCREEN_MOD_HACKS - // HACK - if (g_fakeMultiMode==2) - { - G_DrawStatusBar(1); - G_PrintGameQuotes(1); - } -#endif - - G_PrintGameQuotes(screenpeek); - - if (ud.show_level_text && hud_showmapname && g_levelTextTime > 1) - { - int32_t bits = 10+16; - - if (g_levelTextTime < 3) - bits |= 1+32; - else if (g_levelTextTime < 5) - bits |= 1; - - if (MapInfo[(ud.volume_number*MAXLEVELS) + ud.level_number].name != NULL) - { - if (currentboardfilename[0] != 0 && ud.volume_number == 0 && ud.level_number == 7) - menutext_(160,90+16+8,-g_levelTextTime+22/*quotepulseshade*/,0,currentboardfilename,bits); - else menutext_(160,90+16+8,-g_levelTextTime+22/*quotepulseshade*/,0,MapInfo[(ud.volume_number*MAXLEVELS) + ud.level_number].name,bits); - } - } - - if (I_EscapeTrigger() && ud.overhead_on == 0 - && ud.show_help == 0 - && g_player[myconnectindex].ps->newowner == -1) - { - if ((g_player[myconnectindex].ps->gm&MODE_MENU) == MODE_MENU && g_currentMenu <= MENU_MAIN_INGAME) - { - I_EscapeTriggerClear(); - S_PlaySound(EXITMENUSOUND); - M_ChangeMenu(MENU_CLOSE); - S_PauseSounds(0); - } - else if ((g_player[myconnectindex].ps->gm&MODE_MENU) != MODE_MENU && - g_player[myconnectindex].ps->newowner == -1 && - (g_player[myconnectindex].ps->gm&MODE_TYPE) != MODE_TYPE) - { - I_EscapeTriggerClear(); - S_PauseSounds(1); - S_MenuSound(); - - M_OpenMenu(myconnectindex); - - if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2) ready2send = 0; - - if (g_player[myconnectindex].ps->gm&MODE_GAME) M_ChangeMenu(MENU_MAIN_INGAME); - else M_ChangeMenu(MENU_MAIN); - screenpeek = myconnectindex; - } - } - - if (VM_HaveEvent(EVENT_DISPLAYREST)) - { - int32_t vr=viewingrange, asp=yxaspect; - VM_OnEvent_(EVENT_DISPLAYREST, g_player[screenpeek].ps->i, screenpeek); - setaspect(vr, asp); - } - - if (g_player[myconnectindex].ps->newowner == -1 && ud.overhead_on == 0 && ud.crosshair && ud.camerasprite == -1) - { - int32_t a = VM_OnEvent(EVENT_DISPLAYCROSSHAIR, g_player[screenpeek].ps->i, screenpeek); - - if ((unsigned)a < MAXTILES) - { - if (a == 0) - a = CROSSHAIR; - - vec2_t crosshairpos = { 160<<16, 100<<16 }; - - rotatesprite_win(crosshairpos.x-(g_player[myconnectindex].ps->look_ang<<15),crosshairpos.y,scale(65536,ud.crosshairscale,100), - 0,a,0,CROSSHAIR_PAL,2+1); - -#ifdef GEKKO - if ((g_player[myconnectindex].ps->gm&MODE_MENU) == 0 && readmouseabsxy(&crosshairpos, &mouseabs)) - rotatesprite_win(crosshairpos.x,crosshairpos.y,scale(65536,ud.crosshairscale,100),0,a,0,CROSSHAIR_PAL,2+1); -#endif - } - } -#if 0 - if (GametypeFlags[ud.coop] & GAMETYPE_TDM) - { - for (i=0; iteam == g_player[myconnectindex].ps->team) - { - j = min(max((G_GetAngleDelta(getangle(g_player[i].ps->pos.x-g_player[myconnectindex].ps->pos.x, - g_player[i].ps->pos.y-g_player[myconnectindex].ps->pos.y),g_player[myconnectindex].ps->ang))>>1,-160),160); - rotatesprite_win((160-j)<<16,100L<<16,65536L,0,DUKEICON,0,0,2+1); - } - } - } -#endif - - if (ud.pause_on==1 && (g_player[myconnectindex].ps->gm&MODE_MENU) == 0) - menutext(160,100,0,0,"Game Paused"); - - if (ud.coords) - G_PrintCoords(screenpeek); - -#ifdef YAX_DEBUG - M32_drawdebug(); -#endif - -#ifdef USE_OPENGL - extern int32_t mdpause; - mdpause = (ud.pause_on || (ud.recstat==2 && (g_demo_paused && g_demo_goalCnt==0)) || (g_player[myconnectindex].ps->gm&MODE_MENU && numplayers < 2)); -#endif - - G_PrintFPS(); - - // JBF 20040124: display level stats in screen corner - if (ud.overhead_on != 2 && ud.levelstats && VM_OnEvent(EVENT_DISPLAYLEVELSTATS, g_player[myconnectindex].ps->i, myconnectindex) == 0) - { - DukePlayer_t const * const myps = g_player[myconnectindex].ps; - - i = 198<<16; - - if (ud.screen_size == 4) - { - if (ud.althud != 2) - i -= sbarsc(ud.althud ? (tilesiz[BIGALPHANUM].y+8)<<16 : tilesiz[INVENTORYBOX].y<<16); - } - else if (ud.screen_size > 2) - i -= sbarsc(tilesiz[BOTTOMSTATUSBAR].y<<16); - - Bsprintf(tempbuf,"T:^15%d:%02d.%02d", - (myps->player_par/(REALGAMETICSPERSEC*60)), - (myps->player_par/REALGAMETICSPERSEC)%60, - ((myps->player_par%REALGAMETICSPERSEC)*33)/10 - ); - G_ScreenText(STARTALPHANUM, 2<<16, i-gtextsc(21<<16), gtextsc(65536), 0, 0, tempbuf, 0, 10, 2|8|16|256|ROTATESPRITE_FULL16, 0, 5<<16, 8<<16, 8<<16, 0, TEXT_XOFFSETZERO|TEXT_GAMETEXTNUMHACK, 0, 0, xdim-1, ydim-1); - - if (ud.player_skill > 3 || ((g_netServer || ud.multimode > 1) && !GTFLAGS(GAMETYPE_PLAYERSFRIENDLY))) - Bsprintf(tempbuf,"K:^15%d",(ud.multimode>1 &&!GTFLAGS(GAMETYPE_PLAYERSFRIENDLY))? - myps->frag-myps->fraggedself:myps->actors_killed); - else - { - if (myps->actors_killed >= myps->max_actors_killed) - Bsprintf(tempbuf,"K:%d/%d",myps->actors_killed, - myps->max_actors_killed>myps->actors_killed? - myps->max_actors_killed:myps->actors_killed); - else - Bsprintf(tempbuf,"K:^15%d/%d",myps->actors_killed, - myps->max_actors_killed>myps->actors_killed? - myps->max_actors_killed:myps->actors_killed); - } - G_ScreenText(STARTALPHANUM, 2<<16, i-gtextsc(14<<16), gtextsc(65536), 0, 0, tempbuf, 0, 10, 2|8|16|256|ROTATESPRITE_FULL16, 0, 5<<16, 8<<16, 8<<16, 0, TEXT_XOFFSETZERO|TEXT_GAMETEXTNUMHACK, 0, 0, xdim-1, ydim-1); - - if (myps->secret_rooms == myps->max_secret_rooms) - Bsprintf(tempbuf,"S:%d/%d", myps->secret_rooms, myps->max_secret_rooms); - else Bsprintf(tempbuf,"S:^15%d/%d", myps->secret_rooms, myps->max_secret_rooms); - G_ScreenText(STARTALPHANUM, 2<<16, i-gtextsc(7<<16), gtextsc(65536), 0, 0, tempbuf, 0, 10, 2|8|16|256|ROTATESPRITE_FULL16, 0, 5<<16, 8<<16, 8<<16, 0, TEXT_XOFFSETZERO|TEXT_GAMETEXTNUMHACK, 0, 0, xdim-1, ydim-1); - } - - if (g_player[myconnectindex].gotvote == 0 && voting != -1 && voting != myconnectindex) - { - Bsprintf(tempbuf,"%s^00 has called a vote for map",g_player[voting].user_name); - gametext(160,40,tempbuf,0,2+8+16); - Bsprintf(tempbuf,"%s (E%dL%d)",MapInfo[vote_episode*MAXLEVELS + vote_map].name,vote_episode+1,vote_map+1); - gametext(160,48,tempbuf,0,2+8+16); - gametext(160,70,"Press F1 to Accept, F2 to Decline",0,2+8+16); - } - - if (BUTTON(gamefunc_Show_DukeMatch_Scores)) - G_ShowScores(); - - if (g_Debug) - G_ShowCacheLocks(); - -#ifdef LUNATIC - El_DisplayErrors(); -#endif - -#ifndef EDUKE32_TOUCH_DEVICES - if (VOLUMEONE) - { - if (ud.show_help == 0 && g_showShareware > 0 && (g_player[myconnectindex].ps->gm&MODE_MENU) == 0) - rotatesprite_fs((320-50)<<16,9<<16,65536L,0,BETAVERSION,0,0,2+8+16+128); - } -#endif - - if (!Demo_IsProfiling()) - { - if (g_player[myconnectindex].ps->gm&MODE_TYPE) - Net_SendMessage(); - else - M_DisplayMenus(); - } - - { - static int32_t applied = 0; - - if (tint.maxf) - { - G_FadePalaccum(&tint); - applied = 1; - } - else if (applied) - { - // be sure to always un-apply a tint. - setpalettefade(0,0,0, 0); - applied = 0; - } - } -} - static int32_t G_DoThirdPerson(const DukePlayer_t *pp, vec3_t *vect, int16_t *vsectnum, int32_t ang, int32_t horiz) { spritetype *sp = &sprite[pp->i]; @@ -6382,87 +4964,6 @@ FAKE_F3: } } -static void G_ShowParameterHelp(void) -{ - const char *s = "Usage: eduke32 [files] [options]\n" - "Example: eduke32 -q4 -a -m -tx -map nukeland.map\n\n" - "Files can be *.grp/zip/con/def/rts\n" - "\n" - "-cfg [file.cfg]\tUse an alternate configuration file\n" -#ifdef HAVE_CLIPSHAPE_FEATURE - "-clipmap [file.map]\tLoad an additional clipping map for use with clipshape\n" -#endif - "-connect [host]\tConnect to a multiplayer game\n" - "-c#\t\tUse MP mode #, 1 = Dukematch, 2 = Coop, 3 = Dukematch(no spawn)\n" - "-d [file.edm or demonum]\tPlay a demo\n" - "-g [file.grp]\tLoad additional game data\n" - "-h [file.def]\tLoad an alternate definitions file\n" - "-j [dir]\t\tAdds a directory to EDuke32's search list\n" - "-l#\t\tWarp to level #, see -v\n" - "-map [file.map]\tLoads a map\n" - "-mh [file.def]\tInclude an additional definitions module\n" - "-mx [file.con]\tInclude an additional CON script module\n" - "-m\t\tDisable monsters\n" - "-nam\t\tRun in NAM compatibility mode\n" - "-napalm\t\tRun in NAPALM compatibility mode\n" - "-rts [file.rts]\tLoad a custom Remote Ridicule sound bank\n" - "-r\t\tRecord demo\n" - "-s#\t\tSet skill level (1-4)\n" - "-server\t\tStart a multiplayer game for other players to join\n" -#ifdef STARTUP_SETUP_WINDOW - "-setup/nosetup\tEnables/disables startup window\n" -#endif - "-t#\t\tSet respawn mode: 1 = Monsters, 2 = Items, 3 = Inventory, x = All\n" - "-usecwd\t\tRead game data and configuration file from working directory\n" - "-u#########\tUser's favorite weapon order (default: 3425689071)\n" - "-v#\t\tWarp to volume #, see -l\n" - "-ww2gi\t\tRun in WWII GI compatibility mode\n" - "-x [game.con]\tLoad custom CON script\n" - "-#\t\tLoad and run a game from slot # (0-9)\n" -// "\n-?/--help\tDisplay this help message and exit\n" - "\nSee eduke32 -debughelp for debug parameters" - ; -#ifdef WM_MSGBOX_WINDOW - Bsnprintf(tempbuf, sizeof(tempbuf), HEAD2 " %s", s_buildRev); - wm_msgbox(tempbuf,"%s",s); -#else - initprintf("%s\n",s); -#endif -} - -static void G_ShowDebugHelp(void) -{ - const char *s = "Usage: eduke32 [files] [options]\n" - "\n" - "-a\t\tUse fake player AI (fake multiplayer only)\n" - "-cachesize #\tSets cache size, in Kb\n" - "-game_dir [dir]\tDuke3d_w32 compatibility option, see -j\n" - "-gamegrp \tSelects which file to use as main grp\n" - "-name [name]\tPlayer name in multiplay\n" - "-noautoload\tDisable loading content from autoload dir\n" -#ifdef _WIN32 - "-nodinput\t\tDisable DirectInput (joystick) support\n" -#endif - "-nologo\t\tSkip the logo anim\n" - "-ns/-nm\t\tDisable sound or music\n" - "-rotatesprite-no-widescreen\tpass bit 1024 to all CON rotatesprite calls\n" - "-q#\t\tFake multiplayer with # (2-8) players\n" - "-z#/-condebug\tEnable line-by-line CON compile debugging at level #\n" - "-conversion YYYYMMDD\tSelects CON script version for compatibility with older mods\n" -#ifdef LUNATIC - "-Lopts=,,...\n" - " Pass options to Lunatic, valid ones are:\n" - " diag, nojit, traces, dump, strict\n" -#endif - ; -#ifdef WM_MSGBOX_WINDOW - Bsnprintf(tempbuf, sizeof(tempbuf), HEAD2 " %s", s_buildRev); - wm_msgbox(tempbuf,"%s",s); -#else - initprintf("%s\n",s); -#endif -} - static int32_t S_DefineAudioIfSupported(char **fn, const char *name) { #if !defined HAVE_FLAC || !defined HAVE_VORBIS @@ -6915,730 +5416,7 @@ int32_t loaddefinitions_game(const char *fn, int32_t preload) return 0; } -#ifdef LUNATIC -char const * const * g_argv; -const char **g_elModules; -#endif -static void G_AddDemo(const char* param) -{ - Bstrncpy(tempbuf, param, sizeof(tempbuf)); - char * colon = (char *)Bstrchr(tempbuf, ':'); - int32_t framespertic=-1, numrepeats=1; - - if (colon && colon != tempbuf) - { - // -d:[,] - // profiling options - *(colon++) = 0; - Bsscanf(colon, "%u,%u", &framespertic, &numrepeats); - } - - Demo_SetFirst(tempbuf); - - if (framespertic < 0) - { - initprintf("Play demo %s.\n", g_firstDemoFile); - } - else - { - framespertic = clamp(framespertic, 0, 8)+1; - // TODO: repeat count and gathering statistics. - initprintf("Profile demo %s, %d frames/gametic, repeated 1x.\n", g_firstDemoFile, - framespertic-1); - Demo_PlayFirst(framespertic, 1); - g_noLogo = 1; - } -} - -static void G_CheckCommandLine(int32_t argc, char const * const * argv) -{ - int16_t i = 1, j; - const char *c, *k; - -#ifdef LUNATIC - g_argv = argv; - g_elModules = (const char **)Xcalloc(argc+1, sizeof(char *)); -#endif - ud.fta_on = 1; - ud.god = 0; - ud.m_respawn_items = 0; - ud.m_respawn_monsters = 0; - ud.m_respawn_inventory = 0; - ud.warp_on = 0; - ud.cashman = 0; - ud.m_player_skill = ud.player_skill = 2; - g_player[0].wchoice[0] = 3; - g_player[0].wchoice[1] = 4; - g_player[0].wchoice[2] = 5; - g_player[0].wchoice[3] = 7; - g_player[0].wchoice[4] = 8; - g_player[0].wchoice[5] = 6; - g_player[0].wchoice[6] = 0; - g_player[0].wchoice[7] = 2; - g_player[0].wchoice[8] = 9; - g_player[0].wchoice[9] = 1; - Bsprintf(ud.wchoice, "3457860291"); - -#ifdef HAVE_CLIPSHAPE_FEATURE - // pre-form the default 10 clipmaps - for (j = '0'; j<='9'; ++j) - { - char clipshape[16] = "_clipshape0.map"; - - clipshape[10] = j; - g_clipMapFiles = (char **)Xrealloc(g_clipMapFiles, (g_clipMapFilesNum+1) * sizeof(char *)); - g_clipMapFiles[g_clipMapFilesNum] = Xstrdup(clipshape); - ++g_clipMapFilesNum; - } -#endif - - if (argc > 1) - { -#ifdef LUNATIC - int32_t numlmods = 0; -#endif - initprintf("Application parameters: "); - while (i < argc) - initprintf("%s ",argv[i++]); - initprintf("\n"); - - i = 1; - do - { - const char *const oc = argv[i]; - int32_t shortopt = 0, ignored_short_opt = 0; - - c = oc; - - if ((*c == '-') -#ifdef _WIN32 - || (*c == '/') -#endif - ) - { - shortopt = 0; - - if (!Bstrcasecmp(c+1,"?") || !Bstrcasecmp(c+1,"help") || !Bstrcasecmp(c+1,"-help")) - { - G_ShowParameterHelp(); - Bexit(0); - } - if (!Bstrcasecmp(c+1,"addon")) - { - if (argc > i+1) - { - g_usingAddon = Batoi(argv[i+1]); - - if (g_usingAddon > ADDON_NONE && g_usingAddon < NUMADDONS) - g_noSetup = 1; - else g_usingAddon = ADDON_NONE; - - i++; - } - i++; - continue; - } - if (!Bstrcasecmp(c+1,"debughelp") || !Bstrcasecmp(c+1,"-debughelp")) - { - G_ShowDebugHelp(); - Bexit(0); - } - if (!Bstrcasecmp(c+1,"grp") || !Bstrcasecmp(c+1,"g")) - { - if (argc > i+1) - { - G_AddGroup(argv[i+1]); - i++; - } - i++; - continue; - } - if (!Bstrcasecmp(c+1,"game_dir")) - { - if (argc > i+1) - { - Bstrncpyz(g_modDir, argv[i+1], sizeof(g_modDir)); - G_AddPath(argv[i+1]); - i++; - } - i++; - continue; - } - if (!Bstrcasecmp(c+1,"cfg")) - { - if (argc > i+1) - { - Bstrcpy(setupfilename,argv[i+1]); - i++; - } - i++; - continue; - } - if (!Bstrcasecmp(c+1,"gamegrp")) - { - if (argc > i+1) - { - clearGrpNamePtr(); - g_grpNamePtr = dup_filename(argv[i+1]); - i++; - } - i++; - continue; - } - if (!Bstrcasecmp(c+1,"nam")) - { - g_gameType = GAMEFLAG_NAM; - i++; - continue; - } - if (!Bstrcasecmp(c+1,"napalm")) - { - g_gameType = GAMEFLAG_NAM|GAMEFLAG_NAPALM; - i++; - continue; - } - if (!Bstrcasecmp(c+1,"ww2gi")) - { - g_gameType = GAMEFLAG_WW2GI; - i++; - continue; - } - if (!Bstrcasecmp(c+1,"setup")) - { - g_commandSetup = TRUE; - i++; - continue; - } - if (!Bstrcasecmp(c+1,"nosetup")) - { - g_noSetup = 1; - g_commandSetup = 0; - i++; - continue; - } -#if defined RENDERTYPEWIN - if (!Bstrcasecmp(c+1,"nodinput")) - { - initprintf("DirectInput (joystick) support disabled\n"); - di_disabled = 1; - i++; - continue; - } -#endif - if (!Bstrcasecmp(c+1,"noautoload")) - { - initprintf("Autoload disabled\n"); - g_noAutoLoad = 1; - i++; - continue; - } - if (!Bstrcasecmp(c+1,"net")) - { - G_GameExit("EDuke32 no longer supports legacy networking.\n\n" - "If using YANG or other launchers that only support legacy netplay, download an older build of EDuke32. " - "Otherwise, run the following:\n\n" - "eduke32 -server\n\n" - "Other clients can then connect by typing \"connect [host]\" in the console.\n\n" - "EDuke32 will now close."); - } - if (!Bstrcasecmp(c+1,"port")) - { - if (argc > i+1) - { - g_netPort = Batoi(argv[i+1]); - i++; - } - i++; - continue; - } - if (!Bstrcasecmp(c+1,"server")) - { - g_networkMode = NET_SERVER; - g_noSetup = g_noLogo = TRUE; - i++; - continue; - } - if (!Bstrcasecmp(c+1,"dedicated")) - { - g_networkMode = NET_DEDICATED_SERVER; - g_noSetup = g_noLogo = TRUE; - i++; - continue; - } - if (!Bstrcasecmp(c+1,"connect")) - { - if (argc > i+1) - { - Net_Connect(argv[i+1]); - g_noSetup = g_noLogo = TRUE; - i++; - } - i++; - continue; - } - if (!Bstrcasecmp(c+1,"password")) - { - if (argc > i+1) - { - Bstrncpyz(g_netPassword, argv[i+1], sizeof(g_netPassword)); - i++; - } - i++; - continue; - } - if (!Bstrcasecmp(c+1,"name")) - { - if (argc > i+1) - { - CommandName = argv[i+1]; - i++; - } - i++; - continue; - } - if (!Bstrcasecmp(c+1,"map")) - { - if (argc > i+1) - { - CommandMap = argv[i+1]; - i++; - } - i++; - continue; - } - if (!Bstrcasecmp(c+1,"rts")) - { - if (argc > i+1) - { - g_rtsNamePtr = argv[i+1]; - Bstrncpyz(ud.rtsname, g_rtsNamePtr, sizeof(ud.rtsname)); - initprintf("Using RTS file \"%s\".\n", ud.rtsname); - i++; - } - i++; - continue; - } - if (!Bstrcasecmp(c+1,"x")) - { - if (argc > i+1) - { - G_AddCon(argv[i+1]); - i++; - } - i++; - continue; - } - if (!Bstrcasecmp(c+1,"mx")) - { - if (argc > i+1) - { - G_AddConModule(argv[i+1]); - i++; - } - i++; - continue; - } - if (!Bstrcasecmp(c+1,"h")) - { - if (argc > i+1) - { - G_AddDef(argv[i+1]); - i++; - } - i++; - continue; - } - if (!Bstrcasecmp(c+1,"mh")) - { - if (argc > i+1) - { - G_AddDefModule(argv[i+1]); - i++; - } - i++; - continue; - } - if (!Bstrcasecmp(c+1,"j")) - { - if (argc > i+1) - { - G_AddPath(argv[i+1]); - i++; - } - i++; - continue; - } - if (!Bstrcasecmp(c+1,"d")) - { - if (argc > i+1) - { - G_AddDemo(argv[i+1]); - i++; - } - i++; - continue; - } -#ifdef HAVE_CLIPSHAPE_FEATURE - if (!Bstrcasecmp(c+1,"clipmap")) - { - if (argc > i+1) - { - G_AddClipMap(argv[i+1]); - i++; - } - i++; - continue; - } -#endif - if (!Bstrcasecmp(c+1,"condebug")) - { - g_scriptDebug = 1; - i++; - continue; - } - if (!Bstrcasecmp(c+1,"nologo")) - { - g_noLogo = 1; - i++; - continue; - } - if (!Bstrcasecmp(c+1,"rotatesprite-no-widescreen")) - { - g_rotatespriteNoWidescreen = 1; - i++; - continue; - } - if (!Bstrcasecmp(c+1,"usecwd")) - { - usecwd = 1; - i++; - continue; - } - if (!Bstrcasecmp(c+1,"cachesize")) - { - if (argc > i+1) - { - uint32_t j = Batol(argv[i+1]); - MAXCACHE1DSIZE = j<<10; - initprintf("Cache size: %dkB\n",j); - i++; - } - i++; - continue; - } - if (!Bstrcasecmp(c+1,"noinstancechecking")) - { - i++; - continue; - } -#if defined(RENDERTYPEWIN) && defined(USE_OPENGL) - if (!Bstrcasecmp(c+1,"forcegl")) - { - forcegl = 1; - i++; - continue; - } -#endif - // the following two dummy entries allow us to serve as a drop-in replacement for NAM on Steam - if (!Bstrcasecmp(c+1,"noconsole")) - { - i++; - continue; - } - if (!Bstrcasecmp(c+1,"conf")) - { - if (argc > i+1) - i++; - i++; - continue; - } - } - - if ((*c == '-') -#ifdef _WIN32 - || (*c == '/') -#endif - ) - { - shortopt = 1; - - c++; - switch (Btolower(*c)) - { - case 'a': - ud.playerai = 1; - initprintf("Other player AI.\n"); - break; - case 'c': - c++; - ud.m_coop = 0; - while ((*c >= '0')&&(*c <= '9')) - { - ud.m_coop *= 10; - ud.m_coop += *c - '0'; - c++; - } - ud.m_coop--; - break; - case 'd': - { - c++; - if (*c) - G_AddDemo(c); - break; - } -#ifdef LUNATIC - case 'f': - break; -#endif - case 'g': - c++; - if (*c) - G_AddGroup(c); - break; - case 'h': - c++; - if (*c) - G_AddDef(c); - break; - case 'j': - c++; - if (*c) - G_AddPath(c); - break; - case 'l': - // NOTE: Overlaid with -Lopts=... options for Lunatic, hence the check. - if (Bisdigit(c[1])) - { - ud.warp_on = 1; - c++; - ud.m_level_number = ud.level_number = ((unsigned)(Batoi(c)-1))%MAXLEVELS; - } - break; - case 'm': - if (*(c+1) != 'a' && *(c+1) != 'A') - { - ud.m_monsters_off = 1; - ud.m_player_skill = ud.player_skill = 0; - initprintf("Monsters off.\n"); - } - break; - case 'n': - c++; - if (*c == 's' || *c == 'S') - { - g_noSound = 2; - initprintf("Sound off.\n"); - } - else if (*c == 'm' || *c == 'M') - { - g_noMusic = 1; - initprintf("Music off.\n"); - } - else - { - G_ShowParameterHelp(); - exit(-1); - } - break; - case 'q': - if (*(++c) == 0) - { - ud.multimode = 1; - initprintf("Fake multiplayer mode: expected number after -q, falling back to 1 player.\n"); - } - else - { - int32_t numpl = Batoi(c); - - if (numpl < 2 || numpl > MAXPLAYERS) - { - initprintf("Fake multiplayer mode: expected 2-%d players, falling back to 1.\n", - MAXPLAYERS); - } - else - { - ud.multimode = numpl; - initprintf("Fake multiplayer mode: %d players.\n", ud.multimode); - - g_fakeMultiMode = numpl; - } - } - - ud.m_coop = ud.coop = 0; - ud.m_marker = ud.marker = 1; - ud.m_respawn_monsters = ud.respawn_monsters = 1; - ud.m_respawn_items = ud.respawn_items = 1; - ud.m_respawn_inventory = ud.respawn_inventory = 1; - break; - case 'r': - ud.m_recstat = 1; - initprintf("Demo record mode on.\n"); - break; - case 's': - c++; - ud.m_player_skill = ud.player_skill = (Batoi(c)%5); - if (ud.m_player_skill == 4) - ud.m_respawn_monsters = ud.respawn_monsters = 1; - break; - case 't': - c++; - if (*c == '1') ud.m_respawn_monsters = 1; - else if (*c == '2') ud.m_respawn_items = 1; - else if (*c == '3') ud.m_respawn_inventory = 1; - else - { - ud.m_respawn_monsters = 1; - ud.m_respawn_items = 1; - ud.m_respawn_inventory = 1; - } - initprintf("Respawn on.\n"); - break; - case 'u': - g_forceWeaponChoice = 1; - c++; - j = 0; - if (*c) - { - initprintf("Using favorite weapon order(s).\n"); - while (*c) - { - g_player[0].wchoice[j] = *c-'0'; - ud.wchoice[j] = *c; - c++; - j++; - } - - while (j < 10) - { - if (j == 9) - { - g_player[0].wchoice[9] = 1; - ud.wchoice[9] = '1'; - } - else - { - g_player[0].wchoice[j] = 2; - ud.wchoice[j] = '2'; - } - - j++; - } - } - else - { - initprintf("Using default weapon orders.\n"); - g_player[0].wchoice[0] = 3; - g_player[0].wchoice[1] = 4; - g_player[0].wchoice[2] = 5; - g_player[0].wchoice[3] = 7; - g_player[0].wchoice[4] = 8; - g_player[0].wchoice[5] = 6; - g_player[0].wchoice[6] = 0; - g_player[0].wchoice[7] = 2; - g_player[0].wchoice[8] = 9; - g_player[0].wchoice[9] = 1; - - Bsprintf(ud.wchoice, "3457860291"); - } - break; - case 'v': - c++; - ud.warp_on = 1; - ud.m_volume_number = ud.volume_number = ((unsigned)(Batoi(c)-1))%MAXVOLUMES; - break; - case 'w': - ud.coords = 1; - break; -#ifdef LUNATIC - case 'W': - break; -#endif - case 'x': - c++; - if (*c) - G_AddCon(c); - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - ud.warp_on = 2 + (*c) - '0'; - break; - case 'z': - c++; - g_scriptDebug = Batoi(c); - if (!g_scriptDebug) - g_scriptDebug = 1; - break; - default: - ignored_short_opt = 1; - break; - } - } - else - { - shortopt = 0; - - k = Bstrrchr(c,'.'); - if (k) - { - if (!Bstrcasecmp(k,".map")) - { - CommandMap = argv[i++]; - continue; - } - if (!Bstrcasecmp(k,".grp") || !Bstrcasecmp(k,".zip") || !Bstrcasecmp(k,".pk3") || !Bstrcasecmp(k,".pk4")) - { - G_AddGroup(argv[i++]); - continue; - } - if (!Bstrcasecmp(k,".con")) - { - clearScriptNamePtr(); - g_scriptNamePtr = dup_filename(argv[i++]); - initprintf("Using CON file \"%s\".\n",g_scriptNamePtr); - continue; - } - if (!Bstrcasecmp(k,".def")) - { - clearDefNamePtr(); - g_defNamePtr = dup_filename(argv[i++]); - initprintf("Using DEF file \"%s\".\n",g_defNamePtr); - continue; - } - if (!Bstrcasecmp(k,".rts")) - { - g_rtsNamePtr = argv[i++]; - Bstrncpyz(ud.rtsname, g_rtsNamePtr, sizeof(ud.rtsname)); - initprintf("Using RTS file \"%s\".\n", ud.rtsname); - continue; - } -#ifdef LUNATIC - if (!Bstrcmp(k,".lua")) // NOTE: case sensitive! - { - g_elModules[numlmods++] = argv[i++]; - continue; - } -#endif - } - } - - if (!shortopt || ignored_short_opt) - initprintf("Warning: ignored application parameter \"%s\".\n", oc); - - i++; - } - while (i < argc); - } -} void G_UpdateAppTitle(void) { @@ -7653,235 +5431,6 @@ void G_UpdateAppTitle(void) } } -static void G_DisplayLogo(void) -{ - int32_t soundanm = 0; - int32_t logoflags = G_GetLogoFlags(); - - ready2send = 0; - - I_ClearAllInput(); - - setview(0,0,xdim-1,ydim-1); - clearallviews(0L); - G_FadePalette(0,0,0,252); - - flushperms(); - nextpage(); - - G_UpdateAppTitle(); - - S_StopMusic(); - FX_StopAllSounds(); // JBF 20031228 - S_ClearSoundLocks(); // JBF 20031228 - if ((!g_netServer && ud.multimode < 2) && (logoflags & LOGO_ENABLED) && !g_noLogo) - { - if ( -#ifndef EDUKE32_TOUCH_DEVICES - VOLUMEALL && -#endif - (logoflags & LOGO_PLAYANIM)) - { - if (!I_CheckAllInput() && g_noLogoAnim == 0) - { - Net_GetPackets(); - Anim_Play("logo.anm"); - G_FadePalette(0,0,0,252); - I_ClearAllInput(); - } - - clearallviews(0L); - nextpage(); - - if (logoflags & LOGO_STOPANIMSOUNDS) - { - FX_StopAllSounds(); - S_ClearSoundLocks(); - } - } - - if (logoflags & LOGO_PLAYMUSIC) - { - g_musicIndex = MUS_INTRO; - S_PlayMusic(MapInfo[g_musicIndex].musicfn); - } - - if (!NAM) - { - //g_player[myconnectindex].ps->palette = drealms; - //G_FadePalette(0,0,0,252); - - if (logoflags & LOGO_3DRSCREEN) - { - - if (!I_CheckAllInput() && g_noLogoAnim == 0) - { - int32_t i; - Net_GetPackets(); - - i = kopen4loadfrommod("3dr.ivf", 0); - - if (i == -1) - i = kopen4loadfrommod("3dr.anm", 0); - - if (i != -1) - { - kclose(i); - Anim_Play("3dr.anm"); - G_FadePalette(0,0,0,252); - I_ClearAllInput(); - } - else - { - clearallviews(0); - - P_SetGamePalette(g_player[myconnectindex].ps, DREALMSPAL, 8 + 2 + 1); // JBF 20040308 - fadepal(0,0,0, 0,252,28); - flushperms(); - rotatesprite_fs(160 << 16, 100 << 16, 65536L, 0, DREALMS, 0, 0, 2 + 8 + BGSTRETCH); - nextpage(); - fadepaltile(0,0,0, 252,0,-28, DREALMS); - totalclock = 0; - while (totalclock < (120 * 7) && !I_CheckAllInput()) - { - clearallviews(0); - - rotatesprite_fs(160 << 16, 100 << 16, 65536L, 0, DREALMS, 0, 0, 2 + 8 + 64 + BGSTRETCH); - - G_HandleAsync(); - - if (g_restorePalette) - { - P_SetGamePalette(g_player[myconnectindex].ps, g_player[myconnectindex].ps->palette, 0); - g_restorePalette = 0; - } - nextpage(); - } - fadepaltile(0,0,0, 0,252,28, DREALMS); - } - } - - clearallviews(0L); - nextpage(); - } - - I_ClearAllInput(); - } - - clearallviews(0L); - nextpage(); - - if (logoflags & LOGO_TITLESCREEN) - { - clearallviews(0); - - //g_player[myconnectindex].ps->palette = titlepal; - P_SetGamePalette(g_player[myconnectindex].ps, TITLEPAL, 8+2+1); // JBF 20040308 - flushperms(); - rotatesprite_fs(160<<16,100<<16,65536L,0,BETASCREEN,0,0,2+8+64+BGSTRETCH); - KB_FlushKeyboardQueue(); - fadepaltile(0,0,0, 252,0,-28,BETASCREEN); - totalclock = 0; - - while ( -#ifndef DROIDMENU - totalclock < (860+120) && -#endif - !I_CheckAllInput()) - { - clearallviews(0); - - rotatesprite_fs(160<<16,100<<16,65536L,0,BETASCREEN,0,0,2+8+64+BGSTRETCH); - if (logoflags & LOGO_DUKENUKEM) - { - if (totalclock > 120 && totalclock < (120+60)) - { - if (soundanm == 0) - { - soundanm++; - S_PlaySound(PIPEBOMB_EXPLODE); - } - rotatesprite_fs(160<<16,104<<16,(totalclock-120)<<10,0,DUKENUKEM,0,0,2+8); - } - else if (totalclock >= (120+60)) - rotatesprite_fs(160<<16,(104)<<16,60<<10,0,DUKENUKEM,0,0,2+8); - } - else soundanm++; - - if (logoflags & LOGO_THREEDEE) - { - if (totalclock > 220 && totalclock < (220+30)) - { - if (soundanm == 1) - { - soundanm++; - S_PlaySound(PIPEBOMB_EXPLODE); - } - - rotatesprite_fs(160<<16,(104)<<16,60<<10,0,DUKENUKEM,0,0,2+8); - rotatesprite_fs(160<<16,(129)<<16,(totalclock - 220)<<11,0,THREEDEE,0,0,2+8); - } - else if (totalclock >= (220+30)) - rotatesprite_fs(160<<16,(129)<<16,30<<11,0,THREEDEE,0,0,2+8); - } - else soundanm++; - - if (PLUTOPAK && (logoflags & LOGO_PLUTOPAKSPRITE)) - { - // JBF 20030804 - if (totalclock >= 280 && totalclock < 395) - { - rotatesprite_fs(160<<16,(151)<<16,(410-totalclock)<<12,0,PLUTOPAKSPRITE+1,0,0,2+8); - if (soundanm == 2) - { - soundanm++; - S_PlaySound(FLY_BY); - } - } - else if (totalclock >= 395) - { - if (soundanm == 3) - { - soundanm++; - S_PlaySound(PIPEBOMB_EXPLODE); - } - rotatesprite_fs(160<<16,(151)<<16,30<<11,0,PLUTOPAKSPRITE+1,0,0,2+8); - } - } - -#ifdef LUNATIC - g_elEventError = 0; -#endif - VM_OnEvent(EVENT_LOGO, -1, screenpeek); - G_HandleAsync(); - - if (g_restorePalette) - { - P_SetGamePalette(g_player[myconnectindex].ps,g_player[myconnectindex].ps->palette,0); - g_restorePalette = 0; - } -#ifdef LUNATIC - if (g_elEventError) - break; -#endif - nextpage(); - } - } - I_ClearAllInput(); - } - - flushperms(); - clearallviews(0L); - nextpage(); - - //g_player[myconnectindex].ps->palette = palette; - P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 0); // JBF 20040308 - S_PlaySound(NITEVISION_ONOFF); - - //G_FadePalette(0,0,0,0); - clearallviews(0L); -} - static void G_FreeHashAnim(const char *UNUSED(string), intptr_t key) { Bfree((void *)key); @@ -9344,833 +6893,7 @@ int32_t G_DoMoveThings(void) return 0; } -static void G_DoOrderScreen(void) -{ - int32_t i; - setview(0,0,xdim-1,ydim-1); - - P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 1); // JBF 20040308 - - for (i=0; i<4; i++) - { - fadepal(0,0,0, 0,252,28); - I_ClearAllInput(); - rotatesprite_fs(160<<16,100<<16,65536L,0,ORDERING+i,0,0,2+8+64+BGSTRETCH); - fadepal(0,0,0, 252,0,-28); - while (!I_CheckAllInput()) - G_HandleAsync(); - } - - I_ClearAllInput(); -} - - -static void G_BonusCutscenes(void) -{ - int32_t bonuscnt=0; - int32_t t; - - int32_t breathe[] = - { - 0, 30, VICTORY1+1, 176, 59, - 30, 60, VICTORY1+2, 176, 59, - 60, 90, VICTORY1+1, 176, 59, - 90, 120, 0, 176, 59 - }; - - int32_t bossmove[] = - { - 0, 120, VICTORY1+3, 86, 59, - 220, 260, VICTORY1+4, 86, 59, - 260, 290, VICTORY1+5, 86, 59, - 290, 320, VICTORY1+6, 86, 59, - 320, 350, VICTORY1+7, 86, 59, - 350, 380, VICTORY1+8, 86, 59, - 350, 380, VICTORY1+8, 86, 59 // duplicate row to alleviate overflow in the for loop below "boss" - }; - - if (!(numplayers < 2 && ud.eog && ud.from_bonus == 0)) - return; - - switch (ud.volume_number) - { - case 0: - if ((G_GetLogoFlags() & LOGO_NOE1BONUSSCENE) && (G_GetLogoFlags() & LOGO_NOE1ENDSCREEN)) - return; - - if (ud.lockout == 0 && !(G_GetLogoFlags() & LOGO_NOE1BONUSSCENE)) - { - P_SetGamePalette(g_player[myconnectindex].ps, ENDINGPAL, 8+2+1); // JBF 20040308 - clearallviews(0L); - rotatesprite_fs(0,50<<16,65536L,0,VICTORY1,0,0,2+8+16+64+128+BGSTRETCH); - nextpage(); - fadepal(0,0,0, 252,0,-4); - - I_ClearAllInput(); - totalclock = 0; - - while (1) - { - clearallviews(0L); - rotatesprite_fs(0,50<<16,65536L,0,VICTORY1,0,0,2+8+16+64+128+BGSTRETCH); - - // boss - if (totalclock > 390 && totalclock < 780) - for (t=0; t<35; t+=5) if (bossmove[t+2] && (totalclock%390) > bossmove[t] && (totalclock%390) <= bossmove[t+1]) - { - if (t==10 && bonuscnt == 1) - { - S_PlaySound(SHOTGUN_FIRE); - S_PlaySound(SQUISHED); - bonuscnt++; - } - rotatesprite_fs(bossmove[t+3]<<16,bossmove[t+4]<<16,65536L,0,bossmove[t+2],0,0,2+8+16+64+128+BGSTRETCH); - } - - // Breathe - if (totalclock < 450 || totalclock >= 750) - { - if (totalclock >= 750) - { - rotatesprite_fs(86<<16,59<<16,65536L,0,VICTORY1+8,0,0,2+8+16+64+128+BGSTRETCH); - if (totalclock >= 750 && bonuscnt == 2) - { - S_PlaySound(DUKETALKTOBOSS); - bonuscnt++; - } - - } - for (t=0; t<20; t+=5) - if (breathe[t+2] && (totalclock%120) > breathe[t] && (totalclock%120) <= breathe[t+1]) - { - if (t==5 && bonuscnt == 0) - { - S_PlaySound(BOSSTALKTODUKE); - bonuscnt++; - } - rotatesprite_fs(breathe[t+3]<<16,breathe[t+4]<<16,65536L,0,breathe[t+2],0,0,2+8+16+64+128+BGSTRETCH); - } - } - - G_HandleAsync(); - - nextpage(); - if (I_CheckAllInput()) break; - } - - fadepal(0,0,0, 0,252,4); - } - - if (G_GetLogoFlags() & LOGO_NOE1ENDSCREEN) - goto VOL1_END; - - I_ClearAllInput(); - P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 8+2+1); // JBF 20040308 - - rotatesprite_fs(160<<16,100<<16,65536L,0,3292,0,0,2+8+64+BGSTRETCH); - fadepal(0,0,0, 252,0,-4); - G_HandleEventsWhileNoInput(); - fadepal(0,0,0, 0,252,4); - -VOL1_END: - S_StopMusic(); - FX_StopAllSounds(); - S_ClearSoundLocks(); - break; - - case 1: - if ((G_GetLogoFlags() & LOGO_NOE2BONUSSCENE) && (G_GetLogoFlags() & LOGO_NOE2ENDSCREEN)) - return; - - setview(0,0,xdim-1,ydim-1); - - S_StopMusic(); - clearallviews(0L); - nextpage(); - - if (ud.lockout == 0 && !(G_GetLogoFlags() & LOGO_NOE2BONUSSCENE)) - { - fadepal(0,0,0, 252,0,-4); - Anim_Play("cineov2.anm"); - I_ClearAllInput(); - clearallviews(0L); - nextpage(); - - S_PlaySound(PIPEBOMB_EXPLODE); - fadepal(0,0,0, 0,252,4); - } - - if (G_GetLogoFlags() & LOGO_NOE2ENDSCREEN) - return; - - I_ClearAllInput(); - P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 8+2+1); // JBF 20040308 - rotatesprite_fs(160<<16,100<<16,65536L,0,3293,0,0,2+8+64+BGSTRETCH); - fadepal(0,0,0, 252,0,-4); - G_HandleEventsWhileNoInput(); - fadepal(0,0,0, 0,252,4); - - break; - - case 3: - if ((G_GetLogoFlags() & LOGO_NOE4BONUSSCENE) && (G_GetLogoFlags() & LOGO_NODUKETEAMTEXT) && (G_GetLogoFlags() & LOGO_NODUKETEAMPIC)) - return; - - setview(0,0,xdim-1,ydim-1); - - S_StopMusic(); - clearallviews(0L); - nextpage(); - - if (ud.lockout == 0 && !(G_GetLogoFlags() & LOGO_NOE4BONUSSCENE)) - { - fadepal(0,0,0, 252,0,-4); - - I_ClearAllInput(); - t = Anim_Play("vol4e1.anm"); - clearallviews(0L); - nextpage(); - if (t) - goto end_vol4e; - - t = Anim_Play("vol4e2.anm"); - clearallviews(0L); - nextpage(); - if (t) - goto end_vol4e; - - Anim_Play("vol4e3.anm"); - clearallviews(0L); - nextpage(); - } - -end_vol4e: - if ((G_GetLogoFlags() & LOGO_NODUKETEAMTEXT) && (G_GetLogoFlags() & LOGO_NODUKETEAMPIC)) - goto VOL4_END; - - FX_StopAllSounds(); - S_ClearSoundLocks(); - S_PlaySound(ENDSEQVOL3SND4); - I_ClearAllInput(); - - if (G_GetLogoFlags() & LOGO_NODUKETEAMTEXT) - goto VOL4_DUKETEAM; - - G_FadePalette(0,0,0,0); - P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 8+2+1); // JBF 20040308 -// G_FadePalette(0,0,0,252); - clearallviews(0L); - menutext(160,60,0,0,"Thanks to all our"); - menutext(160,60+16,0,0,"fans for giving"); - menutext(160,60+16+16,0,0,"us big heads."); - menutext(160,70+16+16+16,0,0,"Look for a Duke Nukem 3D"); - menutext(160,70+16+16+16+16,0,0,"sequel soon."); - nextpage(); - - fadepal(0,0,0, 252,0,-12); - nextpage(); - I_ClearAllInput(); - G_HandleEventsWhileNoInput(); - fadepal(0,0,0, 0,252,12); - - if (G_GetLogoFlags() & LOGO_NODUKETEAMPIC) - goto VOL4_END; - -VOL4_DUKETEAM: - clearallviews(0L); - nextpage(); - - Anim_Play("DUKETEAM.ANM"); - - I_ClearAllInput(); - G_HandleEventsWhileNoInput(); - - clearallviews(0L); - nextpage(); - G_FadePalette(0,0,0,252); - -VOL4_END: - FX_StopAllSounds(); - S_ClearSoundLocks(); - I_ClearAllInput(); - - break; - - case 2: - if ((G_GetLogoFlags() & LOGO_NOE3BONUSSCENE) && (G_GetLogoFlags() & LOGO_NOE3RADLOGO) && (PLUTOPAK || (G_GetLogoFlags() & LOGO_NODUKETEAMPIC))) - return; - - S_StopMusic(); - clearallviews(0L); - nextpage(); - if (ud.lockout == 0 && !(G_GetLogoFlags() & LOGO_NOE3BONUSSCENE)) - { - fadepal(0,0,0, 252,0,-4); - Anim_Play("cineov3.anm"); - I_ClearAllInput(); - ototalclock = totalclock+200; - while (totalclock < ototalclock) - G_HandleAsync(); - clearallviews(0L); - nextpage(); - - FX_StopAllSounds(); - S_ClearSoundLocks(); - } - - if (G_GetLogoFlags() & LOGO_NOE3RADLOGO) - goto ENDANM; - - Anim_Play("RADLOGO.ANM"); - - if (ud.lockout == 0 && !I_CheckAllInput()) - { - if (G_PlaySoundWhileNoInput(ENDSEQVOL3SND5)) goto ENDANM; - if (G_PlaySoundWhileNoInput(ENDSEQVOL3SND6)) goto ENDANM; - if (G_PlaySoundWhileNoInput(ENDSEQVOL3SND7)) goto ENDANM; - if (G_PlaySoundWhileNoInput(ENDSEQVOL3SND8)) goto ENDANM; - if (G_PlaySoundWhileNoInput(ENDSEQVOL3SND9)) goto ENDANM; - } - - I_ClearAllInput(); - - totalclock = 0; - if (PLUTOPAK || (G_GetLogoFlags() & LOGO_NODUKETEAMPIC)) - { - while (totalclock < 120 && !I_CheckAllInput()) - G_HandleAsync(); - - I_ClearAllInput(); - } - else - { - G_HandleEventsWhileNoInput(); - } - -ENDANM: - if (!PLUTOPAK && !(G_GetLogoFlags() & LOGO_NODUKETEAMPIC)) - { - FX_StopAllSounds(); - S_ClearSoundLocks(); - S_PlaySound(ENDSEQVOL3SND4); - - clearallviews(0L); - nextpage(); - - Anim_Play("DUKETEAM.ANM"); - - I_ClearAllInput(); - G_HandleEventsWhileNoInput(); - - clearallviews(0L); - nextpage(); - G_FadePalette(0,0,0,252); - } - - I_ClearAllInput(); - FX_StopAllSounds(); - S_ClearSoundLocks(); - - clearallviews(0L); - - break; - } -} - -static void G_DisplayMPResultsScreen(void) -{ - int32_t i, y, t = 0; - - rotatesprite_fs(160<<16,100<<16,65536L,0,MENUSCREEN,16,0,2+8+64+BGSTRETCH); - rotatesprite_fs(160<<16,34<<16,65536L,0,INGAMEDUKETHREEDEE,0,0,10); - if (PLUTOPAK) // JBF 20030804 - rotatesprite_fs((260)<<16,36<<16,65536L,0,PLUTOPAKSPRITE+2,0,0,2+8); - gametext(160,58+2,"Multiplayer Totals",0,2+8+16); - gametext(160,58+10,MapInfo[G_LastMapInfoIndex()].name,0,2+8+16); - - gametext(160,165,"Press any key or button to continue",quotepulseshade,2+8+16); - - minitext(23,80," Name Kills",8,2+8+16+128); - for (i=0; ipalookup,2+8+16+128); - - for (y=0; yfraggedself); - minitext(92+(y*23),90+t,tempbuf,2,2+8+16+128); - xfragtotal -= g_player[y].ps->fraggedself; - } - else - { - Bsprintf(tempbuf,"%-4d",g_player[i].frags[y]); - minitext(92+(y*23),90+t,tempbuf,0,2+8+16+128); - xfragtotal += g_player[i].frags[y]; - } - } - - Bsprintf(tempbuf,"%-4d",xfragtotal); - minitext(101+(8*23),90+t,tempbuf,2,2+8+16+128); - - t += 7; - } - - for (y=0; yfraggedself; - yfragtotal += g_player[i].frags[y]; - } - Bsprintf(tempbuf,"%-4d",yfragtotal); - minitext(92+(y*23),96+(8*7),tempbuf,2,2+8+16+128); - } - - minitext(45,96+(8*7),"Deaths",8,2+8+16+128); -} - -static int32_t G_PrintTime_ClockPad(void) -{ - int32_t clockpad = 2; - int32_t ii, ij; - - for (ii=g_player[myconnectindex].ps->player_par/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++) ; - clockpad = max(clockpad,ij); - if (!(ud.volume_number == 0 && ud.last_level-1 == 7 && boardfilename[0])) - { - for (ii=MapInfo[G_LastMapInfoIndex()].partime/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++) ; - clockpad = max(clockpad,ij); - if (!NAM_WW2GI && MapInfo[G_LastMapInfoIndex()].designertime) - { - for (ii=MapInfo[G_LastMapInfoIndex()].designertime/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++) ; - clockpad = max(clockpad,ij); - } - } - if (ud.playerbest > 0) for (ii=ud.playerbest/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++) ; - clockpad = max(clockpad,ij); - - return clockpad; -} - -static const char* G_PrintTime2(int32_t time) -{ - Bsprintf(tempbuf, "%0*d:%02d", G_PrintTime_ClockPad(), time/(REALGAMETICSPERSEC*60), (time/REALGAMETICSPERSEC)%60); - return tempbuf; -} -static const char* G_PrintTime3(int32_t time) -{ - Bsprintf(tempbuf, "%0*d:%02d.%02d", G_PrintTime_ClockPad(), time/(REALGAMETICSPERSEC*60), (time/REALGAMETICSPERSEC)%60, ((time%REALGAMETICSPERSEC)*33)/10); - return tempbuf; -} - -const char* G_PrintYourTime(void) -{ - return G_PrintTime3(g_player[myconnectindex].ps->player_par); -} -const char* G_PrintParTime(void) -{ - if (ud.last_level < 1) - return ""; - return G_PrintTime2(MapInfo[G_LastMapInfoIndex()].partime); -} -const char* G_PrintDesignerTime(void) -{ - if (ud.last_level < 1) - return ""; - return G_PrintTime2(MapInfo[G_LastMapInfoIndex()].designertime); -} -const char* G_PrintBestTime(void) -{ - return G_PrintTime3(ud.playerbest); -} - -void G_BonusScreen(int32_t bonusonly) -{ - int32_t gfx_offset; - int32_t bonuscnt; - int32_t clockpad = 2; - char *lastmapname; - - if (g_networkMode == NET_DEDICATED_SERVER) - return; - - G_UpdateAppTitle(); - - if (ud.volume_number == 0 && ud.last_level == 8 && boardfilename[0]) - { - lastmapname = Bstrrchr(boardfilename,'\\'); - if (!lastmapname) lastmapname = Bstrrchr(boardfilename,'/'); - if (!lastmapname) lastmapname = boardfilename; - } - else - { - lastmapname = MapInfo[G_LastMapInfoIndex()].name; - if (!lastmapname) // this isn't right but it's better than no name at all - lastmapname = MapInfo[G_LastMapInfoIndex()].name; - } - - - fadepal(0,0,0, 0,252,28); - setview(0,0,xdim-1,ydim-1); - clearallviews(0L); - nextpage(); - flushperms(); - - FX_StopAllSounds(); - S_ClearSoundLocks(); - FX_SetReverb(0L); - CONTROL_BindsEnabled = 1; // so you can use your screenshot bind on the score screens - - if (!bonusonly) - G_BonusCutscenes(); - - P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 8+2+1); // JBF 20040308 - G_FadePalette(0,0,0,252); // JBF 20031228 - KB_FlushKeyboardQueue(); - totalclock = 0; - bonuscnt = 0; - - S_StopMusic(); - FX_StopAllSounds(); - S_ClearSoundLocks(); - - if (playerswhenstarted > 1 && (GametypeFlags[ud.coop]&GAMETYPE_SCORESHEET)) - { - clearallviews(0); - G_DisplayMPResultsScreen(); - - if (ud.config.MusicToggle) - S_PlaySound(BONUSMUSIC); - - nextpage(); - I_ClearAllInput(); - fadepal(0,0,0, 252,0,-28); - totalclock = 0; - - while (totalclock < TICRATE*10) - { - G_HandleAsync(); - - MUSIC_Update(); - - clearallviews(0); - G_DisplayMPResultsScreen(); - nextpage(); - - if (I_CheckAllInput()) - { - I_ClearAllInput(); - break; - } - } - - fadepal(0,0,0, 0,252,28); - } - - if (bonusonly || (g_netServer || ud.multimode > 1)) return; - - gfx_offset = (ud.volume_number==1) ? 5 : 0; - rotatesprite_fs(160<<16,100<<16,65536L,0,BONUSSCREEN+gfx_offset,0,0,2+8+64+128+BGSTRETCH); - - if (lastmapname) - menutext(160,20-6,0,0,lastmapname); - menutext(160,36-6,0,0,"Completed"); - - gametext(160,192,"Press any key or button to continue",quotepulseshade,2+8+16); - - if (ud.config.MusicToggle) - S_PlaySound(BONUSMUSIC); - - nextpage(); - I_ClearAllInput(); - fadepal(0,0,0, 252,0,-4); - bonuscnt = 0; - totalclock = 0; - - if (g_player[myconnectindex].ps->player_par > 0 && (g_player[myconnectindex].ps->player_par < ud.playerbest || ud.playerbest < 0)) - CONFIG_SetMapBestTime(g_loadedMapHack.md4, g_player[myconnectindex].ps->player_par); - - do - { - int32_t yy = 0, zz; - - G_HandleAsync(); - - MUSIC_Update(); - - if (g_player[myconnectindex].ps->gm&MODE_EOL) - { - clearallviews(0); - - rotatesprite_fs(160<<16,100<<16,65536L,0,BONUSSCREEN+gfx_offset,0,0,2+8+64+128+BGSTRETCH); - - if (totalclock >= 1000000000 && totalclock < 1000000320) - { - switch ((totalclock>>4)%15) - { - case 0: - if (bonuscnt == 6) - { - bonuscnt++; - S_PlaySound(SHOTGUN_COCK); - switch (rand()&3) - { - case 0: - S_PlaySound(BONUS_SPEECH1); - break; - case 1: - S_PlaySound(BONUS_SPEECH2); - break; - case 2: - S_PlaySound(BONUS_SPEECH3); - break; - case 3: - S_PlaySound(BONUS_SPEECH4); - break; - } - } - case 1: - case 4: - case 5: - rotatesprite_fs(199<<16,31<<16,65536L,0,BONUSSCREEN+3+gfx_offset,0,0,2+8+16+64+128+BGSTRETCH); - break; - case 2: - case 3: - rotatesprite_fs(199<<16,31<<16,65536L,0,BONUSSCREEN+4+gfx_offset,0,0,2+8+16+64+128+BGSTRETCH); - break; - } - } - else if (totalclock > (10240+120L)) break; - else - { - switch ((totalclock>>5)&3) - { - case 1: - case 3: - rotatesprite_fs(199<<16,31<<16,65536L,0,BONUSSCREEN+1+gfx_offset,0,0,2+8+16+64+128+BGSTRETCH); - break; - case 2: - rotatesprite_fs(199<<16,31<<16,65536L,0,BONUSSCREEN+2+gfx_offset,0,0,2+8+16+64+128+BGSTRETCH); - break; - } - } - - if (lastmapname) - menutext(160,20-6,0,0,lastmapname); - menutext(160,36-6,0,0,"Completed"); - - gametext(160,192,"Press any key or button to continue",quotepulseshade,2+8+16); - - if (totalclock > (60*3)) - { - yy = zz = 59; - - gametext(10,yy+9,"Your Time:",0,2+8+16); - - yy+=10; - if (!(ud.volume_number == 0 && ud.last_level-1 == 7 && boardfilename[0])) - { - if (MapInfo[G_LastMapInfoIndex()].partime) - { - gametext(10,yy+9,"Par Time:",0,2+8+16); - yy+=10; - } - if (!NAM_WW2GI && !DUKEBETA && MapInfo[G_LastMapInfoIndex()].designertime) - { - // EDuke 2.0 / NAM source suggests "Green Beret's Time:" - gametext(10,yy+9,"3D Realms' Time:",0,2+8+16); - yy+=10; - } - - } - if (ud.playerbest > 0) - { - gametext(10,yy+9,(g_player[myconnectindex].ps->player_par > 0 && g_player[myconnectindex].ps->player_par < ud.playerbest)?"Prev Best Time:":"Your Best Time:",0,2+8+16); - yy += 10; - } - - if (bonuscnt == 0) - bonuscnt++; - - yy = zz; - if (totalclock > (60*4)) - { - if (bonuscnt == 1) - { - bonuscnt++; - S_PlaySound(PIPEBOMB_EXPLODE); - } - - if (g_player[myconnectindex].ps->player_par > 0) - { - G_PrintYourTime(); - gametext((320>>2)+71,yy+9,tempbuf,0,2+8+16); - if (g_player[myconnectindex].ps->player_par < ud.playerbest) - gametext((320>>2)+89+(clockpad*24),yy+9,"New record!",0,2+8+16); - } - else - gametextpalbits((320>>2)+71,yy+9,"Cheated!",0,2,2+8+16,0); - yy+=10; - - if (!(ud.volume_number == 0 && ud.last_level-1 == 7 && boardfilename[0])) - { - if (MapInfo[G_LastMapInfoIndex()].partime) - { - G_PrintParTime(); - gametext((320>>2)+71,yy+9,tempbuf,0,2+8+16); - yy+=10; - } - if (!NAM_WW2GI && !DUKEBETA && MapInfo[G_LastMapInfoIndex()].designertime) - { - G_PrintDesignerTime(); - gametext((320>>2)+71,yy+9,tempbuf,0,2+8+16); - yy+=10; - } - } - - if (ud.playerbest > 0) - { - G_PrintBestTime(); - gametext((320>>2)+71,yy+9,tempbuf,0,2+8+16); - yy+=10; - } - } - } - - zz = yy += 5; - if (totalclock > (60*6)) - { - gametext(10,yy+9,"Enemies Killed:",0,2+8+16); - yy += 10; - gametext(10,yy+9,"Enemies Left:",0,2+8+16); - yy += 10; - - if (bonuscnt == 2) - { - bonuscnt++; - S_PlaySound(FLY_BY); - } - - yy = zz; - - if (totalclock > (60*7)) - { - if (bonuscnt == 3) - { - bonuscnt++; - S_PlaySound(PIPEBOMB_EXPLODE); - } - Bsprintf(tempbuf,"%-3d",g_player[myconnectindex].ps->actors_killed); - gametext((320>>2)+70,yy+9,tempbuf,0,2+8+16); - yy += 10; - if (ud.player_skill > 3) - { - Bsprintf(tempbuf,"N/A"); - gametext((320>>2)+70,yy+9,tempbuf,0,2+8+16); - yy += 10; - } - else - { - if ((g_player[myconnectindex].ps->max_actors_killed-g_player[myconnectindex].ps->actors_killed) < 0) - Bsprintf(tempbuf,"%-3d",0); - else Bsprintf(tempbuf,"%-3d",g_player[myconnectindex].ps->max_actors_killed-g_player[myconnectindex].ps->actors_killed); - gametext((320>>2)+70,yy+9,tempbuf,0,2+8+16); - yy += 10; - } - } - } - - zz = yy += 5; - if (totalclock > (60*9)) - { - gametext(10,yy+9,"Secrets Found:",0,2+8+16); - yy += 10; - gametext(10,yy+9,"Secrets Missed:",0,2+8+16); - yy += 10; - if (bonuscnt == 4) bonuscnt++; - - yy = zz; - if (totalclock > (60*10)) - { - if (bonuscnt == 5) - { - bonuscnt++; - S_PlaySound(PIPEBOMB_EXPLODE); - } - Bsprintf(tempbuf,"%-3d",g_player[myconnectindex].ps->secret_rooms); - gametext((320>>2)+70,yy+9,tempbuf,0,2+8+16); - yy += 10; - if (g_player[myconnectindex].ps->secret_rooms > 0) - Bsprintf(tempbuf,"%-3d%%",(100*g_player[myconnectindex].ps->secret_rooms/g_player[myconnectindex].ps->max_secret_rooms)); - Bsprintf(tempbuf,"%-3d",g_player[myconnectindex].ps->max_secret_rooms-g_player[myconnectindex].ps->secret_rooms); - gametext((320>>2)+70,yy+9,tempbuf,0,2+8+16); - yy += 10; - } - } - - if (totalclock > 10240 && totalclock < 10240+10240) - totalclock = 1024; - - if (I_CheckAllInput() && totalclock > (60*2)) // JBF 20030809 - { - I_ClearAllInput(); - if (totalclock < (60*13)) - { - KB_FlushKeyboardQueue(); - totalclock = (60*13); - } - else if (totalclock < 1000000000) - totalclock = 1000000000; - } - } - else - break; - - VM_OnEvent(EVENT_DISPLAYBONUSSCREEN, g_player[screenpeek].ps->i, screenpeek); - nextpage(); - } - while (1); -} - -static void G_DrawCameraText(int16_t i) -{ - if (VM_OnEvent(EVENT_DISPLAYCAMERAOSD, i, screenpeek) != 0) - return; - - if (!T1) - { - rotatesprite_win(24<<16,33<<16,65536L,0,CAMCORNER,0,0,2); - rotatesprite_win((320-26)<<16,34<<16,65536L,0,CAMCORNER+1,0,0,2); - rotatesprite_win(22<<16,163<<16,65536L,512,CAMCORNER+1,0,0,2+4); - rotatesprite_win((310-10)<<16,163<<16,65536L,512,CAMCORNER+1,0,0,2); - - if (totalclock&16) - rotatesprite_win(46<<16,32<<16,65536L,0,CAMLIGHT,0,0,2); - } - else - { - int32_t flipbits = (totalclock<<1)&48; - - for (int32_t x=-64; x<394; x+=64) - for (int32_t y=0; y<200; y+=64) - rotatesprite_win(x<<16,y<<16,65536L,0,STATIC,0,0,2+flipbits); - } -} #if 0 void vglass(int32_t x,int32_t y,short a,short wn,short n) diff --git a/polymer/eduke32/source/game.h b/polymer/eduke32/source/game.h index fe1ad989b..2ccbc14ca 100644 --- a/polymer/eduke32/source/game.h +++ b/polymer/eduke32/source/game.h @@ -276,6 +276,7 @@ extern int32_t ticrandomseed; extern int32_t vote_map; extern int32_t voting; +extern int32_t MAXCACHE1DSIZE; //extern int8_t cheatbuf[MAXCHEATLEN],cheatbuflen; #define CROSSHAIR_PAL (MAXPALOOKUPS-RESERVEDPALS-1) @@ -326,12 +327,6 @@ void G_DrawFrags(void); void G_HandleMirror(int32_t x, int32_t y, int32_t z, int32_t a, int32_t horiz, int32_t smoothratio); void G_DrawRooms(int32_t snum,int32_t smoothratio); void G_DrawTXDigiNumZ(int32_t starttile,int32_t x,int32_t y,int32_t n,int32_t s,int32_t pal,int32_t cs,int32_t x1,int32_t y1,int32_t x2,int32_t y2,int32_t z); -#if !defined LUNATIC -void G_DrawTile(int32_t x,int32_t y,int32_t tilenum,int32_t shade,int32_t orientation); -void G_DrawTilePal(int32_t x,int32_t y,int32_t tilenum,int32_t shade,int32_t orientation,int32_t p); -void G_DrawTilePalSmall(int32_t x,int32_t y,int32_t tilenum,int32_t shade,int32_t orientation,int32_t p); -void G_DrawTileSmall(int32_t x,int32_t y,int32_t tilenum,int32_t shade,int32_t orientation); -#endif void G_FadePalette(int32_t r,int32_t g,int32_t b,int32_t e); void G_GameExit(const char *t) ATTRIBUTE((noreturn)); void G_GameQuit(void); @@ -519,8 +514,6 @@ extern void G_StartMusic(void); #ifdef LUNATIC void El_SetCON(const char *conluacode); -void G_DrawTileGeneric(int32_t x, int32_t y, int32_t zoom, int32_t tilenum, - int32_t shade, int32_t orientation, int32_t p); #endif EXTERN_INLINE_HEADER void G_SetStatusBarScale(int32_t sc); diff --git a/polymer/eduke32/source/gameexec.c b/polymer/eduke32/source/gameexec.c index 5d04dc3d0..ceb93a1b9 100644 --- a/polymer/eduke32/source/gameexec.c +++ b/polymer/eduke32/source/gameexec.c @@ -2385,16 +2385,16 @@ nullquote: switch (tw) { case CON_MYOS: - G_DrawTile(pos.x, pos.y, tilenum, shade, orientation); + VM_DrawTile(pos.x, pos.y, tilenum, shade, orientation); break; case CON_MYOSPAL: - G_DrawTilePal(pos.x, pos.y, tilenum, shade, orientation, Gv_GetVarX(*insptr++)); + VM_DrawTilePal(pos.x, pos.y, tilenum, shade, orientation, Gv_GetVarX(*insptr++)); break; case CON_MYOSX: - G_DrawTileSmall(pos.x, pos.y, tilenum, shade, orientation); + VM_DrawTileSmall(pos.x, pos.y, tilenum, shade, orientation); break; case CON_MYOSPALX: - G_DrawTilePalSmall(pos.x, pos.y, tilenum, shade, orientation, Gv_GetVarX(*insptr++)); + VM_DrawTilePalSmall(pos.x, pos.y, tilenum, shade, orientation, Gv_GetVarX(*insptr++)); break; } continue; @@ -6136,3 +6136,51 @@ int32_t VM_CheckSquished2(int32_t i, int32_t snum) return VM_CheckSquished(); } #endif + +// MYOS* CON commands. +LUNATIC_EXTERN void VM_DrawTileGeneric(int32_t x, int32_t y, int32_t zoom, int32_t tilenum, + int32_t shade, int32_t orientation, int32_t p) +{ + int32_t a = 0; + + orientation &= (ROTATESPRITE_MAX-1); + + if (orientation&4) + a = 1024; + + if (!(orientation&ROTATESPRITE_FULL16)) + { + x<<=16; + y<<=16; + } + + rotatesprite_win(x, y, zoom, a, tilenum, shade, p, 2|orientation); +} + +#if !defined LUNATIC +void VM_DrawTile(int32_t x, int32_t y, int32_t tilenum, int32_t shade, int32_t orientation) +{ + DukePlayer_t *ps = g_player[screenpeek].ps; + int32_t p = ps->cursectnum >= 0 ? sector[ps->cursectnum].floorpal : 0; + + VM_DrawTileGeneric(x, y, 65536, tilenum, shade, orientation, p); +} + +void VM_DrawTilePal(int32_t x, int32_t y, int32_t tilenum, int32_t shade, int32_t orientation, int32_t p) +{ + VM_DrawTileGeneric(x, y, 65536, tilenum, shade, orientation, p); +} + +void VM_DrawTileSmall(int32_t x, int32_t y, int32_t tilenum, int32_t shade, int32_t orientation) +{ + DukePlayer_t *ps = g_player[screenpeek].ps; + int32_t p = ps->cursectnum >= 0 ? sector[ps->cursectnum].floorpal : 0; + + VM_DrawTileGeneric(x, y, 32768, tilenum, shade, orientation, p); +} + +void VM_DrawTilePalSmall(int32_t x, int32_t y, int32_t tilenum, int32_t shade, int32_t orientation, int32_t p) +{ + VM_DrawTileGeneric(x, y, 32768, tilenum, shade, orientation, p); +} +#endif diff --git a/polymer/eduke32/source/gameexec.h b/polymer/eduke32/source/gameexec.h index c6a8ef8ff..20585eb5d 100644 --- a/polymer/eduke32/source/gameexec.h +++ b/polymer/eduke32/source/gameexec.h @@ -56,6 +56,16 @@ int32_t G_GetAngleDelta(int32_t a,int32_t na); void G_RestoreMapState(); void G_SaveMapState(); +#if !defined LUNATIC +void VM_DrawTile(int32_t x, int32_t y, int32_t tilenum, int32_t shade, int32_t orientation); +void VM_DrawTilePal(int32_t x, int32_t y, int32_t tilenum, int32_t shade, int32_t orientation, int32_t p); +void VM_DrawTilePalSmall(int32_t x, int32_t y, int32_t tilenum, int32_t shade, int32_t orientation, int32_t p); +void VM_DrawTileSmall(int32_t x, int32_t y, int32_t tilenum, int32_t shade, int32_t orientation); +#else +void VM_DrawTileGeneric(int32_t x, int32_t y, int32_t zoom, int32_t tilenum, + int32_t shade, int32_t orientation, int32_t p); +#endif + int32_t VM_OnEventWithBoth_(int32_t iEventID, int32_t iActor, int32_t iPlayer, int32_t lDist, int32_t iReturn); int32_t VM_OnEventWithReturn_(int32_t iEventID, int32_t iActor, int32_t iPlayer, int32_t iReturn); int32_t VM_OnEventWithDist_(int32_t iEventID, int32_t iActor, int32_t iPlayer, int32_t lDist); diff --git a/polymer/eduke32/source/gamevars.h b/polymer/eduke32/source/gamevars.h index 9ca7e44f8..464fa9bd2 100644 --- a/polymer/eduke32/source/gamevars.h +++ b/polymer/eduke32/source/gamevars.h @@ -65,14 +65,14 @@ enum GamearrayFlags_t { GAMEARRAY_OFCHAR = 0x00000001, GAMEARRAY_OFSHORT = 0x00000002, GAMEARRAY_OFINT = 0x00000004, + GAMEARRAY_RESET = 0x00000008, GAMEARRAY_TYPE_MASK = GAMEARRAY_OFCHAR|GAMEARRAY_OFSHORT|GAMEARRAY_OFINT, + GAMEARRAY_RESTORE = 0x00000010, GAMEARRAY_VARSIZE = 0x00000020, GAMEARRAY_STRIDE2 = 0x00000100, - GAMEARRAY_RESET = 0x00000008, -/// GAMEARRAY_NORESET = 0x00000001, }; #pragma pack(push,1) diff --git a/polymer/eduke32/source/screens.c b/polymer/eduke32/source/screens.c new file mode 100644 index 000000000..7861a0f3a --- /dev/null +++ b/polymer/eduke32/source/screens.c @@ -0,0 +1,2426 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 2016 EDuke32 developers and contributors + +This file is part of EDuke32. + +EDuke32 is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 2 +as published by the Free Software Foundation. + +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ +//------------------------------------------------------------------------- + +#include "duke3d.h" +#include "compat.h" +#include "screens.h" +#include "colmatch.h" +#include "input.h" +#include "anim.h" +#include "sbar.h" +#include "menus.h" +#include "osdfuncs.h" +#include "demo.h" + +#define COLOR_RED redcol +#define COLOR_WHITE whitecol + +#define quotepulseshade (sintable[((uint32_t)totalclock<<5)&2047]>>11) + +palette_t CrosshairColors ={ 255, 255, 255, 0 }; +palette_t DefaultCrosshairColors ={ 0, 0, 0, 0 }; +int32_t g_crosshairSum = 0; +// yxaspect and viewingrange just before the 'main' drawrooms call +int32_t dr_yxaspect, dr_viewingrange; +double g_moveActorsTime = 0; // in ms, smoothed +int32_t g_noLogoAnim = 0; +int32_t g_noLogo = 0; + +////////// OFTEN-USED FEW-LINERS ////////// +static void G_HandleEventsWhileNoInput(void) +{ + I_ClearAllInput(); + + while (!I_CheckAllInput()) + G_HandleAsync(); + + I_ClearAllInput(); +} + +static int32_t G_PlaySoundWhileNoInput(int32_t soundnum) +{ + S_PlaySound(soundnum); + I_ClearAllInput(); + while (S_CheckSoundPlaying(-1, soundnum)) + { + G_HandleAsync(); + if (I_CheckAllInput()) + { + I_ClearAllInput(); + return 1; + } + } + + return 0; +} +////////// + +void P_SetGamePalette(DukePlayer_t *player, uint32_t palid, int32_t set) +{ + if (palid >= MAXBASEPALS) + palid = 0; + + player->palette = palid; + + if (player != g_player[screenpeek].ps) + return; + + setbrightness(ud.brightness>>2, palid, set); +} + +void G_GetCrosshairColor(void) +{ + // use the brightest color in the original 8-bit tile + int32_t bri = 0, j = 0, i; + int32_t ii; + char *ptr = (char *) waloff[CROSSHAIR]; + + if (DefaultCrosshairColors.f) + return; + + if (waloff[CROSSHAIR] == 0) + { + loadtile(CROSSHAIR); + ptr = (char *) waloff[CROSSHAIR]; + } + + ii = tilesiz[CROSSHAIR].x * tilesiz[CROSSHAIR].y; + + if (ii <= 0) return; + + do + { + if (*ptr != 255) + { + i = curpalette[(int32_t) *ptr].r+curpalette[(int32_t) *ptr].g+curpalette[(int32_t) *ptr].b; + if (i > j) { j = i; bri = *ptr; } + } + ptr++; + } while (--ii); + + Bmemcpy(&CrosshairColors, &curpalette[bri], sizeof(palette_t)); + Bmemcpy(&DefaultCrosshairColors, &curpalette[bri], sizeof(palette_t)); + DefaultCrosshairColors.f = 1; // this flag signifies that the color has been detected +} + +void G_SetCrosshairColor(int32_t r, int32_t g, int32_t b) +{ + int32_t i, ii; + + if (g_crosshairSum == r+(g<<8)+(b<<16)) return; + + if (!DefaultCrosshairColors.f) + G_GetCrosshairColor(); + + g_crosshairSum = r+(g<<8)+(b<<16); + CrosshairColors.r = r; + CrosshairColors.g = g; + CrosshairColors.b = b; + + char *ptr = (char *) waloff[CROSSHAIR]; + + if (waloff[CROSSHAIR] == 0) + { + loadtile(CROSSHAIR); + ptr = (char *) waloff[CROSSHAIR]; + } + + ii = tilesiz[CROSSHAIR].x * tilesiz[CROSSHAIR].y; + if (ii <= 0) return; + + if (getrendermode() == REND_CLASSIC) + i = getclosestcol(CrosshairColors.r, CrosshairColors.g, CrosshairColors.b); + else i = getclosestcol(255, 255, 255); // use white in GL so we can tint it to the right color + + do + { + if (*ptr != 255) + *ptr = i; + ptr++; + } while (--ii); + + makepalookup(CROSSHAIR_PAL, NULL, CrosshairColors.r, CrosshairColors.g, CrosshairColors.b, 1); + +#ifdef USE_OPENGL + // XXX: this makes us also load all hightile textures tinted with the crosshair color! + Bmemcpy(&hictinting[CROSSHAIR_PAL], &CrosshairColors, sizeof(palette_t)); + hictinting[CROSSHAIR_PAL].f = HICTINT_USEONART | HICTINT_GRAYSCALE; +#endif + invalidatetile(CROSSHAIR, -1, -1); +} + +#define SCORESHEETOFFSET -20 +static void G_ShowScores(void) +{ + int32_t t, i; + + if (playerswhenstarted > 1 && (GametypeFlags[ud.coop]&GAMETYPE_SCORESHEET)) + { + gametext(160, SCORESHEETOFFSET+58+2, "Multiplayer Totals", 0, 2+8+16); + gametext(160, SCORESHEETOFFSET+58+10, MapInfo[G_LastMapInfoIndex()].name, 0, 2+8+16); + + t = 0; + minitext(70, SCORESHEETOFFSET+80, "Name", 8, 2+8+16+ROTATESPRITE_MAX); + minitext(170, SCORESHEETOFFSET+80, "Frags", 8, 2+8+16+ROTATESPRITE_MAX); + minitext(200, SCORESHEETOFFSET+80, "Deaths", 8, 2+8+16+ROTATESPRITE_MAX); + minitext(235, SCORESHEETOFFSET+80, "Ping", 8, 2+8+16+ROTATESPRITE_MAX); + + for (i=playerswhenstarted-1; i>=0; i--) + { + if (!g_player[i].playerquitflag) + continue; + + minitext(70, SCORESHEETOFFSET+90+t, g_player[i].user_name, g_player[i].ps->palookup, 2+8+16+ROTATESPRITE_MAX); + + Bsprintf(tempbuf, "%-4d", g_player[i].ps->frag); + minitext(170, SCORESHEETOFFSET+90+t, tempbuf, 2, 2+8+16+ROTATESPRITE_MAX); + + Bsprintf(tempbuf, "%-4d", g_player[i].frags[i] + g_player[i].ps->fraggedself); + minitext(200, SCORESHEETOFFSET+90+t, tempbuf, 2, 2+8+16+ROTATESPRITE_MAX); + + Bsprintf(tempbuf, "%-4d", g_player[i].ping); + minitext(235, SCORESHEETOFFSET+90+t, tempbuf, 2, 2+8+16+ROTATESPRITE_MAX); + + t += 7; + } + } +} +#undef SCORESHEETOFFSET + +////////// TINT ACCUMULATOR ////////// + +typedef struct { + int32_t r, g, b; + // f: 0-63 scale + int32_t maxf, sumf; +} palaccum_t; + +#define PALACCUM_INITIALIZER { 0, 0, 0, 0, 0 } + +/* For a picture frame F and n tints C_1, C_2, ... C_n weighted a_1, a_2, +* ... a_n (on a 0-1 scale), the faded frame is calculated as +* +* F_new := (1-max_i(a_i))*F + d*sum_i(a_i), where +* +* d := max_i(a_i)/sum_i(a_i). +* +* This means that +* 1) tint application is independent of their order. +* 2) going from n+1 to n tints is continuous when the leaving one has faded. +* +* But note that for more than one tint, the composite tint will in general +* change its hue as the ratio of the weights of the individual ones changes. +*/ +static void palaccum_add(palaccum_t *pa, const palette_t *pal, int32_t f) +{ + f = clamp(f, 0, 63); + if (f == 0) + return; + + pa->maxf = max(pa->maxf, f); + pa->sumf += f; + + pa->r += f*clamp(pal->r, 0, 63); + pa->g += f*clamp(pal->g, 0, 63); + pa->b += f*clamp(pal->b, 0, 63); +} + +static void G_FadePalaccum(const palaccum_t *pa) +{ + setpalettefade(tabledivide32_noinline(pa->r, pa->sumf)<<2, + tabledivide32_noinline(pa->g, pa->sumf)<<2, + tabledivide32_noinline(pa->b, pa->sumf)<<2, pa->maxf<<2); +} + + +static int32_t gtextsc(int32_t sc) +{ + return scale(sc, ud.textscale, 400); +} + +////////// DISPLAYREST ////////// + +static void G_DrawCameraText(int16_t i) +{ + if (VM_OnEvent(EVENT_DISPLAYCAMERAOSD, i, screenpeek) != 0) + return; + + if (!T1) + { + rotatesprite_win(24<<16, 33<<16, 65536L, 0, CAMCORNER, 0, 0, 2); + rotatesprite_win((320-26)<<16, 34<<16, 65536L, 0, CAMCORNER+1, 0, 0, 2); + rotatesprite_win(22<<16, 163<<16, 65536L, 512, CAMCORNER+1, 0, 0, 2+4); + rotatesprite_win((310-10)<<16, 163<<16, 65536L, 512, CAMCORNER+1, 0, 0, 2); + + if (totalclock&16) + rotatesprite_win(46<<16, 32<<16, 65536L, 0, CAMLIGHT, 0, 0, 2); + } + else + { + int32_t flipbits = (totalclock<<1)&48; + + for (int32_t x=-64; x<394; x+=64) + for (int32_t y=0; y<200; y+=64) + rotatesprite_win(x<<16, y<<16, 65536L, 0, STATIC, 0, 0, 2+flipbits); + } +} + +static inline void G_MoveClouds(void) +{ + int32_t i; + + if (totalclock <= cloudtotalclock && totalclock >= (cloudtotalclock-7)) + return; + + cloudtotalclock = totalclock+6; + + cloudx += sintable[(g_player[screenpeek].ps->ang+512)&2047]>>9; + cloudy += sintable[g_player[screenpeek].ps->ang&2047]>>9; + + for (i=g_numClouds-1; i>=0; i--) + { + sector[clouds[i]].ceilingxpanning = cloudx>>6; + sector[clouds[i]].ceilingypanning = cloudy>>6; + } +} + +static void G_DrawOverheadMap(int32_t cposx, int32_t cposy, int32_t czoom, int16_t cang) +{ + int32_t i, j, k, l, x1, y1, x2=0, y2=0, x3, y3, x4, y4, ox, oy, xoff, yoff; + int32_t dax, day, cosang, sinang, xspan, yspan, sprx, spry; + int32_t xrepeat, yrepeat, z1, z2, startwall, endwall, tilenum, daang; + int32_t xvect, yvect, xvect2, yvect2; + int16_t p; + char col; + walltype *wal, *wal2; + spritetype *spr; + + int32_t tmpydim = (xdim*5)/8; + + setaspect(65536, divscale16(tmpydim*320, xdim*200)); + + xvect = sintable[(-cang)&2047] * czoom; + yvect = sintable[(1536-cang)&2047] * czoom; + xvect2 = mulscale16(xvect, yxaspect); + yvect2 = mulscale16(yvect, yxaspect); + + push_nofog(); + + //Draw red lines + for (i=numsectors-1; i>=0; i--) + { + if (!(show2dsector[i>>3]&(1<<(i&7)))) continue; + + startwall = sector[i].wallptr; + endwall = sector[i].wallptr + sector[i].wallnum; + + z1 = sector[i].ceilingz; + z2 = sector[i].floorz; + + for (j=startwall, wal=&wall[startwall]; jnextwall; + if (k < 0) continue; + + if (sector[wal->nextsector].ceilingz == z1) + if (sector[wal->nextsector].floorz == z2) + if (((wal->cstat|wall[wal->nextwall].cstat)&(16+32)) == 0) continue; + + col = 139; //red + if ((wal->cstat|wall[wal->nextwall].cstat)&1) col = 234; //magenta + + if (!(show2dsector[wal->nextsector>>3]&(1<<(wal->nextsector&7)))) + col = 24; + else continue; + + ox = wal->x-cposx; + oy = wal->y-cposy; + x1 = dmulscale16(ox, xvect, -oy, yvect)+(xdim<<11); + y1 = dmulscale16(oy, xvect2, ox, yvect2)+(ydim<<11); + + wal2 = &wall[wal->point2]; + ox = wal2->x-cposx; + oy = wal2->y-cposy; + x2 = dmulscale16(ox, xvect, -oy, yvect)+(xdim<<11); + y2 = dmulscale16(oy, xvect2, ox, yvect2)+(ydim<<11); + + drawline256(x1, y1, x2, y2, col); + } + } + + pop_nofog(); + + //Draw sprites + k = g_player[screenpeek].ps->i; + for (i=numsectors-1; i>=0; i--) + { + if (!(show2dsector[i>>3]&(1<<(i&7)))) continue; + for (j=headspritesect[i]; j>=0; j=nextspritesect[j]) + { + spr = &sprite[j]; + + if (j == k || (spr->cstat&0x8000) || spr->cstat == 257 || spr->xrepeat == 0) continue; + + col = 71; //cyan + if (spr->cstat&1) col = 234; //magenta + + sprx = spr->x; + spry = spr->y; + + if ((spr->cstat&257) != 0) switch (spr->cstat&48) + { + case 0: + // break; + + ox = sprx-cposx; + oy = spry-cposy; + x1 = dmulscale16(ox, xvect, -oy, yvect); + y1 = dmulscale16(oy, xvect2, ox, yvect2); + + ox = (sintable[(spr->ang+512)&2047]>>7); + oy = (sintable[(spr->ang)&2047]>>7); + x2 = dmulscale16(ox, xvect, -oy, yvect); + y2 = dmulscale16(oy, xvect, ox, yvect); + + x3 = mulscale16(x2, yxaspect); + y3 = mulscale16(y2, yxaspect); + + drawline256(x1-x2+(xdim<<11), y1-y3+(ydim<<11), + x1+x2+(xdim<<11), y1+y3+(ydim<<11), col); + drawline256(x1-y2+(xdim<<11), y1+x3+(ydim<<11), + x1+x2+(xdim<<11), y1+y3+(ydim<<11), col); + drawline256(x1+y2+(xdim<<11), y1-x3+(ydim<<11), + x1+x2+(xdim<<11), y1+y3+(ydim<<11), col); + break; + + case 16: + if (spr->picnum == LASERLINE) + { + x1 = sprx; + y1 = spry; + tilenum = spr->picnum; + xoff = picanm[tilenum].xofs + spr->xoffset; + if ((spr->cstat&4) > 0) xoff = -xoff; + k = spr->ang; + l = spr->xrepeat; + dax = sintable[k&2047]*l; + day = sintable[(k+1536)&2047]*l; + l = tilesiz[tilenum].x; + k = (l>>1)+xoff; + x1 -= mulscale16(dax, k); + x2 = x1+mulscale16(dax, l); + y1 -= mulscale16(day, k); + y2 = y1+mulscale16(day, l); + + ox = x1-cposx; + oy = y1-cposy; + x1 = dmulscale16(ox, xvect, -oy, yvect); + y1 = dmulscale16(oy, xvect2, ox, yvect2); + + ox = x2-cposx; + oy = y2-cposy; + x2 = dmulscale16(ox, xvect, -oy, yvect); + y2 = dmulscale16(oy, xvect2, ox, yvect2); + + drawline256(x1+(xdim<<11), y1+(ydim<<11), + x2+(xdim<<11), y2+(ydim<<11), col); + } + + break; + + case 32: + tilenum = spr->picnum; + xoff = picanm[tilenum].xofs + spr->xoffset; + yoff = picanm[tilenum].yofs + spr->yoffset; + if ((spr->cstat&4) > 0) xoff = -xoff; + if ((spr->cstat&8) > 0) yoff = -yoff; + + k = spr->ang; + cosang = sintable[(k+512)&2047]; + sinang = sintable[k&2047]; + xspan = tilesiz[tilenum].x; + xrepeat = spr->xrepeat; + yspan = tilesiz[tilenum].y; + yrepeat = spr->yrepeat; + + dax = ((xspan>>1)+xoff)*xrepeat; + day = ((yspan>>1)+yoff)*yrepeat; + x1 = sprx + dmulscale16(sinang, dax, cosang, day); + y1 = spry + dmulscale16(sinang, day, -cosang, dax); + l = xspan*xrepeat; + x2 = x1 - mulscale16(sinang, l); + y2 = y1 + mulscale16(cosang, l); + l = yspan*yrepeat; + k = -mulscale16(cosang, l); + x3 = x2+k; + x4 = x1+k; + k = -mulscale16(sinang, l); + y3 = y2+k; + y4 = y1+k; + + ox = x1-cposx; + oy = y1-cposy; + x1 = dmulscale16(ox, xvect, -oy, yvect); + y1 = dmulscale16(oy, xvect2, ox, yvect2); + + ox = x2-cposx; + oy = y2-cposy; + x2 = dmulscale16(ox, xvect, -oy, yvect); + y2 = dmulscale16(oy, xvect2, ox, yvect2); + + ox = x3-cposx; + oy = y3-cposy; + x3 = dmulscale16(ox, xvect, -oy, yvect); + y3 = dmulscale16(oy, xvect2, ox, yvect2); + + ox = x4-cposx; + oy = y4-cposy; + x4 = dmulscale16(ox, xvect, -oy, yvect); + y4 = dmulscale16(oy, xvect2, ox, yvect2); + + drawline256(x1+(xdim<<11), y1+(ydim<<11), + x2+(xdim<<11), y2+(ydim<<11), col); + + drawline256(x2+(xdim<<11), y2+(ydim<<11), + x3+(xdim<<11), y3+(ydim<<11), col); + + drawline256(x3+(xdim<<11), y3+(ydim<<11), + x4+(xdim<<11), y4+(ydim<<11), col); + + drawline256(x4+(xdim<<11), y4+(ydim<<11), + x1+(xdim<<11), y1+(ydim<<11), col); + + break; + } + } + } + + push_nofog(); + + //Draw white lines + for (i=numsectors-1; i>=0; i--) + { + if (!(show2dsector[i>>3]&(1<<(i&7)))) continue; + + startwall = sector[i].wallptr; + endwall = sector[i].wallptr + sector[i].wallnum; + + k = -1; + for (j=startwall, wal=&wall[startwall]; jnextwall >= 0) continue; + + if (tilesiz[wal->picnum].x == 0) continue; + if (tilesiz[wal->picnum].y == 0) continue; + + if (j == k) + { + x1 = x2; + y1 = y2; + } + else + { + ox = wal->x-cposx; + oy = wal->y-cposy; + x1 = dmulscale16(ox, xvect, -oy, yvect)+(xdim<<11); + y1 = dmulscale16(oy, xvect2, ox, yvect2)+(ydim<<11); + } + + k = wal->point2; + wal2 = &wall[k]; + ox = wal2->x-cposx; + oy = wal2->y-cposy; + x2 = dmulscale16(ox, xvect, -oy, yvect)+(xdim<<11); + y2 = dmulscale16(oy, xvect2, ox, yvect2)+(ydim<<11); + + drawline256(x1, y1, x2, y2, 24); + } + } + + pop_nofog(); + + setaspect_new(); + + for (TRAVERSE_CONNECT(p)) + { + if (ud.scrollmode && p == screenpeek) continue; + + ox = sprite[g_player[p].ps->i].x-cposx; + oy = sprite[g_player[p].ps->i].y-cposy; + daang = (sprite[g_player[p].ps->i].ang-cang)&2047; + if (p == screenpeek) + { + ox = 0; + oy = 0; + daang = 0; + } + x1 = mulscale(ox, xvect, 16) - mulscale(oy, yvect, 16); + y1 = mulscale(oy, xvect2, 16) + mulscale(ox, yvect2, 16); + + if (p == screenpeek || GTFLAGS(GAMETYPE_OTHERPLAYERSINMAP)) + { + if (sprite[g_player[p].ps->i].xvel > 16 && g_player[p].ps->on_ground) + i = APLAYERTOP+((totalclock>>4)&3); + else + i = APLAYERTOP; + + j = klabs(g_player[p].ps->truefz-g_player[p].ps->pos.z)>>8; + j = mulscale(czoom*(sprite[g_player[p].ps->i].yrepeat+j), yxaspect, 16); + + if (j < 22000) j = 22000; + else if (j >(65536<<1)) j = (65536<<1); + + rotatesprite_win((x1<<4)+(xdim<<15), (y1<<4)+(ydim<<15), j, daang, i, sprite[g_player[p].ps->i].shade, + (g_player[p].ps->cursectnum > -1) ? sector[g_player[p].ps->cursectnum].floorpal : 0, 0); + } + } +} + +#define printcoordsline(fmt, ...) do { \ + Bsprintf(tempbuf, fmt, ## __VA_ARGS__); \ + printext256(20, y+=9, COLOR_WHITE, -1, tempbuf, 0); \ +} while (0) + +static void G_PrintCoords(int32_t snum) +{ + const int32_t x = 250; + int32_t y = 16; + + const DukePlayer_t *ps = g_player[snum].ps; + const int32_t sectnum = ps->cursectnum; + + if ((GametypeFlags[ud.coop] & GAMETYPE_FRAGBAR)) + { + if (ud.multimode > 4) + y = 32; + else if (g_netServer || ud.multimode > 1) + y = 24; + } + Bsprintf(tempbuf, "XYZ= (%d, %d, %d)", ps->pos.x, ps->pos.y, ps->pos.z); + printext256(x, y, COLOR_WHITE, -1, tempbuf, 0); + Bsprintf(tempbuf, "A/H/HO= %d, %d, %d", ps->ang, ps->horiz, ps->horizoff); + printext256(x, y+9, COLOR_WHITE, -1, tempbuf, 0); + Bsprintf(tempbuf, "VEL= (%d, %d, %d) + (%d, %d, 0)", + ps->vel.x>>14, ps->vel.y>>14, ps->vel.z, ps->fric.x>>5, ps->fric.y>>5); + printext256(x, y+18, COLOR_WHITE, -1, tempbuf, 0); + Bsprintf(tempbuf, "OG= %d SBRIDGE=%d SBS=%d", ps->on_ground, ps->spritebridge, ps->sbs); + printext256(x, y+27, COLOR_WHITE, -1, tempbuf, 0); + if (sectnum >= 0) + Bsprintf(tempbuf, "SECT= %d (LO=%d EX=%d)", sectnum, + TrackerCast(sector[sectnum].lotag), TrackerCast(sector[sectnum].extra)); + else + Bsprintf(tempbuf, "SECT= %d", sectnum); + printext256(x, y+36, COLOR_WHITE, -1, tempbuf, 0); + // Bsprintf(tempbuf,"SEED= %d",randomseed); + // printext256(x,y+45,COLOR_WHITE,-1,tempbuf,0); + y -= 9; + + y += 7; + Bsprintf(tempbuf, "THOLD= %d", ps->transporter_hold); + printext256(x, y+54, COLOR_WHITE, -1, tempbuf, 0); + Bsprintf(tempbuf, "GAMETIC= %d, TOTALCLOCK=%d", g_moveThingsCount, totalclock); + printext256(x, y+63, COLOR_WHITE, -1, tempbuf, 0); +#ifdef DEBUGGINGAIDS + Bsprintf(tempbuf, "NUMSPRITES= %d", Numsprites); + printext256(x, y+72, COLOR_WHITE, -1, tempbuf, 0); + if (g_moveThingsCount > g_spriteStat.lastgtic + REALGAMETICSPERSEC) + { + g_spriteStat.lastgtic = g_moveThingsCount; + g_spriteStat.lastnumins = g_spriteStat.numins; + g_spriteStat.numins = 0; + } + Bsprintf(tempbuf, "INSERTIONS/s= %u", g_spriteStat.lastnumins); + printext256(x, y+81, COLOR_WHITE, -1, tempbuf, 0); + Bsprintf(tempbuf, "ONSCREEN= %d", g_spriteStat.numonscreen); + printext256(x, y+90, COLOR_WHITE, -1, tempbuf, 0); + y += 3*9; +#endif + y += 7; + Bsprintf(tempbuf, "VR=%.03f YX=%.03f", (double) dr_viewingrange/65536.0, (double) dr_yxaspect/65536.0); + printext256(x, y+72, COLOR_WHITE, -1, tempbuf, 0); + Bsprintf(tempbuf, "MOVEACTORS [ms]= %.3e", g_moveActorsTime); + printext256(x, y+81, COLOR_WHITE, -1, tempbuf, 0); + +#ifdef USE_OPENGL + if (ud.coords == 2) + { + y=16; + + printcoordsline("rendmode = %d", getrendermode()); + printcoordsline("r_ambientlight = %.03f", r_ambientlight); + + if (rendmode >= 3) + { + if (rendmode==3) + printcoordsline("r_usenewshading = %d", r_usenewshading); +# ifdef POLYMER + else + printcoordsline("r_pr_artmapping = %d", pr_artmapping); +#endif + printcoordsline("r_usetileshades = %d", r_usetileshades); + } + } +#endif +} + +#if !defined DEBUG_ALLOCACHE_AS_MALLOC +extern int32_t cacnum; +extern cactype cac []; +#endif + +static void G_ShowCacheLocks(void) +{ + int16_t i, k; + + if (offscreenrendering) + return; + + k = 0; +#if !defined DEBUG_ALLOCACHE_AS_MALLOC + for (i=cacnum-1; i>=0; i--) + if ((*cac[i].lock) >= 200) + { + if (k >= ydim-12) + break; + + Bsprintf(tempbuf, "Locked- %d: Leng:%d, Lock:%d", i, cac[i].leng, *cac[i].lock); + printext256(0L, k, COLOR_WHITE, -1, tempbuf, 1); + k += 6; + } +#endif + if (k < ydim-12) + k += 6; + + for (i=10; i>=0; i--) + if (rts_lumplockbyte[i] >= 200) + { + if (k >= ydim-12) + break; + + Bsprintf(tempbuf, "RTS Locked %d:", i); + printext256(0, k, COLOR_WHITE, -1, tempbuf, 1); + k += 6; + } + + if (k >= ydim-12 && k 0) + { + int32_t j, n=g_sounds[i].num; + + for (j=0; j= ydim-12) + break; + + Bsprintf(tempbuf, "snd #%d inst %d: voice %d, ow %d", i, j, + g_sounds[i].SoundOwner[j].voice, g_sounds[i].SoundOwner[j].ow); + printext256(240, k, COLOR_WHITE, -1, tempbuf, 0); + + k += 9; + } + } +} + +#define LOW_FPS 30 + +#if defined GEKKO +# define FPS_YOFFSET 16 +#else +# define FPS_YOFFSET 0 +#endif + +static void G_PrintFPS(void) +{ + // adapted from ZDoom because I like it better than what we had + // applicable ZDoom code available under GPL from csDoom + static int32_t FrameCount = 0, LastCount = 0, LastSec = 0, LastMS = 0; + static int32_t MinFrames = INT32_MAX, MaxFrames = 0; + + int32_t ms = getticks(); + int32_t howlong = ms - LastMS; + + if (g_player[0].ps->player_par < 2) + { + MinFrames = INT32_MAX; + MaxFrames = 0; + } + + if (howlong >= 0) + { + int32_t thisSec = ms/1000; + int32_t x = (xdim <= 640); + + if (ud.tickrate) + { + int32_t chars = Bsprintf(tempbuf, "%d ms (%3u fps)", howlong, LastCount); + + printext256(windowx2-(chars<<(3-x))+1, windowy1+2+FPS_YOFFSET, 0, -1, tempbuf, x); + printext256(windowx2-(chars<<(3-x)), windowy1+1+FPS_YOFFSET, + (LastCount < LOW_FPS) ? COLOR_RED : COLOR_WHITE, -1, tempbuf, x); + + if (ud.tickrate > 1) + { + chars = Bsprintf(tempbuf, "max fps: %3u", MaxFrames); + + printext256(windowx2-(chars<<(3-x))+1, windowy1+10+2+FPS_YOFFSET, 0, -1, tempbuf, x); + printext256(windowx2-(chars<<(3-x)), windowy1+10+FPS_YOFFSET, + (MaxFrames < LOW_FPS) ? COLOR_RED : COLOR_WHITE, -1, tempbuf, x); + + chars = Bsprintf(tempbuf, "min fps: %3u", MinFrames); + + printext256(windowx2-(chars<<(3-x))+1, windowy1+20+2+FPS_YOFFSET, 0, -1, tempbuf, x); + printext256(windowx2-(chars<<(3-x)), windowy1+20+FPS_YOFFSET, + (MinFrames < LOW_FPS) ? COLOR_RED : COLOR_WHITE, -1, tempbuf, x); + } + + // lag meter + if (g_netClientPeer) + { + chars = Bsprintf(tempbuf, "%d +- %d ms", (g_netClientPeer->lastRoundTripTime + g_netClientPeer->roundTripTime)/2, + (g_netClientPeer->lastRoundTripTimeVariance + g_netClientPeer->roundTripTimeVariance)/2); + + printext256(windowx2-(chars<<(3-x))+1, windowy1+30+2+FPS_YOFFSET, 0, -1, tempbuf, x); + printext256(windowx2-(chars<<(3-x)), windowy1+30+1+FPS_YOFFSET, g_netClientPeer->lastRoundTripTime > 200 ? COLOR_RED : COLOR_WHITE, -1, tempbuf, x); + } + } + + if (thisSec - LastSec) + { + g_currentFrameRate = LastCount = tabledivide32_noinline(FrameCount, thisSec - LastSec); + LastSec = thisSec; + FrameCount = 0; + + if (!osdshown) + { + if (LastCount > MaxFrames) MaxFrames = LastCount; + if (LastCount < MinFrames) MinFrames = LastCount; + } + } + FrameCount++; + } + LastMS = ms; +} + +void G_DisplayRest(int32_t smoothratio) +{ + int32_t i, j; + palaccum_t tint = PALACCUM_INITIALIZER; + + DukePlayer_t *const pp = g_player[screenpeek].ps; +#ifdef SPLITSCREEN_MOD_HACKS + DukePlayer_t *const pp2 = g_fakeMultiMode==2 ? g_player[1].ps : NULL; +#endif + int32_t cposx, cposy, cang; + +#ifdef USE_OPENGL + // this takes care of fullscreen tint for OpenGL + if (getrendermode() >= REND_POLYMOST) + { + if (pp->palette == WATERPAL) + { + static const palette_t wp ={ 224, 192, 255, 0 }; + Bmemcpy(&hictinting[MAXPALOOKUPS-1], &wp, sizeof(palette_t)); + } + else if (pp->palette == SLIMEPAL) + { + static const palette_t sp ={ 208, 255, 192, 0 }; + Bmemcpy(&hictinting[MAXPALOOKUPS-1], &sp, sizeof(palette_t)); + } + else + { + hictinting[MAXPALOOKUPS-1].r = 255; + hictinting[MAXPALOOKUPS-1].g = 255; + hictinting[MAXPALOOKUPS-1].b = 255; + } + } +#endif // USE_OPENGL + + palaccum_add(&tint, &pp->pals, pp->pals.f); +#ifdef SPLITSCREEN_MOD_HACKS + if (pp2) + palaccum_add(&tint, &pp2->pals, pp2->pals.f); +#endif + { + static const palette_t loogiepal ={ 0, 63, 0, 0 }; + + palaccum_add(&tint, &loogiepal, pp->loogcnt>>1); +#ifdef SPLITSCREEN_MOD_HACKS + if (pp2) + palaccum_add(&tint, &loogiepal, pp2->loogcnt>>1); +#endif + } + + if (g_restorePalette) + { + // reset a normal palette + static uint32_t omovethingscnt; + + if (g_restorePalette < 2 || omovethingscnt+1 == g_moveThingsCount) + { + int32_t pal = pp->palette; +#ifdef SPLITSCREEN_MOD_HACKS + const int32_t opal = pal; + + if (pp2) // splitscreen HACK: BASEPAL trumps all, then it's arbitrary. + pal = min(pal, pp2->palette); +#endif + + // g_restorePalette < 0: reset tinting, too (e.g. when loading new game) + P_SetGamePalette(pp, pal, 2 + (g_restorePalette>0)*16); + +#ifdef SPLITSCREEN_MOD_HACKS + if (pp2) // keep first player's pal as its member! + pp->palette = opal; +#endif + + g_restorePalette = 0; + } + else + { + // delay setting the palette by one game tic + omovethingscnt = g_moveThingsCount; + } + } + + if (ud.show_help) + { + switch (ud.show_help) + { + case 1: + rotatesprite_fs(160<<16, 100<<16, 65536L, 0, TEXTSTORY, 0, 0, 10+64); + break; + case 2: + rotatesprite_fs(160<<16, 100<<16, 65536L, 0, F1HELP, 0, 0, 10+64); + break; + } + + if (I_ReturnTrigger()) + { + I_ReturnTriggerClear(); + ud.show_help = 0; + if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2) + { + ready2send = 1; + totalclock = ototalclock; + } + G_UpdateScreenArea(); + } + + return; + } + + i = pp->cursectnum; + if (i > -1) + { + const walltype *wal = &wall[sector[i].wallptr]; + + show2dsector[i>>3] |= (1<<(i&7)); + for (j=sector[i].wallnum; j>0; j--, wal++) + { + i = wal->nextsector; + if (i < 0) continue; + if (wal->cstat&0x0071) continue; + if (wall[wal->nextwall].cstat&0x0071) continue; + if (sector[i].lotag == 32767) continue; + if (sector[i].ceilingz >= sector[i].floorz) continue; + show2dsector[i>>3] |= (1<<(i&7)); + } + } + + if (ud.camerasprite == -1) + { + if (ud.overhead_on != 2) + { + if (pp->newowner >= 0) + G_DrawCameraText(pp->newowner); + else + { + P_DisplayWeapon(); +#ifdef SPLITSCREEN_MOD_HACKS + if (pp2) // HACK + { + const int32_t oscreenpeek = screenpeek; + screenpeek = 1; + P_DisplayWeapon(); + screenpeek = oscreenpeek; + } +#endif + + if (pp->over_shoulder_on == 0) + P_DisplayScuba(); +#ifdef SPLITSCREEN_MOD_HACKS + if (pp2 && pp2->over_shoulder_on == 0) // HACK + { + const int32_t oscreenpeek = screenpeek; + screenpeek = 1; + P_DisplayScuba(); + screenpeek = oscreenpeek; + } +#endif + } + G_MoveClouds(); + } + + if (ud.overhead_on > 0) + { + // smoothratio = min(max(smoothratio,0),65536); + smoothratio = calc_smoothratio(totalclock, ototalclock); + G_DoInterpolations(smoothratio); + + if (ud.scrollmode == 0) + { + if (pp->newowner == -1 && !ud.pause_on) + { + cposx = pp->opos.x + mulscale16(pp->pos.x-pp->opos.x, smoothratio); + cposy = pp->opos.y + mulscale16(pp->pos.y-pp->opos.y, smoothratio); + cang = pp->oang + mulscale16(((pp->ang+1024-pp->oang)&2047)-1024, smoothratio); + } + else + { + cposx = pp->opos.x; + cposy = pp->opos.y; + cang = pp->oang; + } + } + else + { +#ifdef __ANDROID__ + CONTROL_Android_ScrollMap(&ud.fola, &ud.folx, &ud.foly, &pp->zoom); +#else + if (!ud.pause_on) + { + ud.fola += ud.folavel>>3; + ud.folx += (ud.folfvel*sintable[(512+2048-ud.fola)&2047])>>14; + ud.foly += (ud.folfvel*sintable[(512+1024-512-ud.fola)&2047])>>14; + } +#endif + cposx = ud.folx; + cposy = ud.foly; + cang = ud.fola; + } + + if (ud.overhead_on == 2) + { + clearview(0L); + drawmapview(cposx, cposy, pp->zoom, cang); + } + G_DrawOverheadMap(cposx, cposy, pp->zoom, cang); + + G_RestoreInterpolations(); + + if (ud.overhead_on == 2) + { + const int32_t a = (ud.screen_size > 0) ? 147 : 179; + minitext(5, a+6, EpisodeNames[ud.volume_number], 0, 2+8+16+256); + minitext(5, a+6+6, MapInfo[ud.volume_number*MAXLEVELS + ud.level_number].name, 0, 2+8+16+256); + } + } + } + + if (pp->invdisptime > 0) G_DrawInventory(pp); + + if (VM_OnEvent(EVENT_DISPLAYSBAR, g_player[screenpeek].ps->i, screenpeek) == 0) + G_DrawStatusBar(screenpeek); + +#ifdef SPLITSCREEN_MOD_HACKS + // HACK + if (g_fakeMultiMode==2) + { + G_DrawStatusBar(1); + G_PrintGameQuotes(1); + } +#endif + + G_PrintGameQuotes(screenpeek); + + if (ud.show_level_text && hud_showmapname && g_levelTextTime > 1) + { + int32_t bits = 10+16; + + if (g_levelTextTime < 3) + bits |= 1+32; + else if (g_levelTextTime < 5) + bits |= 1; + + if (MapInfo[(ud.volume_number*MAXLEVELS) + ud.level_number].name != NULL) + { + if (currentboardfilename[0] != 0 && ud.volume_number == 0 && ud.level_number == 7) + menutext_(160, 90+16+8, -g_levelTextTime+22/*quotepulseshade*/, 0, currentboardfilename, bits); + else menutext_(160, 90+16+8, -g_levelTextTime+22/*quotepulseshade*/, 0, MapInfo[(ud.volume_number*MAXLEVELS) + ud.level_number].name, bits); + } + } + + if (I_EscapeTrigger() && ud.overhead_on == 0 + && ud.show_help == 0 + && g_player[myconnectindex].ps->newowner == -1) + { + if ((g_player[myconnectindex].ps->gm&MODE_MENU) == MODE_MENU && g_currentMenu <= MENU_MAIN_INGAME) + { + I_EscapeTriggerClear(); + S_PlaySound(EXITMENUSOUND); + M_ChangeMenu(MENU_CLOSE); + S_PauseSounds(0); + } + else if ((g_player[myconnectindex].ps->gm&MODE_MENU) != MODE_MENU && + g_player[myconnectindex].ps->newowner == -1 && + (g_player[myconnectindex].ps->gm&MODE_TYPE) != MODE_TYPE) + { + I_EscapeTriggerClear(); + S_PauseSounds(1); + S_MenuSound(); + + M_OpenMenu(myconnectindex); + + if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2) ready2send = 0; + + if (g_player[myconnectindex].ps->gm&MODE_GAME) M_ChangeMenu(MENU_MAIN_INGAME); + else M_ChangeMenu(MENU_MAIN); + screenpeek = myconnectindex; + } + } + + if (VM_HaveEvent(EVENT_DISPLAYREST)) + { + int32_t vr=viewingrange, asp=yxaspect; + VM_OnEvent_(EVENT_DISPLAYREST, g_player[screenpeek].ps->i, screenpeek); + setaspect(vr, asp); + } + + if (g_player[myconnectindex].ps->newowner == -1 && ud.overhead_on == 0 && ud.crosshair && ud.camerasprite == -1) + { + int32_t a = VM_OnEvent(EVENT_DISPLAYCROSSHAIR, g_player[screenpeek].ps->i, screenpeek); + + if ((unsigned) a < MAXTILES) + { + if (a == 0) + a = CROSSHAIR; + + vec2_t crosshairpos ={ 160<<16, 100<<16 }; + + rotatesprite_win(crosshairpos.x-(g_player[myconnectindex].ps->look_ang<<15), crosshairpos.y, scale(65536, ud.crosshairscale, 100), + 0, a, 0, CROSSHAIR_PAL, 2+1); + +#ifdef GEKKO + if ((g_player[myconnectindex].ps->gm&MODE_MENU) == 0 && readmouseabsxy(&crosshairpos, &mouseabs)) + rotatesprite_win(crosshairpos.x, crosshairpos.y, scale(65536, ud.crosshairscale, 100), 0, a, 0, CROSSHAIR_PAL, 2+1); +#endif + } + } +#if 0 + if (GametypeFlags[ud.coop] & GAMETYPE_TDM) + { + for (i=0; iteam == g_player[myconnectindex].ps->team) + { + j = min(max((G_GetAngleDelta(getangle(g_player[i].ps->pos.x-g_player[myconnectindex].ps->pos.x, + g_player[i].ps->pos.y-g_player[myconnectindex].ps->pos.y), g_player[myconnectindex].ps->ang))>>1, -160), 160); + rotatesprite_win((160-j)<<16, 100L<<16, 65536L, 0, DUKEICON, 0, 0, 2+1); + } + } + } +#endif + + if (ud.pause_on==1 && (g_player[myconnectindex].ps->gm&MODE_MENU) == 0) + menutext(160, 100, 0, 0, "Game Paused"); + + if (ud.coords) + G_PrintCoords(screenpeek); + +#ifdef YAX_DEBUG + M32_drawdebug(); +#endif + +#ifdef USE_OPENGL + extern int32_t mdpause; + mdpause = (ud.pause_on || (ud.recstat==2 && (g_demo_paused && g_demo_goalCnt==0)) || (g_player[myconnectindex].ps->gm&MODE_MENU && numplayers < 2)); +#endif + + G_PrintFPS(); + + // JBF 20040124: display level stats in screen corner + if (ud.overhead_on != 2 && ud.levelstats && VM_OnEvent(EVENT_DISPLAYLEVELSTATS, g_player[myconnectindex].ps->i, myconnectindex) == 0) + { + DukePlayer_t const * const myps = g_player[myconnectindex].ps; + + i = 198<<16; + + if (ud.screen_size == 4) + { + if (ud.althud != 2) + i -= sbarsc(ud.althud ? (tilesiz[BIGALPHANUM].y+8)<<16 : tilesiz[INVENTORYBOX].y<<16); + } + else if (ud.screen_size > 2) + i -= sbarsc(tilesiz[BOTTOMSTATUSBAR].y<<16); + + Bsprintf(tempbuf, "T:^15%d:%02d.%02d", + (myps->player_par/(REALGAMETICSPERSEC*60)), + (myps->player_par/REALGAMETICSPERSEC)%60, + ((myps->player_par%REALGAMETICSPERSEC)*33)/10 + ); + G_ScreenText(STARTALPHANUM, 2<<16, i-gtextsc(21<<16), gtextsc(65536), 0, 0, tempbuf, 0, 10, 2|8|16|256|ROTATESPRITE_FULL16, 0, 5<<16, 8<<16, 8<<16, 0, TEXT_XOFFSETZERO|TEXT_GAMETEXTNUMHACK, 0, 0, xdim-1, ydim-1); + + if (ud.player_skill > 3 || ((g_netServer || ud.multimode > 1) && !GTFLAGS(GAMETYPE_PLAYERSFRIENDLY))) + Bsprintf(tempbuf, "K:^15%d", (ud.multimode>1 &&!GTFLAGS(GAMETYPE_PLAYERSFRIENDLY)) ? + myps->frag-myps->fraggedself : myps->actors_killed); + else + { + if (myps->actors_killed >= myps->max_actors_killed) + Bsprintf(tempbuf, "K:%d/%d", myps->actors_killed, + myps->max_actors_killed>myps->actors_killed ? + myps->max_actors_killed : myps->actors_killed); + else + Bsprintf(tempbuf, "K:^15%d/%d", myps->actors_killed, + myps->max_actors_killed>myps->actors_killed ? + myps->max_actors_killed : myps->actors_killed); + } + G_ScreenText(STARTALPHANUM, 2<<16, i-gtextsc(14<<16), gtextsc(65536), 0, 0, tempbuf, 0, 10, 2|8|16|256|ROTATESPRITE_FULL16, 0, 5<<16, 8<<16, 8<<16, 0, TEXT_XOFFSETZERO|TEXT_GAMETEXTNUMHACK, 0, 0, xdim-1, ydim-1); + + if (myps->secret_rooms == myps->max_secret_rooms) + Bsprintf(tempbuf, "S:%d/%d", myps->secret_rooms, myps->max_secret_rooms); + else Bsprintf(tempbuf, "S:^15%d/%d", myps->secret_rooms, myps->max_secret_rooms); + G_ScreenText(STARTALPHANUM, 2<<16, i-gtextsc(7<<16), gtextsc(65536), 0, 0, tempbuf, 0, 10, 2|8|16|256|ROTATESPRITE_FULL16, 0, 5<<16, 8<<16, 8<<16, 0, TEXT_XOFFSETZERO|TEXT_GAMETEXTNUMHACK, 0, 0, xdim-1, ydim-1); + } + + if (g_player[myconnectindex].gotvote == 0 && voting != -1 && voting != myconnectindex) + { + Bsprintf(tempbuf, "%s^00 has called a vote for map", g_player[voting].user_name); + gametext(160, 40, tempbuf, 0, 2+8+16); + Bsprintf(tempbuf, "%s (E%dL%d)", MapInfo[vote_episode*MAXLEVELS + vote_map].name, vote_episode+1, vote_map+1); + gametext(160, 48, tempbuf, 0, 2+8+16); + gametext(160, 70, "Press F1 to Accept, F2 to Decline", 0, 2+8+16); + } + + if (BUTTON(gamefunc_Show_DukeMatch_Scores)) + G_ShowScores(); + + if (g_Debug) + G_ShowCacheLocks(); + +#ifdef LUNATIC + El_DisplayErrors(); +#endif + +#ifndef EDUKE32_TOUCH_DEVICES + if (VOLUMEONE) + { + if (ud.show_help == 0 && g_showShareware > 0 && (g_player[myconnectindex].ps->gm&MODE_MENU) == 0) + rotatesprite_fs((320-50)<<16, 9<<16, 65536L, 0, BETAVERSION, 0, 0, 2+8+16+128); + } +#endif + + if (!Demo_IsProfiling()) + { + if (g_player[myconnectindex].ps->gm&MODE_TYPE) + Net_SendMessage(); + else + M_DisplayMenus(); + } + + { + static int32_t applied = 0; + + if (tint.maxf) + { + G_FadePalaccum(&tint); + applied = 1; + } + else if (applied) + { + // be sure to always un-apply a tint. + setpalettefade(0, 0, 0, 0); + applied = 0; + } + } +} + +void G_FadePalette(int32_t r, int32_t g, int32_t b, int32_t e) +{ + int32_t tc; + setpalettefade(r, g, b, e); + + nextpage(); + tc = totalclock; + while (totalclock < tc + 4) + G_HandleAsync(); +} + +// START and END limits are always inclusive! +// STEP must evenly divide END-START, i.e. abs(end-start)%step == 0 +void fadepal(int32_t r, int32_t g, int32_t b, int32_t start, int32_t end, int32_t step) +{ + if (getrendermode() >= REND_POLYMOST) + { + G_FadePalette(r, g, b, end); + return; + } + + // (end-start)/step + 1 iterations + do + { + if (KB_KeyPressed(sc_Space)) + { + KB_ClearKeyDown(sc_Space); + setpalettefade(r, g, b, end); // have to set to end fade value if we break! + return; + } + + G_FadePalette(r, g, b, start); + + start += step; + } while (start != end+step); +} + +// START and END limits are always inclusive! +static void fadepaltile(int32_t r, int32_t g, int32_t b, int32_t start, int32_t end, int32_t step, int32_t tile) +{ + // STEP must evenly divide END-START + Bassert(klabs(end-start)%step == 0); + + clearallviews(0); + + // (end-start)/step + 1 iterations + do + { +#ifdef __ANDROID__ //Needed for N7 2013 to stop corruption while fading video + clearview(0); +#endif + if (KB_KeyPressed(sc_Space)) + { + KB_ClearKeyDown(sc_Space); + setpalettefade(r, g, b, end); // have to set to end fade value if we break! + return; + } + rotatesprite_fs(160<<16, 100<<16, 65536L, 0, tile, 0, 0, 2+8+BGSTRETCH); + G_FadePalette(r, g, b, start); + + start += step; + } while (start != end+step); +} + +#ifdef LUNATIC +int32_t g_logoFlags = 255; +#endif + +#ifdef __ANDROID__ +int inExtraScreens = 0; +#endif + +void G_DisplayExtraScreens(void) +{ + int32_t flags = G_GetLogoFlags(); + + S_StopMusic(); + FX_StopAllSounds(); + + if (!DUKEBETA && (!VOLUMEALL || flags & LOGO_SHAREWARESCREENS)) + { +#ifdef __ANDROID__ + inExtraScreens = 1; +#endif + setview(0, 0, xdim-1, ydim-1); + flushperms(); + //g_player[myconnectindex].ps->palette = palette; + P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 1); // JBF 20040308 + fadepal(0, 0, 0, 0, 252, 28); + I_ClearAllInput(); + rotatesprite_fs(160<<16, 100<<16, 65536L, 0, 3291, 0, 0, 2+8+64+BGSTRETCH); + fadepaltile(0, 0, 0, 252, 0, -28, 3291); + while (!I_CheckAllInput()) + G_HandleAsync(); + + fadepaltile(0, 0, 0, 0, 252, 28, 3291); + I_ClearAllInput(); + rotatesprite_fs(160<<16, 100<<16, 65536L, 0, 3290, 0, 0, 2+8+64+BGSTRETCH); + fadepaltile(0, 0, 0, 252, 0, -28, 3290); + while (!I_CheckAllInput()) + G_HandleAsync(); + +#ifdef __ANDROID__ + inExtraScreens = 0; +#endif + } + + if (flags & LOGO_TENSCREEN) + { +#ifdef __ANDROID__ + inExtraScreens = 1; +#endif + setview(0, 0, xdim-1, ydim-1); + flushperms(); + //g_player[myconnectindex].ps->palette = palette; + P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 1); // JBF 20040308 + fadepal(0, 0, 0, 0, 252, 28); + I_ClearAllInput(); + totalclock = 0; + rotatesprite_fs(160<<16, 100<<16, 65536L, 0, TENSCREEN, 0, 0, 2+8+64+BGSTRETCH); + fadepaltile(0, 0, 0, 252, 0, -28, TENSCREEN); + while (!I_CheckAllInput() && totalclock < 2400) + G_HandleAsync(); + + fadepaltile(0, 0, 0, 0, 252, 28, TENSCREEN); + I_ClearAllInput(); +#ifdef __ANDROID__ + inExtraScreens = 0; +#endif + } +} + +void G_DisplayLogo(void) +{ + int32_t soundanm = 0; + int32_t logoflags = G_GetLogoFlags(); + + ready2send = 0; + + I_ClearAllInput(); + + setview(0, 0, xdim-1, ydim-1); + clearallviews(0L); + G_FadePalette(0, 0, 0, 252); + + flushperms(); + nextpage(); + + G_UpdateAppTitle(); + + S_StopMusic(); + FX_StopAllSounds(); // JBF 20031228 + S_ClearSoundLocks(); // JBF 20031228 + if ((!g_netServer && ud.multimode < 2) && (logoflags & LOGO_ENABLED) && !g_noLogo) + { + if ( +#ifndef EDUKE32_TOUCH_DEVICES + VOLUMEALL && +#endif + (logoflags & LOGO_PLAYANIM)) + { + if (!I_CheckAllInput() && g_noLogoAnim == 0) + { + Net_GetPackets(); + Anim_Play("logo.anm"); + G_FadePalette(0, 0, 0, 252); + I_ClearAllInput(); + } + + clearallviews(0L); + nextpage(); + + if (logoflags & LOGO_STOPANIMSOUNDS) + { + FX_StopAllSounds(); + S_ClearSoundLocks(); + } + } + + if (logoflags & LOGO_PLAYMUSIC) + { + g_musicIndex = MUS_INTRO; + S_PlayMusic(MapInfo[g_musicIndex].musicfn); + } + + if (!NAM) + { + //g_player[myconnectindex].ps->palette = drealms; + //G_FadePalette(0,0,0,252); + + if (logoflags & LOGO_3DRSCREEN) + { + + if (!I_CheckAllInput() && g_noLogoAnim == 0) + { + int32_t i; + Net_GetPackets(); + + i = kopen4loadfrommod("3dr.ivf", 0); + + if (i == -1) + i = kopen4loadfrommod("3dr.anm", 0); + + if (i != -1) + { + kclose(i); + Anim_Play("3dr.anm"); + G_FadePalette(0, 0, 0, 252); + I_ClearAllInput(); + } + else + { + clearallviews(0); + + P_SetGamePalette(g_player[myconnectindex].ps, DREALMSPAL, 8 + 2 + 1); // JBF 20040308 + fadepal(0, 0, 0, 0, 252, 28); + flushperms(); + rotatesprite_fs(160 << 16, 100 << 16, 65536L, 0, DREALMS, 0, 0, 2 + 8 + BGSTRETCH); + nextpage(); + fadepaltile(0, 0, 0, 252, 0, -28, DREALMS); + totalclock = 0; + while (totalclock < (120 * 7) && !I_CheckAllInput()) + { + clearallviews(0); + + rotatesprite_fs(160 << 16, 100 << 16, 65536L, 0, DREALMS, 0, 0, 2 + 8 + 64 + BGSTRETCH); + + G_HandleAsync(); + + if (g_restorePalette) + { + P_SetGamePalette(g_player[myconnectindex].ps, g_player[myconnectindex].ps->palette, 0); + g_restorePalette = 0; + } + nextpage(); + } + fadepaltile(0, 0, 0, 0, 252, 28, DREALMS); + } + } + + clearallviews(0L); + nextpage(); + } + + I_ClearAllInput(); + } + + clearallviews(0L); + nextpage(); + + if (logoflags & LOGO_TITLESCREEN) + { + clearallviews(0); + + //g_player[myconnectindex].ps->palette = titlepal; + P_SetGamePalette(g_player[myconnectindex].ps, TITLEPAL, 8+2+1); // JBF 20040308 + flushperms(); + rotatesprite_fs(160<<16, 100<<16, 65536L, 0, BETASCREEN, 0, 0, 2+8+64+BGSTRETCH); + KB_FlushKeyboardQueue(); + fadepaltile(0, 0, 0, 252, 0, -28, BETASCREEN); + totalclock = 0; + + while ( +#ifndef DROIDMENU + totalclock < (860+120) && +#endif + !I_CheckAllInput()) + { + clearallviews(0); + + rotatesprite_fs(160<<16, 100<<16, 65536L, 0, BETASCREEN, 0, 0, 2+8+64+BGSTRETCH); + if (logoflags & LOGO_DUKENUKEM) + { + if (totalclock > 120 && totalclock < (120+60)) + { + if (soundanm == 0) + { + soundanm++; + S_PlaySound(PIPEBOMB_EXPLODE); + } + rotatesprite_fs(160<<16, 104<<16, (totalclock-120)<<10, 0, DUKENUKEM, 0, 0, 2+8); + } + else if (totalclock >= (120+60)) + rotatesprite_fs(160<<16, (104)<<16, 60<<10, 0, DUKENUKEM, 0, 0, 2+8); + } + else soundanm++; + + if (logoflags & LOGO_THREEDEE) + { + if (totalclock > 220 && totalclock < (220+30)) + { + if (soundanm == 1) + { + soundanm++; + S_PlaySound(PIPEBOMB_EXPLODE); + } + + rotatesprite_fs(160<<16, (104)<<16, 60<<10, 0, DUKENUKEM, 0, 0, 2+8); + rotatesprite_fs(160<<16, (129)<<16, (totalclock - 220)<<11, 0, THREEDEE, 0, 0, 2+8); + } + else if (totalclock >= (220+30)) + rotatesprite_fs(160<<16, (129)<<16, 30<<11, 0, THREEDEE, 0, 0, 2+8); + } + else soundanm++; + + if (PLUTOPAK && (logoflags & LOGO_PLUTOPAKSPRITE)) + { + // JBF 20030804 + if (totalclock >= 280 && totalclock < 395) + { + rotatesprite_fs(160<<16, (151)<<16, (410-totalclock)<<12, 0, PLUTOPAKSPRITE+1, 0, 0, 2+8); + if (soundanm == 2) + { + soundanm++; + S_PlaySound(FLY_BY); + } + } + else if (totalclock >= 395) + { + if (soundanm == 3) + { + soundanm++; + S_PlaySound(PIPEBOMB_EXPLODE); + } + rotatesprite_fs(160<<16, (151)<<16, 30<<11, 0, PLUTOPAKSPRITE+1, 0, 0, 2+8); + } + } + +#ifdef LUNATIC + g_elEventError = 0; +#endif + VM_OnEvent(EVENT_LOGO, -1, screenpeek); + G_HandleAsync(); + + if (g_restorePalette) + { + P_SetGamePalette(g_player[myconnectindex].ps, g_player[myconnectindex].ps->palette, 0); + g_restorePalette = 0; + } +#ifdef LUNATIC + if (g_elEventError) + break; +#endif + nextpage(); + } + } + I_ClearAllInput(); + } + + flushperms(); + clearallviews(0L); + nextpage(); + + //g_player[myconnectindex].ps->palette = palette; + P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 0); // JBF 20040308 + S_PlaySound(NITEVISION_ONOFF); + + //G_FadePalette(0,0,0,0); + clearallviews(0L); +} + +void G_DoOrderScreen(void) +{ + int32_t i; + + setview(0, 0, xdim-1, ydim-1); + + P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 1); // JBF 20040308 + + for (i=0; i<4; i++) + { + fadepal(0, 0, 0, 0, 252, 28); + I_ClearAllInput(); + rotatesprite_fs(160<<16, 100<<16, 65536L, 0, ORDERING+i, 0, 0, 2+8+64+BGSTRETCH); + fadepal(0, 0, 0, 252, 0, -28); + while (!I_CheckAllInput()) + G_HandleAsync(); + } + + I_ClearAllInput(); +} + + +static void G_BonusCutscenes(void) +{ + int32_t bonuscnt=0; + int32_t t; + + int32_t breathe [] = + { + 0, 30, VICTORY1+1, 176, 59, + 30, 60, VICTORY1+2, 176, 59, + 60, 90, VICTORY1+1, 176, 59, + 90, 120, 0, 176, 59 + }; + + int32_t bossmove [] = + { + 0, 120, VICTORY1+3, 86, 59, + 220, 260, VICTORY1+4, 86, 59, + 260, 290, VICTORY1+5, 86, 59, + 290, 320, VICTORY1+6, 86, 59, + 320, 350, VICTORY1+7, 86, 59, + 350, 380, VICTORY1+8, 86, 59, + 350, 380, VICTORY1+8, 86, 59 // duplicate row to alleviate overflow in the for loop below "boss" + }; + + if (!(numplayers < 2 && ud.eog && ud.from_bonus == 0)) + return; + + switch (ud.volume_number) + { + case 0: + if ((G_GetLogoFlags() & LOGO_NOE1BONUSSCENE) && (G_GetLogoFlags() & LOGO_NOE1ENDSCREEN)) + return; + + if (ud.lockout == 0 && !(G_GetLogoFlags() & LOGO_NOE1BONUSSCENE)) + { + P_SetGamePalette(g_player[myconnectindex].ps, ENDINGPAL, 8+2+1); // JBF 20040308 + clearallviews(0L); + rotatesprite_fs(0, 50<<16, 65536L, 0, VICTORY1, 0, 0, 2+8+16+64+128+BGSTRETCH); + nextpage(); + fadepal(0, 0, 0, 252, 0, -4); + + I_ClearAllInput(); + totalclock = 0; + + while (1) + { + clearallviews(0L); + rotatesprite_fs(0, 50<<16, 65536L, 0, VICTORY1, 0, 0, 2+8+16+64+128+BGSTRETCH); + + // boss + if (totalclock > 390 && totalclock < 780) + for (t=0; t<35; t+=5) if (bossmove[t+2] && (totalclock%390) > bossmove[t] && (totalclock%390) <= bossmove[t+1]) + { + if (t==10 && bonuscnt == 1) + { + S_PlaySound(SHOTGUN_FIRE); + S_PlaySound(SQUISHED); + bonuscnt++; + } + rotatesprite_fs(bossmove[t+3]<<16, bossmove[t+4]<<16, 65536L, 0, bossmove[t+2], 0, 0, 2+8+16+64+128+BGSTRETCH); + } + + // Breathe + if (totalclock < 450 || totalclock >= 750) + { + if (totalclock >= 750) + { + rotatesprite_fs(86<<16, 59<<16, 65536L, 0, VICTORY1+8, 0, 0, 2+8+16+64+128+BGSTRETCH); + if (totalclock >= 750 && bonuscnt == 2) + { + S_PlaySound(DUKETALKTOBOSS); + bonuscnt++; + } + + } + for (t=0; t<20; t+=5) + if (breathe[t+2] && (totalclock%120) > breathe[t] && (totalclock%120) <= breathe[t+1]) + { + if (t==5 && bonuscnt == 0) + { + S_PlaySound(BOSSTALKTODUKE); + bonuscnt++; + } + rotatesprite_fs(breathe[t+3]<<16, breathe[t+4]<<16, 65536L, 0, breathe[t+2], 0, 0, 2+8+16+64+128+BGSTRETCH); + } + } + + G_HandleAsync(); + + nextpage(); + if (I_CheckAllInput()) break; + } + + fadepal(0, 0, 0, 0, 252, 4); + } + + if (G_GetLogoFlags() & LOGO_NOE1ENDSCREEN) + goto VOL1_END; + + I_ClearAllInput(); + P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 8+2+1); // JBF 20040308 + + rotatesprite_fs(160<<16, 100<<16, 65536L, 0, 3292, 0, 0, 2+8+64+BGSTRETCH); + fadepal(0, 0, 0, 252, 0, -4); + G_HandleEventsWhileNoInput(); + fadepal(0, 0, 0, 0, 252, 4); + + VOL1_END: + S_StopMusic(); + FX_StopAllSounds(); + S_ClearSoundLocks(); + break; + + case 1: + if ((G_GetLogoFlags() & LOGO_NOE2BONUSSCENE) && (G_GetLogoFlags() & LOGO_NOE2ENDSCREEN)) + return; + + setview(0, 0, xdim-1, ydim-1); + + S_StopMusic(); + clearallviews(0L); + nextpage(); + + if (ud.lockout == 0 && !(G_GetLogoFlags() & LOGO_NOE2BONUSSCENE)) + { + fadepal(0, 0, 0, 252, 0, -4); + Anim_Play("cineov2.anm"); + I_ClearAllInput(); + clearallviews(0L); + nextpage(); + + S_PlaySound(PIPEBOMB_EXPLODE); + fadepal(0, 0, 0, 0, 252, 4); + } + + if (G_GetLogoFlags() & LOGO_NOE2ENDSCREEN) + return; + + I_ClearAllInput(); + P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 8+2+1); // JBF 20040308 + rotatesprite_fs(160<<16, 100<<16, 65536L, 0, 3293, 0, 0, 2+8+64+BGSTRETCH); + fadepal(0, 0, 0, 252, 0, -4); + G_HandleEventsWhileNoInput(); + fadepal(0, 0, 0, 0, 252, 4); + + break; + + case 3: + if ((G_GetLogoFlags() & LOGO_NOE4BONUSSCENE) && (G_GetLogoFlags() & LOGO_NODUKETEAMTEXT) && (G_GetLogoFlags() & LOGO_NODUKETEAMPIC)) + return; + + setview(0, 0, xdim-1, ydim-1); + + S_StopMusic(); + clearallviews(0L); + nextpage(); + + if (ud.lockout == 0 && !(G_GetLogoFlags() & LOGO_NOE4BONUSSCENE)) + { + fadepal(0, 0, 0, 252, 0, -4); + + I_ClearAllInput(); + t = Anim_Play("vol4e1.anm"); + clearallviews(0L); + nextpage(); + if (t) + goto end_vol4e; + + t = Anim_Play("vol4e2.anm"); + clearallviews(0L); + nextpage(); + if (t) + goto end_vol4e; + + Anim_Play("vol4e3.anm"); + clearallviews(0L); + nextpage(); + } + + end_vol4e: + if ((G_GetLogoFlags() & LOGO_NODUKETEAMTEXT) && (G_GetLogoFlags() & LOGO_NODUKETEAMPIC)) + goto VOL4_END; + + FX_StopAllSounds(); + S_ClearSoundLocks(); + S_PlaySound(ENDSEQVOL3SND4); + I_ClearAllInput(); + + if (G_GetLogoFlags() & LOGO_NODUKETEAMTEXT) + goto VOL4_DUKETEAM; + + G_FadePalette(0, 0, 0, 0); + P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 8+2+1); // JBF 20040308 + // G_FadePalette(0,0,0,252); + clearallviews(0L); + menutext(160, 60, 0, 0, "Thanks to all our"); + menutext(160, 60+16, 0, 0, "fans for giving"); + menutext(160, 60+16+16, 0, 0, "us big heads."); + menutext(160, 70+16+16+16, 0, 0, "Look for a Duke Nukem 3D"); + menutext(160, 70+16+16+16+16, 0, 0, "sequel soon."); + nextpage(); + + fadepal(0, 0, 0, 252, 0, -12); + nextpage(); + I_ClearAllInput(); + G_HandleEventsWhileNoInput(); + fadepal(0, 0, 0, 0, 252, 12); + + if (G_GetLogoFlags() & LOGO_NODUKETEAMPIC) + goto VOL4_END; + + VOL4_DUKETEAM: + clearallviews(0L); + nextpage(); + + Anim_Play("DUKETEAM.ANM"); + + I_ClearAllInput(); + G_HandleEventsWhileNoInput(); + + clearallviews(0L); + nextpage(); + G_FadePalette(0, 0, 0, 252); + + VOL4_END: + FX_StopAllSounds(); + S_ClearSoundLocks(); + I_ClearAllInput(); + + break; + + case 2: + if ((G_GetLogoFlags() & LOGO_NOE3BONUSSCENE) && (G_GetLogoFlags() & LOGO_NOE3RADLOGO) && (PLUTOPAK || (G_GetLogoFlags() & LOGO_NODUKETEAMPIC))) + return; + + S_StopMusic(); + clearallviews(0L); + nextpage(); + if (ud.lockout == 0 && !(G_GetLogoFlags() & LOGO_NOE3BONUSSCENE)) + { + fadepal(0, 0, 0, 252, 0, -4); + Anim_Play("cineov3.anm"); + I_ClearAllInput(); + ototalclock = totalclock+200; + while (totalclock < ototalclock) + G_HandleAsync(); + clearallviews(0L); + nextpage(); + + FX_StopAllSounds(); + S_ClearSoundLocks(); + } + + if (G_GetLogoFlags() & LOGO_NOE3RADLOGO) + goto ENDANM; + + Anim_Play("RADLOGO.ANM"); + + if (ud.lockout == 0 && !I_CheckAllInput()) + { + if (G_PlaySoundWhileNoInput(ENDSEQVOL3SND5)) goto ENDANM; + if (G_PlaySoundWhileNoInput(ENDSEQVOL3SND6)) goto ENDANM; + if (G_PlaySoundWhileNoInput(ENDSEQVOL3SND7)) goto ENDANM; + if (G_PlaySoundWhileNoInput(ENDSEQVOL3SND8)) goto ENDANM; + if (G_PlaySoundWhileNoInput(ENDSEQVOL3SND9)) goto ENDANM; + } + + I_ClearAllInput(); + + totalclock = 0; + if (PLUTOPAK || (G_GetLogoFlags() & LOGO_NODUKETEAMPIC)) + { + while (totalclock < 120 && !I_CheckAllInput()) + G_HandleAsync(); + + I_ClearAllInput(); + } + else + { + G_HandleEventsWhileNoInput(); + } + + ENDANM: + if (!PLUTOPAK && !(G_GetLogoFlags() & LOGO_NODUKETEAMPIC)) + { + FX_StopAllSounds(); + S_ClearSoundLocks(); + S_PlaySound(ENDSEQVOL3SND4); + + clearallviews(0L); + nextpage(); + + Anim_Play("DUKETEAM.ANM"); + + I_ClearAllInput(); + G_HandleEventsWhileNoInput(); + + clearallviews(0L); + nextpage(); + G_FadePalette(0, 0, 0, 252); + } + + I_ClearAllInput(); + FX_StopAllSounds(); + S_ClearSoundLocks(); + + clearallviews(0L); + + break; + } +} + +static void G_DisplayMPResultsScreen(void) +{ + int32_t i, y, t = 0; + + rotatesprite_fs(160<<16, 100<<16, 65536L, 0, MENUSCREEN, 16, 0, 2+8+64+BGSTRETCH); + rotatesprite_fs(160<<16, 34<<16, 65536L, 0, INGAMEDUKETHREEDEE, 0, 0, 10); + if (PLUTOPAK) // JBF 20030804 + rotatesprite_fs((260)<<16, 36<<16, 65536L, 0, PLUTOPAKSPRITE+2, 0, 0, 2+8); + gametext(160, 58+2, "Multiplayer Totals", 0, 2+8+16); + gametext(160, 58+10, MapInfo[G_LastMapInfoIndex()].name, 0, 2+8+16); + + gametext(160, 165, "Press any key or button to continue", quotepulseshade, 2+8+16); + + minitext(23, 80, " Name Kills", 8, 2+8+16+128); + for (i=0; ipalookup, 2+8+16+128); + + for (y=0; yfraggedself); + minitext(92+(y*23), 90+t, tempbuf, 2, 2+8+16+128); + xfragtotal -= g_player[y].ps->fraggedself; + } + else + { + Bsprintf(tempbuf, "%-4d", g_player[i].frags[y]); + minitext(92+(y*23), 90+t, tempbuf, 0, 2+8+16+128); + xfragtotal += g_player[i].frags[y]; + } + } + + Bsprintf(tempbuf, "%-4d", xfragtotal); + minitext(101+(8*23), 90+t, tempbuf, 2, 2+8+16+128); + + t += 7; + } + + for (y=0; yfraggedself; + yfragtotal += g_player[i].frags[y]; + } + Bsprintf(tempbuf, "%-4d", yfragtotal); + minitext(92+(y*23), 96+(8*7), tempbuf, 2, 2+8+16+128); + } + + minitext(45, 96+(8*7), "Deaths", 8, 2+8+16+128); +} + +static int32_t G_PrintTime_ClockPad(void) +{ + int32_t clockpad = 2; + int32_t ii, ij; + + for (ii=g_player[myconnectindex].ps->player_par/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++); + clockpad = max(clockpad, ij); + if (!(ud.volume_number == 0 && ud.last_level-1 == 7 && boardfilename[0])) + { + for (ii=MapInfo[G_LastMapInfoIndex()].partime/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++); + clockpad = max(clockpad, ij); + if (!NAM_WW2GI && MapInfo[G_LastMapInfoIndex()].designertime) + { + for (ii=MapInfo[G_LastMapInfoIndex()].designertime/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++); + clockpad = max(clockpad, ij); + } + } + if (ud.playerbest > 0) for (ii=ud.playerbest/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++); + clockpad = max(clockpad, ij); + + return clockpad; +} + +static const char* G_PrintTime2(int32_t time) +{ + Bsprintf(tempbuf, "%0*d:%02d", G_PrintTime_ClockPad(), time/(REALGAMETICSPERSEC*60), (time/REALGAMETICSPERSEC)%60); + return tempbuf; +} +static const char* G_PrintTime3(int32_t time) +{ + Bsprintf(tempbuf, "%0*d:%02d.%02d", G_PrintTime_ClockPad(), time/(REALGAMETICSPERSEC*60), (time/REALGAMETICSPERSEC)%60, ((time%REALGAMETICSPERSEC)*33)/10); + return tempbuf; +} + +const char* G_PrintYourTime(void) +{ + return G_PrintTime3(g_player[myconnectindex].ps->player_par); +} +const char* G_PrintParTime(void) +{ + if (ud.last_level < 1) + return ""; + return G_PrintTime2(MapInfo[G_LastMapInfoIndex()].partime); +} +const char* G_PrintDesignerTime(void) +{ + if (ud.last_level < 1) + return ""; + return G_PrintTime2(MapInfo[G_LastMapInfoIndex()].designertime); +} +const char* G_PrintBestTime(void) +{ + return G_PrintTime3(ud.playerbest); +} + +void G_BonusScreen(int32_t bonusonly) +{ + int32_t gfx_offset; + int32_t bonuscnt; + int32_t clockpad = 2; + char *lastmapname; + + if (g_networkMode == NET_DEDICATED_SERVER) + return; + + G_UpdateAppTitle(); + + if (ud.volume_number == 0 && ud.last_level == 8 && boardfilename[0]) + { + lastmapname = Bstrrchr(boardfilename, '\\'); + if (!lastmapname) lastmapname = Bstrrchr(boardfilename, '/'); + if (!lastmapname) lastmapname = boardfilename; + } + else + { + lastmapname = MapInfo[G_LastMapInfoIndex()].name; + if (!lastmapname) // this isn't right but it's better than no name at all + lastmapname = MapInfo[G_LastMapInfoIndex()].name; + } + + + fadepal(0, 0, 0, 0, 252, 28); + setview(0, 0, xdim-1, ydim-1); + clearallviews(0L); + nextpage(); + flushperms(); + + FX_StopAllSounds(); + S_ClearSoundLocks(); + FX_SetReverb(0L); + CONTROL_BindsEnabled = 1; // so you can use your screenshot bind on the score screens + + if (!bonusonly) + G_BonusCutscenes(); + + P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 8+2+1); // JBF 20040308 + G_FadePalette(0, 0, 0, 252); // JBF 20031228 + KB_FlushKeyboardQueue(); + totalclock = 0; + bonuscnt = 0; + + S_StopMusic(); + FX_StopAllSounds(); + S_ClearSoundLocks(); + + if (playerswhenstarted > 1 && (GametypeFlags[ud.coop]&GAMETYPE_SCORESHEET)) + { + clearallviews(0); + G_DisplayMPResultsScreen(); + + if (ud.config.MusicToggle) + S_PlaySound(BONUSMUSIC); + + nextpage(); + I_ClearAllInput(); + fadepal(0, 0, 0, 252, 0, -28); + totalclock = 0; + + while (totalclock < TICRATE*10) + { + G_HandleAsync(); + + MUSIC_Update(); + + clearallviews(0); + G_DisplayMPResultsScreen(); + nextpage(); + + if (I_CheckAllInput()) + { + I_ClearAllInput(); + break; + } + } + + fadepal(0, 0, 0, 0, 252, 28); + } + + if (bonusonly || (g_netServer || ud.multimode > 1)) return; + + gfx_offset = (ud.volume_number==1) ? 5 : 0; + rotatesprite_fs(160<<16, 100<<16, 65536L, 0, BONUSSCREEN+gfx_offset, 0, 0, 2+8+64+128+BGSTRETCH); + + if (lastmapname) + menutext(160, 20-6, 0, 0, lastmapname); + menutext(160, 36-6, 0, 0, "Completed"); + + gametext(160, 192, "Press any key or button to continue", quotepulseshade, 2+8+16); + + if (ud.config.MusicToggle) + S_PlaySound(BONUSMUSIC); + + nextpage(); + I_ClearAllInput(); + fadepal(0, 0, 0, 252, 0, -4); + bonuscnt = 0; + totalclock = 0; + + if (g_player[myconnectindex].ps->player_par > 0 && (g_player[myconnectindex].ps->player_par < ud.playerbest || ud.playerbest < 0)) + CONFIG_SetMapBestTime(g_loadedMapHack.md4, g_player[myconnectindex].ps->player_par); + + do + { + int32_t yy = 0, zz; + + G_HandleAsync(); + + MUSIC_Update(); + + if (g_player[myconnectindex].ps->gm&MODE_EOL) + { + clearallviews(0); + + rotatesprite_fs(160<<16, 100<<16, 65536L, 0, BONUSSCREEN+gfx_offset, 0, 0, 2+8+64+128+BGSTRETCH); + + if (totalclock >= 1000000000 && totalclock < 1000000320) + { + switch ((totalclock>>4)%15) + { + case 0: + if (bonuscnt == 6) + { + bonuscnt++; + S_PlaySound(SHOTGUN_COCK); + switch (rand()&3) + { + case 0: + S_PlaySound(BONUS_SPEECH1); + break; + case 1: + S_PlaySound(BONUS_SPEECH2); + break; + case 2: + S_PlaySound(BONUS_SPEECH3); + break; + case 3: + S_PlaySound(BONUS_SPEECH4); + break; + } + } + case 1: + case 4: + case 5: + rotatesprite_fs(199<<16, 31<<16, 65536L, 0, BONUSSCREEN+3+gfx_offset, 0, 0, 2+8+16+64+128+BGSTRETCH); + break; + case 2: + case 3: + rotatesprite_fs(199<<16, 31<<16, 65536L, 0, BONUSSCREEN+4+gfx_offset, 0, 0, 2+8+16+64+128+BGSTRETCH); + break; + } + } + else if (totalclock > (10240+120L)) break; + else + { + switch ((totalclock>>5)&3) + { + case 1: + case 3: + rotatesprite_fs(199<<16, 31<<16, 65536L, 0, BONUSSCREEN+1+gfx_offset, 0, 0, 2+8+16+64+128+BGSTRETCH); + break; + case 2: + rotatesprite_fs(199<<16, 31<<16, 65536L, 0, BONUSSCREEN+2+gfx_offset, 0, 0, 2+8+16+64+128+BGSTRETCH); + break; + } + } + + if (lastmapname) + menutext(160, 20-6, 0, 0, lastmapname); + menutext(160, 36-6, 0, 0, "Completed"); + + gametext(160, 192, "Press any key or button to continue", quotepulseshade, 2+8+16); + + if (totalclock > (60*3)) + { + yy = zz = 59; + + gametext(10, yy+9, "Your Time:", 0, 2+8+16); + + yy+=10; + if (!(ud.volume_number == 0 && ud.last_level-1 == 7 && boardfilename[0])) + { + if (MapInfo[G_LastMapInfoIndex()].partime) + { + gametext(10, yy+9, "Par Time:", 0, 2+8+16); + yy+=10; + } + if (!NAM_WW2GI && !DUKEBETA && MapInfo[G_LastMapInfoIndex()].designertime) + { + // EDuke 2.0 / NAM source suggests "Green Beret's Time:" + gametext(10, yy+9, "3D Realms' Time:", 0, 2+8+16); + yy+=10; + } + + } + if (ud.playerbest > 0) + { + gametext(10, yy+9, (g_player[myconnectindex].ps->player_par > 0 && g_player[myconnectindex].ps->player_par < ud.playerbest) ? "Prev Best Time:" : "Your Best Time:", 0, 2+8+16); + yy += 10; + } + + if (bonuscnt == 0) + bonuscnt++; + + yy = zz; + if (totalclock >(60*4)) + { + if (bonuscnt == 1) + { + bonuscnt++; + S_PlaySound(PIPEBOMB_EXPLODE); + } + + if (g_player[myconnectindex].ps->player_par > 0) + { + G_PrintYourTime(); + gametext((320>>2)+71, yy+9, tempbuf, 0, 2+8+16); + if (g_player[myconnectindex].ps->player_par < ud.playerbest) + gametext((320>>2)+89+(clockpad*24), yy+9, "New record!", 0, 2+8+16); + } + else + gametextpalbits((320>>2)+71, yy+9, "Cheated!", 0, 2, 2+8+16, 0); + yy+=10; + + if (!(ud.volume_number == 0 && ud.last_level-1 == 7 && boardfilename[0])) + { + if (MapInfo[G_LastMapInfoIndex()].partime) + { + G_PrintParTime(); + gametext((320>>2)+71, yy+9, tempbuf, 0, 2+8+16); + yy+=10; + } + if (!NAM_WW2GI && !DUKEBETA && MapInfo[G_LastMapInfoIndex()].designertime) + { + G_PrintDesignerTime(); + gametext((320>>2)+71, yy+9, tempbuf, 0, 2+8+16); + yy+=10; + } + } + + if (ud.playerbest > 0) + { + G_PrintBestTime(); + gametext((320>>2)+71, yy+9, tempbuf, 0, 2+8+16); + yy+=10; + } + } + } + + zz = yy += 5; + if (totalclock > (60*6)) + { + gametext(10, yy+9, "Enemies Killed:", 0, 2+8+16); + yy += 10; + gametext(10, yy+9, "Enemies Left:", 0, 2+8+16); + yy += 10; + + if (bonuscnt == 2) + { + bonuscnt++; + S_PlaySound(FLY_BY); + } + + yy = zz; + + if (totalclock > (60*7)) + { + if (bonuscnt == 3) + { + bonuscnt++; + S_PlaySound(PIPEBOMB_EXPLODE); + } + Bsprintf(tempbuf, "%-3d", g_player[myconnectindex].ps->actors_killed); + gametext((320>>2)+70, yy+9, tempbuf, 0, 2+8+16); + yy += 10; + if (ud.player_skill > 3) + { + Bsprintf(tempbuf, "N/A"); + gametext((320>>2)+70, yy+9, tempbuf, 0, 2+8+16); + yy += 10; + } + else + { + if ((g_player[myconnectindex].ps->max_actors_killed-g_player[myconnectindex].ps->actors_killed) < 0) + Bsprintf(tempbuf, "%-3d", 0); + else Bsprintf(tempbuf, "%-3d", g_player[myconnectindex].ps->max_actors_killed-g_player[myconnectindex].ps->actors_killed); + gametext((320>>2)+70, yy+9, tempbuf, 0, 2+8+16); + yy += 10; + } + } + } + + zz = yy += 5; + if (totalclock > (60*9)) + { + gametext(10, yy+9, "Secrets Found:", 0, 2+8+16); + yy += 10; + gametext(10, yy+9, "Secrets Missed:", 0, 2+8+16); + yy += 10; + if (bonuscnt == 4) bonuscnt++; + + yy = zz; + if (totalclock > (60*10)) + { + if (bonuscnt == 5) + { + bonuscnt++; + S_PlaySound(PIPEBOMB_EXPLODE); + } + Bsprintf(tempbuf, "%-3d", g_player[myconnectindex].ps->secret_rooms); + gametext((320>>2)+70, yy+9, tempbuf, 0, 2+8+16); + yy += 10; + if (g_player[myconnectindex].ps->secret_rooms > 0) + Bsprintf(tempbuf, "%-3d%%", (100*g_player[myconnectindex].ps->secret_rooms/g_player[myconnectindex].ps->max_secret_rooms)); + Bsprintf(tempbuf, "%-3d", g_player[myconnectindex].ps->max_secret_rooms-g_player[myconnectindex].ps->secret_rooms); + gametext((320>>2)+70, yy+9, tempbuf, 0, 2+8+16); + yy += 10; + } + } + + if (totalclock > 10240 && totalclock < 10240+10240) + totalclock = 1024; + + if (I_CheckAllInput() && totalclock >(60*2)) // JBF 20030809 + { + I_ClearAllInput(); + if (totalclock < (60*13)) + { + KB_FlushKeyboardQueue(); + totalclock = (60*13); + } + else if (totalclock < 1000000000) + totalclock = 1000000000; + } + } + else + break; + + VM_OnEvent(EVENT_DISPLAYBONUSSCREEN, g_player[screenpeek].ps->i, screenpeek); + nextpage(); + } while (1); +} + diff --git a/polymer/eduke32/source/screens.h b/polymer/eduke32/source/screens.h new file mode 100644 index 000000000..e3291e84a --- /dev/null +++ b/polymer/eduke32/source/screens.h @@ -0,0 +1,44 @@ +//------------------------------------------------------------------------- +/* +Copyright (C) 2016 EDuke32 developers and contributors + +This file is part of EDuke32. + +EDuke32 is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 2 +as published by the Free Software Foundation. + +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ +//------------------------------------------------------------------------- + +extern void G_DisplayExtraScreens(void); +extern void G_DisplayLogo(void); +extern void G_DoOrderScreen(void); + +static inline int G_LastMapInfoIndex(void) +{ + Bassert(ud.last_level >= 1); // NOTE: last_level is 1-based + return ud.volume_number*MAXLEVELS + ud.last_level-1; +} + +#ifdef DEBUGGINGAIDS +typedef struct { + uint32_t lastgtic; + uint32_t lastnumins, numins; + int32_t numonscreen; +} sprstat_t; + +sprstat_t g_spriteStat; +#endif + +extern int32_t dr_yxaspect, dr_viewingrange; +extern int32_t g_noLogoAnim, g_noLogo; diff --git a/polymer/eduke32/source/sector.h b/polymer/eduke32/source/sector.h index dd86337b1..afcbe6c15 100644 --- a/polymer/eduke32/source/sector.h +++ b/polymer/eduke32/source/sector.h @@ -86,6 +86,7 @@ typedef struct { twalltype wall[MAXWALLS]; #if !defined LUNATIC intptr_t *vars[MAXGAMEVARS]; + intptr_t *arrays[MAXGAMEARRAYS]; #else char *savecode; #endif