You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
593 lines
15 KiB
593 lines
15 KiB
/* $Id: menu.c,v 1.29 2003/07/25 12:28:50 stpohle Exp $ */
|
|
/* menu's for the game */
|
|
|
|
#include <SDL.h>
|
|
#include "bomberclone.h"
|
|
#include "gfx.h"
|
|
|
|
/* draws a box size (x,y) */
|
|
void
|
|
draw_menubox (int x, int y)
|
|
{
|
|
int x1,
|
|
x2,
|
|
y1,
|
|
y2,
|
|
i;
|
|
SDL_Rect src,
|
|
dest;
|
|
|
|
x1 = gfx.res.x / 2 - x / 2;
|
|
x2 = gfx.res.x / 2 + x / 2;
|
|
y1 = gfx.res.y / 2 - y / 2;
|
|
y2 = gfx.res.y / 2 + y / 2;
|
|
|
|
if (gfx_locksurface (gfx.screen))
|
|
return;
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
src.x = x1 + i;
|
|
src.w = x2 + i;
|
|
src.y = y1 + i;
|
|
src.h = y2 + i;
|
|
draw_shadefield (gfx.screen, &src, MENU_BG_SHADE_BRIGHT);
|
|
}
|
|
|
|
gfx_unlocksurface (gfx.screen);
|
|
|
|
dest.w = src.w = x - 2;
|
|
dest.h = src.h = y - 2;
|
|
dest.x = src.x = x1 + 2;
|
|
dest.y = src.y = y1 + 2;
|
|
|
|
redraw_logo_shaded (x1 + 2, y1 + 2, x - 2, y - 2, MENU_BG_SHADE_DARK);
|
|
}
|
|
|
|
|
|
void
|
|
draw_menu (char *text, _menu menu[], int *x, int *y)
|
|
{
|
|
int last,
|
|
maxlen,
|
|
y1,
|
|
i;
|
|
char vers[20];
|
|
|
|
// count the number of entrys
|
|
for (last = 0, maxlen = 0; menu[last].index != -1; last++)
|
|
if (((3+strlen (menu[last].text))*font[0].size.x) > maxlen) {
|
|
*x = gfx.res.x / 2 - (3+strlen (menu[last].text))*font[0].size.x / 2;
|
|
maxlen = (3+strlen (menu[last].text))*font[0].size.x;
|
|
}
|
|
if ((1+strlen (text))*font[2].size.x > maxlen)
|
|
maxlen = (1 + strlen (text))*font[2].size.x;
|
|
|
|
y1 = 2 * font[2].size.y + (last) * font[0].size.y;
|
|
draw_menubox (maxlen + 8, y1);
|
|
y1 = gfx.res.y / 2 - y1 / 2;
|
|
font_setcolor (128,128,0, 2);
|
|
font_draw ((gfx.res.x / 2) - ((font[2].size.x * strlen (text))/2) - 2, y1 - 2, text, 2);
|
|
font_setcolor (255,255,0, 2);
|
|
font_draw ((gfx.res.x / 2) - ((font[2].size.x * strlen (text))/2), y1, text, 2);
|
|
|
|
*y = y1 = y1 + (font[2].size.y * 2);
|
|
|
|
font_setcolor (255,255,255,0);
|
|
for (i = 0; i < last; i++) {
|
|
font_draw ((gfx.res.x / 2) - ((font[0].size.x * strlen (menu[i].text))/2) , y1, menu[i].text, 0);
|
|
y1 = y1 + font[0].size.y;
|
|
}
|
|
|
|
font_setcolor (255,255,255,0);
|
|
sprintf (vers, "v%s", VERSION);
|
|
font_draw (gfx.res.x - font[0].size.x * strlen (vers), gfx.res.y - font[0].size.y, vers, 0);
|
|
};
|
|
|
|
|
|
void
|
|
draw_select (int select, _menu menu[], int x, int y)
|
|
{
|
|
SDL_Rect dest,
|
|
src;
|
|
int last;
|
|
|
|
for (last = 0; menu[last].index != -1; last++)
|
|
redraw_logo_shaded (x, y + last * font[0].size.y, gfx.menuselect.image->w,
|
|
gfx.menuselect.image->h, MENU_BG_SHADE_DARK);
|
|
|
|
dest.x = x;
|
|
dest.y = y + select * font[0].size.y;
|
|
|
|
src.x = 0;
|
|
src.y = 0;
|
|
src.w = font[0].size.y;
|
|
src.h = font[0].size.y;
|
|
|
|
SDL_BlitSurface (gfx.menuselect.image, &src, gfx.screen, &dest);
|
|
};
|
|
|
|
|
|
int
|
|
menu_loop (char *menutitle, _menu menu[], int lastselect)
|
|
{
|
|
int menuselect = lastselect,
|
|
done = 0,
|
|
ds = 0,
|
|
lastentry,
|
|
eventstate;
|
|
SDL_Event event;
|
|
Uint8 *keys;
|
|
int keypressed = 0,
|
|
bx,
|
|
by;
|
|
|
|
draw_logo ();
|
|
draw_menu (menutitle, menu, &bx, &by);
|
|
for (lastentry = 0; menu[lastentry].index != -1; lastentry++);
|
|
draw_select (menuselect, menu, bx, by);
|
|
SDL_Flip (gfx.screen);
|
|
keys = SDL_GetKeyState (NULL);
|
|
if (keys[SDLK_RETURN] || keys[SDLK_ESCAPE])
|
|
keypressed = 1;
|
|
|
|
while (menuselect != -1 && done == 0) {
|
|
/* do the network loop if we have to */
|
|
if (bman.gametype == GT_multi && bman.sock != -1) {
|
|
network_loop ();
|
|
eventstate = SDL_PollEvent (&event);
|
|
}
|
|
else
|
|
eventstate = SDL_WaitEvent (&event);
|
|
|
|
if ( eventstate != 0)
|
|
switch (event.type) {
|
|
case (SDL_QUIT):
|
|
menuselect = -1;
|
|
bman.state = GS_quit;
|
|
done = 1;
|
|
break;
|
|
}
|
|
|
|
/* keyboard handling */
|
|
keys = SDL_GetKeyState (NULL);
|
|
|
|
if (keys[SDLK_ESCAPE] && (!keypressed)) {
|
|
/* we want to quit */
|
|
keypressed = 1;
|
|
menuselect = -1;
|
|
}
|
|
|
|
if (keys[SDLK_DOWN] && (!keypressed)) {
|
|
menuselect++;
|
|
while (menu[menuselect].index == 0)
|
|
menuselect++;
|
|
if (menu[menuselect].index == -1) {
|
|
menuselect = 0;
|
|
while (menu[menuselect].index == 0)
|
|
menuselect++;
|
|
}
|
|
keypressed = 1;
|
|
ds = 1;
|
|
}
|
|
|
|
if (keys[SDLK_UP] && (!keypressed)) {
|
|
menuselect--;
|
|
while (menu[menuselect].index == 0 && menuselect >= 0)
|
|
menuselect--;
|
|
if (menuselect == -1)
|
|
menuselect = lastentry - 1;
|
|
keypressed = 1;
|
|
ds = 1;
|
|
}
|
|
|
|
if ((keys[SDLK_LCTRL] || keys[SDLK_RCTRL] || keys[SDLK_RETURN]) && (!keypressed) && (event.type = SDL_KEYDOWN)) {
|
|
done = 1;
|
|
keypressed = 1;
|
|
// d_printf("return pressed - done=1\n");
|
|
}
|
|
if (event.type == SDL_KEYUP) { // d_printf("keyup\n");
|
|
|
|
keypressed = 0;
|
|
}
|
|
else if (event.type == SDL_KEYDOWN) {
|
|
// d_printf("keydown\n");
|
|
keypressed = 1;
|
|
}
|
|
|
|
if (ds) {
|
|
draw_select (menuselect, menu, bx, by);
|
|
ds = 0;
|
|
SDL_Flip (gfx.screen);
|
|
}
|
|
s_delay (25);
|
|
};
|
|
return menuselect;
|
|
};
|
|
|
|
void
|
|
menu_get_text (char *title, char *text, int len)
|
|
{
|
|
char t[255];
|
|
int done = 0,
|
|
keypressed = 0,
|
|
curpos,
|
|
x,
|
|
y,
|
|
i,
|
|
len_,
|
|
eventstate,
|
|
maxwidth;
|
|
SDL_Event event;
|
|
Uint8 *keys;
|
|
|
|
text[len] = 0;
|
|
curpos = strlen (text);
|
|
if (curpos >= len)
|
|
curpos = len - 1;
|
|
strcpy (t, text);
|
|
|
|
maxwidth = len * font[0].size.x;
|
|
if (maxwidth < font[1].size.x * strlen (title))
|
|
maxwidth = font[1].size.x * strlen (title);
|
|
|
|
draw_menubox (maxwidth + 8, font[1].size.y + font[0].size.y + 8);
|
|
|
|
x = gfx.res.x / 2 - maxwidth / 2;
|
|
y = gfx.res.y / 2 - (font[1].size.y + font[0].size.y) / 2;
|
|
|
|
font_setcolor (128,64,0,1);
|
|
font_draw (x - 2, y - 2, title, 1);
|
|
font_setcolor (192,128,0,1);
|
|
font_draw (x, y, title, 1);
|
|
|
|
font_setcolor (192,192,192,0);
|
|
y = y + font[1].size.y;
|
|
|
|
if ((len - 1) * (font[0].size.x) > gfx.res.x)
|
|
len_ = 40;
|
|
else
|
|
len_ = len;
|
|
|
|
while (!done || keypressed == 1) {
|
|
|
|
redraw_logo_shaded (x, y, font[0].size.x * len_, font[0].size.y,
|
|
MENU_BG_SHADE_DARK);
|
|
font_draw (x, y, t, 0);
|
|
font_draw (x + font[0].size.x * curpos, y, "_", 0);
|
|
SDL_Flip (gfx.screen);
|
|
|
|
/* do the network loop if we have to */
|
|
if (bman.gametype == GT_multi && bman.sock != -1) {
|
|
network_loop ();
|
|
eventstate = SDL_PollEvent (&event);
|
|
}
|
|
else
|
|
eventstate = SDL_WaitEvent (&event);
|
|
|
|
if ( eventstate != 0)
|
|
switch (event.type) {
|
|
case (SDL_QUIT):
|
|
bman.state = GS_quit;
|
|
done = 1;
|
|
}
|
|
|
|
keys = SDL_GetKeyState (NULL);
|
|
if (!keypressed && keys[SDLK_LEFT] && event.type == SDL_KEYDOWN) {
|
|
if (curpos > 0)
|
|
curpos--;
|
|
keypressed = 1;
|
|
}
|
|
if (!keypressed && keys[SDLK_RIGHT] && event.type == SDL_KEYDOWN) {
|
|
if (curpos < strlen (text) && curpos < len - 1)
|
|
curpos++;
|
|
keypressed = 1;
|
|
}
|
|
|
|
if (!keypressed && keys[SDLK_ESCAPE] && event.type == SDL_KEYDOWN) {
|
|
done = 1;
|
|
keypressed = 1;
|
|
}
|
|
|
|
if (!keypressed && keys[SDLK_RETURN] && event.type == SDL_KEYDOWN) {
|
|
done = 1;
|
|
keypressed = 1;
|
|
strcpy (text, t);
|
|
}
|
|
|
|
if (!keypressed && keys[8] && event.type == SDL_KEYDOWN)
|
|
if (curpos > 0) {
|
|
curpos--;
|
|
t[curpos] = t[curpos + 1];
|
|
t[curpos + 1] = t[curpos + 2];
|
|
keypressed = 1;
|
|
}
|
|
|
|
for (i = ' '; i <= 255; i++)
|
|
if (i != 127 && !keypressed && keys[i] && event.type == SDL_KEYDOWN) {
|
|
if (t[curpos] == 0)
|
|
t[curpos + 1] = 0;
|
|
t[curpos] = event.key.keysym.unicode;
|
|
if (curpos < strlen (t) && curpos < len - 1)
|
|
curpos++;
|
|
keypressed = 1;
|
|
}
|
|
|
|
if (event.type == SDL_KEYUP)
|
|
keypressed = 0;
|
|
|
|
s_delay (25);
|
|
}
|
|
};
|
|
|
|
|
|
void
|
|
menu_displaytext (char *title, char *text, Uint8 r, Uint8 g, Uint8 b)
|
|
{
|
|
int x,
|
|
x1,
|
|
y,
|
|
y1,
|
|
len,
|
|
maxwidth;
|
|
SDL_Rect dest;
|
|
|
|
len = strlen (title);
|
|
if (len < strlen (text))
|
|
len = strlen (text);
|
|
|
|
maxwidth = strlen(title) * font[1].size.x;
|
|
if (maxwidth < font[0].size.x * strlen (text))
|
|
maxwidth = font[0].size.x * strlen (text);
|
|
|
|
y = (gfx.res.y - (font[1].size.y + font[1].size.y)) / 2;
|
|
x = (gfx.res.x - maxwidth) / 2;
|
|
|
|
y1 = font[0].size.y + font[1].size.y;
|
|
x1 = maxwidth + 8;
|
|
|
|
dest.x = x - 4;
|
|
dest.y = y - 4;
|
|
dest.h = y1 + 8;
|
|
dest.w = x1 + 8;
|
|
SDL_FillRect (gfx.screen, &dest, SDL_MapRGB (gfx.screen->format, r, g, b));
|
|
|
|
font_setcolor (128,128,128, 1);
|
|
font_draw ((gfx.res.x - font[1].size.x * strlen (title)) / 2 - 2, y - 2, title, 1);
|
|
font_setcolor (255,255,255, 1);
|
|
font_draw ((gfx.res.x - font[1].size.x * strlen (title)) / 2, y, title, 1);
|
|
|
|
font_setcolor (255,255,0, 1);
|
|
font_draw ((gfx.res.x - font[0].size.x * strlen (text)) / 2, y + font[1].size.y + 2, text,
|
|
0);
|
|
|
|
SDL_Flip (gfx.screen);
|
|
};
|
|
|
|
|
|
void
|
|
menu_displaymessage (char *title, char *text)
|
|
{
|
|
SDL_Event event;
|
|
Uint8 *keys;
|
|
int done = 0,
|
|
keypressed = 0,
|
|
eventstate;
|
|
|
|
menu_displaytext (title, text, 64, 0, 0);
|
|
|
|
while (done == 0 || (done == 1 && keypressed == 1)) {
|
|
/* do the network loop if we have to */
|
|
if (bman.gametype == GT_multi && bman.sock != -1) {
|
|
network_loop ();
|
|
eventstate = SDL_PollEvent (&event);
|
|
}
|
|
else
|
|
eventstate = SDL_WaitEvent (&event);
|
|
|
|
if ( eventstate != 0)
|
|
switch (event.type) {
|
|
case (SDL_QUIT):
|
|
done = 1;
|
|
bman.state = GS_quit;
|
|
}
|
|
keys = SDL_GetKeyState (NULL);
|
|
|
|
if (!keypressed && keys[SDLK_ESCAPE] && event.type == SDL_KEYDOWN) {
|
|
done = 1;
|
|
keypressed = 1;
|
|
}
|
|
|
|
if (!keypressed && keys[SDLK_RETURN] && event.type == SDL_KEYDOWN) {
|
|
done = 1;
|
|
keypressed = 1;
|
|
}
|
|
|
|
if (event.type == SDL_KEYUP)
|
|
keypressed = 0;
|
|
|
|
s_delay (100);
|
|
}
|
|
};
|
|
|
|
void
|
|
menu_clearkeybuff ()
|
|
{
|
|
SDL_Event event;
|
|
Uint8 *keys;
|
|
int i;
|
|
SDL_PollEvent (&event);
|
|
keys = SDL_GetKeyState (NULL);
|
|
if (!(keys[SDLK_RETURN]))
|
|
return;
|
|
for (i = 0; i < 20; i++) {
|
|
s_delay (25);
|
|
SDL_PollEvent (&event);
|
|
keys = SDL_GetKeyState (NULL);
|
|
if (!(keys[SDLK_RETURN]))
|
|
return;
|
|
}
|
|
menu_displaytext ("", " Press Return ", 64, 0, 0);
|
|
while (keys[SDLK_RETURN]) {
|
|
s_delay (25);
|
|
SDL_PollEvent (&event);
|
|
keys = SDL_GetKeyState (NULL);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/***
|
|
*** Menu Selection of a file ior a directory
|
|
***/
|
|
#define DIRSCRMAX 10
|
|
/* draws the selection on the screen..
|
|
dirstart - first entry do display
|
|
flags - flags what should be shown directorys or files
|
|
selected - Selected file in the list
|
|
*/
|
|
int
|
|
menu_dir_draw (char *title, _direntry * dirstart, int start, int selected)
|
|
{
|
|
_direntry *de = dirstart;
|
|
int maxlen = 0, maxchar = 0,
|
|
pos = 0;
|
|
SDL_Rect wnd;
|
|
|
|
/* look for the longest name */
|
|
maxlen = font[1].size.x * strlen (title);
|
|
|
|
for (; de != NULL; de = de->next)
|
|
if (maxlen < font[0].size.x * strlen (de->name))
|
|
maxlen = font[0].size.x * strlen (de->name);
|
|
|
|
if (maxlen > gfx.res.x - 32)
|
|
maxchar = (gfx.res.x - 40) / font[0].size.x;
|
|
else
|
|
maxchar = maxlen / font[0].size.x;
|
|
|
|
wnd.h = DIRSCRMAX * font[0].size.y * 2;
|
|
wnd.w = maxlen;
|
|
wnd.x = (gfx.res.x - wnd.w) / 2;
|
|
wnd.y = (gfx.res.y - wnd.h) / 2;
|
|
|
|
draw_menubox (wnd.w + 8, wnd.h + 8);
|
|
font_setcolor (128,64,0,1);
|
|
font_draw ((gfx.res.x - font[1].size.x * strlen (title)) / 2 - 2, wnd.y - 2, title, 1);
|
|
font_setcolor (192,128,0,1);
|
|
font_draw ((gfx.res.x - font[1].size.x * strlen (title)) / 2, wnd.y, title, 1);
|
|
|
|
for (de = dirstart, pos = 0; de != NULL && pos < start + DIRSCRMAX - 1; de = de->next, pos++) {
|
|
if (pos >= start && pos < (start + DIRSCRMAX - 1)) {
|
|
if (pos == selected)
|
|
font_setcolor (255,255,255, 0);
|
|
else
|
|
font_setcolor (128,128,128, 0);
|
|
|
|
font_draw (wnd.x + gfx.menuselect.image->w + 2,
|
|
8 + wnd.y + (1 + pos - start) * font[0].size.y * 2, de->name, 0);
|
|
}
|
|
}
|
|
|
|
return (de == NULL);
|
|
}
|
|
|
|
char *
|
|
menu_dir_select (char *title, char *path, signed char dirflags)
|
|
{
|
|
_direntry *destart,
|
|
*de;
|
|
SDL_Event event;
|
|
Uint8 *keys;
|
|
int max = 0,
|
|
sel = 0,
|
|
keypressed = 0,
|
|
done = 0,
|
|
listend = 0,
|
|
liststart = 0,
|
|
oldsel = -1,
|
|
eventstate;
|
|
|
|
/* get the directory list and count the numbers */
|
|
destart = s_getdir (path);
|
|
destart = s_dirfilter (destart, dirflags);
|
|
for (max = 0, de = destart; de != NULL; de = de->next)
|
|
max++;
|
|
if (max <= 0)
|
|
return NULL;
|
|
|
|
while (done == 0 || (done == 1 && keypressed == 1)) {
|
|
if (sel != oldsel) {
|
|
listend = menu_dir_draw (title, destart, liststart, sel);
|
|
SDL_Flip (gfx.screen);
|
|
oldsel = sel;
|
|
}
|
|
|
|
/* do the network loop if we have to */
|
|
if (bman.gametype == GT_multi && bman.sock != -1) {
|
|
network_loop ();
|
|
eventstate = SDL_PollEvent (&event);
|
|
}
|
|
else
|
|
eventstate = SDL_WaitEvent (&event);
|
|
|
|
if ( eventstate != 0)
|
|
switch (event.type) {
|
|
case (SDL_QUIT):
|
|
sel = -1;
|
|
bman.state = GS_quit;
|
|
done = 1;
|
|
}
|
|
|
|
/* keyboard handling */
|
|
keys = SDL_GetKeyState (NULL);
|
|
if (keys[SDLK_DOWN] && event.type == SDL_KEYDOWN && keypressed == 0) {
|
|
keypressed = 1;
|
|
sel++;
|
|
if (!(listend)) /* if we can move this list down */
|
|
liststart++;
|
|
if (sel >= max) {
|
|
liststart = 0;
|
|
sel = 0;
|
|
}
|
|
}
|
|
|
|
if (keys[SDLK_UP] && event.type == SDL_KEYDOWN && keypressed == 0) {
|
|
keypressed = 1;
|
|
sel--;
|
|
if (liststart > 0)
|
|
liststart--;
|
|
if (sel < 0) {
|
|
sel = max - 1;
|
|
if (sel > (DIRSCRMAX / 2))
|
|
liststart = sel - (DIRSCRMAX / 2);
|
|
}
|
|
}
|
|
|
|
if (keys[SDLK_ESCAPE] && event.type == SDL_KEYDOWN) {
|
|
keypressed = 1;
|
|
return NULL;
|
|
}
|
|
if (!keys[SDLK_ESCAPE] && event.type == SDL_KEYUP)
|
|
keypressed = 0;
|
|
|
|
if (keys[SDLK_RETURN] && event.type == SDL_KEYDOWN) {
|
|
done = 1;
|
|
keypressed = 1;
|
|
}
|
|
if (!keys[SDLK_RETURN] && event.type == SDL_KEYUP)
|
|
keypressed = 0;
|
|
|
|
s_delay (25);
|
|
}
|
|
|
|
for (max = 0, de = destart; max != sel && de != NULL; de = de->next)
|
|
max++;
|
|
|
|
if (de == NULL)
|
|
return NULL;
|
|
|
|
return de->name;
|
|
};
|
|
|
|
#undef DIRSCRMAX
|