aboutsummaryrefslogtreecommitdiff
path: root/src/parsec/m_option.cpp
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@gmail.com>2026-08-24 11:16:07 +0200
committerFelix Morgner <felix.morgner@gmail.com>2026-08-24 11:16:07 +0200
commitc068f22329d5cc722622a2183bbb22eef2093df7 (patch)
tree12d56c1aede67988a55e241364606bfbb4dba933 /src/parsec/m_option.cpp
downloadopenparsec-c068f22329d5cc722622a2183bbb22eef2093df7.tar.xz
openparsec-c068f22329d5cc722622a2183bbb22eef2093df7.zip
initial importHEADmain
Diffstat (limited to 'src/parsec/m_option.cpp')
-rw-r--r--src/parsec/m_option.cpp1769
1 files changed, 1769 insertions, 0 deletions
diff --git a/src/parsec/m_option.cpp b/src/parsec/m_option.cpp
new file mode 100644
index 0000000..d736213
--- /dev/null
+++ b/src/parsec/m_option.cpp
@@ -0,0 +1,1769 @@
+/*
+ * PARSEC - Options Window
+ *
+ * $Author: uberlinuxguy $ - $Date: 2004/09/26 03:43:37 $
+ *
+ * Orginally written by:
+ * Copyright (c) Markus Hadwiger <msh@parsec.org> 1998-2000
+ * Copyright (c) Andreas Varga <sid@parsec.org> 1999-2000
+ *
+ * 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
+ */
+
+// C library
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+// compilation flags/debug support
+#include "config.h"
+#include "debug.h"
+
+// general definitions
+#include "general.h"
+#include "objstruc.h"
+
+// global externals
+#include "globals.h"
+
+#include "con_com.h"
+
+// subsystem headers
+#include "aud_defs.h"
+#include "net_defs.h"
+#include "sys_defs.h"
+#include "vid_defs.h"
+
+// drawing subsystem
+#include "d_font.h"
+
+// rendering subsystem
+#include "r_patch.h"
+#include "r_supp.h"
+
+// local module header
+#include "m_option.h"
+
+// proprietary module headers
+#include "con_aux.h"
+#include "e_color.h"
+#include "e_demo.h"
+#include "e_draw.h"
+#include "e_supp.h"
+#include "m_main.h"
+#include "net_conn.h"
+#include "sys_bind.h"
+#include "vid_plug.h"
+
+#ifdef SYSTEM_TARGET_LINUX
+ #include <SDL/SDL.h>
+#else
+ #include <SDL.h>
+#endif
+
+// flags
+#define DISABLE_VID_SUBSYS_SWITCHING
+
+
+
+// generic string paste area --------------------------------------------------
+//
+#define PASTE_STR_LEN 2047
+static char paste_str[ PASTE_STR_LEN + 1 ];
+
+static char tmp_name[MAX_PLAYER_NAME + 1];
+
+bool mod_player_name;
+
+// string constants -----------------------------------------------------------
+//
+static char not_available[] = "not available ";
+
+
+// options menu configuration and state variables -----------------------------
+//
+#define OPT_POS_RIGHT 0
+#define OPT_POS_LEFT ( m_sintab_size - 1 )
+#define OPT_SLIDE_SPEED 12
+
+#define OPT_MAX_BLINK_COUNT 900
+#define OPT_MAX_TEXTLEN 255
+
+static const char *option_lines[ NUM_OPTIONS ] = {
+
+ " resolution: ",
+ " color depth: ",
+ " fullscreen: ",
+ " vertical sync: ",
+ " apply video settings ",
+ " texture detail: ",
+ " geometry detail: ",
+ " sound-fx detail: ",
+ " apply detail settings ",
+ " protocol: ",
+ " kill limit: ",
+ " solar system: ",
+ " apply network settings ",
+ " audio settings: ",
+ " controller: ",
+ " invert mouse y axis: ",
+ " mouse sensitivity: ",
+ " mouse centering speed: ",
+ //" ",
+ " name: ",
+ " exit options menu ",
+};
+
+enum {
+
+ OPT_SPACING_NONE = 0,
+ OPT_SPACING_NEWLINE = 1,
+ OPT_SPACING_DIVIDER = 2
+};
+
+static int option_spacing[ NUM_OPTIONS ] = {
+
+ OPT_SPACING_NONE, // RES_OPT,
+ OPT_SPACING_NONE, // DEPTH_OPT,
+ OPT_SPACING_NONE, // FULL_OPT,
+ OPT_SPACING_NEWLINE, // SYNC_OPT,
+ OPT_SPACING_DIVIDER, // APPLY_VID_OPT,
+ OPT_SPACING_NONE, // TEXDETAIL_OPT,
+ OPT_SPACING_NONE, // GEOMDETAIL_OPT,
+ OPT_SPACING_NEWLINE, // SFXDETAIL_OPT,
+ OPT_SPACING_DIVIDER, // APPLY_DETAIL_OPT
+ OPT_SPACING_NONE, // PROTOCOL_OPT,
+ OPT_SPACING_NONE, // KILL_LIMIT_OPT,
+ OPT_SPACING_NEWLINE, // SOLAR_OPT,
+ OPT_SPACING_DIVIDER, // APPLY_NET_OPT,
+ OPT_SPACING_NONE, // SOUND_OPT,
+ OPT_SPACING_NONE, // CTRL_OPT,
+ OPT_SPACING_NONE, // INVERT_OPT,
+ OPT_SPACING_NONE, // SENSITIVITY_OPT,
+ OPT_SPACING_DIVIDER, // CENTER_OPT,
+ //OPT_SPACING_DIVIDER, // APPLY_MOUSE_OPT (Actually a blank line),
+ OPT_SPACING_NEWLINE, // NAME_OPT,
+ OPT_SPACING_DIVIDER, // EXIT_OPT,
+};
+
+static int option_apply_blinking[ NUM_OPTIONS ] = {
+
+ FALSE,
+ FALSE,
+ FALSE,
+ FALSE,
+ FALSE, // APPLY_VID_OPT,
+ FALSE,
+ FALSE,
+ FALSE,
+ FALSE, // APPLY_DETAIL_OPT
+ FALSE,
+ FALSE,
+ FALSE,
+ FALSE, // APPLY_NET_OPT,
+ FALSE,
+ FALSE,
+ FALSE,
+ FALSE,
+ FALSE,
+ FALSE,
+};
+
+static int enable_dynamic_options = TRUE;
+
+static int option_dynamic[ NUM_OPTIONS ] = {
+
+ FALSE,
+ FALSE,
+ FALSE,
+ FALSE,
+ FALSE, // APPLY_VID_OPT,
+ FALSE,
+ FALSE,
+ FALSE,
+ FALSE, // APPLY_DETAIL_OPT
+ FALSE,
+ FALSE,
+ FALSE,
+ FALSE, // APPLY_NET_OPT,
+ FALSE,
+ FALSE,
+ TRUE,
+ TRUE,
+ TRUE,
+ FALSE,
+};
+
+
+static const char *binopt_strings[] = {
+
+ "off ",
+ "on ",
+};
+
+static const char *detailopt_strings[] = {
+
+ "high ",
+ "low ",
+};
+
+static const char *qualityopt_strings[] = {
+
+ "high ",
+ "medium ",
+ "low ",
+};
+
+static const char *soundopt_strings[] = {
+
+ "off ",
+ "sfx ",
+ "music ",
+ "music+sfx ",
+};
+
+static const char *ctrlopt_strings[] = {
+
+ "off ",
+ "joystick ",
+ "mouse ",
+ "joy+mouse ",
+};
+
+
+static int opt_slidepos = OPT_POS_RIGHT;
+static int opt_slidetarget = OPT_POS_RIGHT;
+static refframe_t opt_lastref = REFFRAME_INVALID;
+
+static int opt_blink_count = 0;
+static int opt_blink_ctr = 0;
+static int opt_show_warning_text = FALSE;
+static char opt_warning_str[] = "disconnect first";
+
+static char opt_caption_str[] = "OPTIONS MENU";
+
+static char opt_text_buffer[ OPT_MAX_TEXTLEN + 1 ];
+
+static resinfo_s cur_res = resinfo_s();
+static int cur_depthmode = 0;
+static int cur_winstatus = 0;
+static int cur_flipsync = 0;
+static int cur_mipmapbias = 0;
+static int cur_geombias = 0;
+
+PUBLIC int cur_sfxquality = 0;
+PUBLIC int prev_sfxquality = 0;
+
+static int cur_killlimit = 0;
+static int cur_solarsys = 0;
+
+static int cur_sensitivity = 0;
+static int cur_centerspeed = 0;
+
+static int vidsubsys_id = 0;
+static int prev_vidsubsys_id = 0;
+
+static int protsubsys_id = 0;
+static int prev_protsubsys_id = 0;
+
+
+struct user_names_s {
+
+ const char *internal_name;
+ const char *visible_name;
+};
+
+static user_names_s user_names[] = {
+
+ { "glx", "opengl" },
+ { "udp", "tcp/ip" },
+
+ { NULL, NULL },
+};
+
+// number of option menu entries and currently selected entry -----------------
+//
+static int cur_opmenu_size = NUM_OPTIONS;
+static int cur_opmenu_selindx = 0;
+
+
+// return current selection in options menu -----------------------------------
+//
+int OptionsListSelection()
+{
+ return cur_opmenu_selindx;
+}
+
+
+// select default item in options menu ----------------------------------------
+//
+void OptionsListSelectDefault()
+{
+ cur_opmenu_selindx = 0;
+}
+
+
+// one item up in options menu ------------------------------------------------
+//
+void OptionsListCursorUp()
+{
+ if ( --cur_opmenu_selindx < 0 )
+ cur_opmenu_selindx = cur_opmenu_size - 1;
+
+ AUD_Select2();
+}
+
+
+// one item down in options menu ----------------------------------------------
+//
+void OptionsListCursorDown()
+{
+ if ( ++cur_opmenu_selindx >= cur_opmenu_size )
+ cur_opmenu_selindx = 0;
+
+ AUD_Select2();
+}
+
+
+
+// current metrics of options menu contents -----------------------------------
+//
+static list_window_metrics_s options_content_metrics = { FALSE };
+
+
+// detect whether mouse position is over options menu item --------------------
+//
+int MouseOverOption( int mousex, int mousey )
+{
+ if ( !options_content_metrics.valid )
+ return MOUSE_OVER_NOTHING;
+
+ if ( !SlideFinishedOptions() )
+ return MOUSE_OVER_NOTHING;
+
+ int chwidth = options_content_metrics.chwidth;
+ int chheight = options_content_metrics.chheight;
+ int text_x = options_content_metrics.text_x;
+ int text_y = options_content_metrics.text_y;
+ int linewidth = options_content_metrics.maxcontwidth * chwidth;
+
+ // check against options menu items
+ for ( int mid = 0; mid < cur_opmenu_size; mid++ ) {
+
+ if ( ( mousex >= text_x ) && ( mousex < ( text_x + linewidth ) ) &&
+ ( mousey >= text_y ) && ( mousey < ( text_y + chheight ) ) ) {
+
+ // set selected index directly
+ if ( cur_opmenu_selindx != mid )
+ AUD_Select2();
+ cur_opmenu_selindx = mid;
+
+ return MOUSE_OVER_OPTION;
+ }
+
+ text_y += chheight;
+ if ( option_spacing[ mid ] != OPT_SPACING_NONE ) {
+ text_y += chheight;
+ }
+ }
+
+ return MOUSE_OVER_NOTHING;
+}
+
+
+// set position and slide target for options menu to left (in) ----------------
+//
+void MoveInOptions()
+{
+ opt_slidepos = OPT_POS_LEFT;
+ opt_slidetarget = opt_slidepos;
+}
+
+
+// set position and slide target for options menu to right (out) --------------
+//
+void MoveOutOptions()
+{
+ opt_slidepos = OPT_POS_RIGHT;
+ opt_slidetarget = opt_slidepos;
+}
+
+
+// set slide target for options menu to left (in) -----------------------------
+//
+void SlideInOptions()
+{
+ opt_slidetarget = OPT_POS_LEFT;
+}
+
+
+// set slide target for options menu to right (out) ---------------------------
+//
+void SlideOutOptions()
+{
+ opt_slidetarget = OPT_POS_RIGHT;
+}
+
+
+// check if options menu is at its desired slide position ---------------------
+//
+int SlideFinishedOptions()
+{
+ return ( opt_slidepos == opt_slidetarget );
+}
+
+
+// init info on current subsystems for options menu ---------------------------
+//
+void InitOptionsSubsystemInfo()
+{
+ // get current mode values
+ cur_res = GameScreenRes;
+ cur_depthmode = GameScreenBPP;
+ cur_winstatus = GameScreenWindowed;
+
+
+ vidsubsys_id = 0;
+ prev_vidsubsys_id = 0;
+
+
+ cur_mipmapbias = AUXDATA_TMM_MIPMAP_LOD_BIAS;
+ cur_geombias = AUXDATA_LOD_DISCRETE_GEOMETRY_BIAS;
+
+ // search for currently selected protocol in table
+ int id = 0;
+ for ( id = 0; protocol_table[ id ].name; id++ )
+ if ( protocol_table[ id ].id == sys_BindType_PROTOCOL )
+ break;
+
+ protsubsys_id = id;
+ prev_protsubsys_id = id;
+
+ //NOTE:
+ // ( protocol_table[ id ].name == NULL ) must be
+ // handled correctly by users of protsubsys_id.
+
+ cur_killlimit = AUX_KILL_LIMIT_FOR_GAME_END;
+ cur_solarsys = AUXDATA_BACKGROUND_NEBULA_ID;
+
+ enable_dynamic_options = Op_Mouse;
+}
+
+
+// init vidmode state variables for options menu ------------------------------
+//
+void InitOptionsWindow()
+{
+ static int mode_init_done = FALSE;
+ if ( mode_init_done )
+ return;
+
+ // init mode state variables
+ cur_res = GameScreenRes;
+ cur_depthmode = GameScreenBPP;
+ cur_winstatus = GameScreenWindowed;
+ cur_flipsync = FlipSynched;
+
+ int id = 0;
+
+ vidsubsys_id = 0;
+
+ // search for currently selected protocol in table
+ for ( id = 0; protocol_table[ id ].name; id++ )
+ if ( protocol_table[ id ].id == sys_BindType_PROTOCOL )
+ break;
+
+ protsubsys_id = prev_protsubsys_id = id;
+
+
+ cur_sensitivity = inp_mouse_sensitivity;
+ cur_centerspeed = inp_mouse_drift;
+
+ enable_dynamic_options = Op_Mouse;
+
+ mode_init_done = TRUE;
+}
+
+
+// exec options menu item selection: screen resolution ------------------------
+//
+PRIVATE
+void ExecOptionSelectResolution()
+{
+ if (!cur_res.isValid())
+ return;
+
+ int resindex = GetResolutionIndex(cur_res.width, cur_res.height);
+ resindex = (resindex + 1) % Resolutions.size();
+
+ if (VID_MODE_AVAILABLE(resindex)) {
+ cur_res = Resolutions[resindex];
+ }
+}
+
+
+// exec options menu item selection: color depth ------------------------------
+//
+PRIVATE
+void ExecOptionSelectColordepth()
+{
+ if ( cur_depthmode == -1 )
+ return;
+
+ int prev_depthmode = cur_depthmode;
+
+ if ( cur_depthmode == MODE_COL_16BPP )
+ cur_depthmode = MODE_COL_32BPP;
+ else if ( cur_depthmode == MODE_COL_32BPP )
+ cur_depthmode = MODE_COL_16BPP;
+
+ if (cur_depthmode > MaxScreenBPP)
+ cur_depthmode = prev_depthmode;
+}
+
+
+// exec options menu item selection: fullscreen/windowed mode -----------------
+//
+PRIVATE
+void ExecOptionSelectFullscreen()
+{
+ if ( cur_winstatus == -1 )
+ return;
+
+ // toggle winstatus flag
+ cur_winstatus = !cur_winstatus;
+}
+
+
+// exec options menu item selection: sync to screen ---------------------------
+//
+PRIVATE
+void ExecOptionSelectFlipsync()
+{
+ // toggle flipsync flag
+ if ( cur_flipsync == -1 )
+ return;
+
+ cur_flipsync = !cur_flipsync;
+}
+
+
+// exec options menu item selection: texture detail ---------------------------
+//
+PRIVATE
+void ExecOptionSelectTextureDetail()
+{
+ if ( ++cur_mipmapbias > 1 ) {
+ cur_mipmapbias = 0;
+ }
+}
+
+
+// exec options menu item selection: geometry detail --------------------------
+//
+PRIVATE
+void ExecOptionSelectGeometryDetail()
+{
+ if ( ++cur_geombias > 1 ) {
+ cur_geombias = 0;
+ }
+}
+
+
+// exec options menu item selection: sound detail -----------------------------
+//
+PRIVATE
+void ExecOptionSelectSoundDetail()
+{
+ if ( ++cur_sfxquality > 2 ) {
+ cur_sfxquality = 0;
+ }
+}
+
+
+// exec options menu item selection: select game protocol ---------------------
+//
+PRIVATE
+void ExecOptionSelectProtocol()
+{
+ // ensure that there is atleast one protocol linked
+ if ( protocol_table[ 0 ].id == -1 )
+ return;
+
+ // take next available protocol
+ if ( protocol_table[ protsubsys_id ].id != -1 )
+ protsubsys_id++;
+ if ( protocol_table[ protsubsys_id ].id == -1 )
+ protsubsys_id = 0;
+}
+
+
+// exec options menu item selection: kill limit -------------------------------
+//
+PRIVATE
+void ExecOptionSelectKillLimit()
+{
+ cur_killlimit += 10;
+ if ( cur_killlimit > 99 ) {
+ cur_killlimit = 0;
+ }
+}
+
+
+// exec options menu item selection: solar system -----------------------------
+//
+PRIVATE
+void ExecOptionSelectSolarSystem()
+{
+ // currently 2 to 5 are valid
+ if ( ++cur_solarsys > 5 ) {
+ cur_solarsys = 2;
+ }
+}
+
+
+// exec options menu item selection: enable/disable sound effects -------------
+//
+PRIVATE
+void ExecOptionSelectSoundEnabling()
+{
+ if ( SoundDisabled )
+ return;
+
+ // determine current setting
+ int cursetting = 0x00;
+ if ( Op_SoundEffects )
+ cursetting |= 0x01;
+ if ( Op_Music )
+ cursetting |= 0x02;
+
+ // go to next setting
+ cursetting = ( cursetting + 1 ) & 0x03;
+
+ // determine new setting
+ Op_SoundEffects = ( ( cursetting & 0x01 ) != 0x00 );
+ Op_Music = ( ( cursetting & 0x02 ) != 0x00 );
+
+ // start/stop according to setting
+ switch ( cursetting ) {
+
+ //NOTE:
+ // the sequence of AUDs_CloseMenuSound() and AUDs_StopAudioStream()
+ // must not be changed, or the stream active flag will wrongly stick.
+
+ case 0x00:
+ //AUDs_CDStop();
+ AUDs_CloseMenuSound();
+ AUDs_StopAudioStream();
+ break;
+
+ case 0x01:
+ //AUDs_CDStop();
+ AUDs_CloseMenuSound();
+ AUDs_StopAudioStream();
+ break;
+
+ case 0x02:
+ AUDs_OpenMenuSound();
+ break;
+
+ case 0x03:
+ AUDs_OpenMenuSound();
+ break;
+
+ default:
+ ASSERT( 0 );
+ }
+}
+
+
+// exec options menu item selection: select controller ------------------------
+//
+PRIVATE
+void ExecOptionSelectControllerEnabling()
+{
+ // determine current setting
+ int cursetting = 0x00;
+ if ( Op_Joystick )
+ cursetting |= 0x01;
+ if ( Op_Mouse )
+ cursetting |= 0x02;
+
+
+ bool foundsetting = false;
+
+ while (!foundsetting) {
+ // go to next setting
+ cursetting = ( cursetting + 1 ) & 0x03;
+
+ foundsetting = true;
+
+ // prevent setting both mouse and joystick
+ if ( cursetting == 3 ) {
+ foundsetting = false;
+ }
+
+ // ensure joystick is available
+ if ( ( cursetting & 0x01 ) && JoystickDisabled ) {
+ foundsetting = false;
+ }
+ };
+
+ // determine new setting
+ Op_Joystick = ( ( cursetting & 0x01 ) != 0x00 );
+ Op_Mouse = ( ( cursetting & 0x02 ) != 0x00 );
+
+ enable_dynamic_options = Op_Mouse;
+}
+
+
+// exec options menu item selection: select controller ------------------------
+//
+PRIVATE
+void ExecOptionSelectInvertYAxis()
+{
+ if ( !enable_dynamic_options )
+ return;
+
+ inp_mouse_invert_yaxis ^= 1;
+}
+
+
+// exec options menu item selection: select mouse sensitivity -----------------
+//
+PRIVATE
+void ExecOptionSelectSensitivity()
+{
+ if ( !enable_dynamic_options )
+ return;
+
+ cur_sensitivity += 100;
+ if ( cur_sensitivity > 2000 ) {
+ cur_sensitivity = 100;
+ }
+
+ inp_mouse_sensitivity = cur_sensitivity;
+}
+
+
+// exec options menu item selection: select mouse sensitivity -----------------
+//
+PRIVATE
+void ExecOptionSelectCenterSpeed()
+{
+ if ( !enable_dynamic_options )
+ return;
+
+ cur_centerspeed += 10;
+ if ( cur_centerspeed > 100 ) {
+ cur_centerspeed = 10;
+ }
+
+ inp_mouse_drift = cur_centerspeed;
+}
+
+// exec options menu item selection: select name-----------------
+//
+PRIVATE
+void ExecOptionSelectName()
+{
+ // toggle the flag to modify the LocalPlayerName
+ mod_player_name = !mod_player_name;
+ if(mod_player_name) {
+ // if we are modifying the player, copy the local player
+ // name to paste_str for editing.
+ strncpy(tmp_name, LocalPlayerName, MAX_PLAYER_NAME + 1);
+ } else {
+ CheckPlayerName(tmp_name);
+ //strncpy(LocalPlayerName, tmp_name, MAX_PLAYER_NAME + 1);
+ }
+
+
+}
+
+// exec options menu item selection: exit options menu ------------------------
+//
+PRIVATE
+void ExecOptionSelectExit()
+{
+ ExitOptionsMenu();
+}
+
+
+// exec options menu item selection: apply video settings ---------------------
+//
+PRIVATE
+void ExecOptionApplyVideo()
+{
+ option_apply_blinking[ APPLY_VID_OPT ] = FALSE;
+
+ FlipSynched = cur_flipsync;
+
+ // apply video mode change
+ int resindex = GetResolutionIndex(cur_res.width, cur_res.height);
+ if ( VID_MODE_AVAILABLE( resindex ) ) {
+ VID_HotChangeMode(cur_res.width, cur_res.height, !cur_winstatus, cur_depthmode); }
+
+ // get the default mode that is active after switching
+ cur_res = GameScreenRes;
+ cur_depthmode = GameScreenBPP;
+ cur_winstatus = GameScreenWindowed;
+}
+
+
+// exec options menu item selection: apply detail settings --------------------
+//
+PRIVATE
+void ExecOptionApplyDetail()
+{
+ option_apply_blinking[ APPLY_DETAIL_OPT ] = FALSE;
+
+ if ( AUXDATA_TMM_MIPMAP_LOD_BIAS != cur_mipmapbias ) {
+
+ // set new mip map bias
+ AUXDATA_TMM_MIPMAP_LOD_BIAS = cur_mipmapbias;
+
+ // flush entire texture cache
+ R_InvalidateCachedTexture( NULL );
+
+ // make sure texture data that might have been freed
+ // by the texture cache is available once again
+ ReloadFreedTextureBitmaps();
+
+ // precache textures
+ R_PrecacheTextures();
+ }
+
+ AUXDATA_LOD_DISCRETE_GEOMETRY_BIAS = cur_geombias;
+
+ // trigger reloading samples if quality has been changed
+ if ( cur_sfxquality != prev_sfxquality ) {
+
+ if ( DEMO_ReplayActive() ) {
+ DEMO_StopReplay();
+ }
+
+ extern int itemvis_loading;
+ itemvis_loading = TRUE;
+
+ prev_sfxquality = cur_sfxquality;
+ }
+}
+
+
+// defined in CON_AUX.C -------------------------------------------------------
+//
+extern void RESyncKillLimit();
+extern void RESyncNebulaId();
+
+
+// exec options menu item selection: apply network settings -------------------
+//
+PRIVATE
+void ExecOptionApplyNetwork()
+{
+ option_apply_blinking[ APPLY_NET_OPT ] = FALSE;
+
+ // apply kill limit change
+ if ( AUX_KILL_LIMIT_FOR_GAME_END != cur_killlimit ) {
+ AUX_KILL_LIMIT_FOR_GAME_END = cur_killlimit;
+ RESyncKillLimit();
+ }
+
+ // apply nebula change
+ if ( AUXDATA_BACKGROUND_NEBULA_ID != cur_solarsys ) {
+ AUXDATA_BACKGROUND_NEBULA_ID = cur_solarsys;
+ RESyncNebulaId();
+ }
+
+ // plug in new network subsystem only if different
+ if ( protsubsys_id == prev_protsubsys_id ) {
+ return;
+ }
+
+ // only if not connected
+ if ( NetConnected ) {
+
+ opt_show_warning_text = TRUE;
+ opt_blink_ctr = 0;
+
+ return;
+ }
+
+ // deinit old subsystem
+ NETs_KillAPI();
+
+ // rebind protocol
+ sys_BindType_PROTOCOL = protocol_table[ protsubsys_id ].id;
+ SYS_Bind_PROTOCOL();
+
+ // init new subsystem
+ NETs_InitAPI();
+
+ prev_protsubsys_id = protsubsys_id;
+}
+
+
+// user has selected option <optno> -------------------------------------------
+//
+void ExecOptionSelection( int optno )
+{
+ // reset the mod_player_name flag
+ mod_player_name = 0;
+
+ // invoke corresponding function
+ switch ( optno ) {
+
+ case RES_OPT:
+ ExecOptionSelectResolution();
+ break;
+
+ case DEPTH_OPT:
+ ExecOptionSelectColordepth();
+ break;
+
+ case FULL_OPT:
+ ExecOptionSelectFullscreen();
+ break;
+
+ case SYNC_OPT:
+ ExecOptionSelectFlipsync();
+ break;
+
+ case APPLY_VID_OPT:
+ ExecOptionApplyVideo();
+ break;
+
+ case TEXDETAIL_OPT:
+ ExecOptionSelectTextureDetail();
+ break;
+
+ case GEOMDETAIL_OPT:
+ ExecOptionSelectGeometryDetail();
+ break;
+
+ case SFXDETAIL_OPT:
+ ExecOptionSelectSoundDetail();
+ break;
+
+ case APPLY_DETAIL_OPT:
+ ExecOptionApplyDetail();
+ break;
+
+ case PROTOCOL_OPT:
+ ExecOptionSelectProtocol();
+ break;
+
+ case KILL_LIMIT_OPT:
+ ExecOptionSelectKillLimit();
+ break;
+
+ case SOLAR_OPT:
+ ExecOptionSelectSolarSystem();
+ break;
+
+ case APPLY_NET_OPT:
+ ExecOptionApplyNetwork();
+ break;
+
+ case SOUND_OPT:
+ ExecOptionSelectSoundEnabling();
+ break;
+
+ case CTRL_OPT:
+ ExecOptionSelectControllerEnabling();
+ break;
+
+ case INVERT_OPT:
+ ExecOptionSelectInvertYAxis();
+ break;
+
+ case SENSITIVITY_OPT:
+ ExecOptionSelectSensitivity();
+ break;
+
+ case CENTER_OPT:
+ ExecOptionSelectCenterSpeed();
+ break;
+
+ case EXIT_OPT:
+ ExecOptionSelectExit();
+ break;
+ case NAME_OPT:
+ ExecOptionSelectName();
+ break;
+
+ default:
+ ASSERT( 0 );
+ }
+}
+
+
+// create options menu item text: screen resolution ---------------------------
+//
+PRIVATE
+void CreateOptionTextResolution( int id )
+{
+ ASSERT( strlen( option_lines[ id ] ) <= OPT_MAX_TEXTLEN );
+ strcpy( opt_text_buffer, option_lines[ id ] );
+
+ if ( !cur_res.isValid() )
+ sprintf( paste_str, "default" );
+ else
+ sprintf( paste_str, "%dx%d", cur_res.width, cur_res.height );
+
+ ASSERT( strlen( paste_str ) + 2 + strlen( opt_text_buffer ) <= OPT_MAX_TEXTLEN );
+ strcat( opt_text_buffer, paste_str );
+ strcat( opt_text_buffer, " " );
+}
+
+
+// create options menu item text: color depth ---------------------------------
+//
+PRIVATE
+void CreateOptionTextColordepth( int id )
+{
+ ASSERT( strlen( option_lines[ id ] ) <= OPT_MAX_TEXTLEN );
+ strcpy( opt_text_buffer, option_lines[ id ] );
+
+ if ( cur_depthmode == -1 ) {
+ sprintf( paste_str, "default" );
+ } else {
+
+ int colbits = cur_depthmode;
+ sprintf( paste_str, "%d bit", colbits );
+ }
+
+ ASSERT( strlen( paste_str ) + 2 + strlen( opt_text_buffer ) <= OPT_MAX_TEXTLEN );
+ strcat( opt_text_buffer, paste_str );
+ strcat( opt_text_buffer, " " );
+}
+
+
+// create options menu item text: fullscreen/windowed mode --------------------
+//
+PRIVATE
+void CreateOptionTextFullscreen( int id )
+{
+ ASSERT( strlen( option_lines[ id ] ) <= OPT_MAX_TEXTLEN );
+ strcpy( opt_text_buffer, option_lines[ id ] );
+
+ if ( cur_winstatus == -1 ) {
+ ASSERT( 9 + strlen( opt_text_buffer ) <= OPT_MAX_TEXTLEN );
+ strcat( opt_text_buffer, "default " );
+ } else {
+ ASSERT( strlen( binopt_strings[ cur_winstatus == 0 ] ) + strlen( opt_text_buffer ) <= OPT_MAX_TEXTLEN );
+ strcat( opt_text_buffer, binopt_strings[ cur_winstatus == 0 ] );
+ }
+}
+
+
+// create options menu item text: sync to screen ------------------------------
+//
+PRIVATE
+void CreateOptionTextFlipsync( int id )
+{
+ ASSERT( strlen( option_lines[ id ] ) + strlen( binopt_strings[ cur_flipsync ] ) <= OPT_MAX_TEXTLEN );
+ strcpy( opt_text_buffer, option_lines[ id ] );
+ strcat( opt_text_buffer, binopt_strings[ cur_flipsync ] );
+}
+
+
+// create options menu item text: texture detail ------------------------------
+//
+PRIVATE
+void CreateOptionTextTextureDetail( int id )
+{
+ ASSERT( strlen( option_lines[ id ] ) + strlen( detailopt_strings[ cur_mipmapbias ] ) <= OPT_MAX_TEXTLEN );
+ strcpy( opt_text_buffer, option_lines[ id ] );
+ strcat( opt_text_buffer, detailopt_strings[ cur_mipmapbias ] );
+}
+
+
+// create options menu item text: geometry detail -----------------------------
+//
+PRIVATE
+void CreateOptionTextGeometryDetail( int id )
+{
+ ASSERT( strlen( option_lines[ id ] ) + strlen( detailopt_strings[ cur_geombias ] ) <= OPT_MAX_TEXTLEN );
+ strcpy( opt_text_buffer, option_lines[ id ] );
+ strcat( opt_text_buffer, detailopt_strings[ cur_geombias ] );
+}
+
+
+// create options menu item text: sound detail --------------------------------
+//
+PRIVATE
+void CreateOptionTextSoundDetail( int id )
+{
+ ASSERT( strlen( option_lines[ id ] ) + strlen( qualityopt_strings[ cur_sfxquality ] ) <= OPT_MAX_TEXTLEN );
+ strcpy( opt_text_buffer, option_lines[ id ] );
+ strcat( opt_text_buffer, qualityopt_strings[ cur_sfxquality ] );
+}
+
+
+// create options menu item text: game protocol -------------------------------
+//
+PRIVATE
+void CreateOptionTextProtocol( int id )
+{
+ ASSERT( strlen( option_lines[ id ] ) <= OPT_MAX_TEXTLEN );
+ strcpy( opt_text_buffer, option_lines[ id ] );
+
+ if ( protocol_table[ protsubsys_id ].name == NULL ) {
+ ASSERT( strlen( not_available ) + strlen( opt_text_buffer ) <= OPT_MAX_TEXTLEN );
+ strcat( opt_text_buffer, not_available );
+ return;
+ }
+
+ ASSERT( strlen( protocol_table[ protsubsys_id ].name ) + 2 + strlen( opt_text_buffer ) <= OPT_MAX_TEXTLEN );
+ strcat( opt_text_buffer, protocol_table[ protsubsys_id ].name );
+ strcat( opt_text_buffer, " " );
+}
+
+
+// create options menu item text: kill limit ----------------------------------
+//
+PRIVATE
+void CreateOptionTextKillLimit( int id )
+{
+ ASSERT( strlen( option_lines[ id ] ) + 2 <= OPT_MAX_TEXTLEN );
+ strcpy( opt_text_buffer, option_lines[ id ] );
+
+ if ( cur_killlimit == 0 ) {
+ sprintf( paste_str, "off" );
+ } else {
+ sprintf( paste_str, "%d", cur_killlimit );
+ }
+
+ strcat( opt_text_buffer, paste_str );
+ strcat( opt_text_buffer, " " );
+}
+
+
+// create options menu item text: kill limit ----------------------------------
+//
+PRIVATE
+void CreateOptionTextSolarSystem( int id )
+{
+ ASSERT( strlen( option_lines[ id ] ) + 2 <= OPT_MAX_TEXTLEN );
+ strcpy( opt_text_buffer, option_lines[ id ] );
+
+ sprintf( paste_str, "%d", cur_solarsys - 1 );
+
+ strcat( opt_text_buffer, paste_str );
+ strcat( opt_text_buffer, " " );
+}
+
+
+// create options menu item text: enable/disable sound effects ----------------
+//
+PRIVATE
+void CreateOptionTextSoundEnabling( int id )
+{
+ // determine current setting
+ int cursetting = 0x00;
+ if ( Op_SoundEffects )
+ cursetting |= 0x01;
+ if ( Op_Music )
+ cursetting |= 0x02;
+
+ ASSERT( strlen( option_lines[ id ] ) + strlen( soundopt_strings[ cursetting ] ) <= OPT_MAX_TEXTLEN );
+ strcpy( opt_text_buffer, option_lines[ id ] );
+ strcat( opt_text_buffer, soundopt_strings[ cursetting ] );
+}
+
+
+// create options menu item text: select controller ---------------------------
+//
+PRIVATE
+void CreateOptionTextControllerEnabling( int id )
+{
+ // determine current setting
+ int cursetting = 0x00;
+ if ( Op_Joystick )
+ cursetting |= 0x01;
+ if ( Op_Mouse )
+ cursetting |= 0x02;
+
+ ASSERT( strlen( option_lines[ id ] ) + strlen( ctrlopt_strings[ cursetting ] ) <= OPT_MAX_TEXTLEN );
+ strcpy( opt_text_buffer, option_lines[ id ] );
+ strcat( opt_text_buffer, ctrlopt_strings[ cursetting ] );
+}
+
+
+// create options menu item text: invert y axis of mouse ----------------------
+//
+PRIVATE
+void CreateOptionTextInvertYAxis( int id )
+{
+ ASSERT( strlen( option_lines[ id ] ) + strlen( binopt_strings[ inp_mouse_invert_yaxis ] ) <= OPT_MAX_TEXTLEN );
+ strcpy( opt_text_buffer, option_lines[ id ] );
+ strcat( opt_text_buffer, binopt_strings[ inp_mouse_invert_yaxis ] );
+}
+
+
+// create options menu item text: set mouse sensitivity -----------------------
+//
+PRIVATE
+void CreateOptionTextMouseSensitivity( int id )
+{
+ ASSERT( strlen( option_lines[ id ] ) + 2 <= OPT_MAX_TEXTLEN );
+ strcpy( opt_text_buffer, option_lines[ id ] );
+
+ sprintf( paste_str, "%d", cur_sensitivity );
+
+ strcat( opt_text_buffer, paste_str );
+ strcat( opt_text_buffer, " " );
+}
+
+
+// create options menu item text: set mouse centering speed -------------------
+//
+PRIVATE
+void CreateOptionTextCenterSpeed( int id )
+{
+ ASSERT( strlen( option_lines[ id ] ) + 2 <= OPT_MAX_TEXTLEN );
+ strcpy( opt_text_buffer, option_lines[ id ] );
+
+ sprintf( paste_str, "%d", cur_centerspeed );
+
+ strcat( opt_text_buffer, paste_str );
+ strcat( opt_text_buffer, " " );
+}
+
+// create options menu item text: set mouse centering speed -------------------
+//
+PRIVATE
+void CreateOptionTextName( int id )
+{
+ ASSERT( strlen( option_lines[ id ] ) + 2 <= OPT_MAX_TEXTLEN );
+ strcpy( opt_text_buffer, option_lines[ id ] );
+ if(!mod_player_name) {
+ sprintf( paste_str, "%s", LocalPlayerName );
+ } else {
+ sprintf(paste_str, "%s", tmp_name);
+ }
+
+ strcat( opt_text_buffer, paste_str );
+ strcat( opt_text_buffer, " " );
+}
+// create options menu item text: default -------------------------------------
+//
+PRIVATE
+void CreateOptionTextDefault( int id )
+{
+ ASSERT( strlen( option_lines[ id ] ) <= OPT_MAX_TEXTLEN );
+ strcpy( opt_text_buffer, option_lines[ id ] );
+}
+
+
+// create text for one line in the options menu -------------------------------
+//
+PRIVATE
+void CreateOptionsText( int id )
+{
+ switch ( id ) {
+
+ case RES_OPT:
+ CreateOptionTextResolution( id );
+ break;
+
+ case DEPTH_OPT:
+ CreateOptionTextColordepth( id );
+ break;
+
+ case FULL_OPT:
+ CreateOptionTextFullscreen( id );
+ break;
+
+ case SYNC_OPT:
+ CreateOptionTextFlipsync( id );
+ break;
+
+ case TEXDETAIL_OPT:
+ CreateOptionTextTextureDetail( id );
+ break;
+
+ case GEOMDETAIL_OPT:
+ CreateOptionTextGeometryDetail( id );
+ break;
+
+ case SFXDETAIL_OPT:
+ CreateOptionTextSoundDetail( id );
+ break;
+
+ case PROTOCOL_OPT:
+ CreateOptionTextProtocol( id );
+ break;
+
+ case KILL_LIMIT_OPT:
+ CreateOptionTextKillLimit( id );
+ break;
+
+ case SOLAR_OPT:
+ CreateOptionTextSolarSystem( id );
+ break;
+
+ case SOUND_OPT:
+ CreateOptionTextSoundEnabling( id );
+ break;
+
+ case CTRL_OPT:
+ CreateOptionTextControllerEnabling( id );
+ break;
+
+ case INVERT_OPT:
+ CreateOptionTextInvertYAxis( id );
+ break;
+
+ case SENSITIVITY_OPT:
+ CreateOptionTextMouseSensitivity( id );
+ break;
+
+ case CENTER_OPT:
+ CreateOptionTextCenterSpeed( id );
+ break;
+ case NAME_OPT:
+ CreateOptionTextName( id );
+ break;
+ default:
+ CreateOptionTextDefault( id );
+ break;
+ }
+}
+
+// filters unsafe charaters from the key pressed buffer.
+//void OptionsNameCharaterFilter(dword key){
+
+
+
+
+// used to modify name, modifies the past_str buffer thing
+void OptionsKeyPressed(char key)
+{
+
+ /*
+ // don't write console open/close key
+ if (character == '`' || character == '~')
+ return;
+
+ int curlinelen = strlen( con_lines[ con_bottom ] + PROMPT_SIZE );
+
+ // typeable characters
+ if ( ( character & CON_ASCII_MASK ) && (character <= CON_ASCII_MASK) && (cursor_x < edit_max_x ) ) {
+ if ( insert_mode && ( cursor_x < curlinelen ) ) {
+ if ( curlinelen < edit_max_x ) {
+ strcpy( paste_str, con_lines[ con_bottom ] + PROMPT_SIZE + cursor_x );
+ strcpy( con_lines[ con_bottom ] + PROMPT_SIZE + cursor_x + 1, paste_str );
+ con_lines[ con_bottom ][ PROMPT_SIZE + cursor_x++ ] = (byte) character;
+ }
+ } else {
+ con_lines[ con_bottom ][ PROMPT_SIZE + cursor_x++ ] = (byte) character;
+ }
+ }*/
+ // filter some ascii keys.
+ if( (key > 32 && key < 45) ||
+ (key == 46 || key == 47 ) ||
+ (key > 57 && key < 65) ||
+ (key > 90 && key < 95) ||
+ (key == 96) ||
+ (key > 121) ) {
+ return;
+ }
+
+
+ if(key == SDLK_BACKSPACE) {
+ if(tmp_name[0] != '\0'){
+ tmp_name[strlen(tmp_name)-1]='\0';
+ }
+ } else if (key == SDLK_RETURN) {
+ ExecOptionSelectName();
+
+ } else if(key == SDLK_ESCAPE) {
+ mod_player_name = 0; // exit with no modification
+ } else {
+ if(strlen(tmp_name) + 1 < MAX_PLAYER_NAME ) {
+ tmp_name[strlen(tmp_name)] = (char)key;
+ }
+ }
+
+
+}
+
+
+
+// slide the options menu to its specifed target x position -------------------
+//
+PRIVATE
+void DoOptionsSliding()
+{
+ if ( opt_slidepos == opt_slidetarget ) {
+ opt_lastref = REFFRAME_INVALID;
+ return;
+ }
+
+ if ( opt_slidepos < opt_slidetarget ) {
+
+ // slide right
+ refframe_t refframecount = SYSs_GetRefFrameCount();
+ if ( opt_lastref == REFFRAME_INVALID ) {
+ opt_lastref = refframecount;
+ } else {
+ refframe_t delta = refframecount - opt_lastref;
+ for ( ; delta >= OPT_SLIDE_SPEED; delta -= OPT_SLIDE_SPEED ) {
+ opt_slidepos++;
+ if ( opt_slidepos >= opt_slidetarget ) {
+ opt_slidepos = opt_slidetarget;
+ opt_lastref = REFFRAME_INVALID;
+ break;
+ }
+ opt_lastref += OPT_SLIDE_SPEED;
+ }
+ }
+
+ } else {
+
+ // slide left
+ refframe_t refframecount = SYSs_GetRefFrameCount();
+ if ( opt_lastref == REFFRAME_INVALID ) {
+ opt_lastref = refframecount;
+ } else {
+ refframe_t delta = refframecount - opt_lastref;
+ for ( ; delta >= OPT_SLIDE_SPEED; delta -= OPT_SLIDE_SPEED ) {
+ opt_slidepos--;
+ if ( opt_slidepos <= opt_slidetarget ) {
+ opt_slidepos = opt_slidetarget;
+ opt_lastref = REFFRAME_INVALID;
+ break;
+ }
+ opt_lastref += OPT_SLIDE_SPEED;
+ }
+ }
+ }
+}
+
+
+// get blink states, reset each automatically if option and state identical ---
+//
+PRIVATE
+void UpdateBlinkStates()
+{
+ // blink state of apply video options
+ int diffvid = 0;
+ diffvid += ( vidsubsys_id != prev_vidsubsys_id );
+ diffvid += ((cur_res != GameScreenRes));
+ diffvid += ( cur_depthmode != GameScreenBPP );
+ diffvid += ( (dword)cur_winstatus != GameScreenWindowed );
+ diffvid += ( cur_flipsync != FlipSynched );
+
+ option_apply_blinking[ APPLY_VID_OPT ] = ( diffvid > 0 );
+
+ // blink state of apply detail options
+ int diffdet = 0;
+ diffdet += ( cur_mipmapbias != AUXDATA_TMM_MIPMAP_LOD_BIAS );
+ diffdet += ( cur_geombias != AUXDATA_LOD_DISCRETE_GEOMETRY_BIAS );
+ diffdet += ( cur_sfxquality != prev_sfxquality );
+
+ option_apply_blinking[ APPLY_DETAIL_OPT ] = ( diffdet > 0 );
+
+ // blink state of apply net options
+ int diffnet = 0;
+ diffnet += ( protsubsys_id != prev_protsubsys_id );
+ diffnet += ( cur_killlimit != AUX_KILL_LIMIT_FOR_GAME_END );
+ diffnet += ( cur_solarsys != AUXDATA_BACKGROUND_NEBULA_ID );
+
+ option_apply_blinking[ APPLY_NET_OPT ] = ( diffnet > 0 );
+}
+
+
+// type for writestring function pointer --------------------------------------
+//
+typedef void (*WSFP)( ... );
+
+//NOTE:
+// this declaration is in global scope because of the extern "C".
+// only gcc needs the otherwise redundant curly braces.
+
+
+// draw horizontal divider line built from minus signs ------------------------
+//
+static
+void DrawDividerLine( WSFP wstrfp, int lx, int ly, int len )
+{
+ ASSERT( wstrfp != NULL );
+
+ ASSERT( len <= PASTE_STR_LEN );
+ int dpos = 0;
+ for ( dpos = 0; dpos < len; dpos++ ) {
+ paste_str[ dpos ] = '-';
+ }
+ paste_str[ dpos ] = 0;
+
+ wstrfp( paste_str, lx, ly, TRTAB_PANELTEXT );
+}
+
+
+// draw translucent background window for options menu ------------------------
+//
+PRIVATE
+void DrawOptionsFrame()
+{
+ int frame_l = options_content_metrics.frame_l;
+ int frame_r = options_content_metrics.frame_r;
+ int frame_t = options_content_metrics.frame_t;
+ int frame_b = options_content_metrics.frame_b;
+ int chwidth = options_content_metrics.chwidth;
+ int chheight = options_content_metrics.chheight;
+ int text_x = options_content_metrics.text_x;
+ int text_y = options_content_metrics.text_y;
+ int maxcontwidth = options_content_metrics.maxcontwidth;
+ int maxcontheight = options_content_metrics.maxcontheight;
+
+ int backx = text_x - frame_l * chwidth;
+ int backy = text_y - frame_t * chheight;
+ int backw = ( frame_l + frame_r + maxcontwidth ) * chwidth;
+ int backh = ( frame_t + frame_b + maxcontheight ) * chheight;
+
+ DRAW_ClippedTrRect( backx, backy, backw, backh, TRTAB_PANELBACK );
+}
+
+
+// draw caption of options window ---------------------------------------------
+//
+PRIVATE
+void DrawOptionsCaption( WSFP wstrfp )
+{
+ unsigned int chwidth = options_content_metrics.chwidth;
+ unsigned int chheight = options_content_metrics.chheight;
+ int text_x = options_content_metrics.text_x;
+ int text_y = options_content_metrics.text_y;
+ unsigned int maxcontwidth = options_content_metrics.maxcontwidth;
+ unsigned int maxcontheight = options_content_metrics.maxcontheight;
+
+ // display options menu caption
+ ASSERT( maxcontwidth >= strlen( opt_caption_str ) );
+ int xofs = ( ( maxcontwidth - strlen( opt_caption_str ) ) * chwidth ) / 2;
+ wstrfp( opt_caption_str, text_x + xofs, text_y, TRTAB_PANELTEXT );
+ text_y += chheight * 2;
+
+ // this destroys paste_str
+ DrawDividerLine( wstrfp, text_x, text_y, maxcontwidth );
+ text_y += chheight;
+
+ options_content_metrics.text_y = text_y;
+}
+
+
+// draw all options menu items (text lines) -----------------------------------
+//
+void DrawOptionsItems( WSFP wstrfp )
+{
+ unsigned int chwidth = options_content_metrics.chwidth;
+ unsigned int chheight = options_content_metrics.chheight;
+ int text_x = options_content_metrics.text_x;
+ int text_y = options_content_metrics.text_y;
+ unsigned int maxcontwidth = options_content_metrics.maxcontwidth;
+
+ // display all options
+ for ( int id = 0; id < cur_opmenu_size; id++ ) {
+
+ CreateOptionsText( id );
+
+ // draw/erase cursor
+ char cursor = ( cur_opmenu_selindx == id ) ? '-' : ' ';
+ *opt_text_buffer = cursor;
+ *( opt_text_buffer + strlen( opt_text_buffer ) - 1 ) = cursor;
+
+ ASSERT( maxcontwidth >= strlen( opt_text_buffer ) );
+ int xofs = ( ( maxcontwidth - strlen( opt_text_buffer ) ) * chwidth ) / 2;
+
+ int oldalpha = PanelTextColor.A;
+
+ if ( option_dynamic[ id ] && !enable_dynamic_options ) {
+ PanelTextColor.A = 0x20;
+ }
+
+ if ( option_apply_blinking[ id ] ) {
+
+ if ( opt_blink_count < OPT_MAX_BLINK_COUNT/2 ) {
+ // double bright
+ wstrfp( opt_text_buffer, text_x + xofs, text_y, TRTAB_PANELTEXT );
+ wstrfp( opt_text_buffer, text_x + xofs, text_y, TRTAB_PANELTEXT );
+ }
+
+ } else {
+
+ // double bright if line of cursor
+ if ( cur_opmenu_selindx == id && enable_dynamic_options )
+ wstrfp( opt_text_buffer, text_x + xofs, text_y, TRTAB_PANELTEXT );
+ wstrfp( opt_text_buffer, text_x + xofs, text_y, TRTAB_PANELTEXT );
+ }
+
+ if ( option_dynamic[ id ] && !enable_dynamic_options ) {
+ PanelTextColor.A = oldalpha;
+ }
+
+ text_y += chheight;
+ if ( option_spacing[ id ] != OPT_SPACING_NONE ) {
+ if ( option_spacing[ id ] == OPT_SPACING_DIVIDER ) {
+ // this destroys paste_str
+ DrawDividerLine( wstrfp, text_x, text_y, maxcontwidth );
+ }
+ text_y += chheight;
+ }
+ }
+}
+
+
+// draw warning text in options menu if active --------------------------------
+//
+PRIVATE
+void DrawOptionsWarnings( WSFP wstrfp )
+{
+ unsigned int chwidth = options_content_metrics.chwidth;
+ unsigned int chheight = options_content_metrics.chheight;
+ int text_x = options_content_metrics.text_x;
+ int text_y = options_content_metrics.text_y;
+ unsigned int maxcontwidth = options_content_metrics.maxcontwidth;
+ unsigned int maxcontheight = options_content_metrics.maxcontheight;
+
+ // draw connect warning
+ if ( opt_show_warning_text ) {
+
+ if ( opt_blink_ctr >= 4 ) {
+
+ opt_show_warning_text = FALSE;
+ opt_blink_ctr = 0;
+
+ } else {
+
+ if ( opt_blink_count < OPT_MAX_BLINK_COUNT/2 ) {
+
+ ASSERT( maxcontwidth >= strlen( opt_warning_str ) );
+
+ int xofs = ( ( maxcontwidth - strlen( opt_warning_str ) ) * chwidth ) / 2;
+ int stry = text_y + ( maxcontheight - 1 ) * chheight;
+
+ // double bright
+ wstrfp( opt_warning_str, text_x + xofs, stry, TRTAB_PANELTEXT );
+ wstrfp( opt_warning_str, text_x + xofs, stry, TRTAB_PANELTEXT );
+ }
+ }
+ }
+}
+
+
+// calc and store metrics for options window ----------------------------------
+//
+PRIVATE
+void CalcOptionsContentMetrics()
+{
+ // bounds for content
+ int maxcontwidth = strlen( opt_caption_str );
+ int maxcontheight = 32;
+
+ // ensure maximum content width is big enough
+ for ( int id = 0; id < cur_opmenu_size; id++ ) {
+
+ CreateOptionsText( id );
+
+ int optexlen = strlen( opt_text_buffer );
+ if ( optexlen > maxcontwidth ) {
+ maxcontwidth = optexlen;
+ }
+ }
+
+ extern int hud_line_dist;
+
+ // font metrics
+ int chwidth = CharsetInfo[ HUD_CHARSETNO ].width;
+ int chheight = hud_line_dist;
+
+ D_SetWStrContext( CharsetInfo[ HUD_CHARSETNO ].charsetpointer,
+ CharsetInfo[ HUD_CHARSETNO ].geompointer,
+ NULL,
+ CharsetInfo[ HUD_CHARSETNO ].width,
+ CharsetInfo[ HUD_CHARSETNO ].height );
+
+ // frame metrics
+ int frame_l = 1;
+ int frame_r = 1;
+ int frame_t = 2;
+ int frame_b = 1;
+
+ // text position
+ int text_x = Screen_Width - ( frame_r + maxcontwidth ) * chwidth - 30;
+ if ( opt_slidepos != -1 )
+ text_x += m_sintab[ opt_slidepos ];
+ int text_y = 62;
+
+ // store metrics
+ options_content_metrics.valid = TRUE;
+ options_content_metrics.frame_l = frame_l;
+ options_content_metrics.frame_r = frame_r;
+ options_content_metrics.frame_t = frame_t;
+ options_content_metrics.frame_b = frame_b;
+ options_content_metrics.chwidth = chwidth;
+ options_content_metrics.chheight = chheight;
+ options_content_metrics.text_x = text_x;
+ options_content_metrics.text_y = text_y;
+ options_content_metrics.maxcontwidth = maxcontwidth;
+ options_content_metrics.maxcontheight = maxcontheight;
+}
+
+
+// draw options menu window ---------------------------------------------------
+//
+void DrawOptionsMenuWindow()
+{
+ DoOptionsSliding();
+ UpdateBlinkStates();
+
+ CalcOptionsContentMetrics();
+
+ // check whether actual drawing disabled
+ if ( AUX_DISABLE_FLOATING_MENU_DRAWING )
+ return;
+
+ // determine whether translucency should be used
+ int translucent = VID_TRANSLUCENCY_SUPPORTED;
+
+ // write text transparent only for color depths below 32 bit per pixel
+ WSFP wstrfp = translucent ? (WSFP)&D_WriteTrString : (WSFP)&D_WriteString;
+
+ // draw frame
+ if ( translucent ) {
+ DrawOptionsFrame();
+ }
+
+ // draw caption
+ DrawOptionsCaption( wstrfp );
+
+ // draw items
+ DrawOptionsItems( wstrfp );
+
+ // draw warnings if active
+ DrawOptionsWarnings( wstrfp );
+
+ // maintain blink counter
+ if ( ( opt_blink_count += CurScreenRefFrames ) > OPT_MAX_BLINK_COUNT ) {
+ opt_blink_count = 0;
+ opt_blink_ctr++;
+ }
+}
+
+
+