⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 menu.c

📁 quake1 dos源代码最新版本
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
Copyright (C) 1996-1997 Id Software, Inc.

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 "quakedef.h"

#ifdef _WIN32
#include "winquake.h"
#endif

void (*vid_menudrawfn)(void);
void (*vid_menukeyfn)(int key);

enum {m_none, m_main, m_singleplayer, m_load, m_save, m_multiplayer, m_setup, m_net, m_options, m_video, m_keys, m_help, m_quit, m_serialconfig, m_modemconfig, m_lanconfig, m_gameoptions, m_search, m_slist} m_state;

void M_Menu_Main_f (void);
	void M_Menu_SinglePlayer_f (void);
		void M_Menu_Load_f (void);
		void M_Menu_Save_f (void);
	void M_Menu_MultiPlayer_f (void);
		void M_Menu_Setup_f (void);
		void M_Menu_Net_f (void);
	void M_Menu_Options_f (void);
		void M_Menu_Keys_f (void);
		void M_Menu_Video_f (void);
	void M_Menu_Help_f (void);
	void M_Menu_Quit_f (void);
void M_Menu_SerialConfig_f (void);
	void M_Menu_ModemConfig_f (void);
void M_Menu_LanConfig_f (void);
void M_Menu_GameOptions_f (void);
void M_Menu_Search_f (void);
void M_Menu_ServerList_f (void);

void M_Main_Draw (void);
	void M_SinglePlayer_Draw (void);
		void M_Load_Draw (void);
		void M_Save_Draw (void);
	void M_MultiPlayer_Draw (void);
		void M_Setup_Draw (void);
		void M_Net_Draw (void);
//	void M_Options_Draw (void);	// 2002-01-31 New menu system by Maddes
		void M_Keys_Draw (void);
		void M_Video_Draw (void);
	void M_Help_Draw (void);
	void M_Quit_Draw (void);
void M_SerialConfig_Draw (void);
	void M_ModemConfig_Draw (void);
void M_LanConfig_Draw (void);
void M_GameOptions_Draw (void);
void M_Search_Draw (void);
void M_ServerList_Draw (void);

void M_Main_Key (int key);
	void M_SinglePlayer_Key (int key);
		void M_Load_Key (int key);
		void M_Save_Key (int key);
	void M_MultiPlayer_Key (int key);
		void M_Setup_Key (int key);
		void M_Net_Key (int key);
//	void M_Options_Key (int key);	// 2002-01-31 New menu system by Maddes
		void M_Keys_Key (int key);
		void M_Video_Key (int key);
	void M_Help_Key (int key);
	void M_Quit_Key (int key);
void M_SerialConfig_Key (int key);
	void M_ModemConfig_Key (int key);
void M_LanConfig_Key (int key);
void M_GameOptions_Key (int key);
void M_Search_Key (int key);
void M_ServerList_Key (int key);

qboolean	m_entersound;		// play after drawing a frame, so caching
								// won't disrupt the sound
qboolean	m_recursiveDraw;

int			m_return_state;
qboolean	m_return_onerror;
char		m_return_reason [32];

#define StartingGame	(m_multiplayer_cursor == 1)
#define JoiningGame		(m_multiplayer_cursor == 0)
#define SerialConfig	(m_net_cursor == 0)
#define DirectConfig	(m_net_cursor == 1)
#define	IPXConfig		(m_net_cursor == 2)
#define	TCPIPConfig		(m_net_cursor == 3)

void M_ConfigureNetSubsystem(void);

// 2002-01-31 New menu system by Maddes  start
// menu entry types
#define MENU_SELECTABLE	0
#define MENU_DRAW_ONLY	1
#define MENU_INVISIBLE	2

typedef struct menu_definition_s
{
	int	funcno;	// Unique number used for displaying and executing a menu entry. Zero = end of menu definition
				// First entry in menu definition defines the ESC function
	int	type;	// Entry type flag, use above DEFINEs and M_Menu_DrawCheck()
} menu_definition_t;

// data of current displayed menu
int		*current_cursor;
menu_definition_t	*current_menu;
int 	menu_last_index, menu_first_index;

// function number definitions
// Menus
#define MENU_OFF				1
#define MENU_MAIN				2
#define MENU_SINGLEPLAYER		3
#define MENU_MULTIPLAYER		4
#define MENU_OPTIONS			5
#define MENU_HELP				6
#define MENU_QUIT				7

// Options
#define MENU_CUSTOMIZE_CONTROLS			101
#define MENU_GO_TO_CONSOLE				102
#define MENU_LOAD_DEFAULT_CFG			103
#define MENU_SCREENSIZE					104
#define MENU_BRIGHTNESS					105
#define MENU_MOUSESPEED					106
#define MENU_CD_VOLUME					107
#define MENU_SOUND_VOLUME				108
#define MENU_ALWAYS_RUN					109
#define MENU_INVERT_MOUSE				110
#define MENU_LOOKSPRING					111
#define MENU_LOOKSTRAFE					112
#define MENU_VIDEO_RESOLUTION			113
#define MENU_USE_MOUSE					114

#define MENU_CONTROL_OPTIONS			120
#define MENU_MOUSELOOK					121

#define MENU_SOUND_OPTIONS				130

#define MENU_EXTERNAL_DATA				140
#define MENU_EXTERNAL_ENT				141
#define MENU_EXTERNAL_VIS				142
#define MENU_EXTERNAL_LIT				143

#define MENU_CLIENT_OPTIONS				150
#define MENU_CL_ENTITIES_MIN			151
#define MENU_CL_ENTITIES_TEMP_MIN		152
#define MENU_CL_ENTITIES_STATIC_MIN		153
#define MENU_CL_COMPATIBILITY			154

#define MENU_SERVER_OPTIONS				160
#define MENU_SV_ENTITIES				161
#define MENU_SV_ENTITIES_TEMP			162
#define MENU_SV_ENTITIES_STATIC			163
#define MENU_SV_ENTITIES_COPY_TO_CL		164
#define MENU_PR_ZONE_MIN_STRINGS		165
#define MENU_BUILTIN_REMAP				166
#define MENU_SV_COMPATIBILITY			167
#define MENU_NVS_ENABLE					168

#define MENU_VIDEO_OPTIONS				170
#define MENU_CON_ALPHA					171
#define MENU_CON_HEIGHT					172
#define MENU_SHOW_FPS					173
#define MENU_GL_MAXDEPTH				174

// menu definitions
int		options_cursor;
menu_definition_t	m_menu_options[] =
{	// Options Menu
	{MENU_MAIN, MENU_OPTIONS},	// this is the ESC key function and title
	{MENU_CUSTOMIZE_CONTROLS, MENU_SELECTABLE},
	{MENU_GO_TO_CONSOLE, MENU_SELECTABLE},
	{MENU_LOAD_DEFAULT_CFG, MENU_SELECTABLE},
	{MENU_CONTROL_OPTIONS, MENU_SELECTABLE},
	{MENU_SOUND_OPTIONS, MENU_SELECTABLE},
	{MENU_EXTERNAL_DATA, MENU_SELECTABLE},
	{MENU_CLIENT_OPTIONS, MENU_SELECTABLE},
	{MENU_SERVER_OPTIONS, MENU_SELECTABLE},
	{MENU_VIDEO_OPTIONS, MENU_SELECTABLE},
	{MENU_VIDEO_RESOLUTION, MENU_SELECTABLE},
	{0, 0},	// end of submenu
};

int		control_options_cursor;
menu_definition_t	m_menu_control_options[] =
{	// Control Options
	{MENU_OPTIONS, MENU_OPTIONS},	// this is the ESC key function and title
	{MENU_ALWAYS_RUN, MENU_SELECTABLE},
	{MENU_MOUSELOOK, MENU_SELECTABLE},
	{MENU_LOOKSPRING, MENU_SELECTABLE},
	{MENU_LOOKSTRAFE, MENU_SELECTABLE},
	{MENU_MOUSESPEED, MENU_SELECTABLE},
	{MENU_INVERT_MOUSE, MENU_SELECTABLE},
#ifdef _WIN32
	{MENU_USE_MOUSE, MENU_INVISIBLE},	// only present in windowed mode on Win32
#endif
	{0, 0},	// end of submenu
};

int		sound_options_cursor;
menu_definition_t	m_menu_sound_options[] =
{	// Sound Options
	{MENU_OPTIONS, MENU_OPTIONS},	// this is the ESC key function and title
	{MENU_CD_VOLUME, MENU_SELECTABLE},
	{MENU_SOUND_VOLUME, MENU_SELECTABLE},
	{0, 0},	// end of submenu
};

int		external_data_cursor;
menu_definition_t	m_menu_external_data[] =
{	// External Data
	{MENU_OPTIONS, MENU_OPTIONS},	// this is the ESC key function and title
	{MENU_EXTERNAL_ENT, MENU_SELECTABLE},
	{MENU_EXTERNAL_VIS, MENU_SELECTABLE},
#ifdef GLQUAKE
	{MENU_EXTERNAL_LIT, MENU_SELECTABLE},	// only useful in GLQuake
#endif
	{0, 0},	// end of submenu
};

int		client_options_cursor;
menu_definition_t	m_menu_client_options[] =
{	// Client Options
	{MENU_OPTIONS, MENU_OPTIONS},	// this is the ESC key function and title
	{MENU_CL_ENTITIES_MIN, MENU_SELECTABLE},
	{MENU_CL_ENTITIES_TEMP_MIN, MENU_SELECTABLE},
	{MENU_CL_ENTITIES_STATIC_MIN, MENU_SELECTABLE},
	{MENU_CL_COMPATIBILITY, MENU_SELECTABLE},
	{0, 0},	// end of submenu
};

int		server_options_cursor;
menu_definition_t	m_menu_server_options[] =
{	// Server Options
	{MENU_OPTIONS, MENU_OPTIONS},	// this is the ESC key function and title
	{MENU_SV_ENTITIES, MENU_SELECTABLE},
	{MENU_SV_ENTITIES_TEMP, MENU_SELECTABLE},
	{MENU_SV_ENTITIES_STATIC, MENU_SELECTABLE},
	{MENU_SV_ENTITIES_COPY_TO_CL, MENU_SELECTABLE},
	{MENU_PR_ZONE_MIN_STRINGS, MENU_SELECTABLE},
	{MENU_BUILTIN_REMAP, MENU_SELECTABLE},
	{MENU_SV_COMPATIBILITY, MENU_SELECTABLE},
	{MENU_NVS_ENABLE, MENU_SELECTABLE},
	{0, 0},	// end of submenu
};

int		video_options_cursor;
menu_definition_t	m_menu_video_options[] =
{	// Video Options
	{MENU_OPTIONS, MENU_OPTIONS},	// this is the ESC key function and title
	{MENU_SCREENSIZE, MENU_SELECTABLE},
	{MENU_BRIGHTNESS, MENU_SELECTABLE},
	{MENU_CON_ALPHA, MENU_SELECTABLE},
	{MENU_CON_HEIGHT, MENU_SELECTABLE},
	{MENU_SHOW_FPS, MENU_SELECTABLE},
#ifdef GLQUAKE
	{MENU_GL_MAXDEPTH, MENU_SELECTABLE},
#endif
#ifdef _WIN32
	{MENU_USE_MOUSE, MENU_INVISIBLE},	// only present in windowed mode on Win32
#endif
	{0, 0},	// end of submenu
};
// 2002-01-31 New menu system by Maddes  end

/*
================
M_DrawCharacter

Draws one solid graphics character
================
*/
void M_DrawCharacter (int cx, int line, int num)
{
	Draw_Character ( cx + ((vid.width - 320)>>1), line, num);
}

void M_Print (int cx, int cy, char *str)
{
	while (*str)
	{
		M_DrawCharacter (cx, cy, (*str)+128);
		str++;
		cx += 8;
	}
}

void M_PrintWhite (int cx, int cy, char *str)
{
	while (*str)
	{
		M_DrawCharacter (cx, cy, *str);
		str++;
		cx += 8;
	}
}

void M_DrawTransPic (int x, int y, qpic_t *pic)
{
	Draw_TransPic (x + ((vid.width - 320)>>1), y, pic);
}

void M_DrawPic (int x, int y, qpic_t *pic)
{
	Draw_Pic (x + ((vid.width - 320)>>1), y, pic);
}

byte identityTable[256];
byte translationTable[256];

void M_BuildTranslationTable(int top, int bottom)
{
	int		j;
	byte	*dest, *source;

	for (j = 0; j < 256; j++)
		identityTable[j] = j;
	dest = translationTable;
	source = identityTable;
	memcpy (dest, source, 256);

	if (top < 128)	// the artists made some backwards ranges.  sigh.
		memcpy (dest + TOP_RANGE, source + top, 16);
	else
		for (j=0 ; j<16 ; j++)
			dest[TOP_RANGE+j] = source[top+15-j];

	if (bottom < 128)
		memcpy (dest + BOTTOM_RANGE, source + bottom, 16);
	else
		for (j=0 ; j<16 ; j++)
			dest[BOTTOM_RANGE+j] = source[bottom+15-j];
}


void M_DrawTransPicTranslate (int x, int y, qpic_t *pic)
{
	Draw_TransPicTranslate (x + ((vid.width - 320)>>1), y, pic, translationTable);
}


void M_DrawTextBox (int x, int y, int width, int lines)
{
	qpic_t	*p;
	int		cx, cy;
	int		n;

	// draw left side
	cx = x;
	cy = y;
	p = Draw_CachePic ("gfx/box_tl.lmp");
	M_DrawTransPic (cx, cy, p);
	p = Draw_CachePic ("gfx/box_ml.lmp");
	for (n = 0; n < lines; n++)
	{
		cy += 8;
		M_DrawTransPic (cx, cy, p);
	}
	p = Draw_CachePic ("gfx/box_bl.lmp");
	M_DrawTransPic (cx, cy+8, p);

	// draw middle
	cx += 8;
	while (width > 0)
	{
		cy = y;
		p = Draw_CachePic ("gfx/box_tm.lmp");
		M_DrawTransPic (cx, cy, p);
		p = Draw_CachePic ("gfx/box_mm.lmp");
		for (n = 0; n < lines; n++)
		{
			cy += 8;
			if (n == 1)
				p = Draw_CachePic ("gfx/box_mm2.lmp");
			M_DrawTransPic (cx, cy, p);
		}
		p = Draw_CachePic ("gfx/box_bm.lmp");
		M_DrawTransPic (cx, cy+8, p);
		width -= 2;
		cx += 16;
	}

	// draw right side
	cy = y;
	p = Draw_CachePic ("gfx/box_tr.lmp");
	M_DrawTransPic (cx, cy, p);
	p = Draw_CachePic ("gfx/box_mr.lmp");
	for (n = 0; n < lines; n++)
	{
		cy += 8;
		M_DrawTransPic (cx, cy, p);
	}
	p = Draw_CachePic ("gfx/box_br.lmp");
	M_DrawTransPic (cx, cy+8, p);
}

//=============================================================================

int m_save_demonum;

/*
================
M_ToggleMenu_f
================
*/
void M_ToggleMenu_f (void)
{
	m_entersound = true;

	if (key_dest == key_menu)
	{
		if (m_state != m_main)
		{
			M_Menu_Main_f ();
			return;
		}
		key_dest = key_game;
		m_state = m_none;
		return;
	}
	if (key_dest == key_console)
	{
		Con_ToggleConsole_f ();
	}
	else
	{
		M_Menu_Main_f ();
	}
}


//=============================================================================
/* MAIN MENU */

int	m_main_cursor;
#define	MAIN_ITEMS	5


void M_Menu_Main_f (void)
{
	if (key_dest != key_menu)
	{
		m_save_demonum = cls.demonum;
		cls.demonum = -1;
	}
	key_dest = key_menu;
	m_state = m_main;
	m_entersound = true;
}


void M_Main_Draw (void)
{
	int		f;
	qpic_t	*p;

	M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") );
	p = Draw_CachePic ("gfx/ttl_main.lmp");
	M_DrawPic ( (320-p->width)/2, 4, p);
	M_DrawTransPic (72, 32, Draw_CachePic ("gfx/mainmenu.lmp") );

// 2001-10-20 TIMESCALE extension by Tomaz/Maddes  start
//	f = (int)(host_time * 10)%6;
	f = (int)(realtime * 10)%6;
// 2001-10-20 TIMESCALE extension by Tomaz/Maddes  end

	M_DrawTransPic (54, 32 + m_main_cursor * 20,Draw_CachePic( va("gfx/menudot%i.lmp", f+1 ) ) );
}


void M_Main_Key (int key)
{
	switch (key)
	{
	case K_ESCAPE:
		key_dest = key_game;
		m_state = m_none;
		cls.demonum = m_save_demonum;
		if (cls.demonum != -1 && !cls.demoplayback && cls.state != ca_connected)
			CL_NextDemo ();
		break;

	case K_DOWNARROW:
		S_LocalSound ("misc/menu1.wav");
		if (++m_main_cursor >= MAIN_ITEMS)
			m_main_cursor = 0;
		break;

	case K_UPARROW:
		S_LocalSound ("misc/menu1.wav");
		if (--m_main_cursor < 0)
			m_main_cursor = MAIN_ITEMS - 1;
		break;

	case K_ENTER:
		m_entersound = true;

		switch (m_main_cursor)
		{
		case 0:
			M_Menu_SinglePlayer_f ();
			break;

		case 1:
			M_Menu_MultiPlayer_f ();
			break;

		case 2:
			M_Menu_Options_f ();
			break;

		case 3:
			M_Menu_Help_f ();
			break;

		case 4:
			M_Menu_Quit_f ();
			break;
		}
	}
}

//=============================================================================
/* SINGLE PLAYER MENU */

int	m_singleplayer_cursor;
#define	SINGLEPLAYER_ITEMS	3


void M_Menu_SinglePlayer_f (void)
{
	key_dest = key_menu;
	m_state = m_singleplayer;
	m_entersound = true;
}


void M_SinglePlayer_Draw (void)
{
	int		f;
	qpic_t	*p;

	M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") );
	p = Draw_CachePic ("gfx/ttl_sgl.lmp");
	M_DrawPic ( (320-p->width)/2, 4, p);
	M_DrawTransPic (72, 32, Draw_CachePic ("gfx/sp_menu.lmp") );

// 2001-10-20 TIMESCALE extension by Tomaz/Maddes  start
//	f = (int)(host_time * 10)%6;
	f = (int)(realtime * 10)%6;
// 2001-10-20 TIMESCALE extension by Tomaz/Maddes  end

	M_DrawTransPic (54, 32 + m_singleplayer_cursor * 20,Draw_CachePic( va("gfx/menudot%i.lmp", f+1 ) ) );
}


void M_SinglePlayer_Key (int key)
{
	switch (key)
	{
	case K_ESCAPE:
		M_Menu_Main_f ();
		break;

	case K_DOWNARROW:
		S_LocalSound ("misc/menu1.wav");
		if (++m_singleplayer_cursor >= SINGLEPLAYER_ITEMS)
			m_singleplayer_cursor = 0;
		break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -