Forum

Maplist Menu

Post tutorials on how to do certain tasks within game or engine code here.

Moderator: InsideQC Admins

Maplist Menu

Postby Rikku2000 » Sat Jan 15, 2011 10:58 pm

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;
User avatar
Rikku2000
 
Posts: 49
Joined: Wed Oct 20, 2010 6:33 pm
Location: Germany

Return to Programming Tutorials

Who is online

Users browsing this forum: No registered users and 1 guest