Maplist Menu

Post tutorials on how to do certain tasks within game or engine code here.
Post Reply
Rikku2000
Posts: 49
Joined: Wed Oct 20, 2010 6:33 pm
Location: Germany
Contact:

Maplist Menu

Post by Rikku2000 »

Hey Guys i write my Maplist menu for Custom maps in Quake.

maplist.h:

Code: Select all

#define MAX_MAPS 1024

typedef struct {
   char *map;
} maps_entry_t;

extern maps_entry_t MapList[MAX_MAPS];

void MapList_Set (int i, char *addr, char *desc);
int MapList_Length (void);
void MapList_Load (void);
maplist.c:

Code: Select all

#include <sys/stat.h>
#include <sys/types.h>
#include <sys/dir.h>
#include <sys/param.h>
#include <stdio.h>

#include "quakedef.h"

maps_entry_t MapList[MAX_MAPS];

void MapList_Set (int i, char *addr, char *desc) {
   if (i >= MAX_MAPS || i < 0)
      Sys_Error ("MapList_Set: Bad index %d", i);

   if (MapList[i].map)
      Z_Free (MapList[i].map);

   MapList[i].map = CopyString(addr);
}

int MapList_Length (void) {
   int count;
   for (count = 0; count < MAX_MAPS && MapList[count].map; count++);
   return count;
}

void MapList_Load (void) {
   int i, argc, count;
   char *desc, *addr;
   struct direct **namelist;
   int MapList_Map();

   int files = scandir(va("%s/maps/", com_gamedir), &namelist, MapList_Map, alphasort);

   count = 0;

   for (i = 0; i < files; i++) {
      if ((argc = Cmd_Argc()) >= 1) {
         addr = Cmd_Argv(0);
         desc = (argc >= 2) ? Cmd_Args() : "Unknown";
         MapList_Set (count, namelist[i]->d_name, namelist[i]->d_name);
         if (++count == MAX_MAPS)
            break;
      }
   }
}

int MapList_Map(struct direct *entry) {
	if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0))
		return 0;

	char *extension = strrchr(entry->d_name, '.');
	if ((extension != NULL) && ((strcmp(extension, ".bsp") == 0)))
		return 1;
	else
		return 0;
}
menu.c:
Okey in the "enum {...}" we add "m_maplist"

the we add 3 voids for the menu:
void M_Menu_MapList_f (void);
void M_MapList_Draw (void);
void M_MapList_Key (int key);

now go to: episode_t episodes[] =

Code: Select all

episode_t	episodes[] =
{
	{"Custom Maps", 0, 0},
	{"Welcome to Quake", 0, 1},
	{"Doomed Dimension", 1, 8},
	{"Realm of Black Magic", 9, 7},
	{"Netherworld", 16, 7},
	{"The Elder World", 23, 8},
	{"Final Level", 31, 1},
	{"Deathmatch Arena", 32, 6}
};
in: void M_NetStart_Change (int dir) i change:

Code: Select all

else if (registered.value)
	count = 7;
to

Code: Select all

else if (registered.value)
	count = 8;
in: void M_GameOptions_Key (int key)
i add an if/else in "case K_ENTER:"

Code: Select all

if (gameoptions_cursor == 0) {
} else if (gameoptions_cursor == 8)
	M_Menu_MapList_f ();
now we make the Maplist

Code: Select all

int maplist_cursor = 0, maplist_mins = 0, maplist_maxs = 15;

void M_Menu_MapList_f (void) {
	MapList_Load ();
	key_dest = key_menu;
	m_state = m_maplist;
	m_entersound = true;
} 

void M_MapList_Draw (void) {
	int	maps, line;
	qpic_t *p;

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

	if (!MapList[0].map) {
		M_PrintWhite (MENU_X + 48, MENU_Y + 16 + 16, "Empty Map list");
		return;
	}

	M_DrawTextBox (MENU_X, MENU_Y, 23, maplist_maxs - maplist_mins + 1);
	for (maps = maplist_mins, line = 1 ; maps <= maplist_maxs && maps < MAX_MAPS && MapList[maps].map ; maps++, line++)
		M_Print (MENU_X + 18, line * 8 + MENU_Y, va("%1.21s", MapList[maps].map));
	M_DrawCharacter (MENU_X + 8, (maplist_cursor - maplist_mins + 1) * 8 + MENU_Y, 12+((int)(realtime*4)&1));
}

void M_MapList_Key (key) {
	switch (key) {
		case K_ESCAPE:
			M_Menu_GameOptions_f ();
		break;

		case K_UPARROW:
			S_LocalSound ("misc/menu1.wav");

			if (maplist_cursor > 0) {
				maplist_cursor--;
			}
		break;

		case K_DOWNARROW:
			S_LocalSound ("misc/menu1.wav");

			if (maplist_cursor < MAX_MAPS - 1 && MapList[maplist_cursor+1].map)
				maplist_cursor++; 
		break; 

		case K_ENTER:
			if (sv.active)
				Cbuf_AddText ("disconnect\n");

			Cbuf_AddText (va("listen 0;maxplayers %u\n", maxplayers));
			SCR_BeginLoadingPlaque ();
			if (valve) {
				Cbuf_AddText (va("sv_progs hlmp.dat;map \"%s\"\n", MapList[maplist_cursor].map));
			} else
				Cbuf_AddText (va("map \"%s\"\n", MapList[maplist_cursor].map));
		break;
	}

	if (maplist_cursor < maplist_mins) {
		maplist_maxs -= (maplist_mins - maplist_cursor);
		maplist_mins = maplist_cursor;
	}

	if (maplist_cursor > maplist_maxs) {
		maplist_mins += (maplist_cursor - maplist_maxs);
		maplist_maxs = maplist_cursor;
	}
}
Now goto "void M_Init (void)" and add:

Code: Select all

Cmd_AddCommand ("menu_modlist", M_Menu_ModList_f);
Goto "void M_Draw (void)", in switch (m_state) we add:

Code: Select all

case m_maplist:
	M_MapList_Draw ();
	break;
Goto "void M_Keydown (int key)", in switch (m_state) we add:

Code: Select all

case m_maplist:
	M_MapList_Key (key);
	return;
Post Reply