sdlbomber/menu.c

361 lines
6.2 KiB
C

#include "bomber.h"
#include "menu.h"
#include "draw.h"
#include "gfx.h"
#include "utils.h"
#include "sound.h"
#include "network.h"
#include "announce.h"
#include "game.h"
unsigned char configopts[10]={2,1,0,2,0,0,0,0,0};
/* Generic menu */
int menuhistory[32]={0};
char menustring[1024];
char *menuput,*menuitems[40],*menutitle;
int menunum;
int menudelta;
static void drawmenu(int selected) {
int i,j;
int tx,ty;
clear();
j=strlen(menutitle)*bigfontxsize;
drawbigstring((IXSIZE-j) >> 1,20,menutitle);
ty=((IYSIZE-(bigfontysize*menunum))>>1)-(IYSIZE>>3);
for(i=0;i<menunum;++i)
{
j=strlen(menuitems[i])*bigfontxsize;
tx=(IXSIZE-j) >> 1;
if(i==selected)
{
greyrect(0,ty-1,tx-5,bigfontysize);
greyrect(tx+j+3,ty-1,IXSIZE-(tx+j+3),bigfontysize);
}
drawbigstring(tx,ty,menuitems[i]);
ty+=bigfontyspace;
}
}
static int domenu(int whichmenu) {
char redraw;
int selected;
int mcount=0;
if(whichmenu>=0)
selected=menuhistory[whichmenu];
else
selected=0;
redraw=1;
clearspritelist();
while(!exitflag) {
if(redraw) {
drawmenu(selected);
redraw=0;
}
mypause();
scaninput();
++mcount;
clearsprites();
clearspritelist();
addsprite(IXSIZE/2-50-20,IYSIZE-80,walking[2]+(30+mcount%15));
addsprite(IXSIZE/2+50-20,IYSIZE-80,walking[3]+(30+(mcount+7)%15));
plotsprites();
copyup();
if(anydown()) playsound(3);
while(anydown())
switch(takedown()) {
case MYLEFT:
menudelta=-1;
return selected;
case MYRIGHT:
case ' ':
case 13:
menudelta=1;
return selected;
case 'k':
case MYUP:
if(selected) --selected;
else selected=menunum-1;
if(whichmenu>=0)
menuhistory[whichmenu]=selected;
redraw=1;
break;
case 'j':
case MYDOWN:
++selected;
if(selected==menunum) selected=0;
if(whichmenu>=0)
menuhistory[whichmenu]=selected;
redraw=1;
break;
case 0x1b:
if(!whichmenu && selected)
{
selected=0;
redraw=1;
break;
}
menudelta=1;
return 0;
}
}
return 0;
}
static void menustart() {
menunum=-1;
menuput=menustring;
*menuput=0;
}
static void additem(char *item,...) {
char output[256];
va_list ap;
va_start(ap, item);
vsprintf(output,item,ap);
if(menunum<0)
menutitle=menuput;
else
menuitems[menunum]=menuput;
++menunum;
strcpy(menuput,output);
menuput+=strlen(output)+1;
}
/* end generic menu */
/* game menues */
static void drawjoinscreen(void) {
int i;
char name[17];
char temp[64];
#define JX (IXSIZE/3)
#define JY (IYSIZE/4)
clear();
centerbig(20,"JOIN NETWORK GAME");
drawbigstring(JX,JY,"SLOT NAME");
for(i=0;i<MAXNETNODES;++i)
{
if(!netnodes[i].used) continue;
memmove(name,netnodes[i].name,16);
name[16]=0;
sprintf(temp," %d %s",i+1,name);
drawbigstring(JX,JY+(i+1)*bigfontyspace,temp);
}
}
static int tryjoin(int which) {
int res;
if (0 == (res = send_join(&gamelistentries[which].netname, playername)))
return 0;
for ( ;; ) {
switch (res) {
case 1: return 0;
case 2:
drawjoinscreen();
copyup();
break;
case 3: return 1;
default: break;
}
scaninput();
while(anydown()) {
switch(takedown()) {
case 0x1b:
send_quit();
return 0;
}
}
res=scaninvite(200);
}
return 0;
}
static void main_menu(void) {
int sel;
while(!exitflag) {
menustart();
additem("BOMBER MAIN MENU");
additem("EXIT GAME");
additem("START SINGLE PLAYER GAME");
additem("OPTIONS");
// additem("REMAP MOVEMENT KEYS");
additem("START NETWORK GAME");
additem("JOIN NETWORK GAME");
sel=domenu(0);
if(!sel) {exitflag=1;break;}
if(sel==1) {gamemode=1;break;}
if(sel==2) {gamemode=2;break;}
if(sel==3) {gamemode=3;break;}
if(sel==4) {gamemode=4;break;}
}
}
char *densities[]={"PACKED","HIGH","MEDIUM","LOW"};
char *generosities[]={"LOW","MEDIUM","HIGH","RIDICULOUS"};
static void config_menu(void) {
int sel;
for(;;) {
menustart();
additem("GAME OPTIONS");
additem("RETURN TO MAIN MENU");
additem("DENSITY: %s",densities[configopts[GO_DENSITY]]);
additem("GENEROSITY: %s",generosities[configopts[GO_GENEROSITY]]);
additem("INITIAL FLAME LENGTH: %d",configopts[GO_FLAMES]+1);
additem("INITIAL NUMBER OF BOMBS: %d",configopts[GO_BOMBS]+1);
sel=domenu(2);
if(!sel) {gamemode=0;break;}
if(sel==1) {
configopts[GO_DENSITY]+=menudelta;
configopts[GO_DENSITY]&=3;
}
if(sel==2) {
configopts[GO_GENEROSITY]+=menudelta;
configopts[GO_GENEROSITY]&=3;
}
if(sel==3) {
configopts[GO_FLAMES]+=menudelta;
configopts[GO_FLAMES]&=7;
}
if(sel==4) {
configopts[GO_BOMBS]+=menudelta;
configopts[GO_BOMBS]&=7;
}
}
}
static void failure(char *str,...) {
gamemode=0;
}
static void draw_host_game(void) {
int i;
char *name;
char temp[64];
#define M3X (IXSIZE/3)
#define M3Y (IYSIZE/4)
clear();
centerbig(20,"HOST NETWORK GAME");
drawbigstring(M3X,M3Y,"SLOT NAME");
for(i=0;i<MAXNETNODES;++i) {
if(!netnodes[i].used) continue;
name=netnodes[i].name;
sprintf(temp," %d %s",i+1,name);
drawbigstring(M3X,M3Y+(i+2)*bigfontyspace,temp);
}
copyup();
}
static void host_game(void) {
create_unique();
if (!start_network_game()) {
failure("COULD NOT REGISTER GAME");
return;
}
draw_host_game();
for(;;) {
scaninput();
while(anydown()) {
switch(takedown()) {
case 0x1b:
unregistergame();
cancel_network_game();
gamemode=0;
return;
case ' ':
case 13:
unregistergame();
if (begin_network_game()) {
gamemode=5;
return;
}
send_invites();
draw_host_game();
}
}
if (!handle_joins()) continue;
send_invites();
draw_host_game();
}
gamemode=0;
}
static void join_game(void) {
int i;
int sel;
if (!searchgames(gameversion)) {
gamemode = 0;
return;
}
if (gamelistsize == 0) {
menustart();
additem("NO GAMES AVAILABLE");
domenu(-1);
gamemode=0;
return;
}
menustart();
additem("JOIN NETWORK GAME");
additem("EXIT");
for (i = 0; i < gamelistsize; i++) {
additem(gamelistentries[i].name);
}
sel=domenu(-1);
if(!sel) {
gamemode=0;
return;
}
if(!tryjoin(sel-1)) {
gamemode=0;
return;
}
network = NETWORK_SLAVE;
gamemode=5;
}
void (*modefunctions[])()= {
main_menu,
run_single_player,
config_menu,
host_game,
join_game,
run_network_game,
};
void mainloop(void) {
exitflag=0;
while(!exitflag)
modefunctions[gamemode]();
}