commit 22fc405736dc4796958de221c07d52432f1b271b
Merge: f391d85c 64918568
Author: Simon Howard <fraggle@gmail.com>
AuthorDate: Tue Aug 31 19:26:32 2010 +0000
Commit: Simon Howard <fraggle@gmail.com>
CommitDate: Tue Aug 31 19:26:32 2010 +0000
Merge from trunk.
Subversion-branch: /branches/raven-branch
Subversion-revision: 1987
ChangeLog | 78 +++
INSTALL | 159 +++--
NEWS | 40 +-
README | 55 +-
codeblocks/config.h | 6 +-
codeblocks/game-res.rc | 10 +-
codeblocks/setup-res.rc | 8 +-
configure.in | 3 +-
msvc/config.h | 6 +-
msvc/win32.rc | 10 +-
opl/Makefile.am | 2 +-
opl/dbopl.c | 1602 ++++++++++++++++++++++++++++++++++++++++++++
opl/dbopl.h | 203 ++++++
opl/fmopl.c | 1155 --------------------------------
opl/fmopl.h | 167 -----
opl/opl_sdl.c | 158 +++--
pkg/config.make.in | 1 +
pkg/osx/GNUmakefile | 4 +
rpm.spec.in | 5 +-
src/doom/d_main.c | 6 +
src/doom/g_game.c | 184 ++++-
src/doom/hu_stuff.c | 12 +-
src/doom/r_draw.c | 111 +--
src/heretic/d_main.c | 1 +
src/hexen/h2_main.c | 1 +
src/i_scale.c | 14 +-
src/i_sdlsound.c | 72 +-
src/i_sound.c | 5 +
src/i_video.c | 281 +++++---
src/i_video.h | 4 +-
src/m_config.c | 132 +++-
src/m_controls.c | 47 +-
src/m_controls.h | 17 +-
src/setup/joystick.c | 2 +
src/setup/keyboard.c | 27 +-
src/setup/keyboard.h | 53 --
src/setup/mainmenu.c | 60 ++
src/setup/mouse.c | 9 +-
src/setup/multiplayer.c | 35 +
src/setup/sound.c | 1 +
src/setup/txt_keyinput.c | 2 +-
src/setup/txt_mouseinput.c | 4 +-
src/z_zone.c | 3 +-
43 files changed, 3015 insertions(+), 1740 deletions(-)
diff --cc src/doom/d_main.c
index 3fee8439,671c4e9c..f3a4b037
--- a/src/doom/d_main.c
+++ b/src/doom/d_main.c
@@@ -340,73 -387,7 +340,79 @@@ void D_Display (void
} while (!done);
}
+//
+// Add configuration file variable bindings.
+//
+
+void D_BindVariables(void)
+{
+ int i;
+
+ M_ApplyPlatformDefaults();
+
+ I_BindVideoVariables();
+ I_BindJoystickVariables();
+ I_BindSoundVariables();
+
+ M_BindBaseControls();
+ M_BindWeaponControls();
+ M_BindMapControls();
+ M_BindMenuControls();
++ M_BindChatControls(MAXPLAYERS);
++
++ key_multi_msgplayer[0] = HUSTR_KEYGREEN;
++ key_multi_msgplayer[1] = HUSTR_KEYINDIGO;
++ key_multi_msgplayer[2] = HUSTR_KEYBROWN;
++ key_multi_msgplayer[3] = HUSTR_KEYRED;
+
+#ifdef FEATURE_MULTIPLAYER
+ NET_BindVariables();
+#endif
+
+ M_BindVariable("mouse_sensitivity", &mouseSensitivity);
+ M_BindVariable("sfx_volume", &sfxVolume);
+ M_BindVariable("music_volume", &musicVolume);
+ M_BindVariable("show_messages", &showMessages);
+ M_BindVariable("screenblocks", &screenblocks);
+ M_BindVariable("detaillevel", &detailLevel);
+ M_BindVariable("snd_channels", &snd_channels);
+ M_BindVariable("vanilla_savegame_limit", &vanilla_savegame_limit);
+ M_BindVariable("vanilla_demo_limit", &vanilla_demo_limit);
+ M_BindVariable("show_endoom", &show_endoom);
+
+ // Multiplayer chat macros
+
+ for (i=0; i<10; ++i)
+ {
+ char buf[12];
+
+ sprintf(buf, "chatmacro%i", i);
+ M_BindVariable(buf, &chat_macros[i]);
+ }
+}
+
+//
+// D_GrabMouseCallback
+//
+// Called to determine whether to grab the mouse pointer
+//
+
+boolean D_GrabMouseCallback(void)
+{
+ // Drone players don't need mouse focus
+
+ if (drone)
+ return false;
+ // when menu is active or game is paused, release the mouse
+
+ if (menuactive || paused)
+ return false;
+
+ // only grab mouse when playing levels (but not demos)
+
+ return (gamestate == GS_LEVEL) && !demoplayback;
+}
//
// D_DoomLoop
diff --cc src/heretic/d_main.c
index 901d763d,00000000..169a86ea
mode 100644,000000..100644
--- a/src/heretic/d_main.c
+++ b/src/heretic/d_main.c
@@@ -1,1074 -1,0 +1,1075 @@@
+// Emacs style mode select -*- C++ -*-
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 1993-1996 Id Software, Inc.
+// Copyright(C) 1993-2008 Raven Software
+// Copyright(C) 2008 Simon Howard
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+//-----------------------------------------------------------------------------
+
+// D_main.c
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "txt_main.h"
+#include "txt_io.h"
+
+#include "config.h"
+#include "ct_chat.h"
+#include "doomdef.h"
+#include "deh_main.h"
+#include "d_iwad.h"
+#include "i_endoom.h"
+#include "i_joystick.h"
+#include "i_sound.h"
+#include "i_system.h"
+#include "i_timer.h"
+#include "i_video.h"
+#include "m_argv.h"
+#include "m_config.h"
+#include "m_controls.h"
+#include "p_local.h"
+#include "s_sound.h"
+#include "w_main.h"
+#include "v_video.h"
+
+#define STARTUP_WINDOW_X 17
+#define STARTUP_WINDOW_Y 7
+
+GameMission_t gamemission = heretic;
+GameMode_t gamemode = indetermined;
+char *gamedescription = "unknown";
+
+boolean nomonsters; // checkparm of -nomonsters
+boolean respawnparm; // checkparm of -respawn
+boolean debugmode; // checkparm of -debug
+boolean ravpic; // checkparm of -ravpic
+boolean cdrom; // true if cd-rom mode active
+boolean singletics; // debug flag to cancel adaptiveness
+boolean noartiskip; // whether shift-enter skips an artifact
+
+skill_t startskill;
+int startepisode;
+int startmap;
+int UpdateState;
+static int graphical_startup = 1;
+static boolean using_graphical_startup;
+boolean autostart;
+extern boolean automapactive;
+
+boolean advancedemo;
+
+FILE *debugfile;
+
+static int show_endoom = 1;
+
+void D_CheckNetGame(void);
+void D_ProcessEvents(void);
+void G_BuildTiccmd(ticcmd_t * cmd);
+void D_DoAdvanceDemo(void);
+void D_PageDrawer(void);
+void D_AdvanceDemo(void);
+void F_Drawer(void);
+boolean F_Responder(event_t * ev);
+
+//---------------------------------------------------------------------------
+//
+// PROC D_ProcessEvents
+//
+// Send all the events of the given timestamp down the responder chain.
+//
+//---------------------------------------------------------------------------
+
+void D_ProcessEvents(void)
+{
+ event_t *ev;
+
+ while ((ev = D_PopEvent()) != NULL)
+ {
+ if (F_Responder(ev))
+ {
+ continue;
+ }
+ if (MN_Responder(ev))
+ {
+ continue;
+ }
+ G_Responder(ev);
+ }
+}
+
+//---------------------------------------------------------------------------
+//
+// PROC DrawMessage
+//
+//---------------------------------------------------------------------------
+
+void DrawMessage(void)
+{
+ player_t *player;
+
+ player = &players[consoleplayer];
+ if (player->messageTics <= 0 || !player->message)
+ { // No message
+ return;
+ }
+ MN_DrTextA(player->message, 160 - MN_TextAWidth(player->message) / 2, 1);
+}
+
+//---------------------------------------------------------------------------
+//
+// PROC D_Display
+//
+// Draw current display, possibly wiping it from the previous.
+//
+//---------------------------------------------------------------------------
+
+void R_ExecuteSetViewSize(void);
+
+extern boolean finalestage;
+
+void D_Display(void)
+{
+ extern boolean MenuActive;
+ extern boolean askforquit;
+
+ // Change the view size if needed
+ if (setsizeneeded)
+ {
+ R_ExecuteSetViewSize();
+ }
+
+//
+// do buffered drawing
+//
+ switch (gamestate)
+ {
+ case GS_LEVEL:
+ if (!gametic)
+ break;
+ if (automapactive)
+ AM_Drawer();
+ else
+ R_RenderPlayerView(&players[displayplayer]);
+ CT_Drawer();
+ UpdateState |= I_FULLVIEW;
+ SB_Drawer();
+ break;
+ case GS_INTERMISSION:
+ IN_Drawer();
+ break;
+ case GS_FINALE:
+ F_Drawer();
+ break;
+ case GS_DEMOSCREEN:
+ D_PageDrawer();
+ break;
+ }
+
+ if (paused && !MenuActive && !askforquit)
+ {
+ if (!netgame)
+ {
+ V_DrawPatch(160, viewwindowy + 5, W_CacheLumpName(DEH_String("PAUSED"),
+ PU_CACHE));
+ }
+ else
+ {
+ V_DrawPatch(160, 70, W_CacheLumpName(DEH_String("PAUSED"), PU_CACHE));
+ }
+ }
+ // Handle player messages
+ DrawMessage();
+
+ // Menu drawing
+ MN_Drawer();
+
+ // Send out any new accumulation
+ NetUpdate();
+
+ // Flush buffered stuff to screen
+ I_FinishUpdate();
+}
+
+//
+// D_GrabMouseCallback
+//
+// Called to determine whether to grab the mouse pointer
+//
+
+boolean D_GrabMouseCallback(void)
+{
+ // when menu is active or game is paused, release the mouse
+
+ if (MenuActive || paused)
+ return false;
+
+ // only grab mouse when playing levels (but not demos)
+
+ return (gamestate == GS_LEVEL) && !demoplayback;
+}
+
+//---------------------------------------------------------------------------
+//
+// PROC D_DoomLoop
+//
+//---------------------------------------------------------------------------
+
+void D_DoomLoop(void)
+{
+ if (M_CheckParm("-debugfile"))
+ {
+ char filename[20];
+ sprintf(filename, "debug%i.txt", consoleplayer);
+ debugfile = fopen(filename, "w");
+ }
+ I_SetWindowTitle(gamedescription);
+ I_InitGraphics();
+ I_SetGrabMouseCallback(D_GrabMouseCallback);
+
+ while (1)
+ {
+ // Frame syncronous IO operations
+ I_StartFrame();
+
+ // Process one or more tics
+ if (singletics)
+ {
+ I_StartTic();
+ D_ProcessEvents();
+ G_BuildTiccmd(&netcmds[consoleplayer][maketic % BACKUPTICS]);
+ if (advancedemo)
+ D_DoAdvanceDemo();
+ G_Ticker();
+ gametic++;
+ maketic++;
+ }
+ else
+ {
+ // Will run at least one tic
+ TryRunTics();
+ }
+
+ // Move positional sounds
+ S_UpdateSounds(players[consoleplayer].mo);
+ D_Display();
+ }
+}
+
+/*
+===============================================================================
+
+ DEMO LOOP
+
+===============================================================================
+*/
+
+int demosequence;
+int pagetic;
+char *pagename;
+
+
+/*
+================
+=
+= D_PageTicker
+=
+= Handles timing for warped projection
+=
+================
+*/
+
+void D_PageTicker(void)
+{
+ if (--pagetic < 0)
+ D_AdvanceDemo();
+}
+
+
+/*
+================
+=
+= D_PageDrawer
+=
+================
+*/
+
+extern boolean MenuActive;
+
+void D_PageDrawer(void)
+{
+ V_DrawRawScreen(W_CacheLumpName(pagename, PU_CACHE));
+ if (demosequence == 1)
+ {
+ V_DrawPatch(4, 160, W_CacheLumpName(DEH_String("ADVISOR"), PU_CACHE));
+ }
+ UpdateState |= I_FULLSCRN;
+}
+
+/*
+=================
+=
+= D_AdvanceDemo
+=
+= Called after each demo or intro demosequence finishes
+=================
+*/
+
+void D_AdvanceDemo(void)
+{
+ advancedemo = true;
+}
+
+void D_DoAdvanceDemo(void)
+{
+ players[consoleplayer].playerstate = PST_LIVE; // don't reborn
+ advancedemo = false;
+ usergame = false; // can't save / end game here
+ paused = false;
+ gameaction = ga_nothing;
+ demosequence = (demosequence + 1) % 7;
+ switch (demosequence)
+ {
+ case 0:
+ pagetic = 210;
+ gamestate = GS_DEMOSCREEN;
+ pagename = DEH_String("TITLE");
+ S_StartSong(mus_titl, false);
+ break;
+ case 1:
+ pagetic = 140;
+ gamestate = GS_DEMOSCREEN;
+ pagename = DEH_String("TITLE");
+ break;
+ case 2:
+ BorderNeedRefresh = true;
+ UpdateState |= I_FULLSCRN;
+ G_DeferedPlayDemo(DEH_String("demo1"));
+ break;
+ case 3:
+ pagetic = 200;
+ gamestate = GS_DEMOSCREEN;
+ pagename = DEH_String("CREDIT");
+ break;
+ case 4:
+ BorderNeedRefresh = true;
+ UpdateState |= I_FULLSCRN;
+ G_DeferedPlayDemo(DEH_String("demo2"));
+ break;
+ case 5:
+ pagetic = 200;
+ gamestate = GS_DEMOSCREEN;
+ if (gamemode == shareware)
+ {
+ pagename = DEH_String("ORDER");
+ }
+ else
+ {
+ pagename = DEH_String("CREDIT");
+ }
+ break;
+ case 6:
+ BorderNeedRefresh = true;
+ UpdateState |= I_FULLSCRN;
+ G_DeferedPlayDemo(DEH_String("demo3"));
+ break;
+ }
+}
+
+
+/*
+=================
+=
+= D_StartTitle
+=
+=================
+*/
+
+void D_StartTitle(void)
+{
+ gameaction = ga_nothing;
+ demosequence = -1;
+ D_AdvanceDemo();
+}
+
+
+/*
+==============
+=
+= D_CheckRecordFrom
+=
+= -recordfrom <savegame num> <demoname>
+==============
+*/
+
+void D_CheckRecordFrom(void)
+{
+ int p;
+ char file[256];
+
+ p = M_CheckParm("-recordfrom");
+ if (!p || p > myargc - 2)
+ return;
+
+ if (cdrom)
+ {
+ sprintf(file, SAVEGAMENAMECD "%c.hsg", myargv[p + 1][0]);
+ }
+ else
+ {
+ sprintf(file, SAVEGAMENAME "%c.hsg", myargv[p + 1][0]);
+ }
+ G_LoadGame(file);
+ G_DoLoadGame(); // load the gameskill etc info from savegame
+
+ G_RecordDemo(gameskill, 1, gameepisode, gamemap, myargv[p + 2]);
+ D_DoomLoop(); // never returns
+}
+
+/*
+===============
+=
+= D_AddFile
+=
+===============
+*/
+
+// MAPDIR should be defined as the directory that holds development maps
+// for the -wart # # command
+
+#define MAPDIR "\\data\\"
+
+#define SHAREWAREWADNAME "heretic1.wad"
+
+char *iwadfile;
+
+char *basedefault = "heretic.cfg";
+
+void wadprintf(void)
+{
+ if (debugmode)
+ {
+ return;
+ }
+ // haleyjd FIXME: convert to textscreen code?
+#ifdef __WATCOMC__
+ _settextposition(23, 2);
+ _setbkcolor(1);
+ _settextcolor(0);
+ _outtext(exrnwads);
+ _settextposition(24, 2);
+ _outtext(exrnwads2);
+#endif
+}
+
+boolean D_AddFile(char *file)
+{
+ wad_file_t *handle;
+
+ printf(" adding %s\n", file);
+
+ handle = W_AddFile(file);
+
+ return handle != NULL;
+}
+
+//==========================================================
+//
+// Startup Thermo code
+//
+//==========================================================
+#define MSG_Y 9
+#define THERM_X 14
+#define THERM_Y 14
+
+int thermMax;
+int thermCurrent;
+char smsg[80]; // status bar line
+
+//
+// Heretic startup screen shit
+//
+
+static int startup_line = STARTUP_WINDOW_Y;
+
+void hprintf(char *string)
+{
+ if (using_graphical_startup)
+ {
+ TXT_BGColor(TXT_COLOR_CYAN, 0);
+ TXT_FGColor(TXT_COLOR_BRIGHT_WHITE);
+
+ TXT_GotoXY(STARTUP_WINDOW_X, startup_line);
+ ++startup_line;
+ TXT_Puts(string);
+
+ TXT_UpdateScreen();
+ }
+
+ // haleyjd: shouldn't be WATCOMC-only
+ if (debugmode)
+ puts(string);
+}
+
+void drawstatus(void)
+{
+ int i;
+
+ TXT_GotoXY(1, 24);
+ TXT_BGColor(TXT_COLOR_BLUE, 0);
+ TXT_FGColor(TXT_COLOR_BRIGHT_WHITE);
+
+ for (i=0; smsg[i] != '\0'; ++i)
+ {
+ TXT_PutChar(smsg[i]);
+ }
+}
+
+void status(char *string)
+{
+ if (using_graphical_startup)
+ {
+ strcat(smsg, string);
+ drawstatus();
+ }
+}
+
+void DrawThermo(void)
+{
+ static int last_progress = -1;
+ int progress;
+ int i;
+
+ if (!using_graphical_startup)
+ {
+ return;
+ }
+
+#if 0
+ progress = (98 * thermCurrent) / thermMax;
+ screen = (char *) 0xb8000 + (THERM_Y * 160 + THERM_X * 2);
+ for (i = 0; i < progress / 2; i++)
+ {
+ switch (i)
+ {
+ case 4:
+ case 9:
+ case 14:
+ case 19:
+ case 29:
+ case 34:
+ case 39:
+ case 44:
+ *screen++ = 0xb3;
+ *screen++ = (THERMCOLOR << 4) + 15;
+ break;
+ case 24:
+ *screen++ = 0xba;
+ *screen++ = (THERMCOLOR << 4) + 15;
+ break;
+ default:
+ *screen++ = 0xdb;
+ *screen++ = 0x40 + THERMCOLOR;
+ break;
+ }
+ }
+ if (progress & 1)
+ {
+ *screen++ = 0xdd;
+ *screen++ = 0x40 + THERMCOLOR;
+ }
+#else
+
+ // No progress? Don't update the screen.
+
+ progress = (50 * thermCurrent) / thermMax + 2;
+
+ if (last_progress == progress)
+ {
+ return;
+ }
+
+ last_progress = progress;
+
+ TXT_GotoXY(THERM_X, THERM_Y);
+
+ TXT_FGColor(TXT_COLOR_BRIGHT_GREEN);
+ TXT_BGColor(TXT_COLOR_GREEN, 0);
+
+ for (i = 0; i < progress; i++)
+ {
+ TXT_PutChar(0xdb);
+ }
+
+ TXT_UpdateScreen();
+#endif
+}
+
+void initStartup(void)
+{
+ byte *textScreen;
+ byte *loading;
+
+ if (!graphical_startup || debugmode)
+ {
+ using_graphical_startup = false;
+ return;
+ }
+
+ if (!TXT_Init())
+ {
+ using_graphical_startup = false;
+ return;
+ }
+
+ // Blit main screen
+ textScreen = TXT_GetScreenData();
+ loading = W_CacheLumpName(DEH_String("LOADING"), PU_CACHE);
+ memcpy(textScreen, loading, 4000);
+
+ // Print version string
+
+ TXT_BGColor(TXT_COLOR_RED, 0);
+ TXT_FGColor(TXT_COLOR_YELLOW);
+ TXT_GotoXY(46, 2);
+ TXT_Puts(HERETIC_VERSION_TEXT);
+
+ TXT_UpdateScreen();
+
+ using_graphical_startup = true;
+}
+
+static void finishStartup(void)
+{
+ if (using_graphical_startup)
+ {
+ TXT_Shutdown();
+ }
+}
+
+char tmsg[300];
+void tprintf(char *msg, int initflag)
+{
+ // haleyjd FIXME: convert to textscreen code?
+#ifdef __WATCOMC__
+ char temp[80];
+ int start;
+ int add;
+ int i;
+
+ if (initflag)
+ tmsg[0] = 0;
+ strcat(tmsg, msg);
+ blitStartup();
+ DrawThermo();
+ _setbkcolor(4);
+ _settextcolor(15);
+ for (add = start = i = 0; i <= strlen(tmsg); i++)
+ if ((tmsg[i] == '\n') || (!tmsg[i]))
+ {
+ memset(temp, 0, 80);
+ strncpy(temp, tmsg + start, i - start);
+ _settextposition(MSG_Y + add, 40 - strlen(temp) / 2);
+ _outtext(temp);
+ start = i + 1;
+ add++;
+ }
+ _settextposition(25, 1);
+ drawstatus();
+#else
+ printf("%s", msg);
+#endif
+}
+
+// haleyjd: moved up, removed WATCOMC code
+void CleanExit(void)
+{
+ DEH_printf("Exited from HERETIC.\n");
+ exit(1);
+}
+
+void CheckAbortStartup(void)
+{
+ // haleyjd: removed WATCOMC
+ // haleyjd FIXME: this should actually work in text mode too, but how to
+ // get input before SDL video init?
+ if(using_graphical_startup)
+ {
+ if(TXT_GetChar() == 27)
+ CleanExit();
+ }
+}
+
+void IncThermo(void)
+{
+ thermCurrent++;
+ DrawThermo();
+ CheckAbortStartup();
+}
+
+void InitThermo(int max)
+{
+ thermMax = max;
+ thermCurrent = 0;
+}
+
+//
+// Add configuration file variable bindings.
+//
+
+void D_BindVariables(void)
+{
+ extern int screenblocks;
+ extern int snd_Channels;
+ int i;
+
+ M_ApplyPlatformDefaults();
+
+ I_BindVideoVariables();
+ I_BindJoystickVariables();
+ I_BindSoundVariables();
+
+ M_BindBaseControls();
+ M_BindHereticControls();
+ M_BindWeaponControls();
++ M_BindChatControls(MAXPLAYERS);
+
+ M_BindMenuControls();
+ M_BindMapControls();
+
+ M_BindVariable("mouse_sensitivity", &mouseSensitivity);
+ M_BindVariable("sfx_volume", &snd_MaxVolume);
+ M_BindVariable("music_volume", &snd_MusicVolume);
+ M_BindVariable("screenblocks", &screenblocks);
+ M_BindVariable("snd_channels", &snd_Channels);
+ M_BindVariable("show_endoom", &show_endoom);
+ M_BindVariable("graphical_startup", &graphical_startup);
+
+ for (i=0; i<10; ++i)
+ {
+ char buf[12];
+
+ sprintf(buf, "chatmacro%i", i);
+ M_BindVariable(buf, &chat_macros[i]);
+ }
+}
+
+//
+// Called at exit to display the ENDOOM screen (ENDTEXT in Heretic)
+//
+
+static void D_Endoom(void)
+{
+ byte *endoom_data;
+
+ // Disable ENDOOM?
+
+ if (!show_endoom)
+ {
+ return;
+ }
+
+ endoom_data = W_CacheLumpName(DEH_String("ENDTEXT"), PU_STATIC);
+
+ I_Endoom(endoom_data);
+}
+
+//---------------------------------------------------------------------------
+//
+// PROC D_DoomMain
+//
+//---------------------------------------------------------------------------
+
+void D_DoomMain(void)
+{
+ int p;
+ char file[256];
+
+ I_PrintBanner(PACKAGE_STRING);
+
+ I_AtExit(D_Endoom, false);
+
+ M_FindResponseFile();
+ nomonsters = M_CheckParm("-nomonsters");
+ respawnparm = M_CheckParm("-respawn");
+ ravpic = M_CheckParm("-ravpic");
+ noartiskip = M_CheckParm("-noartiskip");
+ debugmode = M_CheckParm("-debug");
+ startskill = sk_medium;
+ startepisode = 1;
+ startmap = 1;
+ autostart = false;
+
+//
+// get skill / episode / map from parms
+//
+ if (M_CheckParm("-deathmatch"))
+ {
+ deathmatch = true;
+ }
+
+ p = M_CheckParm("-skill");
+ if (p && p < myargc - 1)
+ {
+ startskill = myargv[p + 1][0] - '1';
+ autostart = true;
+ }
+
+ p = M_CheckParm("-episode");
+ if (p && p < myargc - 1)
+ {
+ startepisode = myargv[p + 1][0] - '0';
+ startmap = 1;
+ autostart = true;
+ }
+
+ p = M_CheckParm("-warp");
+ if (p && p < myargc - 2)
+ {
+ startepisode = myargv[p + 1][0] - '0';
+ startmap = myargv[p + 2][0] - '0';
+ autostart = true;
+ }
+
+//
+// init subsystems
+//
+ DEH_printf("V_Init: allocate screens.\n");
+ V_Init();
+
+ // Check for -CDROM
+
+ cdrom = false;
+
+#ifdef _WIN32
+
+ //!
+ // @platform windows
+ // @vanilla
+ //
+ // Save configuration data and savegames in c:\heretic.cd,
+ // allowing play from CD.
+ //
+
+ if (M_CheckParm("-cdrom"))
+ {
+ cdrom = true;
+ }
+#endif
+
+ if (cdrom)
+ {
+ M_SetConfigDir(DEH_String("c:\\heretic.cd"));
+ }
+ else
+ {
+ M_SetConfigDir(NULL);
+ }
+
+ // Load defaults before initing other systems
+ DEH_printf("M_LoadDefaults: Load system defaults.\n");
+ D_BindVariables();
+ M_SetConfigFilenames("heretic.cfg", PROGRAM_PREFIX "heretic.cfg");
+ M_LoadDefaults();
+
+ I_AtExit(M_SaveDefaults, false);
+
+ DEH_printf("Z_Init: Init zone memory allocation daemon.\n");
+ Z_Init();
+
+#ifdef FEATURE_DEHACKED
+ printf("DEH_Init: Init Dehacked support.\n");
+ DEH_Init();
+#endif
+
+ DEH_printf("W_Init: Init WADfiles.\n");
+
+ iwadfile = D_FindIWAD(IWAD_MASK_HERETIC, &gamemission);
+
+ if (iwadfile == NULL)
+ {
+ I_Error("Game mode indeterminate. No IWAD was found. Try specifying\n"
+ "one with the '-iwad' command line parameter.");
+ }
+
+ D_AddFile(iwadfile);
+ W_ParseCommandLine();
+
+ p = M_CheckParm("-playdemo");
+ if (!p)
+ {
+ p = M_CheckParm("-timedemo");
+ }
+ if (p && p < myargc - 1)
+ {
+ DEH_snprintf(file, sizeof(file), "%s.lmp", myargv[p + 1]);
+ D_AddFile(file);
+ DEH_printf("Playing demo %s.lmp.\n", myargv[p + 1]);
+ }
+
+ if (W_CheckNumForName(DEH_String("E2M1")) == -1)
+ {
+ gamemode = shareware;
+ gamedescription = "Heretic (shareware)";
+ }
+ else if (W_CheckNumForName("EXTENDED") != -1)
+ {
+ // Presence of the EXTENDED lump indicates the retail version
+
+ gamemode = retail;
+ gamedescription = "Heretic: Shadow of the Serpent Riders";
+ }
+ else
+ {
+ gamemode = registered;
+ gamedescription = "Heretic (registered)";
+ }
+
+ I_PrintStartupBanner(gamedescription);
+
+ // haleyjd: removed WATCOMC
+ initStartup();
+
+ //
+ // Build status bar line!
+ //
+ smsg[0] = 0;
+ if (deathmatch)
+ status(DEH_String("DeathMatch..."));
+ if (nomonsters)
+ status(DEH_String("No Monsters..."));
+ if (respawnparm)
+ status(DEH_String("Respawning..."));
+ if (autostart)
+ {
+ char temp[64];
+ DEH_snprintf(temp, sizeof(temp),
+ "Warp to Episode %d, Map %d, Skill %d ",
+ startepisode, startmap, startskill + 1);
+ status(temp);
+ }
+ wadprintf(); // print the added wadfiles
+
+ tprintf(DEH_String("MN_Init: Init menu system.\n"), 1);
+ MN_Init();
+
+ CT_Init();
+
+ tprintf(DEH_String("R_Init: Init Heretic refresh daemon."), 1);
+ hprintf(DEH_String("Loading graphics"));
+ R_Init();
+ tprintf("\n", 0);
+
+ tprintf(DEH_String("P_Init: Init Playloop state.\n"), 1);
+ hprintf(DEH_String("Init game engine."));
+ P_Init();
+ IncThermo();
+
+ tprintf(DEH_String("I_Init: Setting up machine state.\n"), 1);
+ I_CheckIsScreensaver();
+ I_InitTimer();
+ I_InitJoystick();
+ IncThermo();
+
+ tprintf(DEH_String("S_Init: Setting up sound.\n"), 1);
+ S_Init();
+ //IO_StartupTimer();
+ S_Start();
+
+ tprintf(DEH_String("D_CheckNetGame: Checking network game status.\n"), 1);
+ hprintf(DEH_String("Checking network game status."));
+ D_CheckNetGame();
+ IncThermo();
+
+ // haleyjd: removed WATCOMC
+
+ tprintf(DEH_String("SB_Init: Loading patches.\n"), 1);
+ SB_Init();
+ IncThermo();
+
+//
+// start the apropriate game based on parms
+//
+
+ D_CheckRecordFrom();
+
+ p = M_CheckParm("-record");
+ if (p && p < myargc - 1)
+ {
+ G_RecordDemo(startskill, 1, startepisode, startmap, myargv[p + 1]);
+ D_DoomLoop(); // Never returns
+ }
+
+ p = M_CheckParm("-playdemo");
+ if (p && p < myargc - 1)
+ {
+ singledemo = true; // Quit after one demo
+ G_DeferedPlayDemo(myargv[p + 1]);
+ D_DoomLoop(); // Never returns
+ }
+
+ p = M_CheckParm("-timedemo");
+ if (p && p < myargc - 1)
+ {
+ G_TimeDemo(myargv[p + 1]);
+ D_DoomLoop(); // Never returns
+ }
+
+ p = M_CheckParm("-loadgame");
+ if (p && p < myargc - 1)
+ {
+ if (cdrom)
+ {
+ sprintf(file, SAVEGAMENAMECD "%c.hsg", myargv[p + 1][0]);
+ }
+ else
+ {
+ sprintf(file, SAVEGAMENAME "%c.hsg", myargv[p + 1][0]);
+ }
+ G_LoadGame(file);
+ }
+
+ // Check valid episode and map
+ if (autostart || netgame)
+ {
+ if (!D_ValidEpisodeMap(gamemission, gamemode, startepisode, startmap))
+ {
+ startepisode = 1;
+ startmap = 1;
+ }
+ }
+
+ if (gameaction != ga_loadgame)
+ {
+ UpdateState |= I_FULLSCRN;
+ BorderNeedRefresh = true;
+ if (autostart || netgame)
+ {
+ G_InitNew(startskill, startepisode, startmap);
+ }
+ else
+ {
+ D_StartTitle();
+ }
+ }
+
+ finishStartup();
+
+ D_DoomLoop(); // Never returns
+}
diff --cc src/hexen/h2_main.c
index a20bd91a,00000000..abc58f15
mode 100644,000000..100644
--- a/src/hexen/h2_main.c
+++ b/src/hexen/h2_main.c
@@@ -1,862 -1,0 +1,863 @@@
+// Emacs style mode select -*- C++ -*-
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 1993-1996 Id Software, Inc.
+// Copyright(C) 1993-2008 Raven Software
+// Copyright(C) 2008 Simon Howard
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+//-----------------------------------------------------------------------------
+
+
+// HEADER FILES ------------------------------------------------------------
+
+// haleyjd: removed WATCOMC
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "config.h"
+
+#include "h2def.h"
+#include "ct_chat.h"
+#include "d_iwad.h"
+#include "d_mode.h"
+#include "m_misc.h"
+#include "s_sound.h"
+#include "i_joystick.h"
+#include "i_system.h"
+#include "i_timer.h"
+#include "m_argv.h"
+#include "m_config.h"
+#include "m_controls.h"
+#include "p_local.h"
+#include "v_video.h"
+#include "w_main.h"
+
+// MACROS ------------------------------------------------------------------
+
+#define MAXWADFILES 20
+
+// TYPES -------------------------------------------------------------------
+
+typedef struct
+{
+ char *name;
+ void (*func) (char **args, int tag);
+ int requiredArgs;
+ int tag;
+} execOpt_t;
+
+// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
+
+void R_ExecuteSetViewSize(void);
+void D_CheckNetGame(void);
+void G_BuildTiccmd(ticcmd_t * cmd);
+void F_Drawer(void);
+boolean F_Responder(event_t * ev);
+void I_StartupKeyboard(void);
+void I_StartupJoystick(void);
+void I_ShutdownKeyboard(void);
+void S_InitScript(void);
+
+// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
+
+void H2_ProcessEvents(void);
+void H2_DoAdvanceDemo(void);
+void H2_AdvanceDemo(void);
+void H2_StartTitle(void);
+void H2_PageTicker(void);
+
+// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
+
+static void DrawMessage(void);
+static void PageDrawer(void);
+static void HandleArgs(void);
+static void CheckRecordFrom(void);
+static void DrawAndBlit(void);
+static void ExecOptionSCRIPTS(char **args, int tag);
+static void ExecOptionSKILL(char **args, int tag);
+static void ExecOptionPLAYDEMO(char **args, int tag);
+static void CreateSavePath(void);
+static void WarpCheck(void);
+
+// EXTERNAL DATA DECLARATIONS ----------------------------------------------
+
+extern boolean automapactive;
+extern boolean MenuActive;
+extern boolean askforquit;
+extern char *SavePath;
+
+// PUBLIC DATA DEFINITIONS -------------------------------------------------
+
+GameMode_t gamemode;
+GameMission_t gamemission;
+char *iwadfile;
+boolean nomonsters; // checkparm of -nomonsters
+boolean respawnparm; // checkparm of -respawn
+boolean randomclass; // checkparm of -randclass
+boolean debugmode; // checkparm of -debug
+boolean ravpic; // checkparm of -ravpic
+boolean cdrom = false; // true if cd-rom mode active
+boolean cmdfrag; // true if a CMD_FRAG packet should be sent out
+boolean singletics; // debug flag to cancel adaptiveness
+boolean artiskip; // whether shift-enter skips an artifact
+int maxzone = 0x800000; // Maximum allocated for zone heap (8meg default)
+skill_t startskill;
+int startepisode;
+int startmap;
+boolean autostart;
+boolean advancedemo;
+FILE *debugfile;
+int UpdateState;
+
+// PRIVATE DATA DEFINITIONS ------------------------------------------------
+
+static int WarpMap;
+static int demosequence;
+static int pagetic;
+static char *pagename;
+
+static execOpt_t ExecOptions[] = {
+ {"-scripts", ExecOptionSCRIPTS, 1, 0},
+ {"-skill", ExecOptionSKILL, 1, 0},
+ {"-playdemo", ExecOptionPLAYDEMO, 1, 0},
+ {"-timedemo", ExecOptionPLAYDEMO, 1, 0},
+ {NULL, NULL, 0, 0} // Terminator
+};
+
+// CODE --------------------------------------------------------------------
+
+void D_BindVariables(void)
+{
+ int i;
+
+ M_ApplyPlatformDefaults();
+
+ I_BindVideoVariables();
+ I_BindJoystickVariables();
+ I_BindSoundVariables();
+
+ M_BindBaseControls();
+ M_BindMapControls();
+ M_BindMenuControls();
+ M_BindWeaponControls();
++ M_BindChatControls(MAXPLAYERS);
+ M_BindHereticControls();
+ M_BindHexenControls();
+
+ M_BindVariable("graphical_startup", &graphical_startup);
+ M_BindVariable("mouse_sensitivity", &mouseSensitivity);
+ M_BindVariable("sfx_volume", &snd_MaxVolume);
+ M_BindVariable("music_volume", &snd_MusicVolume);
+ M_BindVariable("messageson", &messageson);
+ M_BindVariable("screenblocks", &screenblocks);
+ M_BindVariable("snd_channels", &snd_Channels);
+ M_BindVariable("savedir", &SavePath);
+
+ // Multiplayer chat macros
+
+ for (i=0; i<10; ++i)
+ {
+ char buf[12];
+
+ sprintf(buf, "chatmacro%i", i);
+ M_BindVariable(buf, &chat_macros[i]);
+ }
+}
+
+// Set the default directory where hub savegames are saved.
+
+static void D_SetDefaultSavePath(void)
+{
+ SavePath = malloc(strlen(configdir) + 10);
+ sprintf(SavePath, "%shexndata%c", configdir, DIR_SEPARATOR);
+}
+
+//
+// D_GrabMouseCallback
+//
+// Called to determine whether to grab the mouse pointer
+//
+
+static boolean D_GrabMouseCallback(void)
+{
+ // when menu is active or game is paused, release the mouse
+
+ if (MenuActive || paused)
+ return false;
+
+ // only grab mouse when playing levels (but not demos)
+
+ return (gamestate == GS_LEVEL) && !demoplayback;
+}
+
+// Message displayed when quitting Hexen
+
+static void D_HexenQuitMessage(void)
+{
+ printf("\nHexen: Beyond Heretic\n");
+}
+
+static void D_AddFile(char *filename)
+{
+ printf(" adding %s\n", filename);
+
+ W_AddFile(filename);
+}
+
+//==========================================================================
+//
+// H2_Main
+//
+//==========================================================================
+void InitMapMusicInfo(void);
+
+void D_DoomMain(void)
+{
+ int p;
+
+ I_AtExit(D_HexenQuitMessage, false);
+ M_FindResponseFile();
+ startepisode = 1;
+ autostart = false;
+ startskill = sk_medium;
+ startmap = 1;
+ gamemode = commercial;
+
+ // Initialize subsystems
+
+ ST_Message("V_Init: allocate screens.\n");
+ V_Init();
+
+ // Load defaults before initing other systems
+ ST_Message("M_LoadDefaults: Load system defaults.\n");
+ D_BindVariables();
+
+#ifdef _WIN32
+
+ //!
+ // @platform windows
+ // @vanilla
+ //
+ // Save configuration data and savegames in c:\hexndata,
+ // allowing play from CD.
+ //
+
+ cdrom = M_ParmExists("-cdrom");
+#endif
+
+ if (cdrom)
+ {
+ M_SetConfigDir("c:\\hexndata\\");
+ }
+ else
+ {
+ M_SetConfigDir(NULL);
+ }
+
+ D_SetDefaultSavePath();
+ M_SetConfigFilenames("hexen.cfg", PROGRAM_PREFIX "hexen.cfg");
+ M_LoadDefaults();
+
+ I_AtExit(M_SaveDefaults, false);
+
+
+ // Now that the savedir is loaded from .CFG, make sure it exists
+ CreateSavePath();
+
+ ST_Message("Z_Init: Init zone memory allocation daemon.\n");
+ Z_Init();
+
+ // haleyjd: removed WATCOMC
+
+ ST_Message("W_Init: Init WADfiles.\n");
+
+ iwadfile = D_FindIWAD(IWAD_MASK_HEXEN, &gamemission);
+
+ if (iwadfile == NULL)
+ {
+ I_Error("Game mode indeterminate. No IWAD was found. Try specifying\n"
+ "one with the '-iwad' command line parameter.");
+ }
+
+ D_AddFile(iwadfile);
+
+ HandleArgs();
+
+ I_PrintStartupBanner("Hexen");
+
+ ST_Message("MN_Init: Init menu system.\n");
+ MN_Init();
+
+ ST_Message("CT_Init: Init chat mode data.\n");
+ CT_Init();
+
+ InitMapMusicInfo(); // Init music fields in mapinfo
+
+ ST_Message("S_InitScript\n");
+ S_InitScript();
+
+ ST_Message("SN_InitSequenceScript: Registering sound sequences.\n");
+ SN_InitSequenceScript();
+ ST_Message("I_Init: Setting up machine state.\n");
+ I_CheckIsScreensaver();
+ I_InitTimer();
+ I_InitJoystick();
+
+ S_Init();
+ S_Start();
+
+ ST_Message("ST_Init: Init startup screen.\n");
+ ST_Init();
+
+ // Show version message now, so it's visible during R_Init()
+ ST_Message("R_Init: Init Hexen refresh daemon");
+ R_Init();
+ ST_Message("\n");
+
+ if (M_CheckParm("-net"))
+ ST_NetProgress(); // Console player found
+
+ ST_Message("P_Init: Init Playloop state.\n");
+ P_Init();
+
+ // Check for command line warping. Follows P_Init() because the
+ // MAPINFO.TXT script must be already processed.
+ WarpCheck();
+
+ if (autostart)
+ {
+ ST_Message("Warp to Map %d (\"%s\":%d), Skill %d\n",
+ WarpMap, P_GetMapName(startmap), startmap, startskill + 1);
+ }
+
+ ST_Message("D_CheckNetGame: Checking network game status.\n");
+ D_CheckNetGame();
+
+ ST_Message("SB_Init: Loading patches.\n");
+ SB_Init();
+
+ ST_Done();
+
+ CheckRecordFrom();
+
+ p = M_CheckParm("-record");
+ if (p && p < myargc - 1)
+ {
+ G_RecordDemo(startskill, 1, startepisode, startmap, myargv[p + 1]);
+ H2_GameLoop(); // Never returns
+ }
+
+ p = M_CheckParm("-playdemo");
+ if (p && p < myargc - 1)
+ {
+ singledemo = true; // Quit after one demo
+ G_DeferedPlayDemo(myargv[p + 1]);
+ H2_GameLoop(); // Never returns
+ }
+
+ p = M_CheckParm("-timedemo");
+ if (p && p < myargc - 1)
+ {
+ G_TimeDemo(myargv[p + 1]);
+ H2_GameLoop(); // Never returns
+ }
+
+ p = M_CheckParm("-loadgame");
+ if (p && p < myargc - 1)
+ {
+ G_LoadGame(atoi(myargv[p + 1]));
+ }
+
+ if (gameaction != ga_loadgame)
+ {
+ UpdateState |= I_FULLSCRN;
+ BorderNeedRefresh = true;
+ if (autostart || netgame)
+ {
+ G_StartNewInit();
+ G_InitNew(startskill, startepisode, startmap);
+ }
+ else
+ {
+ H2_StartTitle();
+ }
+ }
+ H2_GameLoop(); // Never returns
+}
+
+//==========================================================================
+//
+// HandleArgs
+//
+//==========================================================================
+
+static void HandleArgs(void)
+{
+ int p;
+ execOpt_t *opt;
+
+ nomonsters = M_ParmExists("-nomonsters");
+ respawnparm = M_ParmExists("-respawn");
+ randomclass = M_ParmExists("-randclass");
+ ravpic = M_ParmExists("-ravpic");
+ artiskip = M_ParmExists("-artiskip");
+ debugmode = M_ParmExists("-debug");
+ deathmatch = M_ParmExists("-deathmatch");
+
+ cmdfrag = M_ParmExists("-cmdfrag");
+
+ // Check WAD file command line options
+ W_ParseCommandLine();
+
+ // Process command line options
+ for (opt = ExecOptions; opt->name != NULL; opt++)
+ {
+ p = M_CheckParm(opt->name);
+ if (p && p < myargc - opt->requiredArgs)
+ {
+ opt->func(&myargv[p], opt->tag);
+ }
+ }
+}
+
+//==========================================================================
+//
+// WarpCheck
+//
+//==========================================================================
+
+static void WarpCheck(void)
+{
+ int p;
+ int map;
+
+ p = M_CheckParm("-warp");
+ if (p && p < myargc - 1)
+ {
+ WarpMap = atoi(myargv[p + 1]);
+ map = P_TranslateMap(WarpMap);
+ if (map == -1)
+ { // Couldn't find real map number
+ startmap = 1;
+ ST_Message("-WARP: Invalid map number.\n");
+ }
+ else
+ { // Found a valid startmap
+ startmap = map;
+ autostart = true;
+ }
+ }
+ else
+ {
+ WarpMap = 1;
+ startmap = P_TranslateMap(1);
+ if (startmap == -1)
+ {
+ startmap = 1;
+ }
+ }
+}
+
+//==========================================================================
+//
+// ExecOptionSKILL
+//
+//==========================================================================
+
+static void ExecOptionSKILL(char **args, int tag)
+{
+ startskill = args[1][0] - '1';
+ autostart = true;
+}
+
+//==========================================================================
+//
+// ExecOptionPLAYDEMO
+//
+//==========================================================================
+
+static void ExecOptionPLAYDEMO(char **args, int tag)
+{
+ char file[256];
+
+ strcpy(file, args[1]);
+
+ if (strcasecmp(file + strlen(file) - 4, ".lmp") != 0)
+ {
+ strcat(file, ".lmp");
+ }
+
+ W_AddFile(file);
+ ST_Message("Playing demo %s.\n", file);
+}
+
+//==========================================================================
+//
+// ExecOptionSCRIPTS
+//
+//==========================================================================
+
+static void ExecOptionSCRIPTS(char **args, int tag)
+{
+ sc_FileScripts = true;
+ sc_ScriptsDir = args[1];
+}
+
+
+//==========================================================================
+//
+// H2_GameLoop
+//
+//==========================================================================
+
+void H2_GameLoop(void)
+{
+ if (M_CheckParm("-debugfile"))
+ {
+ char filename[20];
+ sprintf(filename, "debug%i.txt", consoleplayer);
+ debugfile = fopen(filename, "w");
+ }
+ I_SetWindowTitle("Hexen");
+ I_InitGraphics();
+ I_SetGrabMouseCallback(D_GrabMouseCallback);
+
+ while (1)
+ {
+ // Frame syncronous IO operations
+ I_StartFrame();
+
+ // Process one or more tics
+ if (singletics)
+ {
+ I_StartTic();
+ H2_ProcessEvents();
+ G_BuildTiccmd(&netcmds[consoleplayer][maketic % BACKUPTICS]);
+ if (advancedemo)
+ {
+ H2_DoAdvanceDemo();
+ }
+ G_Ticker();
+ gametic++;
+ maketic++;
+ }
+ else
+ {
+ // Will run at least one tic
+ TryRunTics();
+ }
+
+ // Move positional sounds
+ S_UpdateSounds(players[displayplayer].mo);
+
+ DrawAndBlit();
+ }
+}
+
+//==========================================================================
+//
+// H2_ProcessEvents
+//
+// Send all the events of the given timestamp down the responder chain.
+//
+//==========================================================================
+
+void H2_ProcessEvents(void)
+{
+ event_t *ev;
+
+ for (;;)
+ {
+ ev = D_PopEvent();
+
+ if (ev == NULL)
+ {
+ break;
+ }
+
+ if (F_Responder(ev))
+ {
+ continue;
+ }
+ if (MN_Responder(ev))
+ {
+ continue;
+ }
+ G_Responder(ev);
+ }
+}
+
+//==========================================================================
+//
+// DrawAndBlit
+//
+//==========================================================================
+
+static void DrawAndBlit(void)
+{
+ // Change the view size if needed
+ if (setsizeneeded)
+ {
+ R_ExecuteSetViewSize();
+ }
+
+ // Do buffered drawing
+ switch (gamestate)
+ {
+ case GS_LEVEL:
+ if (!gametic)
+ {
+ break;
+ }
+ if (automapactive)
+ {
+ AM_Drawer();
+ }
+ else
+ {
+ R_RenderPlayerView(&players[displayplayer]);
+ }
+ CT_Drawer();
+ UpdateState |= I_FULLVIEW;
+ SB_Drawer();
+ break;
+ case GS_INTERMISSION:
+ IN_Drawer();
+ break;
+ case GS_FINALE:
+ F_Drawer();
+ break;
+ case GS_DEMOSCREEN:
+ PageDrawer();
+ break;
+ }
+
+ if (paused && !MenuActive && !askforquit)
+ {
+ if (!netgame)
+ {
+ V_DrawPatch(160, viewwindowy + 5, W_CacheLumpName("PAUSED",
+ PU_CACHE));
+ }
+ else
+ {
+ V_DrawPatch(160, 70, W_CacheLumpName("PAUSED", PU_CACHE));
+ }
+ }
+
+ // Draw current message
+ DrawMessage();
+
+ // Draw Menu
+ MN_Drawer();
+
+ // Send out any new accumulation
+ NetUpdate();
+
+ // Flush buffered stuff to screen
+ I_FinishUpdate();
+}
+
+//==========================================================================
+//
+// DrawMessage
+//
+//==========================================================================
+
+static void DrawMessage(void)
+{
+ player_t *player;
+
+ player = &players[consoleplayer];
+ if (player->messageTics <= 0 || !player->message)
+ { // No message
+ return;
+ }
+ if (player->yellowMessage)
+ {
+ MN_DrTextAYellow(player->message,
+ 160 - MN_TextAWidth(player->message) / 2, 1);
+ }
+ else
+ {
+ MN_DrTextA(player->message, 160 - MN_TextAWidth(player->message) / 2,
+ 1);
+ }
+}
+
+//==========================================================================
+//
+// H2_PageTicker
+//
+//==========================================================================
+
+void H2_PageTicker(void)
+{
+ if (--pagetic < 0)
+ {
+ H2_AdvanceDemo();
+ }
+}
+
+//==========================================================================
+//
+// PageDrawer
+//
+//==========================================================================
+
+static void PageDrawer(void)
+{
+ V_DrawRawScreen(W_CacheLumpName(pagename, PU_CACHE));
+ if (demosequence == 1)
+ {
+ V_DrawPatch(4, 160, W_CacheLumpName("ADVISOR", PU_CACHE));
+ }
+ UpdateState |= I_FULLSCRN;
+}
+
+//==========================================================================
+//
+// H2_AdvanceDemo
+//
+// Called after each demo or intro demosequence finishes.
+//
+//==========================================================================
+
+void H2_AdvanceDemo(void)
+{
+ advancedemo = true;
+}
+
+//==========================================================================
+//
+// H2_DoAdvanceDemo
+//
+//==========================================================================
+
+void H2_DoAdvanceDemo(void)
+{
+ players[consoleplayer].playerstate = PST_LIVE; // don't reborn
+ advancedemo = false;
+ usergame = false; // can't save/end game here
+ paused = false;
+ gameaction = ga_nothing;
+ demosequence = (demosequence + 1) % 7;
+ switch (demosequence)
+ {
+ case 0:
+ pagetic = 280;
+ gamestate = GS_DEMOSCREEN;
+ pagename = "TITLE";
+ S_StartSongName("hexen", true);
+ break;
+ case 1:
+ pagetic = 210;
+ gamestate = GS_DEMOSCREEN;
+ pagename = "TITLE";
+ break;
+ case 2:
+ BorderNeedRefresh = true;
+ UpdateState |= I_FULLSCRN;
+ G_DeferedPlayDemo("demo1");
+ break;
+ case 3:
+ pagetic = 200;
+ gamestate = GS_DEMOSCREEN;
+ pagename = "CREDIT";
+ break;
+ case 4:
+ BorderNeedRefresh = true;
+ UpdateState |= I_FULLSCRN;
+ G_DeferedPlayDemo("demo2");
+ break;
+ case 5:
+ pagetic = 200;
+ gamestate = GS_DEMOSCREEN;
+ pagename = "CREDIT";
+ break;
+ case 6:
+ BorderNeedRefresh = true;
+ UpdateState |= I_FULLSCRN;
+ G_DeferedPlayDemo("demo3");
+ break;
+ }
+}
+
+//==========================================================================
+//
+// H2_StartTitle
+//
+//==========================================================================
+
+void H2_StartTitle(void)
+{
+ gameaction = ga_nothing;
+ demosequence = -1;
+ H2_AdvanceDemo();
+}
+
+//==========================================================================
+//
+// CheckRecordFrom
+//
+// -recordfrom <savegame num> <demoname>
+//
+//==========================================================================
+
+static void CheckRecordFrom(void)
+{
+ int p;
+
+ p = M_CheckParm("-recordfrom");
+ if (!p || p > myargc - 2)
+ { // Bad args
+ return;
+ }
+ G_LoadGame(atoi(myargv[p + 1]));
+ G_DoLoadGame(); // Load the gameskill etc info from savegame
+ G_RecordDemo(gameskill, 1, gameepisode, gamemap, myargv[p + 2]);
+
+ H2_GameLoop(); // Never returns
+}
+
+// haleyjd: removed WATCOMC
+/*
+void CleanExit(void)
+{
+ union REGS regs;
+
+ I_ShutdownKeyboard();
+ regs.x.eax = 0x3;
+ int386(0x10, ®s, ®s);
+ printf("Exited from HEXEN: Beyond Heretic.\n");
+ exit(1);
+}
+*/
+
+//==========================================================================
+//
+// CreateSavePath
+//
+//==========================================================================
+
+static void CreateSavePath(void)
+{
+ M_MakeDirectory(SavePath);
+}
+
diff --cc src/i_sdlsound.c
index 0b3f8aa3,a758289a..7deb683d
--- a/src/i_sdlsound.c
+++ b/src/i_sdlsound.c
@@@ -39,16 -38,18 +38,18 @@@
#include <samplerate.h>
#endif
-#include "deh_main.h"
+#include "deh_str.h"
+#include "i_sound.h"
#include "i_system.h"
+ #include "i_swap.h"
-#include "s_sound.h"
#include "m_argv.h"
#include "w_wad.h"
#include "z_zone.h"
-#include "doomdef.h"
+#include "doomtype.h"
#define LOW_PASS_FILTER
+ //#define DEBUG_DUMP_WAVS
#define MAX_SOUND_SLICE_TIME 70 /* ms */
#define NUM_CHANNELS 16
@@@ -288,16 -160,64 +289,66 @@@ static boolean ConvertibleRatio(int fre
}
}
+ #ifdef DEBUG_DUMP_WAVS
+
+ // Debug code to dump resampled sound effects to WAV files for analysis.
+
+ static void WriteWAV(char *filename, byte *data,
+ uint32_t length, int samplerate)
+ {
+ FILE *wav;
+ unsigned int i;
+ unsigned short s;
+
+ wav = fopen(filename, "wb");
+
+ // Header
+
+ fwrite("RIFF", 1, 4, wav);
+ i = LONG(36 + samplerate);
+ fwrite(&i, 4, 1, wav);
+ fwrite("WAVE", 1, 4, wav);
+
+ // Subchunk 1
+
+ fwrite("fmt ", 1, 4, wav);
+ i = LONG(16);
+ fwrite(&i, 4, 1, wav); // Length
+ s = SHORT(1);
+ fwrite(&s, 2, 1, wav); // Format (PCM)
+ s = SHORT(2);
+ fwrite(&s, 2, 1, wav); // Channels (2=stereo)
+ i = LONG(samplerate);
+ fwrite(&i, 4, 1, wav); // Sample rate
+ i = LONG(samplerate * 2 * 2);
+ fwrite(&i, 4, 1, wav); // Byte rate (samplerate * stereo * 16 bit)
+ s = SHORT(2 * 2);
+ fwrite(&s, 2, 1, wav); // Block align (stereo * 16 bit)
+ s = SHORT(16);
+ fwrite(&s, 2, 1, wav); // Bits per sample (16 bit)
+
+ // Data subchunk
+
+ fwrite("data", 1, 4, wav);
+ i = LONG(length);
+ fwrite(&i, 4, 1, wav); // Data length
+ fwrite(data, 1, length, wav); // Data
+
+ fclose(wav);
+ }
+
+ #endif
+
// Generic sound expansion function for any sample rate.
+// Returns number of clipped samples (always 0).
-static void ExpandSoundData_SDL(byte *data,
+static void ExpandSoundData_SDL(sfxinfo_t *sfxinfo,
+ byte *data,
int samplerate,
- uint32_t length,
- Mix_Chunk *destination)
+ int length)
{
SDL_AudioCVT convertor;
+ Mix_Chunk *chunk;
uint32_t expanded_length;
// Calculate the length of the expanded version of the sample.
@@@ -307,13 -227,12 +358,13 @@@
// Double up twice: 8 -> 16 bit and mono -> stereo
expanded_length *= 4;
- destination->alen = expanded_length;
- destination->abuf
- = Z_Malloc(expanded_length, PU_STATIC, &destination->abuf);
+
+ // Allocate a chunk in which to expand the sound
+
+ chunk = AllocateChunk(sfxinfo, expanded_length);
// If we can, use the standard / optimized SDL conversion routines.
-
+
if (samplerate <= mixer_freq
&& ConvertibleRatio(samplerate, mixer_freq)
&& SDL_BuildAudioCVT(&convertor,
@@@ -417,21 -350,64 +471,31 @@@ static boolean CacheSFX(sfxinfo_t *sfxi
// 16 bit sample rate field, 32 bit length field
- *samplerate = (data[3] << 8) | data[2];
- *length = (data[7] << 24) | (data[6] << 16) | (data[5] << 8) | data[4];
+ samplerate = (data[3] << 8) | data[2];
+ length = (data[7] << 24) | (data[6] << 16) | (data[5] << 8) | data[4];
- // If the header specifies that the length of the sound is
- // greater than the length of the lump itself, this is an invalid
- // sound lump.
+ // If the header specifies that the length of the sound is greater than
+ // the length of the lump itself, this is an invalid sound lump
- if (*length > lumplen - 8)
+ if (length > lumplen - 8)
{
- W_ReleaseLumpNum(*lumpnum);
- return false;
- }
-
- // Prune header
- *data_ref += 8;
-
- return true;
-}
-
-
-// Load and convert a sound effect
-// Returns true if successful
-
-static boolean CacheSFX_SDL(int sound)
-{
- int lumpnum;
- int samplerate;
- uint32_t length;
- byte *data;
-
-#ifdef HAVE_LIBSAMPLERATE
- assert(!use_libsamplerate); // Should be using I_PrecacheSounds_SRC instead
-#endif
-
- if (!LoadSoundLump(sound, &lumpnum, &samplerate, &length, &data))
return false;
+ }
// Sample rate conversion
- // sound_chunks[sound].alen and abuf are determined by ExpandSoundData.
-
- sound_chunks[sound].allocated = 1;
- sound_chunks[sound].volume = MIX_MAX_VOLUME;
- ExpandSoundData_SDL(data,
- samplerate,
- length,
- &sound_chunks[sound]);
+ ExpandSoundData(sfxinfo, data + 8, samplerate, length);
+ #ifdef DEBUG_DUMP_WAVS
+ {
+ char filename[16];
+
+ sprintf(filename, "%s.wav", DEH_String(S_sfx[sound].name));
+ WriteWAV(filename, sound_chunks[sound].abuf,
+ sound_chunks[sound].alen, mixer_freq);
+ }
+ #endif
+
// don't need the original lump any more
W_ReleaseLumpNum(lumpnum);
diff --cc src/i_sound.c
index cf9e17a3,00000000..0c771dc2
mode 100644,000000..100644
--- a/src/i_sound.c
+++ b/src/i_sound.c
@@@ -1,431 -1,0 +1,436 @@@
+// Emacs style mode select -*- C++ -*-
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 1993-1996 Id Software, Inc.
+// Copyright(C) 2005 Simon Howard
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+// DESCRIPTION: none
+//
+//-----------------------------------------------------------------------------
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "SDL_mixer.h"
+
+#include "config.h"
+#include "doomfeatures.h"
+#include "doomtype.h"
+
+#include "i_sound.h"
+#include "i_video.h"
+#include "m_argv.h"
+#include "m_config.h"
+
+// Sound sample rate to use for digital output (Hz)
+
+int snd_samplerate = 44100;
+
+// Low-level sound and music modules we are using
+
+static sound_module_t *sound_module;
+static music_module_t *music_module;
+
+int snd_musicdevice = SNDDEVICE_GENMIDI;
+int snd_sfxdevice = SNDDEVICE_SB;
+
+// Sound modules
+
+extern sound_module_t sound_sdl_module;
+extern sound_module_t sound_pcsound_module;
+extern music_module_t music_sdl_module;
+extern music_module_t music_opl_module;
+
++// For OPL module:
++
++extern int opl_io_port;
++
+// DOS-specific options: These are unused but should be maintained
+// so that the config file can be shared between chocolate
+// doom and doom.exe
+
+static int snd_sbport = 0;
+static int snd_sbirq = 0;
+static int snd_sbdma = 0;
+static int snd_mport = 0;
+
+// Compiled-in sound modules:
+
+static sound_module_t *sound_modules[] =
+{
+#ifdef FEATURE_SOUND
+ &sound_sdl_module,
+ &sound_pcsound_module,
+#endif
+ NULL,
+};
+
+// Compiled-in music modules:
+
+static music_module_t *music_modules[] =
+{
+#ifdef FEATURE_SOUND
+ &music_sdl_module,
+ &music_opl_module,
+#endif
+ NULL,
+};
+
+// Check if a sound device is in the given list of devices
+
+static boolean SndDeviceInList(snddevice_t device, snddevice_t *list,
+ int len)
+{
+ int i;
+
+ for (i=0; i<len; ++i)
+ {
+ if (device == list[i])
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// Find and initialize a sound_module_t appropriate for the setting
+// in snd_sfxdevice.
+
+static void InitSfxModule(boolean use_sfx_prefix)
+{
+ int i;
+
+ sound_module = NULL;
+
+ for (i=0; sound_modules[i] != NULL; ++i)
+ {
+ // Is the sfx device in the list of devices supported by
+ // this module?
+
+ if (SndDeviceInList(snd_sfxdevice,
+ sound_modules[i]->sound_devices,
+ sound_modules[i]->num_sound_devices))
+ {
+ // Initialize the module
+
+ if (sound_modules[i]->Init(use_sfx_prefix))
+ {
+ sound_module = sound_modules[i];
+ return;
+ }
+ }
+ }
+}
+
+// Initialize music according to snd_musicdevice.
+
+static void InitMusicModule(void)
+{
+ int i;
+
+ music_module = NULL;
+
+ for (i=0; music_modules[i] != NULL; ++i)
+ {
+ // Is the music device in the list of devices supported
+ // by this module?
+
+ if (SndDeviceInList(snd_musicdevice,
+ music_modules[i]->sound_devices,
+ music_modules[i]->num_sound_devices))
+ {
+ // Initialize the module
+
+ if (music_modules[i]->Init())
+ {
+ music_module = music_modules[i];
+ return;
+ }
+ }
+ }
+}
+
+//
+// Initializes sound stuff, including volume
+// Sets channels, SFX and music volume,
+// allocates channel buffer, sets S_sfx lookup.
+//
+
+void I_InitSound(boolean use_sfx_prefix)
+{
+ boolean nosound, nosfx, nomusic;
+
+ //!
+ // @vanilla
+ //
+ // Disable all sound output.
+ //
+
+ nosound = M_CheckParm("-nosound") > 0;
+
+ //!
+ // @vanilla
+ //
+ // Disable sound effects.
+ //
+
+ nosfx = M_CheckParm("-nosfx") > 0;
+
+ //!
+ // @vanilla
+ //
+ // Disable music.
+ //
+
+ nomusic = M_CheckParm("-nomusic") > 0;
+
+ // Initialize the sound and music subsystems.
+
+ if (!nosound && !screensaver_mode)
+ {
+ if (!nosfx)
+ {
+ InitSfxModule(use_sfx_prefix);
+ }
+
+ if (!nomusic)
+ {
+ InitMusicModule();
+ }
+ }
+}
+
+void I_ShutdownSound(void)
+{
+ if (sound_module != NULL)
+ {
+ sound_module->Shutdown();
+ }
+
+ if (music_module != NULL)
+ {
+ music_module->Shutdown();
+ }
+}
+
+int I_GetSfxLumpNum(sfxinfo_t *sfxinfo)
+{
+ if (sound_module != NULL)
+ {
+ return sound_module->GetSfxLumpNum(sfxinfo);
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+void I_UpdateSound(void)
+{
+ if (sound_module != NULL)
+ {
+ sound_module->Update();
+ }
+}
+
+static void CheckVolumeSeparation(int *sep, int *vol)
+{
+ if (*sep < 0)
+ {
+ *sep = 0;
+ }
+ else if (*sep > 254)
+ {
+ *sep = 254;
+ }
+
+ if (*vol < 0)
+ {
+ *vol = 0;
+ }
+ else if (*vol > 127)
+ {
+ *vol = 127;
+ }
+}
+
+void I_UpdateSoundParams(int channel, int vol, int sep)
+{
+ if (sound_module != NULL)
+ {
+ CheckVolumeSeparation(&vol, &sep);
+ sound_module->UpdateSoundParams(channel, vol, sep);
+ }
+}
+
+int I_StartSound(sfxinfo_t *sfxinfo, int channel, int vol, int sep)
+{
+ if (sound_module != NULL)
+ {
+ CheckVolumeSeparation(&vol, &sep);
+ return sound_module->StartSound(sfxinfo, channel, vol, sep);
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+void I_StopSound(int channel)
+{
+ if (sound_module != NULL)
+ {
+ sound_module->StopSound(channel);
+ }
+}
+
+boolean I_SoundIsPlaying(int channel)
+{
+ if (sound_module != NULL)
+ {
+ return sound_module->SoundIsPlaying(channel);
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void I_PrecacheSounds(sfxinfo_t *sounds, int num_sounds)
+{
+ if (sound_module != NULL && sound_module->CacheSounds != NULL)
+ {
+ sound_module->CacheSounds(sounds, num_sounds);
+ }
+}
+
+void I_InitMusic(void)
+{
+}
+
+void I_ShutdownMusic(void)
+{
+
+}
+
+void I_SetMusicVolume(int volume)
+{
+ if (music_module != NULL)
+ {
+ music_module->SetMusicVolume(volume);
+ }
+}
+
+void I_PauseSong(void)
+{
+ if (music_module != NULL)
+ {
+ music_module->PauseMusic();
+ }
+}
+
+void I_ResumeSong(void)
+{
+ if (music_module != NULL)
+ {
+ music_module->ResumeMusic();
+ }
+}
+
+void *I_RegisterSong(void *data, int len)
+{
+ if (music_module != NULL)
+ {
+ return music_module->RegisterSong(data, len);
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+void I_UnRegisterSong(void *handle)
+{
+ if (music_module != NULL)
+ {
+ music_module->UnRegisterSong(handle);
+ }
+}
+
+void I_PlaySong(void *handle, boolean looping)
+{
+ if (music_module != NULL)
+ {
+ music_module->PlaySong(handle, looping);
+ }
+}
+
+void I_StopSong(void)
+{
+ if (music_module != NULL)
+ {
+ music_module->StopSong();
+ }
+}
+
+boolean I_MusicIsPlaying(void)
+{
+ if (music_module != NULL)
+ {
+ return music_module->MusicIsPlaying();
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void I_BindSoundVariables(void)
+{
+ extern int use_libsamplerate;
+
+ M_BindVariable("snd_musicdevice", &snd_musicdevice);
+ M_BindVariable("snd_sfxdevice", &snd_sfxdevice);
+ M_BindVariable("snd_sbport", &snd_sbport);
+ M_BindVariable("snd_sbirq", &snd_sbirq);
+ M_BindVariable("snd_sbdma", &snd_sbdma);
+ M_BindVariable("snd_mport", &snd_mport);
+ M_BindVariable("snd_samplerate", &snd_samplerate);
++ M_BindVariable("opl_io_port", &opl_io_port);
+#ifdef FEATURE_SOUND
+ M_BindVariable("use_libsamplerate", &use_libsamplerate);
+#endif
+
+ // Before SDL_mixer version 1.2.11, MIDI music caused the game
+ // to crash when it looped. If this is an old SDL_mixer version,
+ // disable MIDI.
+
+#ifdef __MACOSX__
+ {
+ const SDL_version *v = Mix_Linked_Version();
+
+ if (SDL_VERSIONNUM(v->major, v->minor, v->patch)
+ < SDL_VERSIONNUM(1, 2, 11))
+ {
+ snd_musicdevice = SNDDEVICE_NONE;
+ }
+ }
+#endif
+}
+
diff --cc src/i_video.c
index a370fc08,ee10a12e..733af899
--- a/src/i_video.c
+++ b/src/i_video.c
@@@ -153,15 -105,13 +151,19 @@@ static boolean initialized = false
// disable mouse?
static boolean nomouse = false;
-extern int usemouse;
+int usemouse = 1;
+ // Bit mask of mouse button state.
+
+ static unsigned int mouse_button_state = 0;
+
-// if true, screens[0] is screen->pixel
+// Disallow mouse and joystick movement to cause forward/backward
+// motion. Specified with the '-novert' command line parameter.
+// This is an int to allow saving to config file
+
+int novert = 0;
+
+// if true, I_VideoBuffer is screen->pixels
static boolean native_surface;
@@@ -257,10 -186,8 +265,12 @@@ static int shiftdown = 0
float mouse_acceleration = 2.0;
int mouse_threshold = 10;
+// Gamma correction level to use
+
+int usegamma = 0;
+
+ static void ApplyWindowResize(unsigned int w, unsigned int h);
+
static boolean MouseShouldBeGrabbed()
{
// never grab the mouse when in screensaver mode
@@@ -777,17 -662,9 +815,17 @@@ static void I_ReadMouse(void
if (x != 0 || y != 0)
{
ev.type = ev_mouse;
- ev.data1 = MouseButtonState();
+ ev.data1 = mouse_button_state;
ev.data2 = AccelerateMouse(x);
- ev.data3 = -AccelerateMouse(y);
+
+ if (!novert)
+ {
+ ev.data3 = -AccelerateMouse(y);
+ }
+ else
+ {
+ ev.data3 = 0;
+ }
D_PostEvent(&ev);
}
@@@ -1727,7 -1656,20 +1856,20 @@@ void I_InitGraphics(void
CheckCommandLine();
- doompal = W_CacheLumpName (DEH_String("PLAYPAL"),PU_CACHE);
+ // Set up title and icon. Windows cares about the ordering; this
+ // has to be done before the call to SDL_SetVideoMode.
+
- I_SetWindowCaption();
++ I_InitWindowTitle();
+ #if !SDL_VERSION_ATLEAST(1, 3, 0)
- I_SetWindowIcon();
++ I_InitWindowIcon();
+ #endif
+
+ //
+ // Enter into graphics mode.
+ //
+ // When in screensaver mode, run full screen and auto detect
+ // screen dimensions (don't change video mode)
+ //
if (screensaver_mode)
{
diff --cc src/i_video.h
index af865287,94ffcc29..82368967
--- a/src/i_video.h
+++ b/src/i_video.h
@@@ -30,47 -30,34 +30,49 @@@
#include "doomtype.h"
+// Screen width and height.
+
+#define SCREENWIDTH 320
+#define SCREENHEIGHT 200
+
+// Screen width used for "squash" scale functions
+
+#define SCREENWIDTH_4_3 256
+
+// Screen height used for "stretch" scale functions.
+
+#define SCREENHEIGHT_4_3 240
+
- typedef struct
+ #define MAX_MOUSE_BUTTONS 8
+
+ typedef struct
{
- // Screen width and height
+ // Screen width and height
- int width;
- int height;
+ int width;
+ int height;
- // Initialisation function to call when using this mode.
- // Called with a pointer to the Doom palette.
- //
- // If NULL, no init function is called.
+ // Initialisation function to call when using this mode.
+ // Called with a pointer to the Doom palette.
+ //
+ // If NULL, no init function is called.
- void (*InitMode)(byte *palette);
-
- // Function to call to draw the screen from the source buffer.
- // Return true if draw was successful.
+ void (*InitMode)(byte *palette);
+
+ // Function to call to draw the screen from the source buffer.
+ // Return true if draw was successful.
- boolean (*DrawScreen)(int x1, int y1, int x2, int y2);
+ boolean (*DrawScreen)(int x1, int y1, int x2, int y2);
- // If true, this is a "poor quality" mode. The autoadjust
- // code should always attempt to use a different mode to this
- // mode in fullscreen.
+ // If true, this is a "poor quality" mode. The autoadjust
+ // code should always attempt to use a different mode to this
+ // mode in fullscreen.
- boolean poor_quality;
+ boolean poor_quality;
} screen_mode_t;
+typedef boolean (*grabmouse_callback_t)(void);
+
// Called by D_DoomMain,
// determines the hardware configuration
// and sets up the video mode
diff --cc src/m_config.c
index 056861cc,2065700e..8b93cfd3
--- a/src/m_config.c
+++ b/src/m_config.c
@@@ -95,18 -250,23 +96,23 @@@ typedef struc
typedef struct
{
default_t *defaults;
- int numdefaults;
- char *filename;
+ int numdefaults;
+ char *filename;
} default_collection_t;
-#define CONFIG_VARIABLE_GENERIC(name, variable, type) \
- { #name, &variable, type, 0, 0 }
++#define CONFIG_VARIABLE_GENERIC(name, type) \
++ { #name, NULL, type, 0, 0, false }
+
-#define CONFIG_VARIABLE_KEY(name, variable) \
- CONFIG_VARIABLE_GENERIC(name, variable, DEFAULT_KEY)
-#define CONFIG_VARIABLE_INT(name, variable) \
- CONFIG_VARIABLE_GENERIC(name, variable, DEFAULT_INT)
-#define CONFIG_VARIABLE_INT_HEX(name, variable) \
- CONFIG_VARIABLE_GENERIC(name, variable, DEFAULT_INT_HEX)
-#define CONFIG_VARIABLE_FLOAT(name, variable) \
- CONFIG_VARIABLE_GENERIC(name, variable, DEFAULT_FLOAT)
-#define CONFIG_VARIABLE_STRING(name, variable) \
- CONFIG_VARIABLE_GENERIC(name, variable, DEFAULT_STRING)
+#define CONFIG_VARIABLE_KEY(name) \
- { #name, NULL, DEFAULT_KEY, 0, 0, false }
++ CONFIG_VARIABLE_GENERIC(name, DEFAULT_KEY)
+#define CONFIG_VARIABLE_INT(name) \
- { #name, NULL, DEFAULT_INT, 0, 0, false }
++ CONFIG_VARIABLE_GENERIC(name, DEFAULT_INT)
++#define CONFIG_VARIABLE_INT_HEX(name) \
++ CONFIG_VARIABLE_GENERIC(name, DEFAULT_INT_HEX)
+#define CONFIG_VARIABLE_FLOAT(name) \
- { #name, NULL, DEFAULT_FLOAT, 0, 0, false }
++ CONFIG_VARIABLE_GENERIC(name, DEFAULT_FLOAT)
+#define CONFIG_VARIABLE_STRING(name) \
- { #name, NULL, DEFAULT_STRING, 0, 0, false }
++ CONFIG_VARIABLE_GENERIC(name, DEFAULT_STRING)
//! @begin_config_file default.cfg
@@@ -578,15 -645,22 +584,22 @@@ static default_t extra_defaults_list[]
// acceleration factor (mouse_acceleration).
//
- CONFIG_VARIABLE_INT(mouse_threshold, mouse_threshold),
+ CONFIG_VARIABLE_INT(mouse_threshold),
//!
- // Sound output sample rate, in Hz. Typical values to use are
+ // Sound output sample rate, in Hz. Typical values to use are
// 11025, 22050, 44100 and 48000.
//
- CONFIG_VARIABLE_INT(snd_samplerate, snd_samplerate),
+ CONFIG_VARIABLE_INT(snd_samplerate),
+ //!
+ // The I/O port to use to access the OPL chip. Only relevant when
+ // using native OPL music playback.
+ //
+
- CONFIG_VARIABLE_INT_HEX(opl_io_port, opl_io_port),
++ CONFIG_VARIABLE_INT_HEX(opl_io_port),
+
//!
// If non-zero, the ENDOOM screen is displayed when exiting the
// game. If zero, the ENDOOM screen is not displayed.
@@@ -679,8 -753,20 +692,20 @@@
// Joystick button to strafe right.
//
- CONFIG_VARIABLE_INT(joyb_straferight, joybstraferight),
+ CONFIG_VARIABLE_INT(joyb_straferight),
+ //!
+ // Joystick button to cycle to the previous weapon.
+ //
+
- CONFIG_VARIABLE_INT(joyb_prevweapon, joybprevweapon),
++ CONFIG_VARIABLE_INT(joyb_prevweapon),
+
+ //!
+ // Joystick button to cycle to the next weapon.
+ //
+
- CONFIG_VARIABLE_INT(joyb_nextweapon, joybnextweapon),
++ CONFIG_VARIABLE_INT(joyb_nextweapon),
+
//!
// Mouse button to strafe left.
//
@@@ -703,8 -789,20 +728,20 @@@
// Mouse button to move backwards.
//
- CONFIG_VARIABLE_INT(mouseb_backward, mousebbackward),
+ CONFIG_VARIABLE_INT(mouseb_backward),
+ //!
+ // Mouse button to cycle to the previous weapon.
+ //
+
- CONFIG_VARIABLE_INT(mouseb_prevweapon, mousebprevweapon),
++ CONFIG_VARIABLE_INT(mouseb_prevweapon),
+
+ //!
+ // Mouse button to cycle to the next weapon.
+ //
+
- CONFIG_VARIABLE_INT(mouseb_nextweapon, mousebnextweapon),
++ CONFIG_VARIABLE_INT(mouseb_nextweapon),
+
//!
// If non-zero, double-clicking a mouse button acts like pressing
// the "use" key to use an object in-game, eg. a door or switch.
@@@ -855,8 -953,14 +892,14 @@@
// Keyboard shortcut to toggle the gamma correction level.
//
- CONFIG_VARIABLE_KEY(key_menu_gamma, key_menu_gamma),
+ CONFIG_VARIABLE_KEY(key_menu_gamma),
+ //!
+ // Keyboard shortcut to switch view in multiplayer.
+ //
+
- CONFIG_VARIABLE_KEY(key_spy, key_spy),
++ CONFIG_VARIABLE_KEY(key_spy),
+
//!
// Keyboard shortcut to increase the screen size.
//
@@@ -987,13 -1091,61 +1030,85 @@@
// Key to select weapon 8.
//
- CONFIG_VARIABLE_KEY(key_weapon8, key_weapon8),
+ CONFIG_VARIABLE_KEY(key_weapon8),
+ //!
+ // Key to cycle to the previous weapon.
+ //
+
- CONFIG_VARIABLE_KEY(key_prevweapon, key_prevweapon),
++ CONFIG_VARIABLE_KEY(key_prevweapon),
+
+ //!
+ // Key to cycle to the next weapon.
+ //
+
- CONFIG_VARIABLE_KEY(key_nextweapon, key_nextweapon),
++ CONFIG_VARIABLE_KEY(key_nextweapon),
+
//!
// Key to re-display last message.
//
- CONFIG_VARIABLE_KEY(key_message_refresh, key_message_refresh),
+ CONFIG_VARIABLE_KEY(key_message_refresh),
+
+ //!
+ // Key to quit the game when recording a demo.
+ //
+
- CONFIG_VARIABLE_KEY(key_demo_quit, key_demo_quit),
++ CONFIG_VARIABLE_KEY(key_demo_quit),
+
+ //!
+ // Key to send a message during multiplayer games.
+ //
+
- CONFIG_VARIABLE_KEY(key_multi_msg, key_multi_msg),
++ CONFIG_VARIABLE_KEY(key_multi_msg),
++
++ //!
++ // Key to send a message to player 1 during multiplayer games.
++ //
++
++ CONFIG_VARIABLE_KEY(key_multi_msgplayer1),
++
++ //!
++ // Key to send a message to player 2 during multiplayer games.
++ //
++
++ CONFIG_VARIABLE_KEY(key_multi_msgplayer2),
++
++ //!
++ // Key to send a message to player 3 during multiplayer games.
++ //
++
++ CONFIG_VARIABLE_KEY(key_multi_msgplayer3),
+
+ //!
- // Key to send a message to the green player during multiplayer games.
++ // Key to send a message to player 4 during multiplayer games.
+ //
+
- CONFIG_VARIABLE_KEY(key_multi_msgplayer1, key_multi_msgplayer[0]),
++ CONFIG_VARIABLE_KEY(key_multi_msgplayer4),
+
+ //!
- // Key to send a message to the indigo player during multiplayer games.
++ // Key to send a message to player 5 during multiplayer games.
+ //
+
- CONFIG_VARIABLE_KEY(key_multi_msgplayer2, key_multi_msgplayer[1]),
++ CONFIG_VARIABLE_KEY(key_multi_msgplayer5),
+
+ //!
- // Key to send a message to the brown player during multiplayer games.
++ // Key to send a message to player 6 during multiplayer games.
+ //
+
- CONFIG_VARIABLE_KEY(key_multi_msgplayer3, key_multi_msgplayer[2]),
++ CONFIG_VARIABLE_KEY(key_multi_msgplayer6),
+
+ //!
- // Key to send a message to the red player during multiplayer games.
++ // Key to send a message to player 7 during multiplayer games.
+ //
+
- CONFIG_VARIABLE_KEY(key_multi_msgplayer4, key_multi_msgplayer[3]),
++ CONFIG_VARIABLE_KEY(key_multi_msgplayer7),
++
++ //!
++ // Key to send a message to player 8 during multiplayer games.
++ //
++
++ CONFIG_VARIABLE_KEY(key_multi_msgplayer8)
};
static default_collection_t extra_defaults =
@@@ -1183,53 -1313,61 +1302,54 @@@ static void LoadDefaultCollection(defau
// Find the setting in the list
- for (i=0; i<collection->numdefaults; ++i)
+ def = SearchCollection(collection, defname);
+
+ if (def == NULL || !def->bound)
{
- default_t *def = &collection->defaults[i];
- char *s;
- int intparm;
-
- if (strcmp(defname, def->name) != 0)
- {
- // not this one
- continue;
- }
-
- // parameter found
-
- switch (def->type)
- {
- case DEFAULT_STRING:
- s = strdup(strparm + 1);
- s[strlen(s) - 1] = '\0';
- * (char **) def->location = s;
- break;
-
- case DEFAULT_INT:
- case DEFAULT_INT_HEX:
- * (int *) def->location = ParseIntParameter(strparm);
- break;
-
- case DEFAULT_KEY:
-
- // translate scancodes read from config
- // file (save the old value in untranslated)
-
- intparm = ParseIntParameter(strparm);
- defaults[i].untranslated = intparm;
- if (intparm >= 0 && intparm < 128)
- {
- intparm = scantokey[intparm];
- }
- else
- {
- intparm = 0;
- }
+ // Unknown variable? Unbound variables are also treated
+ // as unknown.
+
+ continue;
+ }
+
+ // parameter found
+
+ switch (def->type)
+ {
+ case DEFAULT_STRING:
+ s = strdup(strparm + 1);
+ s[strlen(s) - 1] = '\0';
+ * (char **) def->location = s;
+ break;
+
+ case DEFAULT_INT:
++ case DEFAULT_INT_HEX:
+ * (int *) def->location = ParseIntParameter(strparm);
+ break;
+
+ case DEFAULT_KEY:
- defaults[i].original_translated = intparm;
- * (int *) def->location = intparm;
- break;
+ // translate scancodes read from config
+ // file (save the old value in untranslated)
- case DEFAULT_FLOAT:
- * (float *) def->location = (float) atof(strparm);
- break;
- }
+ intparm = ParseIntParameter(strparm);
+ def->untranslated = intparm;
+ if (intparm >= 0 && intparm < 128)
+ {
+ intparm = scantokey[intparm];
+ }
+ else
+ {
+ intparm = 0;
+ }
- // finish
+ def->original_translated = intparm;
+ * (int *) def->location = intparm;
+ break;
- break;
+ case DEFAULT_FLOAT:
+ * (float *) def->location = (float) atof(strparm);
+ break;
}
}
diff --cc src/m_controls.c
index 98b1e51b,00000000..60a96ac2
mode 100644,000000..100644
--- a/src/m_controls.c
+++ b/src/m_controls.c
@@@ -1,350 -1,0 +1,393 @@@
+// Emacs style mode select -*- C++ -*-
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 1993-1996 Id Software, Inc.
+// Copyright(C) 1993-2008 Raven Software
+// Copyright(C) 2005-8 Simon Howard
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+//-----------------------------------------------------------------------------
+
++#include <stdio.h>
++
+#include "doomtype.h"
+#include "doomkeys.h"
+
+#include "m_config.h"
+
+//
+// Keyboard controls
+//
+
+int key_right = KEY_RIGHTARROW;
+int key_left = KEY_LEFTARROW;
+
+int key_up = KEY_UPARROW;
+int key_down = KEY_DOWNARROW;
+int key_strafeleft = ',';
+int key_straferight = '.';
+int key_fire = KEY_RCTRL;
+int key_use = ' ';
+int key_strafe = KEY_RALT;
+int key_speed = KEY_RSHIFT;
+
+//
+// Heretic keyboard controls
+//
+
+int key_flyup = KEY_PGUP;
+int key_flydown = KEY_INS;
+int key_flycenter = KEY_HOME;
+
+int key_lookup = KEY_PGDN;
+int key_lookdown = KEY_DEL;
+int key_lookcenter = KEY_END;
+
+int key_invleft = '[';
+int key_invright = ']';
+int key_useartifact = KEY_ENTER;
+
+//
+// Hexen key controls
+//
+
+int key_jump = '/';
+
+//
+// Mouse controls
+//
+
+int mousebfire = 0;
+int mousebstrafe = 1;
+int mousebforward = 2;
+
+int mousebjump = -1;
+
+int mousebstrafeleft = -1;
+int mousebstraferight = -1;
+int mousebbackward = -1;
+int mousebuse = -1;
+
++int mousebprevweapon = -1;
++int mousebnextweapon = -1;
++
++
+int key_message_refresh = KEY_ENTER;
+int key_pause = KEY_PAUSE;
++int key_demo_quit = 'q';
++int key_spy = KEY_F12;
++
++// Multiplayer chat keys:
++
++int key_multi_msg = 't';
++int key_multi_msgplayer[8];
+
+// Weapon selection keys:
+
+int key_weapon1 = '1';
+int key_weapon2 = '2';
+int key_weapon3 = '3';
+int key_weapon4 = '4';
+int key_weapon5 = '5';
+int key_weapon6 = '6';
+int key_weapon7 = '7';
+int key_weapon8 = '8';
++int key_prevweapon = 0;
++int key_nextweapon = 0;
+
- // Map cotnrols keys:
++// Map control keys:
+
+int key_map_north = KEY_UPARROW;
+int key_map_south = KEY_DOWNARROW;
+int key_map_east = KEY_RIGHTARROW;
+int key_map_west = KEY_LEFTARROW;
+int key_map_zoomin = '=';
+int key_map_zoomout = '-';
+int key_map_toggle = KEY_TAB;
+int key_map_maxzoom = '0';
+int key_map_follow = 'f';
+int key_map_grid = 'g';
+int key_map_mark = 'm';
+int key_map_clearmark = 'c';
+
+// menu keys:
+
+int key_menu_activate = KEY_ESCAPE;
+int key_menu_up = KEY_UPARROW;
+int key_menu_down = KEY_DOWNARROW;
+int key_menu_left = KEY_LEFTARROW;
+int key_menu_right = KEY_RIGHTARROW;
+int key_menu_back = KEY_BACKSPACE;
+int key_menu_forward = KEY_ENTER;
+int key_menu_confirm = 'y';
+int key_menu_abort = 'n';
+
+int key_menu_help = KEY_F1;
+int key_menu_save = KEY_F2;
+int key_menu_load = KEY_F3;
+int key_menu_volume = KEY_F4;
+int key_menu_detail = KEY_F5;
+int key_menu_qsave = KEY_F6;
+int key_menu_endgame = KEY_F7;
+int key_menu_messages = KEY_F8;
+int key_menu_qload = KEY_F9;
+int key_menu_quit = KEY_F10;
+int key_menu_gamma = KEY_F11;
+
+int key_menu_incscreen = KEY_EQUALS;
+int key_menu_decscreen = KEY_MINUS;
+
+//
+// Joystick controls
+//
+
+int joybfire = 0;
+int joybstrafe = 1;
+int joybuse = 3;
+int joybspeed = 2;
+
+int joybstrafeleft = -1;
+int joybstraferight = -1;
+
+int joybjump = -1;
+
++int joybprevweapon = -1;
++int joybnextweapon = -1;
++
+// Control whether if a mouse button is double clicked, it acts like
+// "use" has been pressed
+
+int dclick_use = 1;
+
+//
+// Bind all of the common controls used by Doom and all other games.
+//
+
+void M_BindBaseControls(void)
+{
+ M_BindVariable("key_right", &key_right),
+ M_BindVariable("key_left", &key_left),
+ M_BindVariable("key_up", &key_up),
+ M_BindVariable("key_down", &key_down),
+ M_BindVariable("key_strafeleft", &key_strafeleft),
+ M_BindVariable("key_straferight", &key_straferight),
+ M_BindVariable("key_fire", &key_fire),
+ M_BindVariable("key_use", &key_use),
+ M_BindVariable("key_strafe", &key_strafe),
+ M_BindVariable("key_speed", &key_speed),
+
+ M_BindVariable("mouseb_fire", &mousebfire),
+ M_BindVariable("mouseb_strafe", &mousebstrafe),
+ M_BindVariable("mouseb_forward", &mousebforward),
+
+ M_BindVariable("joyb_fire", &joybfire),
+ M_BindVariable("joyb_strafe", &joybstrafe),
+ M_BindVariable("joyb_use", &joybuse),
+ M_BindVariable("joyb_speed", &joybspeed),
+
+ // Extra controls that are not in the Vanilla versions:
-
++
+ M_BindVariable("joyb_strafeleft", &joybstrafeleft);
+ M_BindVariable("joyb_straferight", &joybstraferight);
+ M_BindVariable("mouseb_strafeleft", &mousebstrafeleft);
+ M_BindVariable("mouseb_straferight", &mousebstraferight);
+ M_BindVariable("mouseb_use", &mousebuse);
+ M_BindVariable("mouseb_backward", &mousebbackward);
+ M_BindVariable("dclick_use", &dclick_use);
+ M_BindVariable("key_pause", &key_pause);
+ M_BindVariable("key_message_refresh", &key_message_refresh);
+}
+
+void M_BindHereticControls(void)
+{
+ M_BindVariable("key_flyup", &key_flyup);
+ M_BindVariable("key_flydown", &key_flydown);
+ M_BindVariable("key_flycenter", &key_flycenter);
+
+ M_BindVariable("key_lookup", &key_lookup);
+ M_BindVariable("key_lookdown", &key_lookdown);
+ M_BindVariable("key_lookcenter", &key_lookcenter);
+
+ M_BindVariable("key_invleft", &key_invleft);
+ M_BindVariable("key_invright", &key_invright);
+ M_BindVariable("key_useartifact", &key_useartifact);
+}
+
+void M_BindHexenControls(void)
+{
+ M_BindVariable("key_jump", &key_jump);
+ M_BindVariable("mouseb_jump", &mousebjump);
+ M_BindVariable("joyb_jump", &joybjump);
+}
+
+void M_BindWeaponControls(void)
+{
+ M_BindVariable("key_weapon1", &key_weapon1);
+ M_BindVariable("key_weapon2", &key_weapon2);
+ M_BindVariable("key_weapon3", &key_weapon3);
+ M_BindVariable("key_weapon4", &key_weapon4);
+ M_BindVariable("key_weapon5", &key_weapon5);
+ M_BindVariable("key_weapon6", &key_weapon6);
+ M_BindVariable("key_weapon7", &key_weapon7);
+ M_BindVariable("key_weapon8", &key_weapon8);
++
++ M_BindVariable("key_prevweapon", &key_prevweapon);
++ M_BindVariable("key_nextweapon", &key_nextweapon);
++
++ M_BindVariable("joyb_prevweapon", &joybprevweapon);
++ M_BindVariable("joyb_nextweapon", &joybnextweapon);
++
++ M_BindVariable("mouseb_prevweapon", &mousebprevweapon);
++ M_BindVariable("mouseb_nextweapon", &mousebnextweapon);
+}
+
+void M_BindMapControls(void)
+{
+ M_BindVariable("key_map_north", &key_map_north);
+ M_BindVariable("key_map_south", &key_map_south);
+ M_BindVariable("key_map_east", &key_map_east);
+ M_BindVariable("key_map_west", &key_map_west);
+ M_BindVariable("key_map_zoomin", &key_map_zoomin);
+ M_BindVariable("key_map_zoomout", &key_map_zoomout);
+ M_BindVariable("key_map_toggle", &key_map_toggle);
+ M_BindVariable("key_map_maxzoom", &key_map_maxzoom);
+ M_BindVariable("key_map_follow", &key_map_follow);
+ M_BindVariable("key_map_grid", &key_map_grid);
+ M_BindVariable("key_map_mark", &key_map_mark);
+ M_BindVariable("key_map_clearmark", &key_map_clearmark);
+}
+
+void M_BindMenuControls(void)
+{
+ M_BindVariable("key_menu_activate", &key_menu_activate);
+ M_BindVariable("key_menu_up", &key_menu_up);
+ M_BindVariable("key_menu_down", &key_menu_down);
+ M_BindVariable("key_menu_left", &key_menu_left);
+ M_BindVariable("key_menu_right", &key_menu_right);
+ M_BindVariable("key_menu_back", &key_menu_back);
+ M_BindVariable("key_menu_forward", &key_menu_forward);
+ M_BindVariable("key_menu_confirm", &key_menu_confirm);
+ M_BindVariable("key_menu_abort", &key_menu_abort);
+
+ M_BindVariable("key_menu_help", &key_menu_help);
+ M_BindVariable("key_menu_save", &key_menu_save);
+ M_BindVariable("key_menu_load", &key_menu_load);
+ M_BindVariable("key_menu_volume", &key_menu_volume);
+ M_BindVariable("key_menu_detail", &key_menu_detail);
+ M_BindVariable("key_menu_qsave", &key_menu_qsave);
+ M_BindVariable("key_menu_endgame", &key_menu_endgame);
+ M_BindVariable("key_menu_messages", &key_menu_messages);
+ M_BindVariable("key_menu_qload", &key_menu_qload);
+ M_BindVariable("key_menu_quit", &key_menu_quit);
+ M_BindVariable("key_menu_gamma", &key_menu_gamma);
+
+ M_BindVariable("key_menu_incscreen", &key_menu_incscreen);
+ M_BindVariable("key_menu_decscreen", &key_menu_decscreen);
++ M_BindVariable("key_demo_quit", &key_demo_quit);
++ M_BindVariable("key_spy", &key_spy);
++}
++
++void M_BindChatControls(unsigned int num_players)
++{
++ char name[20];
++ int i;
++
++ M_BindVariable("key_multi_msg", &key_multi_msg);
++
++ for (i=0; i<num_players; ++i)
++ {
++ sprintf(name, "key_multi_msgplayer%i", i + 1);
++ M_BindVariable(name, &key_multi_msgplayer[i]);
++ }
+}
+
+#ifdef _WIN32_WCE
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+static int SystemHasKeyboard(void)
+{
+ HKEY key;
+ DWORD valtype;
+ DWORD valsize;
+ DWORD result;
+
+ if (RegOpenKeyExW(HKEY_CURRENT_USER,
+ L"\\Software\\Microsoft\\Shell", 0,
+ KEY_READ, &key) != ERROR_SUCCESS)
+ {
+ return 0;
+ }
+
+ valtype = REG_SZ;
+ valsize = sizeof(DWORD);
+
+ if (RegQueryValueExW(key, L"HasKeyboard", NULL, &valtype,
+ (LPBYTE) &result, &valsize) != ERROR_SUCCESS)
+ {
+ result = 0;
+ }
+
+ // Close the key
+
+ RegCloseKey(key);
+
+ return result;
+}
+
+//
+// Apply custom defaults for Windows CE.
+//
+
+static void M_ApplyWindowsCEDefaults(void)
+{
+ // If the system doesn't have a keyboard, patch the default
+ // configuration to use the hardware keys.
+
+ if (!SystemHasKeyboard())
+ {
+ key_use = KEY_F1;
+ key_fire = KEY_F2;
+ key_menu_activate = KEY_F3;
+ key_map_toggle = KEY_F4;
+
+ key_menu_help = 0;
+ key_menu_save = 0;
+ key_menu_load = 0;
+ key_menu_volume = 0;
+
+ key_menu_confirm = KEY_ENTER;
+ key_menu_back = KEY_F2;
+ key_menu_abort = KEY_F2;
+ }
+}
+
+#endif
+
+//
+// Apply custom patches to the default values depending on the
+// platform we are running on.
+//
+
+void M_ApplyPlatformDefaults(void)
+{
+#ifdef _WIN32_WCE
+ M_ApplyWindowsCEDefaults();
+#endif
+}
+
diff --cc src/m_controls.h
index 2a4aa3df,73510861..389c94a0
--- a/src/m_controls.h
+++ b/src/m_controls.h
@@@ -36,58 -32,17 +36,66 @@@ extern int key_fire
extern int key_use;
extern int key_strafe;
extern int key_speed;
-extern int joybspeed;
-extern int vanilla_keyboard_mapping;
-extern int key_pause;
+extern int key_jump;
+
+extern int key_flyup;
+extern int key_flydown;
+extern int key_flycenter;
+extern int key_lookup;
+extern int key_lookdown;
+extern int key_lookcenter;
+extern int key_invleft;
+extern int key_invright;
+extern int key_useartifact;
-// Multiplayer messages:
+extern int key_message_refresh;
+extern int key_pause;
+ extern int key_multi_msg;
-extern int key_multi_msgplayer[];
++extern int key_multi_msgplayer[8];
++
+extern int key_weapon1;
+extern int key_weapon2;
+extern int key_weapon3;
+extern int key_weapon4;
+extern int key_weapon5;
+extern int key_weapon6;
+extern int key_weapon7;
+extern int key_weapon8;
+
++extern int key_demo_quit;
++extern int key_spy;
++extern int key_prevweapon;
++extern int key_nextweapon;
++
+extern int key_map_north;
+extern int key_map_south;
+extern int key_map_east;
+extern int key_map_west;
+extern int key_map_zoomin;
+extern int key_map_zoomout;
+extern int key_map_toggle;
+extern int key_map_maxzoom;
+extern int key_map_follow;
+extern int key_map_grid;
+extern int key_map_mark;
+extern int key_map_clearmark;
+
+extern int key_map_north;
+extern int key_map_south;
+extern int key_map_east;
+extern int key_map_west;
+extern int key_map_zoomin;
+extern int key_map_zoomout;
+extern int key_map_toggle;
+extern int key_map_maxzoom;
+extern int key_map_follow;
+extern int key_map_grid;
+extern int key_map_mark;
+extern int key_map_clearmark;
-// Menu keys:
+// menu keys:
extern int key_menu_activate;
extern int key_menu_up;
@@@ -114,37 -70,38 +122,44 @@@ extern int key_menu_gamma
extern int key_menu_incscreen;
extern int key_menu_decscreen;
-// Automap keys:
+extern int mousebfire;
+extern int mousebstrafe;
+extern int mousebforward;
-extern int key_map_north;
-extern int key_map_south;
-extern int key_map_east;
-extern int key_map_west;
-extern int key_map_zoomin;
-extern int key_map_zoomout;
-extern int key_map_toggle;
-extern int key_map_maxzoom;
-extern int key_map_follow;
-extern int key_map_grid;
-extern int key_map_mark;
-extern int key_map_clearmark;
+extern int mousebjump;
-// Weapon keys:
+extern int mousebstrafeleft;
+extern int mousebstraferight;
+extern int mousebbackward;
+extern int mousebuse;
-extern int key_weapon1;
-extern int key_weapon2;
-extern int key_weapon3;
-extern int key_weapon4;
-extern int key_weapon5;
-extern int key_weapon6;
-extern int key_weapon7;
-extern int key_weapon8;
-extern int key_prevweapon;
-extern int key_nextweapon;
++extern int mousebprevweapon;
++extern int mousebnextweapon;
+
-extern int key_message_refresh;
-extern int key_demo_quit;
+extern int joybfire;
+extern int joybstrafe;
+extern int joybuse;
+extern int joybspeed;
+
+extern int joybjump;
+
+extern int joybstrafeleft;
+extern int joybstraferight;
+
++extern int joybprevweapon;
++extern int joybnextweapon;
++
+extern int dclick_use;
-
++
+void M_BindBaseControls(void);
+void M_BindHereticControls(void);
+void M_BindHexenControls(void);
+void M_BindWeaponControls(void);
+void M_BindMapControls(void);
+void M_BindMenuControls(void);
++void M_BindChatControls(unsigned int num_players);
-void ConfigKeyboard(void);
+void M_ApplyPlatformDefaults(void);
-#endif /* #ifndef SETUP_KEYBOARD_H */
+#endif /* #ifndef __M_CONTROLS_H__ */
diff --cc src/setup/joystick.c
index 0094dd81,825cd8b5..fbe3a3f3
--- a/src/setup/joystick.c
+++ b/src/setup/joystick.c
@@@ -425,12 -432,9 +425,14 @@@ void ConfigJoystick(void
AddJoystickControl(button_table, "Strafe Left", &joybstrafeleft);
AddJoystickControl(button_table, "Strafe Right", &joybstraferight);
+ AddJoystickControl(button_table, "Previous weapon", &joybprevweapon);
+ AddJoystickControl(button_table, "Next weapon", &joybnextweapon);
+ if (gamemission == hexen)
+ {
+ AddJoystickControl(button_table, "Jump", &joybjump);
+ }
+
TXT_SignalConnect(joystick_button, "pressed", CalibrateJoystick, NULL);
TXT_SignalConnect(window, "closed", JoystickWindowClosed, NULL);
diff --cc src/setup/keyboard.c
index 6e746ee9,81976f85..3d9f9977
--- a/src/setup/keyboard.c
+++ b/src/setup/keyboard.c
@@@ -178,63 -229,28 +180,65 @@@ static void ConfigExtraKeys(TXT_UNCAST_
table = TXT_NewTable(2);
- TXT_SetColumnWidths(table, 25, 10);
+ TXT_SetColumnWidths(table, 20, 9);
- TXT_AddWidgets(table, TXT_NewLabel(" - Weapons - "),
- TXT_NewStrut(0, 0),
- NULL);
+ if (extra_keys)
+ {
+ // When we have extra controls, a scrollable pane must be used.
+
+ scrollpane = TXT_NewScrollPane(0, 13, table);
+ TXT_AddWidget(window, scrollpane);
+
+ AddSectionLabel(table, "View", false);
+
+ AddKeyControl(table, "Look up", &key_lookup);
+ AddKeyControl(table, "Look down", &key_lookdown);
+ AddKeyControl(table, "Center view", &key_lookcenter);
+
+ AddSectionLabel(table, "Flying", true);
+
+ AddKeyControl(table, "Fly up", &key_flyup);
+ AddKeyControl(table, "Fly down", &key_flydown);
+ AddKeyControl(table, "Fly center", &key_flycenter);
+
+ AddSectionLabel(table, "Inventory", true);
+
+ AddKeyControl(table, "Inventory left", &key_invleft);
+ AddKeyControl(table, "Inventory right", &key_invright);
+ AddKeyControl(table, "Use artifact", &key_useartifact);
+ }
+ else
+ {
+ TXT_AddWidget(window, table);
+ }
- AddKeyControl(table, "Weapon 1", &key_weapon1);
- AddKeyControl(table, "Weapon 2", &key_weapon2);
- AddKeyControl(table, "Weapon 3", &key_weapon3);
- AddKeyControl(table, "Weapon 4", &key_weapon4);
- AddKeyControl(table, "Weapon 5", &key_weapon5);
- AddKeyControl(table, "Weapon 6", &key_weapon6);
- AddKeyControl(table, "Weapon 7", &key_weapon7);
- AddKeyControl(table, "Weapon 8", &key_weapon8);
+ AddSectionLabel(table, "Weapons", extra_keys);
+
+ AddKeyControl(table, "Weapon 1", &key_weapon1);
+ AddKeyControl(table, "Weapon 2", &key_weapon2);
+ AddKeyControl(table, "Weapon 3", &key_weapon3);
+ AddKeyControl(table, "Weapon 4", &key_weapon4);
+ AddKeyControl(table, "Weapon 5", &key_weapon5);
+ AddKeyControl(table, "Weapon 6", &key_weapon6);
+ AddKeyControl(table, "Weapon 7", &key_weapon7);
+ AddKeyControl(table, "Weapon 8", &key_weapon8);
+ AddKeyControl(table, "Previous weapon", &key_prevweapon);
+ AddKeyControl(table, "Next weapon", &key_nextweapon);
+}
- TXT_AddWidgets(table, TXT_NewStrut(0, 1),
- TXT_NewStrut(0, 1),
- TXT_NewLabel(" - Menu navigation - "),
- TXT_NewStrut(0, 0),
- NULL);
+static void OtherKeysDialog(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(unused))
+{
+ txt_window_t *window;
+ txt_table_t *table;
+ txt_scrollpane_t *scrollpane;
+
+ window = TXT_NewWindow("Other keys");
+
+ table = TXT_NewTable(2);
+
+ TXT_SetColumnWidths(table, 25, 9);
+
+ AddSectionLabel(table, "Menu navigation", false);
AddKeyControl(table, "Activate menu", &key_menu_activate);
AddKeyControl(table, "Move cursor up", &key_menu_up);
@@@ -265,9 -286,26 +270,9 @@@
AddKeyControl(table, "Decrease screen size", &key_menu_decscreen);
AddKeyControl(table, "Display last message", &key_message_refresh);
+ AddKeyControl(table, "Finish recording demo", &key_demo_quit);
- TXT_AddWidgets(table, TXT_NewStrut(0, 1),
- TXT_NewStrut(0, 1),
- TXT_NewLabel(" - Multiplayer - "),
- TXT_NewStrut(0, 0),
- NULL);
-
- AddKeyControl(table, "Send message", &key_multi_msg);
- AddKeyControl(table, "- to green", &key_multi_msgplayer[0]);
- AddKeyControl(table, "- to indigo", &key_multi_msgplayer[1]);
- AddKeyControl(table, "- to brown", &key_multi_msgplayer[2]);
- AddKeyControl(table, "- to red", &key_multi_msgplayer[3]);
-
- TXT_AddWidgets(table, TXT_NewStrut(0, 1),
- TXT_NewStrut(0, 1),
- TXT_NewLabel(" - Map - "),
- TXT_NewStrut(0, 0),
- NULL);
-
+ AddSectionLabel(table, "Map", true);
-
AddKeyControl(table, "Toggle map", &key_map_toggle);
AddKeyControl(table, "Zoom in", &key_map_zoomin);
AddKeyControl(table, "Zoom out", &key_map_zoomout);
@@@ -281,7 -319,7 +286,21 @@@
AddKeyControl(table, "Mark location", &key_map_mark);
AddKeyControl(table, "Clear all marks", &key_map_clearmark);
- scrollpane = TXT_NewScrollPane(0, 12, table);
++ AddSectionLabel(table, "Multiplayer", true);
++
++ AddKeyControl(table, "Send message", &key_multi_msg);
++ AddKeyControl(table, "- to green", &key_multi_msgplayer[0]);
++ AddKeyControl(table, "- to indigo", &key_multi_msgplayer[1]);
++ AddKeyControl(table, "- to brown", &key_multi_msgplayer[2]);
++ AddKeyControl(table, "- to red", &key_multi_msgplayer[3]);
++
++ TXT_AddWidgets(table, TXT_NewStrut(0, 1),
++ TXT_NewStrut(0, 1),
++ TXT_NewLabel(" - Map - "),
++ TXT_NewStrut(0, 0),
++ NULL);
++
+ scrollpane = TXT_NewScrollPane(0, 13, table);
TXT_AddWidget(window, scrollpane);
}
diff --cc src/setup/keyboard.h
index 2797ba8f,00000000..12059bf8
mode 100644,000000..100644
--- a/src/setup/keyboard.h
+++ b/src/setup/keyboard.h
@@@ -1,82 -1,0 +1,29 @@@
+// Emacs style mode select -*- C++ -*-
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 2006 Simon Howard
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+
+#ifndef SETUP_KEYBOARD_H
+#define SETUP_KEYBOARD_H
+
- // Menu keys:
-
- extern int key_menu_activate;
- extern int key_menu_up;
- extern int key_menu_down;
- extern int key_menu_left;
- extern int key_menu_right;
- extern int key_menu_back;
- extern int key_menu_forward;
- extern int key_menu_confirm;
- extern int key_menu_abort;
-
- extern int key_menu_help;
- extern int key_menu_save;
- extern int key_menu_load;
- extern int key_menu_volume;
- extern int key_menu_detail;
- extern int key_menu_qsave;
- extern int key_menu_endgame;
- extern int key_menu_messages;
- extern int key_menu_qload;
- extern int key_menu_quit;
- extern int key_menu_gamma;
-
- extern int key_menu_incscreen;
- extern int key_menu_decscreen;
-
- // Automap keys:
-
- extern int key_map_north;
- extern int key_map_south;
- extern int key_map_east;
- extern int key_map_west;
- extern int key_map_zoomin;
- extern int key_map_zoomout;
- extern int key_map_toggle;
- extern int key_map_maxzoom;
- extern int key_map_follow;
- extern int key_map_grid;
- extern int key_map_mark;
- extern int key_map_clearmark;
-
- // Weapon keys:
-
- extern int key_weapon1;
- extern int key_weapon2;
- extern int key_weapon3;
- extern int key_weapon4;
- extern int key_weapon5;
- extern int key_weapon6;
- extern int key_weapon7;
- extern int key_weapon8;
-
+void ConfigKeyboard(void);
+void BindKeyboardVariables(void);
+
+#endif /* #ifndef SETUP_KEYBOARD_H */
+
diff --cc src/setup/mainmenu.c
index 46e4b4e6,006a3547..c3cb7db5
--- a/src/setup/mainmenu.c
+++ b/src/setup/mainmenu.c
@@@ -46,6 -45,61 +46,64 @@@
#include "multiplayer.h"
#include "sound.h"
+ static const int cheat_sequence[] =
+ {
+ KEY_UPARROW, KEY_UPARROW, KEY_DOWNARROW, KEY_DOWNARROW,
+ KEY_LEFTARROW, KEY_RIGHTARROW, KEY_LEFTARROW, KEY_RIGHTARROW,
+ 'b', 'a', KEY_ENTER, 0
+ };
+
+ static unsigned int cheat_sequence_index = 0;
+
+ // I think these are good "sensible" defaults:
+
+ static void SensibleDefaults(void)
+ {
++#if 0
++ // TODO for raven-branch
+ key_up = 'w';
+ key_down = 's';
+ key_strafeleft = 'a';
+ key_straferight = 'd';
+ mousebprevweapon = 4;
+ mousebnextweapon = 3;
+ snd_musicdevice = 3;
+ joybspeed = 29;
+ vanilla_savegame_limit = 0;
+ vanilla_keyboard_mapping = 0;
+ vanilla_demo_limit = 0;
+ show_endoom = 0;
+ dclick_use = 0;
+ novert = 1;
++#endif
+ }
+
+ static int MainMenuKeyPress(txt_window_t *window, int key, void *user_data)
+ {
+ if (key == cheat_sequence[cheat_sequence_index])
+ {
+ ++cheat_sequence_index;
+
+ if (cheat_sequence[cheat_sequence_index] == 0)
+ {
+ SensibleDefaults();
+ cheat_sequence_index = 0;
+
+ window = TXT_NewWindow(NULL);
+ TXT_AddWidget(window, TXT_NewLabel(" \x01 "));
+ TXT_SetWindowAction(window, TXT_HORIZ_RIGHT, NULL);
+
+ return 1;
+ }
+ }
+ else
+ {
+ cheat_sequence_index = 0;
+ }
+
+ return 0;
+ }
+
static void DoQuit(void *widget, void *dosave)
{
if (dosave != NULL)
diff --cc src/setup/mouse.c
index d464261f,16984721..5b555f88
--- a/src/setup/mouse.c
+++ b/src/setup/mouse.c
@@@ -29,16 -27,27 +29,16 @@@
#include "execute.h"
#include "txt_mouseinput.h"
+#include "mode.h"
#include "mouse.h"
-int usemouse = 1;
+static int usemouse = 1;
-int novert = 0;
-int mouseSensitivity = 5;
-float mouse_acceleration = 2.0;
-int mouse_threshold = 10;
-int grabmouse = 1;
-
-int mousebfire = 0;
-int mousebforward = 1;
-int mousebstrafe = 2;
-int mousebstrafeleft = -1;
-int mousebstraferight = -1;
-int mousebbackward = -1;
-int mousebuse = -1;
-int mousebprevweapon = -1;
-int mousebnextweapon = -1;
-
-int dclick_use = 1;
+static int novert = 0;
+static int mouseSensitivity = 5;
- static float mouse_acceleration = 1.0;
++static float mouse_acceleration = 2.0;
+static int mouse_threshold = 10;
+static int grabmouse = 1;
static int *all_mouse_buttons[] = {
&mousebfire,
@@@ -48,7 -57,8 +48,9 @@@
&mousebstraferight,
&mousebbackward,
&mousebuse,
- &mousebjump
++ &mousebjump,
+ &mousebprevweapon,
+ &mousebnextweapon
};
static void MouseSetCallback(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(variable))
@@@ -98,11 -108,8 +100,14 @@@ static void ConfigExtraButtons(TXT_UNCA
AddMouseControl(buttons_table, "Use", &mousebuse);
AddMouseControl(buttons_table, "Strafe left", &mousebstrafeleft);
AddMouseControl(buttons_table, "Strafe right", &mousebstraferight);
+
+ if (gamemission == hexen)
+ {
+ AddMouseControl(buttons_table, "Jump", &mousebjump);
+ }
++
+ AddMouseControl(buttons_table, "Previous weapon", &mousebprevweapon);
+ AddMouseControl(buttons_table, "Next weapon", &mousebnextweapon);
}
void ConfigMouse(void)
diff --cc src/setup/multiplayer.c
index f3b3221d,c5d0d1e9..24cd0670
--- a/src/setup/multiplayer.c
+++ b/src/setup/multiplayer.c
@@@ -23,16 -22,15 +23,17 @@@
#include <stdlib.h>
#include <string.h>
-#include "d_englsh.h"
-#include "textscreen.h"
#include "doomtype.h"
+#include "textscreen.h"
-#include "configfile.h"
-
-#include "execute.h"
+#include "d_iwad.h"
+#include "m_config.h"
+#include "doom/d_englsh.h"
++#include "m_controls.h"
#include "multiplayer.h"
+#include "mode.h"
+#include "execute.h"
#define NUM_WADS 10
#define NUM_EXTRA_PARAMS 10
@@@ -849,19 -782,3 +850,53 @@@ void MultiplayerConfig(void
TXT_AddWidget(window, table);
}
+void BindMultiplayerVariables(void)
+{
+ char buf[15];
+ int i;
+
+#ifdef FEATURE_MULTIPLAYER
+ M_BindVariable("player_name", &net_player_name);
+#endif
+
+ for (i=0; i<10; ++i)
+ {
+ sprintf(buf, "chatmacro%i", i);
+ M_BindVariable(buf, &chat_macros[i]);
+ }
++
++ switch (gamemission)
++ {
++ case doom:
++ M_BindChatControls(4);
++ key_multi_msgplayer[0] = 'g';
++ key_multi_msgplayer[1] = 'i';
++ key_multi_msgplayer[2] = 'b';
++ key_multi_msgplayer[3] = 'r';
++ break;
++
++ case heretic:
++ M_BindChatControls(4);
++ key_multi_msgplayer[0] = 'g';
++ key_multi_msgplayer[1] = 'y';
++ key_multi_msgplayer[2] = 'r';
++ key_multi_msgplayer[3] = 'b';
++ break;
++
++ case hexen:
++ M_BindChatControls(8);
++ key_multi_msgplayer[0] = 'b';
++ key_multi_msgplayer[1] = 'r';
++ key_multi_msgplayer[2] = 'y';
++ key_multi_msgplayer[3] = 'g';
++ key_multi_msgplayer[4] = 'j';
++ key_multi_msgplayer[5] = 'w';
++ key_multi_msgplayer[6] = 'h';
++ key_multi_msgplayer[7] = 'p';
++ break;
++
++ default:
++ break;
++ }
+}
+
diff --cc src/setup/sound.c
index 61182753,59df0532..627549b5
--- a/src/setup/sound.c
+++ b/src/setup/sound.c
@@@ -60,34 -54,23 +60,35 @@@ static char *musicmode_strings[]
{
"Disabled",
"OPL (Adlib/SB)",
- "Native MIDI"
+ "Native MIDI",
+ "CD audio"
};
-int snd_sfxdevice = SNDDEVICE_SB;
-int numChannels = 8;
-int sfxVolume = 15;
+// Config file variables:
+int snd_sfxdevice = SNDDEVICE_SB;
int snd_musicdevice = SNDDEVICE_GENMIDI;
-int musicVolume = 15;
-
int snd_samplerate = 22050;
+ int opl_io_port = 0x388;
-int use_libsamplerate = 0;
+static int numChannels = 8;
+static int sfxVolume = 15;
+static int musicVolume = 15;
+static int use_libsamplerate = 0;
+
+// DOS specific variables: these are unused but should be maintained
+// so that the config file can be shared between chocolate
+// doom and doom.exe
+
+static int snd_sbport = 0;
+static int snd_sbirq = 0;
+static int snd_sbdma = 0;
+static int snd_mport = 0;
+
+// GUI variables:
static int snd_sfxmode;
-static int snd_musmode;
+static int snd_musicmode;
static void UpdateSndDevices(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(data))
{