summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSimon Howard2010-08-31 19:26:32 +0000
committerSimon Howard2010-08-31 19:26:32 +0000
commit22fc405736dc4796958de221c07d52432f1b271b (patch)
treec05962aa5e839566ea40dd9b1f4ba3581954af8a /src
parentf391d85c96afa91a2302c58191ce8d401fdba2e2 (diff)
parent64918568eee62c73cbb87aa1bd68e191f19a4af3 (diff)
downloadchocolate-doom-22fc405736dc4796958de221c07d52432f1b271b.tar.gz
chocolate-doom-22fc405736dc4796958de221c07d52432f1b271b.tar.bz2
chocolate-doom-22fc405736dc4796958de221c07d52432f1b271b.zip
Merge from trunk.
Subversion-branch: /branches/raven-branch Subversion-revision: 1987
Diffstat (limited to 'src')
-rw-r--r--src/doom/d_main.c6
-rw-r--r--src/doom/g_game.c184
-rw-r--r--src/doom/hu_stuff.c12
-rw-r--r--src/doom/r_draw.c111
-rw-r--r--src/heretic/d_main.c1
-rw-r--r--src/hexen/h2_main.c1
-rw-r--r--src/i_scale.c14
-rw-r--r--src/i_sdlsound.c72
-rw-r--r--src/i_sound.c5
-rw-r--r--src/i_video.c281
-rw-r--r--src/i_video.h4
-rw-r--r--src/m_config.c132
-rw-r--r--src/m_controls.c47
-rw-r--r--src/m_controls.h17
-rw-r--r--src/setup/joystick.c2
-rw-r--r--src/setup/keyboard.c27
-rw-r--r--src/setup/keyboard.h53
-rw-r--r--src/setup/mainmenu.c60
-rw-r--r--src/setup/mouse.c9
-rw-r--r--src/setup/multiplayer.c35
-rw-r--r--src/setup/sound.c1
-rw-r--r--src/setup/txt_keyinput.c2
-rw-r--r--src/setup/txt_mouseinput.c4
-rw-r--r--src/z_zone.c3
24 files changed, 830 insertions, 253 deletions
diff --git a/src/doom/d_main.c b/src/doom/d_main.c
index 3fee8439..f3a4b037 100644
--- a/src/doom/d_main.c
+++ b/src/doom/d_main.c
@@ -358,6 +358,12 @@ void D_BindVariables(void)
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();
diff --git a/src/doom/g_game.c b/src/doom/g_game.c
index 9b569594..ad7155a0 100644
--- a/src/doom/g_game.c
+++ b/src/doom/g_game.c
@@ -176,14 +176,37 @@ static int *weapon_keys[] = {
&key_weapon8
};
+// Set to -1 or +1 to switch to the previous or next weapon.
+
+static int next_weapon = 0;
+
+// Used for prev/next weapon keys.
+
+static const struct
+{
+ weapontype_t weapon;
+ weapontype_t weapon_num;
+} weapon_order_table[] = {
+ { wp_fist, wp_fist },
+ { wp_chainsaw, wp_fist },
+ { wp_pistol, wp_pistol },
+ { wp_shotgun, wp_shotgun },
+ { wp_supershotgun, wp_shotgun },
+ { wp_chaingun, wp_chaingun },
+ { wp_missile, wp_missile },
+ { wp_plasma, wp_plasma },
+ { wp_bfg, wp_bfg }
+};
+
#define SLOWTURNTICS 6
#define NUMKEYS 256
+#define MAX_JOY_BUTTONS 20
static boolean gamekeydown[NUMKEYS];
static int turnheld; // for accelerative turning
-static boolean mousearray[4];
+static boolean mousearray[MAX_MOUSE_BUTTONS + 1];
static boolean *mousebuttons = &mousearray[1]; // allow [-1]
// mouse values are used once
@@ -197,8 +220,6 @@ static int dclicktime2;
static boolean dclickstate2;
static int dclicks2;
-#define MAX_JOY_BUTTONS 20
-
// joystick values are repeated
static int joyxmove;
static int joyymove;
@@ -337,7 +358,63 @@ int G_CmdChecksum (ticcmd_t* cmd)
return sum;
}
-
+
+static boolean WeaponSelectable(weapontype_t weapon)
+{
+ // Can't select a weapon if we don't own it.
+
+ if (!players[consoleplayer].weaponowned[weapon])
+ {
+ return false;
+ }
+
+ // Can't select the fist if we have the chainsaw, unless
+ // we also have the berserk pack.
+
+ if (weapon == wp_fist
+ && players[consoleplayer].weaponowned[wp_chainsaw]
+ && !players[consoleplayer].powers[pw_strength])
+ {
+ return false;
+ }
+
+ return true;
+}
+
+static int G_NextWeapon(int direction)
+{
+ weapontype_t weapon;
+ int i;
+
+ // Find index in the table.
+
+ if (players[consoleplayer].pendingweapon == wp_nochange)
+ {
+ weapon = players[consoleplayer].readyweapon;
+ }
+ else
+ {
+ weapon = players[consoleplayer].pendingweapon;
+ }
+
+ for (i=0; i<arrlen(weapon_order_table); ++i)
+ {
+ if (weapon_order_table[i].weapon == weapon)
+ {
+ break;
+ }
+ }
+
+ // Switch weapon.
+
+ do
+ {
+ i += direction;
+ i = (i + arrlen(weapon_order_table)) % arrlen(weapon_order_table);
+ } while (!WeaponSelectable(weapon_order_table[i].weapon));
+
+ return weapon_order_table[i].weapon_num;
+}
//
// G_BuildTiccmd
@@ -465,20 +542,34 @@ void G_BuildTiccmd (ticcmd_t* cmd)
dclicks = 0;
}
- // chainsaw overrides
+ // If the previous or next weapon button is pressed, the
+ // next_weapon variable is set to change weapons when
+ // we generate a ticcmd. Choose a new weapon.
- for (i=0; i<arrlen(weapon_keys); ++i)
+ if (next_weapon != 0)
{
- int key = *weapon_keys[i];
+ i = G_NextWeapon(next_weapon);
+ cmd->buttons |= BT_CHANGE;
+ cmd->buttons |= i << BT_WEAPONSHIFT;
+ next_weapon = 0;
+ }
+ else
+ {
+ // Check weapon keys.
- if (gamekeydown[key])
+ for (i=0; i<arrlen(weapon_keys); ++i)
{
- cmd->buttons |= BT_CHANGE;
- cmd->buttons |= i<<BT_WEAPONSHIFT;
- break;
+ int key = *weapon_keys[i];
+
+ if (gamekeydown[key])
+ {
+ cmd->buttons |= BT_CHANGE;
+ cmd->buttons |= i<<BT_WEAPONSHIFT;
+ break;
+ }
}
}
-
+
// mouse
if (mousebuttons[mousebforward])
{
@@ -657,7 +748,6 @@ void G_DoLoadLevel (void)
players[consoleplayer].message = "Press escape to quit.";
}
}
-
static void SetJoyButtons(unsigned int buttons_mask)
{
@@ -665,10 +755,54 @@ static void SetJoyButtons(unsigned int buttons_mask)
for (i=0; i<MAX_JOY_BUTTONS; ++i)
{
- joybuttons[i] = (buttons_mask & (1 << i)) != 0;
+ int button_on = (buttons_mask & (1 << i)) != 0;
+
+ // Detect button press:
+
+ if (!joybuttons[i] && button_on)
+ {
+ // Weapon cycling:
+
+ if (i == joybprevweapon)
+ {
+ next_weapon = -1;
+ }
+ else if (i == joybnextweapon)
+ {
+ next_weapon = 1;
+ }
+ }
+
+ joybuttons[i] = button_on;
}
}
-
+
+static void SetMouseButtons(unsigned int buttons_mask)
+{
+ int i;
+
+ for (i=0; i<MAX_MOUSE_BUTTONS; ++i)
+ {
+ unsigned int button_on = (buttons_mask & (1 << i)) != 0;
+
+ // Detect button press:
+
+ if (!mousebuttons[i] && button_on)
+ {
+ if (i == mousebprevweapon)
+ {
+ next_weapon = -1;
+ }
+ else if (i == mousebnextweapon)
+ {
+ next_weapon = 1;
+ }
+ }
+
+ mousebuttons[i] = button_on;
+ }
+}
+
//
// G_Responder
// Get info needed to make ticcmd_ts for the players.
@@ -677,7 +811,7 @@ boolean G_Responder (event_t* ev)
{
// allow spy mode changes even during the demo
if (gamestate == GS_LEVEL && ev->type == ev_keydown
- && ev->data1 == KEY_F12 && (singledemo || !deathmatch) )
+ && ev->data1 == key_spy && (singledemo || !deathmatch) )
{
// spy mode
do
@@ -737,6 +871,18 @@ boolean G_Responder (event_t* ev)
testcontrols_mousespeed = abs(ev->data2);
}
+ // If the next/previous weapon keys are pressed, set the next_weapon
+ // variable to change weapons when the next ticcmd is generated.
+
+ if (ev->type == ev_keydown && ev->data1 == key_prevweapon)
+ {
+ next_weapon = -1;
+ }
+ else if (ev->type == ev_keydown && ev->data1 == key_nextweapon)
+ {
+ next_weapon = 1;
+ }
+
switch (ev->type)
{
case ev_keydown:
@@ -757,9 +903,7 @@ boolean G_Responder (event_t* ev)
return false; // always let key up events filter down
case ev_mouse:
- mousebuttons[0] = ev->data1 & 1;
- mousebuttons[1] = ev->data1 & 2;
- mousebuttons[2] = ev->data1 & 4;
+ SetMouseButtons(ev->data1);
mousex = ev->data2*(mouseSensitivity+5)/10;
mousey = ev->data3*(mouseSensitivity+5)/10;
return true; // eat events
@@ -1784,7 +1928,7 @@ void G_WriteDemoTiccmd (ticcmd_t* cmd)
{
byte *demo_start;
- if (gamekeydown['q']) // press q to end demo recording
+ if (gamekeydown[key_demo_quit]) // press q to end demo recording
G_CheckDemoStatus ();
demo_start = demo_p;
diff --git a/src/doom/hu_stuff.c b/src/doom/hu_stuff.c
index 3337f978..f9271b3d 100644
--- a/src/doom/hu_stuff.c
+++ b/src/doom/hu_stuff.c
@@ -529,14 +529,6 @@ boolean HU_Responder(event_t *ev)
int i;
int numplayers;
- static char destination_keys[MAXPLAYERS] =
- {
- HUSTR_KEYGREEN,
- HUSTR_KEYINDIGO,
- HUSTR_KEYBROWN,
- HUSTR_KEYRED
- };
-
static int num_nobrainers = 0;
numplayers = 0;
@@ -565,7 +557,7 @@ boolean HU_Responder(event_t *ev)
message_counter = HU_MSGTIMEOUT;
eatkey = true;
}
- else if (netgame && ev->data2 == HU_INPUTTOGGLE)
+ else if (netgame && ev->data2 == key_multi_msg)
{
eatkey = chat_on = true;
HUlib_resetIText(&w_chat);
@@ -575,7 +567,7 @@ boolean HU_Responder(event_t *ev)
{
for (i=0; i<MAXPLAYERS ; i++)
{
- if (ev->data2 == destination_keys[i])
+ if (ev->data2 == key_multi_msgplayer[i])
{
if (playeringame[i] && i!=consoleplayer)
{
diff --git a/src/doom/r_draw.c b/src/doom/r_draw.c
index 1b6420d9..80362208 100644
--- a/src/doom/r_draw.c
+++ b/src/doom/r_draw.c
@@ -597,48 +597,54 @@ int dscount;
// Draws the actual span.
void R_DrawSpan (void)
{
- fixed_t xfrac;
- fixed_t yfrac;
- byte* dest;
- int count;
- int spot;
-
-#ifdef RANGECHECK
+ unsigned int position, step;
+ byte *dest;
+ int count;
+ int spot;
+ unsigned int xtemp, ytemp;
+
+#ifdef RANGECHECK
if (ds_x2 < ds_x1
|| ds_x1<0
- || ds_x2>=SCREENWIDTH
+ || ds_x2>=SCREENWIDTH
|| (unsigned)ds_y>SCREENHEIGHT)
{
I_Error( "R_DrawSpan: %i to %i at %i",
ds_x1,ds_x2,ds_y);
}
-// dscount++;
-#endif
+// dscount++;
+#endif
+
+ // Pack position and step variables into a single 32-bit integer,
+ // with x in the top 16 bits and y in the bottom 16 bits. For
+ // each 16-bit part, the top 6 bits are the integer part and the
+ // bottom 10 bits are the fractional part of the pixel position.
+
+ position = ((ds_xfrac << 10) & 0xffff0000)
+ | ((ds_yfrac >> 6) & 0x0000ffff);
+ step = ((ds_xstep << 10) & 0xffff0000)
+ | ((ds_ystep >> 6) & 0x0000ffff);
-
- xfrac = ds_xfrac;
- yfrac = ds_yfrac;
-
dest = ylookup[ds_y] + columnofs[ds_x1];
// We do not check for zero spans here?
- count = ds_x2 - ds_x1;
+ count = ds_x2 - ds_x1;
- do
+ do
{
- // Current texture index in u,v.
- spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);
+ // Calculate current texture index in u,v.
+ ytemp = (position >> 4) & 0x0fc0;
+ xtemp = (position >> 26);
+ spot = xtemp | ytemp;
// Lookup pixel from flat texture tile,
// re-index using light/colormap.
*dest++ = ds_colormap[ds_source[spot]];
- // Next step in u,v.
- xfrac += ds_xstep;
- yfrac += ds_ystep;
-
- } while (count--);
-}
+ position += step;
+
+ } while (count--);
+}
@@ -718,49 +724,54 @@ void R_DrawSpan (void)
//
// Again..
//
-void R_DrawSpanLow (void)
-{
- fixed_t xfrac;
- fixed_t yfrac;
- byte* dest;
- int count;
- int spot;
-
-#ifdef RANGECHECK
+void R_DrawSpanLow (void)
+{
+ unsigned int position, step;
+ unsigned int xtemp, ytemp;
+ byte *dest;
+ int count;
+ int spot;
+
+#ifdef RANGECHECK
if (ds_x2 < ds_x1
|| ds_x1<0
- || ds_x2>=SCREENWIDTH
+ || ds_x2>=SCREENWIDTH
|| (unsigned)ds_y>SCREENHEIGHT)
{
I_Error( "R_DrawSpan: %i to %i at %i",
ds_x1,ds_x2,ds_y);
}
// dscount++;
-#endif
-
- xfrac = ds_xfrac;
- yfrac = ds_yfrac;
-
- count = (ds_x2 - ds_x1);
+#endif
+
+ position = ((ds_xfrac << 10) & 0xffff0000)
+ | ((ds_yfrac >> 6) & 0x0000ffff);
+ step = ((ds_xstep << 10) & 0xffff0000)
+ | ((ds_ystep >> 6) & 0x0000ffff);
+
+ count = (ds_x2 - ds_x1);
// Blocky mode, need to multiply by 2.
ds_x1 <<= 1;
ds_x2 <<= 1;
-
+
dest = ylookup[ds_y] + columnofs[ds_x1];
-
- do
- {
- spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);
+
+ do
+ {
+ // Calculate current texture index in u,v.
+ ytemp = (position >> 4) & 0x0fc0;
+ xtemp = (position >> 26);
+ spot = xtemp | ytemp;
+
// Lowres/blocky mode does it twice,
// while scale is adjusted appropriately.
- *dest++ = ds_colormap[ds_source[spot]];
*dest++ = ds_colormap[ds_source[spot]];
-
- xfrac += ds_xstep;
- yfrac += ds_ystep;
+ *dest++ = ds_colormap[ds_source[spot]];
- } while (count--);
+ position += step;
+
+ } while (count--);
}
//
diff --git a/src/heretic/d_main.c b/src/heretic/d_main.c
index 901d763d..169a86ea 100644
--- a/src/heretic/d_main.c
+++ b/src/heretic/d_main.c
@@ -748,6 +748,7 @@ void D_BindVariables(void)
M_BindBaseControls();
M_BindHereticControls();
M_BindWeaponControls();
+ M_BindChatControls(MAXPLAYERS);
M_BindMenuControls();
M_BindMapControls();
diff --git a/src/hexen/h2_main.c b/src/hexen/h2_main.c
index a20bd91a..abc58f15 100644
--- a/src/hexen/h2_main.c
+++ b/src/hexen/h2_main.c
@@ -156,6 +156,7 @@ void D_BindVariables(void)
M_BindMapControls();
M_BindMenuControls();
M_BindWeaponControls();
+ M_BindChatControls(MAXPLAYERS);
M_BindHereticControls();
M_BindHexenControls();
diff --git a/src/i_scale.c b/src/i_scale.c
index 4f08f5d6..2c0b718c 100644
--- a/src/i_scale.c
+++ b/src/i_scale.c
@@ -56,11 +56,11 @@ static int dest_pitch;
// stretch_tables[1] : 40% / 60%
// All other combinations can be reached from these two tables.
-static byte *stretch_tables[2];
+static byte *stretch_tables[2] = { NULL, NULL };
// 50%/50% stretch table, for 800x600 squash mode
-static byte *half_stretch_table;
+static byte *half_stretch_table = NULL;
// Called to set the source and destination buffers before doing the
// scale.
@@ -367,6 +367,11 @@ static byte *GenerateStretchTable(byte *palette, int pct)
static void I_InitStretchTables(byte *palette)
{
+ if (stretch_tables[0] != NULL)
+ {
+ return;
+ }
+
// We only actually need two lookup tables:
//
// mix 0% = just write line 1
@@ -388,6 +393,11 @@ static void I_InitStretchTables(byte *palette)
static void I_InitSquashTable(byte *palette)
{
+ if (half_stretch_table != NULL)
+ {
+ return;
+ }
+
printf("I_InitSquashTable: Generating lookup table..");
fflush(stdout);
half_stretch_table = GenerateStretchTable(palette, 50);
diff --git a/src/i_sdlsound.c b/src/i_sdlsound.c
index 0b3f8aa3..7deb683d 100644
--- a/src/i_sdlsound.c
+++ b/src/i_sdlsound.c
@@ -25,7 +25,6 @@
//
//-----------------------------------------------------------------------------
-
#include "config.h"
#include <stdio.h>
@@ -42,6 +41,7 @@
#include "deh_str.h"
#include "i_sound.h"
#include "i_system.h"
+#include "i_swap.h"
#include "m_argv.h"
#include "w_wad.h"
#include "z_zone.h"
@@ -49,6 +49,7 @@
#include "doomtype.h"
#define LOW_PASS_FILTER
+//#define DEBUG_DUMP_WAVS
#define MAX_SOUND_SLICE_TIME 70 /* ms */
#define NUM_CHANNELS 16
@@ -288,6 +289,56 @@ static boolean ConvertibleRatio(int freq1, int freq2)
}
}
+#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).
@@ -313,7 +364,7 @@ static void ExpandSoundData_SDL(sfxinfo_t *sfxinfo,
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,
@@ -379,9 +430,12 @@ static void ExpandSoundData_SDL(sfxinfo_t *sfxinfo,
rc = 1.0f / (3.14f * samplerate);
alpha = dt / (rc + dt);
- for (i=1; i<expanded_length; ++i)
+ // Both channels are processed in parallel, hence [i-2]:
+
+ for (i=2; i<expanded_length * 2; ++i)
{
- expanded[i] = (Sint16) (alpha * expanded[i] + (1 - alpha) * expanded[i-1]);
+ expanded[i] = (Sint16) (alpha * expanded[i]
+ + (1 - alpha) * expanded[i-2]);
}
}
#endif /* #ifdef LOW_PASS_FILTER */
@@ -432,6 +486,16 @@ static boolean CacheSFX(sfxinfo_t *sfxinfo)
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 --git a/src/i_sound.c b/src/i_sound.c
index cf9e17a3..0c771dc2 100644
--- a/src/i_sound.c
+++ b/src/i_sound.c
@@ -56,6 +56,10 @@ 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
@@ -408,6 +412,7 @@ void I_BindSoundVariables(void)
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
diff --git a/src/i_video.c b/src/i_video.c
index a370fc08..733af899 100644
--- a/src/i_video.c
+++ b/src/i_video.c
@@ -144,8 +144,6 @@ static char *window_title = "";
static SDL_Color palette[256];
static boolean palette_to_set;
-static int windowwidth, windowheight;
-
// display has been set up?
static boolean initialized = false;
@@ -155,6 +153,10 @@ static boolean initialized = false;
static boolean nomouse = false;
int usemouse = 1;
+// Bit mask of mouse button state.
+
+static unsigned int mouse_button_state = 0;
+
// 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
@@ -235,6 +237,12 @@ static SDL_Cursor *cursors[2];
static screen_mode_t *screen_mode;
+// Window resize state.
+
+static boolean need_resize = false;
+static unsigned int resize_w, resize_h;
+static unsigned int last_resize_time;
+
// If true, keyboard mapping is ignored, like in Vanilla Doom.
// The sensible thing to do is to disable this if you have a non-US
// keyboard.
@@ -261,6 +269,8 @@ int mouse_threshold = 10;
int usegamma = 0;
+static void ApplyWindowResize(unsigned int w, unsigned int h);
+
static boolean MouseShouldBeGrabbed()
{
// never grab the mouse when in screensaver mode
@@ -524,29 +534,56 @@ void I_StartFrame (void)
}
-static int MouseButtonState(void)
+static void UpdateMouseButtonState(unsigned int button, boolean on)
{
- Uint8 state;
- int result = 0;
+ event_t event;
-#if SDL_VERSION_ATLEAST(1, 3, 0)
- state = SDL_GetMouseState(0, NULL, NULL);
-#else
- state = SDL_GetMouseState(NULL, NULL);
-#endif
+ if (button < SDL_BUTTON_LEFT || button > MAX_MOUSE_BUTTONS)
+ {
+ return;
+ }
// Note: button "0" is left, button "1" is right,
// button "2" is middle for Doom. This is different
// to how SDL sees things.
- if (state & SDL_BUTTON(1))
- result |= 1;
- if (state & SDL_BUTTON(3))
- result |= 2;
- if (state & SDL_BUTTON(2))
- result |= 4;
+ switch (button)
+ {
+ case SDL_BUTTON_LEFT:
+ button = 0;
+ break;
- return result;
+ case SDL_BUTTON_RIGHT:
+ button = 1;
+ break;
+
+ case SDL_BUTTON_MIDDLE:
+ button = 2;
+ break;
+
+ default:
+ // SDL buttons are indexed from 1.
+ --button;
+ break;
+ }
+
+ // Turn bit representing this button on or off.
+
+ if (on)
+ {
+ mouse_button_state |= (1 << button);
+ }
+ else
+ {
+ mouse_button_state &= ~(1 << button);
+ }
+
+ // Post an event with the new button state.
+
+ event.type = ev_mouse;
+ event.data1 = mouse_button_state;
+ event.data2 = event.data3 = 0;
+ D_PostEvent(&event);
}
static int AccelerateMouse(int val)
@@ -692,7 +729,7 @@ void I_GetEvent(void)
/*
case SDL_MOUSEMOTION:
event.type = ev_mouse;
- event.data1 = MouseButtonState();
+ event.data1 = mouse_button_state;
event.data2 = AccelerateMouse(sdlevent.motion.xrel);
event.data3 = -AccelerateMouse(sdlevent.motion.yrel);
D_PostEvent(&event);
@@ -702,20 +739,14 @@ void I_GetEvent(void)
case SDL_MOUSEBUTTONDOWN:
if (usemouse && !nomouse)
{
- event.type = ev_mouse;
- event.data1 = MouseButtonState();
- event.data2 = event.data3 = 0;
- D_PostEvent(&event);
+ UpdateMouseButtonState(sdlevent.button.button, true);
}
break;
case SDL_MOUSEBUTTONUP:
if (usemouse && !nomouse)
{
- event.type = ev_mouse;
- event.data1 = MouseButtonState();
- event.data2 = event.data3 = 0;
- D_PostEvent(&event);
+ UpdateMouseButtonState(sdlevent.button.button, false);
}
break;
@@ -733,6 +764,13 @@ void I_GetEvent(void)
palette_to_set = true;
break;
+ case SDL_RESIZABLE:
+ need_resize = true;
+ resize_w = sdlevent.resize.w;
+ resize_h = sdlevent.resize.h;
+ last_resize_time = SDL_GetTicks();
+ break;
+
default:
break;
}
@@ -777,7 +815,7 @@ 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);
if (!novert)
@@ -976,14 +1014,20 @@ void I_FinishUpdate (void)
static int lasttic;
int tics;
int i;
- // UNUSED static unsigned char *bigscreen=0;
if (!initialized)
return;
if (noblit)
return;
-
+
+ if (need_resize && SDL_GetTicks() > last_resize_time + 500)
+ {
+ ApplyWindowResize(resize_w, resize_h);
+ need_resize = false;
+ palette_to_set = true;
+ }
+
UpdateGrab();
// Don't update the screen if the window isn't visible.
@@ -1692,11 +1736,96 @@ static char *WindowBoxType(screen_mode_t *mode, int w, int h)
}
}
+static void SetVideoMode(screen_mode_t *mode, int w, int h)
+{
+ byte *doompal;
+ int flags = 0;
+
+ doompal = W_CacheLumpName(DEH_String("PLAYPAL"), PU_CACHE);
+
+ // Generate lookup tables before setting the video mode.
+
+ if (mode != NULL && mode->InitMode != NULL)
+ {
+ mode->InitMode(doompal);
+ }
+
+ // Set the video mode.
+
+ flags |= SDL_SWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF;
+
+ if (fullscreen)
+ {
+ flags |= SDL_FULLSCREEN;
+ }
+ else
+ {
+ flags |= SDL_RESIZABLE;
+ }
+
+ screen = SDL_SetVideoMode(w, h, 8, flags);
+
+ if (screen == NULL)
+ {
+ I_Error("Error setting video mode: %s\n", SDL_GetError());
+ }
+
+ // If mode was not set, it must be set now that we know the
+ // screen size.
+
+ if (mode == NULL)
+ {
+ mode = I_FindScreenMode(screen->w, screen->h);
+
+ if (mode == NULL)
+ {
+ I_Error("I_InitGraphics: Unable to find a screen mode small "
+ "enough for %ix%i", screen->w, screen->h);
+ }
+
+ // Generate lookup tables before setting the video mode.
+
+ if (mode->InitMode != NULL)
+ {
+ mode->InitMode(doompal);
+ }
+ }
+
+ // Save screen mode.
+
+ screen_mode = mode;
+}
+
+static void ApplyWindowResize(unsigned int w, unsigned int h)
+{
+ screen_mode_t *mode;
+
+ // Find the biggest screen mode that will fall within these
+ // dimensions, falling back to the smallest mode possible if
+ // none is found.
+
+ mode = I_FindScreenMode(w, h);
+
+ if (mode == NULL)
+ {
+ mode = I_FindScreenMode(SCREENWIDTH, SCREENHEIGHT);
+ }
+
+ // Reset mode to resize window.
+
+ printf("Resize to %ix%i\n", mode->width, mode->height);
+ SetVideoMode(mode, mode->width, mode->height);
+
+ // Save settings.
+
+ screen_width = mode->width;
+ screen_height = mode->height;
+}
+
void I_InitGraphics(void)
{
SDL_Event dummy;
byte *doompal;
- int flags = 0;
char *env;
// Pass through the XSCREENSAVER_WINDOW environment variable to
@@ -1727,70 +1856,53 @@ 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_InitWindowTitle();
+#if !SDL_VERSION_ATLEAST(1, 3, 0)
+ 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)
{
- windowwidth = 0;
- windowheight = 0;
+ SetVideoMode(NULL, 0, 0);
}
else
{
+ int w, h;
+
if (autoadjust_video_settings)
{
I_AutoAdjustSettings();
}
- windowwidth = screen_width;
- windowheight = screen_height;
+ w = screen_width;
+ h = screen_height;
- screen_mode = I_FindScreenMode(windowwidth, windowheight);
+ screen_mode = I_FindScreenMode(w, h);
if (screen_mode == NULL)
{
I_Error("I_InitGraphics: Unable to find a screen mode small "
- "enough for %ix%i", windowwidth, windowheight);
+ "enough for %ix%i", w, h);
}
- if (windowwidth != screen_mode->width
- || windowheight != screen_mode->height)
+ if (w != screen_mode->width || h != screen_mode->height)
{
printf("I_InitGraphics: %s (%ix%i within %ix%i)\n",
- WindowBoxType(screen_mode, windowwidth, windowheight),
- screen_mode->width, screen_mode->height,
- windowwidth, windowheight);
+ WindowBoxType(screen_mode, w, h),
+ screen_mode->width, screen_mode->height, w, h);
}
- // Generate lookup tables before setting the video mode.
-
- if (screen_mode->InitMode != NULL)
- {
- screen_mode->InitMode(doompal);
- }
- }
-
- // Set up title and icon. Windows cares about the ordering; this
- // has to be done before the call to SDL_SetVideoMode.
-
- I_InitWindowTitle();
-#if !SDL_VERSION_ATLEAST(1, 3, 0)
- I_InitWindowIcon();
-#endif
-
- // Set the video mode.
-
- flags |= SDL_SWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF;
-
- if (fullscreen)
- {
- flags |= SDL_FULLSCREEN;
- }
-
- screen = SDL_SetVideoMode(windowwidth, windowheight, 8, flags);
-
- if (screen == NULL)
- {
- I_Error("Error setting video mode: %s\n", SDL_GetError());
+ SetVideoMode(screen_mode, w, h);
}
// Start with a clear black screen
@@ -1811,6 +1923,7 @@ void I_InitGraphics(void)
// Set the palette
+ doompal = W_CacheLumpName(DEH_String("PLAYPAL"), PU_CACHE);
I_SetPalette(doompal);
SDL_SetColors(screen, palette, 0, 256);
@@ -1819,26 +1932,6 @@ void I_InitGraphics(void)
UpdateFocus();
UpdateGrab();
- // In screensaver mode, now find a screen_mode to use.
-
- if (screensaver_mode)
- {
- screen_mode = I_FindScreenMode(screen->w, screen->h);
-
- if (screen_mode == NULL)
- {
- I_Error("I_InitGraphics: Unable to find a screen mode small "
- "enough for %ix%i", screen->w, screen->h);
- }
-
- // Generate lookup tables before setting the video mode.
-
- if (screen_mode->InitMode != NULL)
- {
- screen_mode->InitMode(doompal);
- }
- }
-
// On some systems, it takes a second or so for the screen to settle
// after changing modes. We include the option to add a delay when
// setting the screen mode, so that the game doesn't start immediately
@@ -1854,12 +1947,12 @@ void I_InitGraphics(void)
// Likewise if the screen pitch is not the same as the width
// If we have to multiply, drawing is done to a separate 320x200 buf
- native_surface = !SDL_MUSTLOCK(screen)
+ native_surface = !SDL_MUSTLOCK(screen)
&& screen_mode == &mode_scale_1x
&& screen->pitch == SCREENWIDTH
&& aspect_ratio_correct;
- // If not, allocate a buffer and copy from that buffer to the
+ // If not, allocate a buffer and copy from that buffer to the
// screen when we do an update
if (native_surface)
diff --git a/src/i_video.h b/src/i_video.h
index af865287..82368967 100644
--- a/src/i_video.h
+++ b/src/i_video.h
@@ -43,7 +43,9 @@
#define SCREENHEIGHT_4_3 240
-typedef struct
+#define MAX_MOUSE_BUTTONS 8
+
+typedef struct
{
// Screen width and height
diff --git a/src/m_config.c b/src/m_config.c
index 056861cc..8b93cfd3 100644
--- a/src/m_config.c
+++ b/src/m_config.c
@@ -60,6 +60,7 @@ static char *default_extra_config;
typedef enum
{
DEFAULT_INT,
+ DEFAULT_INT_HEX,
DEFAULT_STRING,
DEFAULT_FLOAT,
DEFAULT_KEY,
@@ -99,14 +100,19 @@ typedef struct
char *filename;
} default_collection_t;
+#define CONFIG_VARIABLE_GENERIC(name, type) \
+ { #name, NULL, type, 0, 0, false }
+
#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
@@ -574,20 +580,27 @@ static default_t extra_defaults_list[] =
//!
// Mouse acceleration threshold. When the speed of mouse movement
- // exceeds this threshold value, the speed is multiplied by an
+ // exceeds this threshold value, the speed is multiplied by an
// acceleration factor (mouse_acceleration).
//
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),
//!
+ // 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),
+
+ //!
// If non-zero, the ENDOOM screen is displayed when exiting the
// game. If zero, the ENDOOM screen is not displayed.
//
@@ -682,6 +695,18 @@ static default_t extra_defaults_list[] =
CONFIG_VARIABLE_INT(joyb_straferight),
//!
+ // Joystick button to cycle to the previous weapon.
+ //
+
+ CONFIG_VARIABLE_INT(joyb_prevweapon),
+
+ //!
+ // Joystick button to cycle to the next weapon.
+ //
+
+ CONFIG_VARIABLE_INT(joyb_nextweapon),
+
+ //!
// Mouse button to strafe left.
//
@@ -706,6 +731,18 @@ static default_t extra_defaults_list[] =
CONFIG_VARIABLE_INT(mouseb_backward),
//!
+ // Mouse button to cycle to the previous weapon.
+ //
+
+ CONFIG_VARIABLE_INT(mouseb_prevweapon),
+
+ //!
+ // Mouse button to cycle to the next weapon.
+ //
+
+ 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.
//
@@ -858,6 +895,12 @@ static default_t extra_defaults_list[] =
CONFIG_VARIABLE_KEY(key_menu_gamma),
//!
+ // Keyboard shortcut to switch view in multiplayer.
+ //
+
+ CONFIG_VARIABLE_KEY(key_spy),
+
+ //!
// Keyboard shortcut to increase the screen size.
//
@@ -990,10 +1033,82 @@ static default_t extra_defaults_list[] =
CONFIG_VARIABLE_KEY(key_weapon8),
//!
+ // Key to cycle to the previous weapon.
+ //
+
+ CONFIG_VARIABLE_KEY(key_prevweapon),
+
+ //!
+ // Key to cycle to the next weapon.
+ //
+
+ CONFIG_VARIABLE_KEY(key_nextweapon),
+
+ //!
// Key to re-display last message.
//
CONFIG_VARIABLE_KEY(key_message_refresh),
+
+ //!
+ // Key to quit the game when recording a demo.
+ //
+
+ CONFIG_VARIABLE_KEY(key_demo_quit),
+
+ //!
+ // Key to send a message during multiplayer games.
+ //
+
+ 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 player 4 during multiplayer games.
+ //
+
+ CONFIG_VARIABLE_KEY(key_multi_msgplayer4),
+
+ //!
+ // Key to send a message to player 5 during multiplayer games.
+ //
+
+ CONFIG_VARIABLE_KEY(key_multi_msgplayer5),
+
+ //!
+ // Key to send a message to player 6 during multiplayer games.
+ //
+
+ CONFIG_VARIABLE_KEY(key_multi_msgplayer6),
+
+ //!
+ // Key to send a message to player 7 during multiplayer games.
+ //
+
+ 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 =
@@ -1115,6 +1230,10 @@ static void SaveDefaultCollection(default_collection_t *collection)
fprintf(f, "%i", * (int *) defaults[i].location);
break;
+ case DEFAULT_INT_HEX:
+ fprintf(f, "0x%x", * (int *) defaults[i].location);
+ break;
+
case DEFAULT_FLOAT:
fprintf(f, "%f", * (float *) defaults[i].location);
break;
@@ -1204,6 +1323,7 @@ static void LoadDefaultCollection(default_collection_t *collection)
break;
case DEFAULT_INT:
+ case DEFAULT_INT_HEX:
* (int *) def->location = ParseIntParameter(strparm);
break;
diff --git a/src/m_controls.c b/src/m_controls.c
index 98b1e51b..60a96ac2 100644
--- a/src/m_controls.c
+++ b/src/m_controls.c
@@ -22,6 +22,8 @@
//
//-----------------------------------------------------------------------------
+#include <stdio.h>
+
#include "doomtype.h"
#include "doomkeys.h"
@@ -80,8 +82,19 @@ 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:
@@ -93,8 +106,10 @@ 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;
@@ -150,6 +165,9 @@ 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
@@ -182,7 +200,7 @@ void M_BindBaseControls(void)
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);
@@ -226,6 +244,15 @@ void M_BindWeaponControls(void)
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)
@@ -270,6 +297,22 @@ void M_BindMenuControls(void)
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
diff --git a/src/m_controls.h b/src/m_controls.h
index 2a4aa3df..389c94a0 100644
--- a/src/m_controls.h
+++ b/src/m_controls.h
@@ -52,6 +52,9 @@ extern int key_useartifact;
extern int key_message_refresh;
extern int key_pause;
+extern int key_multi_msg;
+extern int key_multi_msgplayer[8];
+
extern int key_weapon1;
extern int key_weapon2;
extern int key_weapon3;
@@ -61,6 +64,11 @@ 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;
@@ -125,6 +133,9 @@ extern int mousebstraferight;
extern int mousebbackward;
extern int mousebuse;
+extern int mousebprevweapon;
+extern int mousebnextweapon;
+
extern int joybfire;
extern int joybstrafe;
extern int joybuse;
@@ -135,14 +146,18 @@ 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 M_ApplyPlatformDefaults(void);
diff --git a/src/setup/joystick.c b/src/setup/joystick.c
index 0094dd81..fbe3a3f3 100644
--- a/src/setup/joystick.c
+++ b/src/setup/joystick.c
@@ -425,6 +425,8 @@ 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)
{
diff --git a/src/setup/keyboard.c b/src/setup/keyboard.c
index 6e746ee9..3d9f9977 100644
--- a/src/setup/keyboard.c
+++ b/src/setup/keyboard.c
@@ -47,7 +47,7 @@ static int *controls[] = { &key_left, &key_right, &key_up, &key_down,
&key_weapon1, &key_weapon2, &key_weapon3,
&key_weapon4, &key_weapon5, &key_weapon6,
&key_weapon7, &key_weapon8,
- NULL };
+ &key_prevweapon, &key_nextweapon, NULL };
static int *menu_nav[] = { &key_menu_activate, &key_menu_up, &key_menu_down,
&key_menu_left, &key_menu_right, &key_menu_back,
@@ -55,10 +55,12 @@ static int *menu_nav[] = { &key_menu_activate, &key_menu_up, &key_menu_down,
static int *shortcuts[] = { &key_menu_help, &key_menu_save, &key_menu_load,
&key_menu_volume, &key_menu_detail, &key_menu_qsave,
- &key_menu_endgame, &key_menu_messages,
+ &key_menu_endgame, &key_menu_messages, &key_spy,
&key_menu_qload, &key_menu_quit, &key_menu_gamma,
&key_menu_incscreen, &key_menu_decscreen,
- &key_message_refresh, NULL };
+ &key_message_refresh, &key_multi_msg,
+ &key_multi_msgplayer[0], &key_multi_msgplayer[1],
+ &key_multi_msgplayer[2], &key_multi_msgplayer[3] };
static int *map_keys[] = { &key_map_north, &key_map_south, &key_map_east,
&key_map_west, &key_map_zoomin, &key_map_zoomout,
@@ -220,6 +222,8 @@ static void ConfigExtraKeys(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(unused))
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);
}
static void OtherKeysDialog(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(unused))
@@ -260,14 +264,15 @@ static void OtherKeysDialog(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(unused))
AddKeyControl(table, "Quick load", &key_menu_qload);
AddKeyControl(table, "Quit game", &key_menu_quit);
AddKeyControl(table, "Toggle gamma", &key_menu_gamma);
+ AddKeyControl(table, "Multiplayer spy", &key_spy);
AddKeyControl(table, "Increase screen size", &key_menu_incscreen);
AddKeyControl(table, "Decrease screen size", &key_menu_decscreen);
AddKeyControl(table, "Display last message", &key_message_refresh);
+ AddKeyControl(table, "Finish recording demo", &key_demo_quit);
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,6 +286,20 @@ static void OtherKeysDialog(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(unused))
AddKeyControl(table, "Mark location", &key_map_mark);
AddKeyControl(table, "Clear all marks", &key_map_clearmark);
+ 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 --git a/src/setup/keyboard.h b/src/setup/keyboard.h
index 2797ba8f..12059bf8 100644
--- a/src/setup/keyboard.h
+++ b/src/setup/keyboard.h
@@ -22,59 +22,6 @@
#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);
diff --git a/src/setup/mainmenu.c b/src/setup/mainmenu.c
index 46e4b4e6..c3cb7db5 100644
--- a/src/setup/mainmenu.c
+++ b/src/setup/mainmenu.c
@@ -46,6 +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)
@@ -174,6 +232,8 @@ void MainMenu(void)
quit_action = TXT_NewWindowAction(KEY_ESCAPE, "Quit");
TXT_SignalConnect(quit_action, "pressed", QuitConfirm, NULL);
TXT_SetWindowAction(window, TXT_HORIZ_LEFT, quit_action);
+
+ TXT_SetKeyListener(window, MainMenuKeyPress, NULL);
}
//
diff --git a/src/setup/mouse.c b/src/setup/mouse.c
index d464261f..5b555f88 100644
--- a/src/setup/mouse.c
+++ b/src/setup/mouse.c
@@ -36,7 +36,7 @@ static int usemouse = 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;
@@ -48,7 +48,9 @@ static int *all_mouse_buttons[] = {
&mousebstraferight,
&mousebbackward,
&mousebuse,
- &mousebjump
+ &mousebjump,
+ &mousebprevweapon,
+ &mousebnextweapon
};
static void MouseSetCallback(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(variable))
@@ -103,6 +105,9 @@ static void ConfigExtraButtons(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(unused))
{
AddMouseControl(buttons_table, "Jump", &mousebjump);
}
+
+ AddMouseControl(buttons_table, "Previous weapon", &mousebprevweapon);
+ AddMouseControl(buttons_table, "Next weapon", &mousebnextweapon);
}
void ConfigMouse(void)
diff --git a/src/setup/multiplayer.c b/src/setup/multiplayer.c
index f3b3221d..24cd0670 100644
--- a/src/setup/multiplayer.c
+++ b/src/setup/multiplayer.c
@@ -29,6 +29,7 @@
#include "d_iwad.h"
#include "m_config.h"
#include "doom/d_englsh.h"
+#include "m_controls.h"
#include "multiplayer.h"
#include "mode.h"
@@ -863,5 +864,39 @@ void BindMultiplayerVariables(void)
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 --git a/src/setup/sound.c b/src/setup/sound.c
index 61182753..627549b5 100644
--- a/src/setup/sound.c
+++ b/src/setup/sound.c
@@ -69,6 +69,7 @@ static char *musicmode_strings[] =
int snd_sfxdevice = SNDDEVICE_SB;
int snd_musicdevice = SNDDEVICE_GENMIDI;
int snd_samplerate = 22050;
+int opl_io_port = 0x388;
static int numChannels = 8;
static int sfxVolume = 15;
diff --git a/src/setup/txt_keyinput.c b/src/setup/txt_keyinput.c
index e385cc59..483c325f 100644
--- a/src/setup/txt_keyinput.c
+++ b/src/setup/txt_keyinput.c
@@ -111,7 +111,7 @@ static void TXT_KeyInputDrawer(TXT_UNCAST_ARG(key_input), int selected)
if (*key_input->variable == 0)
{
- strcpy(buf, "");
+ strcpy(buf, "(none)");
}
else
{
diff --git a/src/setup/txt_mouseinput.c b/src/setup/txt_mouseinput.c
index 05c89b39..8b87e651 100644
--- a/src/setup/txt_mouseinput.c
+++ b/src/setup/txt_mouseinput.c
@@ -91,7 +91,7 @@ static void GetMouseButtonDescription(int button, char *buf)
strcpy(buf, "MID");
break;
default:
- sprintf(buf, "BUTTON #%i", button);
+ sprintf(buf, "BUTTON #%i", button + 1);
break;
}
}
@@ -153,7 +153,7 @@ static int TXT_MouseInputKeyPress(TXT_UNCAST_ARG(mouse_input), int mouse)
static void TXT_MouseInputMousePress(TXT_UNCAST_ARG(widget), int x, int y, int b)
{
TXT_CAST_ARG(txt_mouse_input_t, widget);
-
+
// Clicking is like pressing enter
if (b == TXT_MOUSE_LEFT)
diff --git a/src/z_zone.c b/src/z_zone.c
index a3900f5b..c7425290 100644
--- a/src/z_zone.c
+++ b/src/z_zone.c
@@ -41,6 +41,7 @@
// because it will get overwritten automatically if needed.
//
+#define MEM_ALIGN sizeof(void *)
#define ZONEID 0x1d4a11
typedef struct memblock_s
@@ -201,7 +202,7 @@ Z_Malloc
memblock_t* base;
void *result;
- size = (size + 3) & ~3;
+ size = (size + MEM_ALIGN - 1) & ~(MEM_ALIGN - 1);
// scan through the block list,
// looking for the first free block