map listing and demo listing menu

git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@1523 e016b1c5-ed68-44aa-a2f7-31cac88cffde
This commit is contained in:
driAn
2007-12-29 23:45:35 +00:00
parent c73dea3d5a
commit e31e442f9e
4 changed files with 128 additions and 84 deletions
+2 -1
View File
@@ -644,7 +644,8 @@ void receivefile(uchar *data, int len)
{
case SV_SENDDEMO:
{
s_sprintfd(fname)("%d.dmo", lastmillis);
s_sprintfd(fname)("demos/%d.dmo", lastmillis);
path(fname);
FILE *demo = openfile(fname, "wb");
if(!demo) return;
conoutf("received demo \"%s\"", fname);
+106 -79
View File
@@ -87,82 +87,6 @@ void rendermenu()
m.render();
}
void gmenu::refresh()
{
if(!refreshfunc) return;
(*refreshfunc)(this, !inited);
inited = true;
if(menusel>=items.length()) menusel = max(items.length()-1, 0);
}
void gmenu::open()
{
inited = false;
if(allowinput) player1->stopmoving();
else menusel = 0;
if(items.inrange(menusel)) items[menusel]->focus(true);
init();
}
void gmenu::close()
{
if(items.inrange(menusel)) items[menusel]->focus(false);
}
void gmenu::init() { loopv(items) items[i]->init(); }
void gmenu::render()
{
const char *t = title;
if(!t) { static string buf; s_sprintf(buf)("[ %s menu ]", name); t = buf; }
int hitems = (header ? 2 : 0) + (footer ? 2 : 0),
pagesize = MAXMENU - hitems,
offset = menusel - (menusel%pagesize),
mdisp = min(items.length(), pagesize),
cdisp = min(items.length()-offset, pagesize);
if(title) text_startcolumns();
int w = 0;
loopv(items)
{
int x = items[i]->width();
if(x>w) w = x;
}
int tw = text_width(t);
if(tw>w) w = tw;
if(header)
{
int hw = text_width(header);
if(hw>w) w = hw;
}
int step = (FONTH*5)/4;
int h = (mdisp+hitems+2)*step;
int y = (2*VIRTH-h)/2;
int x = (2*VIRTW-w)/2;
renderbg(x-FONTH*3/2, y-FONTH, x+w+FONTH*3/2, y+h+FONTH, true);
if(offset>0) drawarrow(1, x+w+FONTH*3/2-FONTH*5/6, y-FONTH*5/6, FONTH*2/3);
if(offset+pagesize<items.length()) drawarrow(0, x+w+FONTH*3/2-FONTH*5/6, y+h+FONTH/6, FONTH*2/3);
if(header)
{
draw_text(header, x, y);
y += step*2;
}
draw_text(t, x, y);
y += step*2;
loopj(cdisp)
{
items[offset+j]->render(x, y, w);
y += step;
}
if(title) text_endcolumns();
if(footer)
{
y += ((mdisp-cdisp)+1)*step;
draw_text(footer, x, y);
}
}
void gmenu::renderbg(int x1, int y1, int x2, int y2, bool border)
{
static Texture *tex = NULL;
@@ -213,6 +137,7 @@ struct mitemtext : mitem
{
menustack.add(curmenu);
menuset(NULL);
alias("arg1", text);
execute(action);
}
}
@@ -387,7 +312,7 @@ struct mitemkeyinput : mitem
virtual void render(int x, int y, int w)
{
int tw = text_width(text), tk = (keyname ? text_width(keyname) : char_width('_'));
int tk = (keyname ? text_width(keyname) : char_width('_'));
static color capturec(0.4f, 0, 0);
if(isselection()) blendbox(x+w-tk-FONTH, y-FONTH/6, x+w+FONTH, y+FONTH+FONTH/6, false, -1, capture ? &capturec : NULL);
draw_text(text, x, y);
@@ -432,6 +357,7 @@ void *addmenu(const char *name, const char *title, bool allowinput, void (__cdec
menu.allowinput = allowinput;
menu.inited = false;
menu.refreshfunc = refreshfunc;
menu.dirlist = NULL;
lastmenu = &menu;
return &menu;
}
@@ -490,6 +416,17 @@ void menumdl(char *mdl, char *anim, char *rotspeed, char *scale)
menu.scale = max(0, min(atoi(scale), 100));
}
void menudirlist(char *dir, char *ext, char *action)
{
if(!lastmenu) return;
gmenu *menu = lastmenu;
if(menu->dirlist) delete menu->dirlist;
mdirlist *d = menu->dirlist = new mdirlist();
d->dir = newstring(dir);
d->ext = ext[0] ? newstring(ext): NULL;
d->action = action[0] ? newstring(action) : NULL;
}
void chmenumdl(char *menu, char *mdl, char *anim, char *rotspeed, char *scale)
{
if(!menu || !mdl || !menus.access(menu)) return;
@@ -508,6 +445,7 @@ COMMAND(menuitemkeyinput, ARG_4STR);
COMMAND(showmenu, ARG_1STR);
COMMAND(newmenu, ARG_1STR);
COMMAND(menumdl, ARG_5STR);
COMMAND(menudirlist, ARG_3STR);
COMMAND(chmenumdl, ARG_6STR);
bool menukey(int code, bool isdown, int unicode)
@@ -540,7 +478,7 @@ bool menukey(int code, bool isdown, int unicode)
break;
default:
{
if(!curmenu->allowinput) return false;
if(!curmenu->allowinput || !curmenu->items.inrange(menusel)) return false;
mitem &m = *curmenu->items[menusel];
m.key(code, isdown, unicode);
return true;
@@ -552,7 +490,7 @@ bool menukey(int code, bool isdown, int unicode)
}
else
{
if(!curmenu->allowinput) return false;
if(!curmenu->allowinput || !curmenu->items.inrange(menusel)) return false;
mitem &m = *curmenu->items[menusel];
if(code==SDLK_RETURN || code==-1 || code==-2)
{
@@ -597,3 +535,92 @@ void rendermenumdl()
glPopMatrix();
}
void gmenu::refresh()
{
if(!refreshfunc) return;
(*refreshfunc)(this, !inited);
inited = true;
if(menusel>=items.length()) menusel = max(items.length()-1, 0);
}
void gmenu::open()
{
inited = false;
if(allowinput) player1->stopmoving();
else menusel = 0;
if(items.inrange(menusel)) items[menusel]->focus(true);
init();
}
void gmenu::close()
{
if(items.inrange(menusel)) items[menusel]->focus(false);
}
void gmenu::init()
{
if(dirlist)
{
items.setsize(0);
cvector files;
listdir(dirlist->dir, dirlist->ext, files);
loopv(files)
{
char *f = files[i];
if(!f || !f[0]) continue;
items.add(new mitemtext(this, f, dirlist->action, NULL, NULL));
}
}
loopv(items) items[i]->init();
}
void gmenu::render()
{
const char *t = title;
if(!t) { static string buf; s_sprintf(buf)("[ %s menu ]", name); t = buf; }
int hitems = (header ? 2 : 0) + (footer ? 2 : 0),
pagesize = MAXMENU - hitems,
offset = menusel - (menusel%pagesize),
mdisp = min(items.length(), pagesize),
cdisp = min(items.length()-offset, pagesize);
if(title) text_startcolumns();
int w = 0;
loopv(items)
{
int x = items[i]->width();
if(x>w) w = x;
}
int tw = text_width(t);
if(tw>w) w = tw;
if(header)
{
int hw = text_width(header);
if(hw>w) w = hw;
}
int step = (FONTH*5)/4;
int h = (mdisp+hitems+2)*step;
int y = (2*VIRTH-h)/2;
int x = (2*VIRTW-w)/2;
renderbg(x-FONTH*3/2, y-FONTH, x+w+FONTH*3/2, y+h+FONTH, true);
if(offset>0) drawarrow(1, x+w+FONTH*3/2-FONTH*5/6, y-FONTH*5/6, FONTH*2/3);
if(offset+pagesize<items.length()) drawarrow(0, x+w+FONTH*3/2-FONTH*5/6, y+h+FONTH/6, FONTH*2/3);
if(header)
{
draw_text(header, x, y);
y += step*2;
}
draw_text(t, x, y);
y += step*2;
loopj(cdisp)
{
items[offset+j]->render(x, y, w);
y += step;
}
if(title) text_endcolumns();
if(footer)
{
y += ((mdisp-cdisp)+1)*step;
draw_text(footer, x, y);
}
}
+15 -2
View File
@@ -91,17 +91,30 @@ struct mitem
void renderbg(int x, int y, int w);
};
struct mdirlist
{
char *dir, *ext, *action;
~mdirlist()
{
DELETEA(dir);
DELETEA(ext);
DELETEA(action);
}
};
struct gmenu
{
const char *name, *title, *header, *footer;
vector<mitem *> items;
int mwidth;
int menusel;
const char *mdl; // (optional) md2 mdl
int anim, rotspeed, scale;
bool allowinput, inited;
void (__cdecl *refreshfunc)(void *, bool);
const char *mdl;
int anim, rotspeed, scale;
mdirlist *dirlist;
void render();
void renderbg(int x1, int y1, int x2, int y2, bool border);
void rendermenumdl();
+5 -2
View File
@@ -597,7 +597,7 @@ void setupdemorecord()
if(numlocalclients() || !m_mp(gamemode) || gamemode==1) return;
#ifdef WIN32
gzFile f = gzopen("demorecord", "wb9");
gzFile f = gzopen(path("demos/demorecord", true), "wb9");
if(!f) return;
#else
demotmp = tmpfile();
@@ -633,6 +633,8 @@ void setupdemorecord()
loopv(clients)
{
client *ci = clients[i];
if(ci->type==ST_EMPTY) continue;
uchar header[16];
ucharbuf q(&buf[sizeof(header)], sizeof(buf)-sizeof(header));
putint(q, SV_INITC2S);
@@ -714,7 +716,8 @@ void setupdemoplayback()
demoheader hdr;
string msg;
msg[0] = '\0';
s_sprintfd(file)("%s.dmo", smapname);
s_sprintfd(file)("demos/%s.dmo", smapname);
path(file);
demoplayback = opengzfile(file, "rb9");
if(!demoplayback) s_sprintf(msg)("could not read demo \"%s\"", file);
else if(gzread(demoplayback, &hdr, sizeof(demoheader))!=sizeof(demoheader) || memcmp(hdr.magic, DEMO_MAGIC, sizeof(hdr.magic)))