@ -1,596 +1,394 @@
/* $Id: menu.c,v 1.3 0 2003/11/08 06:27:59 stpohle Exp $ */
/* menu's for the game */
/* $Id: menu.c,v 1.3 1 2003/12/24 02:38:15 stpohle Exp $
* Menuhandling */
# include <SDL.h>
# include "basic.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 ) ;
}
# include "menu.h"
# include "menugui.h"
# include "network.h"
# include "ogcache-client.h"
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 ) ;
}
_menuitem menuitems [ MENU_MAXENTRYS ] ;
_menu menu ;
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 ) ;
/* delete all informations and create a totally new menuscreen */
void menu_new ( char * title , int x , int y ) {
int i ;
if ( menu . oldscreen ! = NULL )
menu_delete ( ) ;
strncpy ( menu . title , title , MENU_TITLELEN ) ;
menu . items = NULL ;
menu . focus = NULL ;
for ( i = 0 ; i < MENU_MAXENTRYS ; i + + ) {
menuitems [ i ] . id = - 1 ;
menuitems [ i ] . type = - 1 ;
menuitems [ i ] . next = NULL ;
}
/* save the old background screen */
x = ( 1 + ( int ) ( x / menu . images [ 1 ] - > w ) ) * menu . images [ 1 ] - > w ;
y = ( 1 + ( int ) ( y / menu . images [ 3 ] - > h ) ) * menu . images [ 3 ] - > h ;
menu . oldscreenpos . x = ( ( gfx . res . x - ( x + 2 * menu . images [ 0 ] - > w ) ) / 2 ) ;
menu . oldscreenpos . y = ( ( gfx . res . y - ( y + 2 * menu . images [ 0 ] - > h ) ) / 2 ) ;
menu . oldscreenpos . w = x + 2 * menu . images [ 0 ] - > w ;
menu . oldscreenpos . h = y + 2 * menu . images [ 0 ] - > h ;
menu . oldscreen = gfx_copyscreen ( & menu . oldscreenpos ) ;
} ;
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 ) ;
/* restore the screen and reset all needed informations, free the old screen */
void menu_delete ( ) {
gfx_restorescreen ( menu . oldscreen , & menu . oldscreenpos ) ;
gfx_blitdraw ( ) ;
SDL_FreeSurface ( menu . oldscreen ) ;
menu . oldscreen = NULL ;
dest . x = x ;
dest . y = y + select * font [ 0 ] . size . y ;
menuitems [ 0 ] . next = NULL ;
menu . items = NULL ;
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 ) ;
if ( GS_RUNNING )
draw_field ( ) ;
} ;
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 ;
/* draw only a part of the Screen */
void menu_draw_background ( SDL_Rect * updaterect ) {
int x , y , dx , dy ;
SDL_Rect dest , cdest , src , csrc , window ;
while ( menuselect ! = - 1 & & done = = 0 ) {
/* do the network loop if we have to */
if ( GT_MP ) {
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 ) ;
y = 0 ; // start at the updaterect. start pos
for ( ; y < = ( menu . oldscreenpos . h - 2 * menu . images [ 0 ] - > h - 1 ) / menu . images [ 4 ] - > h ; y + + ) {
x = 0 ; // start at the updaterect. start pos
for ( ; x < = ( menu . oldscreenpos . w - 2 * menu . images [ 0 ] - > w - 1 ) / menu . images [ 4 ] - > w ; x + + ) {
dest . x = x * menu . images [ 4 ] - > w ; // start pos
dest . y = y * menu . images [ 4 ] - > h ;
if ( keys [ SDLK_ESCAPE ] & & ( ! keypressed ) ) {
/* we want to quit */
keypressed = 1 ;
menuselect = - 1 ;
}
dx = ( 1 + x ) * menu . images [ 4 ] - > w ; // end pos
if ( dx > = ( menu . oldscreenpos . w - 2 * menu . images [ 0 ] - > w ) )
dest . w = menu . images [ 4 ] - > w - ( dx - ( menu . oldscreenpos . w - 2 * menu . images [ 0 ] - > w ) ) ;
else
dest . w = menu . images [ 4 ] - > w ;
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 ;
}
dy = ( 1 + y ) * menu . images [ 4 ] - > h ;
if ( dy > = ( menu . oldscreenpos . h - 2 * menu . images [ 0 ] - > h ) )
dest . h = menu . images [ 4 ] - > h - ( dy - ( menu . oldscreenpos . h - 2 * menu . images [ 0 ] - > h ) ) ;
else
dest . h = menu . images [ 4 ] - > h ;
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 ( dest . w > 0 | | dest . h > 0 ) {
dest . x + = MENUOFFSET_X ;
dest . y + = MENUOFFSET_Y ;
src . x = 0 ; src . y = 0 ; src . h = dest . h ; src . w = dest . w ;
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 ( updaterect = = NULL )
gfx_blit ( menu . images [ 4 ] , & src , gfx . screen , & dest , 10000 ) ;
else {
window = * updaterect ;
window . x + = MENUOFFSET_X ;
window . y + = MENUOFFSET_Y ;
rect_clipping ( & src , & dest , & window , & csrc , & cdest ) ;
if ( csrc . w < UINT16_HALF & & csrc . h < UINT16_HALF & & cdest . w < UINT16_HALF & & cdest . h < UINT16_HALF )
gfx_blit ( menu . images [ 4 ] , & csrc , gfx . screen , & cdest , 10000 ) ;
}
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 ) ;
/* draws the menuborders, this function does not save the background */
void menu_draw_border ( ) {
SDL_Rect dest ;
int i , dx ;
// draw top left
dest . x = menu . oldscreenpos . x ;
dest . y = menu . oldscreenpos . y ;
dest . w = menu . images [ 0 ] - > w ;
dest . h = menu . images [ 0 ] - > h ;
gfx_blit ( menu . images [ 0 ] , NULL , gfx . screen , & dest , 10000 ) ;
// draw top and below
for ( i = 0 ; i < ( ( menu . oldscreenpos . w - ( 2 * menu . images [ 0 ] - > w ) ) / menu . images [ 1 ] - > w ) ; i + + ) {
dest . x = menu . oldscreenpos . x + menu . images [ 0 ] - > w + ( i * menu . images [ 1 ] - > w ) ;
dest . y = menu . oldscreenpos . y ;
dest . w = menu . images [ 1 ] - > w ;
dest . h = menu . images [ 1 ] - > h ;
gfx_blit ( menu . images [ 1 ] , NULL , gfx . screen , & dest , 10000 ) ;
dest . y = menu . oldscreenpos . y + menu . oldscreenpos . h - menu . images [ 7 ] - > h ;
gfx_blit ( menu . images [ 7 ] , NULL , gfx . screen , & dest , 10000 ) ;
}
// draw top right
dest . x = menu . oldscreenpos . x + menu . oldscreenpos . w - menu . images [ 2 ] - > w ;
dest . y = menu . oldscreenpos . y ;
dest . w = menu . images [ 2 ] - > w ;
dest . h = menu . images [ 2 ] - > h ;
gfx_blit ( menu . images [ 2 ] , NULL , gfx . screen , & dest , 10000 ) ;
// draw left and right
for ( i = 0 ; i < ( ( menu . oldscreenpos . h - ( 2 * menu . images [ 0 ] - > h ) ) / menu . images [ 3 ] - > h ) ; i + + ) {
dest . x = menu . oldscreenpos . x ;
dest . y = menu . oldscreenpos . y + menu . images [ 0 ] - > h + menu . images [ 3 ] - > h * i ;
dest . w = menu . images [ 1 ] - > w ;
dest . h = menu . images [ 1 ] - > h ;
gfx_blit ( menu . images [ 3 ] , NULL , gfx . screen , & dest , 10000 ) ;
dest . x = menu . oldscreenpos . x + menu . oldscreenpos . w - menu . images [ 5 ] - > w ;
gfx_blit ( menu . images [ 5 ] , NULL , gfx . screen , & dest , 10000 ) ;
}
// draw below left
dest . x = menu . oldscreenpos . x ;
dest . y = menu . oldscreenpos . y + menu . oldscreenpos . h - menu . images [ 7 ] - > h ;
dest . w = menu . images [ 6 ] - > w ;
dest . h = menu . images [ 6 ] - > h ;
gfx_blit ( menu . images [ 6 ] , NULL , gfx . screen , & dest , 10000 ) ;
// draw below right
dest . x = menu . oldscreenpos . x + menu . oldscreenpos . w - menu . images [ 8 ] - > w ;
dest . y = menu . oldscreenpos . y + menu . oldscreenpos . h - menu . images [ 8 ] - > h ;
dest . w = menu . images [ 8 ] - > w ;
dest . h = menu . images [ 8 ] - > h ;
gfx_blit ( menu . images [ 8 ] , NULL , gfx . screen , & dest , 10000 ) ;
menu_draw_background ( NULL ) ;
// draw title
dx = menu . oldscreenpos . x + ( menu . oldscreenpos . w - font [ 2 ] . size . x * strlen ( menu . title ) ) / 2 ;
font_gfxdrawbold ( dx , menu . oldscreenpos . y + menu . images [ 0 ] - > h + 8 , menu . title , 2 , COLOR_brown , 2 , 10000 ) ;
font_gfxdraw ( dx , menu . oldscreenpos . y + menu . images [ 0 ] - > h + 8 , menu . title , 2 , COLOR_yellow , 10000 ) ;
} ;
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 ;
/* draw the menu, even it is only put into the gfx_blitlist. gfx_blitdraw needs
* to be called before the menu is drawed on the screen */
void menu_draw ( ) {
_menuitem * m ;
while ( ! done | | keypressed = = 1 ) {
menu_draw_border ( ) ;
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 ) ;
for ( m = menu . items ; m ! = NULL ; m = m - > next )
menu_draw_menuitem ( m ) ;
} ;
/* do the network loop if we have to */
if ( GT_MP ) {
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 ;
/* draw an item on the screen */
inline void menu_draw_menuitem ( _menuitem * m ) {
switch ( m - > type ) {
case ( MENU_label ) :
menu_draw_label ( m ) ;
break ;
case ( MENU_button ) :
menu_draw_button ( m ) ;
break ;
case ( MENU_bool ) :
menu_draw_bool ( m ) ;
break ;
case ( MENU_entryint ) :
case ( MENU_entrytext ) :
menu_draw_entry ( m ) ;
break ;
case ( MENU_list ) :
menu_draw_list ( m ) ;
break ;
}
} ;
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 ;
}
/* find the last menuitem in the list. */
int menu_getlastitem ( _menuitem * first ) {
int i = 0 ;
_menuitem * result = first ;
if ( ! keypressed & & keys [ SDLK_RETURN ] & & event . type = = SDL_KEYDOWN ) {
done = 1 ;
keypressed = 1 ;
strcpy ( text , t ) ;
}
if ( first = = NULL ) // no first item there
return - 1 ;
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 ( ; result - > next ! = NULL ; result = result - > next )
i + + ;
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 ;
return i ;
}
if ( event . type = = SDL_KEYUP )
keypressed = 0 ;
s_delay ( 25 ) ;
}
/* get the last and the first id number */
_menuitem * menu_get_firstid ( ) {
_menuitem * result = NULL , * mi = menu . items ;
for ( mi = menu . items ; mi ! = NULL ; mi = mi - > next )
if ( ( result = = NULL | | mi - > id < result - > id ) & & mi - > id ! = - 1 )
result = mi ;
return result ;
} ;
_menuitem * menu_get_lastid ( ) {
_menuitem * result = NULL , * mi = menu . items ;
for ( mi = menu . items ; mi ! = NULL ; mi = mi - > next )
if ( ( result = = NULL | | mi - > id > result - > id ) & & mi - > id ! = - 1 )
result = mi ;
return result ;
} ;
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 ) ;
/* change the focus to the givin element */
void menu_change_focus ( _menuitem * newfocus ) {
_menuitem * oldmi ;
maxwidth = strlen ( title ) * font [ 1 ] . size . x ;
if ( maxwidth < font [ 0 ] . size . x * strlen ( text ) )
maxwidth = font [ 0 ] . size . x * strlen ( text ) ;
if ( newfocus = = menu . focus ) // no focus change
return ;
y = ( gfx . res . y - ( font [ 1 ] . size . y + font [ 1 ] . size . y ) ) / 2 ;
x = ( gfx . res . x - maxwidth ) / 2 ;
/* lose focus */
switch ( menu . focus - > type ) {
case ( MENU_entryint ) :
case ( MENU_entrytext ) :
menu_entry_lose_focus ( menu . focus ) ;
break ;
}
y1 = font [ 0 ] . size . y + font [ 1 ] . size . y ;
x1 = maxwidth + 8 ;
/* draw the old and the new element */
oldmi = menu . focus ;
menu . focus = newfocus ;
menu_draw_menuitem ( oldmi ) ;
menu_draw_menuitem ( menu . focus ) ;
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 ) ) ;
/* get focus ... no function yet */
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 ) ;
d_printf ( " menu_change_focus: ID:%d Name:%s \n " , menu . focus - > id , menu . focus - > label ) ;
} ;
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 ) ;
} ;
/* focus next element, order by ID */
void menu_focus_next ( ) {
_menuitem * newmi = menu . focus , * mi , * oldmi = menu . focus ;
for ( mi = menu . items ; mi ! = NULL ; mi = mi - > next )
if ( mi - > id ! = oldmi - > id & & mi - > id > menu . focus - > id & & ( mi - > id < newmi - > id | | newmi = = oldmi ) )
newmi = mi ;
if ( newmi = = oldmi )
menu_change_focus ( menu_get_firstid ( ) ) ;
else
menu_change_focus ( newmi ) ;
} ;
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 ) ;
/* focus previous element, order by ID */
void menu_focus_prev ( ) {
_menuitem * newmi = menu . focus , * mi , * oldmi = menu . focus ;
while ( done = = 0 | | ( done = = 1 & & keypressed = = 1 ) ) {
/* do the network loop if we have to */
if ( GT_MP ) {
network_loop ( ) ;
eventstate = SDL_PollEvent ( & event ) ;
}
for ( mi = menu . items ; mi ! = NULL ; mi = mi - > next )
if ( mi - > id ! = - 1 & & mi - > id ! = oldmi - > id & & mi - > id < oldmi - > id & & ( mi - > id > newmi - > id | | newmi = = oldmi ) )
newmi = mi ;
if ( newmi = = oldmi )
menu_change_focus ( menu_get_lastid ( ) ) ;
else
eventstate = SDL_WaitEvent ( & event ) ;
if ( eventstate ! = 0 )
switch ( event . type ) {
case ( SDL_QUIT ) :
done = 1 ;
bman . state = GS_quit ;
}
keys = SDL_GetKeyState ( NULL ) ;
menu_change_focus ( newmi ) ;
} ;
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 ;
}
/* focus element with id ID */
void menu_focus_id ( int id ) {
_menuitem * mi , * oldmi = menu . focus ;
if ( event . type = = SDL_KEYUP )
keypressed = 0 ;
for ( mi = menu . items ; mi ! = NULL ; mi = mi - > next )
if ( mi - > id = = id )
menu_change_focus ( mi ) ;
s_delay ( 100 ) ;
}
menu_draw_menuitem ( oldmi ) ;
if ( menu . focus ! = oldmi )
menu_draw_menuitem ( menu . focus ) ;
} ;
void
menu_clearkeybuff ( )
{
/* menu loop, programm will stay in here as long as no ESCAPE is pressed
* and as long as no Button is clicked . Return of - 2 means something needs to reordered */
int menu_loop ( ) {
SDL_Event event ;
Uint8 * keys ;
int i ;
int keypressed = 0 , done = 0 , eventstate = 0 , reorder = 0 ;
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 ;
/* check if the focus is set to something, if not
* set the focus to the first item */
if ( menu . focus = = NULL )
menu . focus = menu . items ;
if ( menu . focus = = NULL ) {
d_fatal ( " menu_loop: focus == NULL, something went wrong \n " ) ;
return - 1 ;
}
menu_focus_id ( 0 ) ;
menu_displaytext ( " " , " Press Return " , 64 , 0 , 0 ) ;
while ( keys [ SDLK_RETURN ] ) {
s_delay ( 25 ) ;
SDL_PollEvent ( & event ) ;
keys = SDL_GetKeyState ( NULL ) ;
}
}
if ( keys [ SDLK_RETURN ] | | keys [ SDLK_ESCAPE ] )
keypressed = 1 ;
timestamp = SDL_GetTicks ( ) ; // needed for time sync.
menu_draw ( ) ;
/***
* * * 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 ;
}
while ( ! reorder & & ! done & & bman . state ! = GS_quit ) {
gfx_blitdraw ( ) ;
/* do the network loop if we have to */
if ( GT_MP ) {
if ( bman . sock > 0 ) {
network_loop ( ) ;
eventstate = SDL_PollEvent ( & event ) ;
if ( bman . notifygamemaster )
reorder = ogc_loop ( ) ;
}
else
eventstate = SDL_WaitEvent ( & event ) ;
if ( eventstate ! = 0 )
eventstate = SDL_PollEvent ( & event ) ;
if ( eventstate > = 1 ) {
switch ( event . type ) {
case ( SDL_QUIT ) :
sel = - 1 ;
bman . state = GS_quit ;
done = 1 ;
}
/* keyboard handling */
return - 1 ;
break ;
case ( SDL_KEYDOWN ) : /* focus next element */
if ( event . key . keysym . sym = = SDLK_TAB ) {
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_LSHIFT ] | | keys [ SDLK_RSHIFT ] )
menu_focus_prev ( ) ;
else
menu_focus_next ( ) ;
break ;
}
else if ( event . key . keysym . sym = = SDLK_ESCAPE ) {
done = 1 ;
return - 1 ;
break ;
}
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 ) ;
default : /* push events to the menu items */
switch ( menu . focus - > type ) {
case ( MENU_button ) :
done = menu_event_button ( menu . focus , & event ) ;
break ;
case ( MENU_bool ) :
done = menu_event_bool ( menu . focus , & event ) ;
break ;
case ( MENU_entryint ) :
case ( MENU_entrytext ) :
done = menu_event_entry ( menu . focus , & event ) ;
break ;
case ( MENU_label ) :
break ;
case ( MENU_list ) :
done = menu_event_list ( menu . focus , & event ) ;
break ;
}
}
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 ;
menu . focusto - = timediff ;
if ( menu . focusto < = 0.0f ) {
menu . focusto = MENU_FOCUSVIS_BLINKTO ;
menu . focusvis = ! menu . focusvis ;
menu_draw_menuitem ( menu . focus ) ;
}
if ( ! keys [ SDLK_RETURN ] & & event . type = = SDL_KEYUP )
keypressed = 0 ;
s_delay ( 25 ) ;
s_calctimesync ( ) ;
}
for ( max = 0 , de = destart ; max ! = sel & & de ! = NULL ; de = de - > next )
max + + ;
if ( reorder )
return - 2 ;
if ( de = = NULL )
return NULL ;
return de - > name ;
return menu . focus - > id ;
} ;
# undef DIRSCRMAX