2007-05-22 15:03:32 +00:00
# include <stdio.h>
# include <math.h>
2007-05-28 13:49:44 +00:00
# include <string.h>
2007-05-22 15:03:32 +00:00
# include <baselib/system.h>
# include <baselib/keys.h>
# include <baselib/mouse.h>
# include <baselib/network.h>
2007-05-24 20:54:08 +00:00
# include <engine/interface.h>
# include <engine/versions.h>
# include "../mapres.h"
2007-05-22 15:03:32 +00:00
2007-05-24 20:54:08 +00:00
# include <engine/client/ui.h>
# include "mapres_image.h"
# include "mapres_tilemap.h"
2007-06-01 11:17:10 +00:00
# include <engine/config.h>
2007-05-22 15:03:32 +00:00
using namespace baselib ;
/********************************************************
MENU
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-05-27 18:14:24 +00:00
enum gui_tileset_enum
{
tileset_regular ,
tileset_hot ,
tileset_active ,
tileset_inactive
} ;
enum gui_parts_enum
{
invalid_part = 0 ,
2007-05-28 13:49:44 +00:00
button_big_topleft ,
button_big_topmid ,
button_big_topright ,
button_big_midleft ,
button_big_midmid ,
button_big_midright ,
button_big_btmleft ,
button_big_btmmid ,
button_big_btmright ,
slider_big_horiz_begin ,
slider_big_horiz_mid ,
slider_big_horiz_end ,
slider_small_horiz_begin ,
slider_small_horiz_mid ,
slider_small_horiz_end ,
slider_small_vert_begin ,
radio_unchecked ,
radio_checked ,
slider_small_vert_mid ,
slider_small_vert_end ,
slider_big_vert_begin ,
slider_big_handle_vert ,
slider_big_handle_horiz ,
slider_small_handle_horiz ,
slider_big_arrow_left ,
slider_big_arrow_up ,
slider_big_arrow_right ,
slider_big_arrow_down ,
slider_small_arrow_left ,
slider_small_arrow_up ,
slider_small_arrow_right ,
slider_small_arrow_down ,
slider_small_handle_vert ,
slider_big_vert_mid ,
slider_big_vert_end ,
screen_thick_topleft ,
screen_thick_topmid ,
screen_thick_topright ,
screen_thick_midleft ,
screen_thick_midmid ,
screen_thick_midright ,
screen_thick_btmleft ,
screen_thick_btmmid ,
screen_thick_btmright ,
screen_transparent_topleft ,
screen_transparent_topmid ,
screen_transparent_topright ,
screen_transparent_midleft ,
screen_transparent_midmid ,
screen_transparent_midright ,
screen_transparent_btmleft ,
screen_transparent_btmmid ,
screen_transparent_btmright ,
screen_info_topleft ,
screen_info_topmid ,
screen_info_topright ,
screen_info_midleft ,
screen_info_midmid ,
screen_info_midright ,
screen_info_btmleft ,
screen_info_btmmid ,
screen_info_btmright ,
screen_textbox_topleft ,
screen_textbox_topmid ,
screen_textbox_topright ,
screen_textbox_midleft ,
screen_textbox_midmid ,
screen_textbox_midright ,
screen_textbox_btmleft ,
screen_textbox_btmmid ,
screen_textbox_btmright ,
screen_list_topleft ,
screen_list_topmid ,
screen_list_topright ,
screen_list_midleft ,
screen_list_midmid ,
screen_list_midright ,
screen_list_btmleft ,
screen_list_btmmid ,
screen_list_btmright
2007-05-27 18:14:24 +00:00
} ;
struct gui_part
{
int x , y ;
int w , h ;
bool stretch_x , stretch_y ;
} ;
gui_part parts [ ] =
{
{ 0 , 0 , 0 , 0 } , // invalid_part
2007-05-28 13:49:44 +00:00
{ 0 , 0 , 16 , 16 } , // button_big_topleft
{ 16 , 0 , 16 , 16 } , // button_big_topmid
{ 32 , 0 , 16 , 16 } , // button_big_topright
{ 0 , 16 , 16 , 16 } , // button_big_midleft
{ 16 , 16 , 16 , 16 } , // button_big_midmid
{ 32 , 16 , 16 , 16 } , // button_big_midright
{ 0 , 32 , 16 , 16 } , // button_big_btmleft
{ 16 , 32 , 16 , 16 } , // button_big_btmmid
{ 32 , 32 , 16 , 16 } , // button_big_btmright
{ 0 , 48 , 16 , 16 } , // slider_big_horiz_begin
{ 16 , 48 , 16 , 16 } , // slider_big_horiz_mid
{ 32 , 48 , 16 , 16 } , // slider_big_horiz_end
{ 0 , 96 , 16 , 16 } , // slider_small_horiz_begin
{ 16 , 96 , 16 , 16 } , // slider_small_horiz_mid
{ 32 , 96 , 16 , 16 } , // slider_small_horiz_end
{ 48 , 96 , 16 , 16 } , // slider_small_vert_begin
{ 64 , 112 , 32 , 32 } , // radio_unchecked
{ 96 , 112 , 32 , 32 } , // radio_checked
{ 48 , 112 , 16 , 16 } , // slider_small_vert_mid
{ 48 , 128 , 16 , 16 } , // slider_small_vert_end
{ 48 , 48 , 16 , 16 } , // slider_big_vert_begin
{ 64 , 48 , 16 , 32 } , // slider_big_handle_vert
{ 80 , 64 , 32 , 16 } , // slider_big_handle_horiz
{ 80 , 48 , 16 , 16 } , // slider_small_handle_horiz
{ 0 , 64 , 16 , 16 } , // slider_big_arrow_left
{ 16 , 64 , 16 , 16 } , // slider_big_arrow_up
{ 32 , 64 , 16 , 16 } , // slider_big_arrow_right
{ 16 , 80 , 16 , 16 } , // slider_big_arrow_down
{ 0 , 112 , 16 , 16 } , // slider_small_arrow_left
{ 16 , 112 , 16 , 16 } , // slider_small_arrow_up
{ 32 , 112 , 16 , 16 } , // slider_small_arrow_right
{ 16 , 128 , 16 , 16 } , // slider_small_arrow_down
{ 96 , 48 , 16 , 16 } , // slider_small_handle_vert
{ 48 , 64 , 16 , 16 } , // slider_big_vert_mid
{ 48 , 80 , 16 , 16 } , // slider_big_vert_end
{ 0 , 384 , 16 , 16 } , // screen_thick_topleft
{ 16 , 384 , 16 , 16 } , // screen_thick_topmid
{ 32 , 384 , 16 , 16 } , // screen_thick_topright
{ 0 , 400 , 16 , 16 } , // screen_thick_midleft
{ 16 , 400 , 16 , 16 } , // screen_thick_midmid
{ 32 , 400 , 16 , 16 } , // screen_thick_midright
{ 0 , 416 , 16 , 16 } , // screen_thick_btmleft
{ 16 , 416 , 16 , 16 } , // screen_thick_btmmid
{ 32 , 416 , 16 , 16 } , // screen_thick_btmright
{ 48 , 384 , 16 , 16 } , // screen_transparent_topleft
{ 64 , 384 , 16 , 16 } , // screen_transparent_topmid
{ 80 , 384 , 16 , 16 } , // screen_transparent_topright
{ 48 , 400 , 16 , 16 } , // screen_transparent_midleft
{ 64 , 400 , 16 , 16 } , // screen_transparent_midmid
{ 80 , 400 , 16 , 16 } , // screen_transparent_midright
{ 48 , 416 , 16 , 16 } , // screen_transparent_btmleft
{ 64 , 416 , 16 , 16 } , // screen_transparent_btmmid
{ 80 , 416 , 16 , 16 } , // screen_transparent_btmright
{ 96 , 384 , 16 , 16 } , // screen_info_topleft
{ 112 , 384 , 16 , 16 } , // screen_info_topmid
{ 128 , 384 , 16 , 16 } , // screen_info_topright
{ 96 , 400 , 16 , 16 } , // screen_info_midleft
{ 112 , 400 , 16 , 16 } , // screen_info_midmid
{ 128 , 400 , 16 , 16 } , // screen_info_midright
{ 96 , 416 , 16 , 16 } , // screen_info_btmleft
{ 112 , 416 , 16 , 16 } , // screen_info_btmmid
{ 128 , 416 , 16 , 16 } , // screen_info_btmright
{ 144 , 384 , 16 , 16 } , // screen_textbox_topleft
{ 160 , 384 , 16 , 16 } , // screen_textbox_topmid
{ 176 , 384 , 16 , 16 } , // screen_textbox_topright
{ 144 , 400 , 16 , 16 } , // screen_textbox_midleft
{ 160 , 400 , 16 , 16 } , // screen_textbox_midmid
{ 176 , 400 , 16 , 16 } , // screen_textbox_midright
{ 144 , 416 , 16 , 16 } , // screen_textbox_btmleft
{ 160 , 416 , 16 , 16 } , // screen_textbox_btmmid
{ 176 , 416 , 16 , 16 } , // screen_textbox_btmright
{ 192 , 384 , 16 , 16 } , // screen_list_topleft
{ 208 , 384 , 16 , 16 } , // screen_list_topmid
{ 224 , 384 , 16 , 16 } , // screen_list_topright
{ 192 , 400 , 16 , 16 } , // screen_list_midleft
{ 208 , 400 , 16 , 16 } , // screen_list_midmid
{ 224 , 400 , 16 , 16 } , // screen_list_midright
{ 192 , 416 , 16 , 16 } , // screen_list_btmleft
{ 208 , 416 , 16 , 16 } , // screen_list_btmmid
{ 224 , 416 , 16 , 16 } // screen_list_btmright
} ;
# define GUI_COMPOSITE_BOX(name) { name ## _topleft, name ## _topmid, name ## _topright, name ## _midleft, name ## _midmid, name ## _midright, name ## _btmleft, name ## _btmmid, name ## _btmright }
enum gui_composite_box_enum
{
button_big_box ,
screen_thick_box ,
screen_transparent_box ,
screen_info_box ,
screen_textbox_box ,
screen_list_box ,
} ;
struct gui_composite_box
{
gui_parts_enum part_topleft , part_topmid , part_topright ;
gui_parts_enum part_midleft , part_midmid , part_midright ;
gui_parts_enum part_btmleft , part_btmmid , part_btmright ;
2007-05-27 18:14:24 +00:00
} ;
2007-05-28 13:49:44 +00:00
gui_composite_box boxes [ ] =
{
GUI_COMPOSITE_BOX ( button_big ) ,
GUI_COMPOSITE_BOX ( screen_thick ) ,
GUI_COMPOSITE_BOX ( screen_transparent ) ,
GUI_COMPOSITE_BOX ( screen_info ) ,
GUI_COMPOSITE_BOX ( screen_textbox ) ,
GUI_COMPOSITE_BOX ( screen_list ) ,
} ;
2007-05-27 18:14:24 +00:00
int gui_tileset_texture ;
2007-05-28 13:49:44 +00:00
void draw_part ( gui_part part , gui_tileset_enum tileset , float x , float y , float w , float h )
2007-05-27 18:14:24 +00:00
{
const float tex_w = 512.0 , tex_h = 512.0 ;
2007-05-28 13:49:44 +00:00
const float start_x = part . x / tex_w , start_y = part . y / tex_h , f_w = part . w / tex_w , f_h = part . h / tex_h ;
2007-05-27 18:14:24 +00:00
float ts_x , ts_y ;
switch ( tileset )
{
case tileset_regular :
ts_x = 0.0f ; ts_y = 0.0f ; break ;
case tileset_hot :
ts_x = 0.375f ; ts_y = 0.375f ; break ;
case tileset_active :
ts_x = 0.0f ; ts_y = 0.375f ; break ;
case tileset_inactive :
ts_x = 0.375f ; ts_y = 0.0f ; break ;
default :
dbg_msg ( " menu " , " invalid tileset given to draw_part " ) ;
}
gfx_blend_normal ( ) ;
gfx_texture_set ( gui_tileset_texture ) ;
gfx_quads_begin ( ) ;
gfx_quads_setcolor ( 1 , 1 , 1 , 1 ) ;
gfx_quads_setsubset (
ts_x + start_x , // startx
ts_y + start_y , // starty
ts_x + start_x + f_w , // endx
ts_y + start_y + f_h ) ; // endy
gfx_quads_drawTL ( x , y , w , h ) ;
gfx_quads_end ( ) ;
2007-05-28 13:49:44 +00:00
}
void draw_part ( gui_parts_enum part , gui_tileset_enum tileset , float x , float y , float w , float h )
{
draw_part ( parts [ part ] , tileset , x , y , w , h ) ;
2007-05-27 18:14:24 +00:00
}
void draw_part ( gui_parts_enum part , gui_tileset_enum tileset , float x , float y )
{
draw_part ( part , tileset , x , y , parts [ part ] . w , parts [ part ] . h ) ;
}
2007-05-28 13:49:44 +00:00
void draw_box ( gui_composite_box_enum box , gui_tileset_enum tileset , float x , float y , float w , float h )
{
gui_composite_box b = boxes [ box ] ;
gui_part topleft_p = parts [ b . part_topleft ] ;
gui_part topmid_p = parts [ b . part_topmid ] ;
gui_part topright_p = parts [ b . part_topright ] ;
gui_part midleft_p = parts [ b . part_midleft ] ;
gui_part btmleft_p = parts [ b . part_btmleft ] ;
float scale = h / ( topleft_p . h + midleft_p . h + btmleft_p . h ) ;
scale = 1.0 ;
float topleft_w = scale * topleft_p . w ;
float topright_w = scale * topright_p . w ;
float topmid_w = w - topright_w - topleft_w ;
float topleft_h = scale * topleft_p . h ;
float btmleft_h = scale * btmleft_p . h ;
float midleft_h = h - topleft_h - btmleft_h ;
draw_part ( b . part_topleft , tileset , x , y ) ;
draw_part ( b . part_topmid , tileset , x + topleft_w , y , topmid_w , topleft_h ) ;
draw_part ( b . part_topright , tileset , x + topleft_w + topmid_w , y ) ;
draw_part ( b . part_midleft , tileset , x , y + topleft_h , topright_w , midleft_h ) ;
draw_part ( b . part_midmid , tileset , x + topleft_w , y + topleft_h , topmid_w , midleft_h ) ;
draw_part ( b . part_midright , tileset , x + topleft_w + topmid_w , y + topleft_h , topright_w , midleft_h ) ;
draw_part ( b . part_btmleft , tileset , x , y + topleft_h + midleft_h ) ;
draw_part ( b . part_btmmid , tileset , x + topleft_w , y + topleft_h + midleft_h , topmid_w , btmleft_h ) ;
draw_part ( b . part_btmright , tileset , x + topleft_w + topmid_w , y + topleft_h + midleft_h ) ;
}
2007-05-22 15:03:32 +00:00
struct pretty_font
{
char m_CharStartTable [ 256 ] ;
char m_CharEndTable [ 256 ] ;
int font_texture ;
} ;
extern pretty_font * current_font ;
float gfx_pretty_text_width ( float size , const char * text ) ;
void draw_scrolling_background ( int id , float w , float h , float t )
{
2007-06-01 02:21:46 +00:00
float tx = w / 512.0f ;
float ty = h / 512.0f ;
2007-05-22 15:03:32 +00:00
float start_x = fmod ( t , 1.0f ) ;
float start_y = 1.0f - fmod ( t * 0.8f , 1.0f ) ;
gfx_blend_normal ( ) ;
gfx_texture_set ( id ) ;
gfx_quads_begin ( ) ;
gfx_quads_setcolor ( 1 , 1 , 1 , 1 ) ;
gfx_quads_setsubset (
start_x , // startx
start_y , // starty
start_x + tx , // endx
start_y + ty ) ; // endy
gfx_quads_drawTL ( 0.0f , 0.0f , w , h ) ;
gfx_quads_end ( ) ;
}
int background_texture ;
int teewars_banner_texture ;
int music_menu ;
int music_menu_id = - 1 ;
void draw_image_button ( void * id , const char * text , int checked , float x , float y , float w , float h , void * extra )
{
ui_do_image ( * ( int * ) id , x , y , w , h ) ;
}
2007-05-27 18:14:24 +00:00
void draw_single_part_button ( void * id , const char * text , int checked , float x , float y , float w , float h , void * extra )
{
gui_tileset_enum tileset ;
if ( ui_active_item ( ) = = id & & ui_hot_item ( ) = = id )
tileset = tileset_active ;
else if ( ui_hot_item ( ) = = id )
tileset = tileset_hot ;
else
tileset = tileset_regular ;
draw_part ( ( gui_parts_enum ) ( int ) ( int * ) extra , tileset , x , y , w , h ) ;
}
2007-06-01 02:21:46 +00:00
void draw_menu_button ( void * id , const char * text , int checked , float x , float y , float w , float h , void * extra )
{
gui_composite_box_enum box_style ;
if ( ( int ) extra )
box_style = screen_info_box ;
else
box_style = screen_list_box ;
draw_box ( box_style , tileset_regular , x , y , w , h ) ;
ui_do_label ( x + 10 , y , text , 28 ) ;
}
2007-05-27 18:14:24 +00:00
void draw_teewars_button ( void * id , const char * text , int checked , float x , float y , float w , float h , void * extra )
{
2007-05-28 13:49:44 +00:00
float text_width = gfx_pretty_text_width ( 46.f , text ) ;
2007-05-27 18:14:24 +00:00
gui_tileset_enum tileset ;
if ( ui_active_item ( ) = = id & & ui_hot_item ( ) = = id )
tileset = tileset_active ;
else if ( ui_hot_item ( ) = = id )
tileset = tileset_hot ;
else
tileset = tileset_regular ;
2007-05-28 13:49:44 +00:00
if ( ( int ) ( int * ) extra = = 1 )
tileset = tileset_inactive ;
2007-05-27 18:14:24 +00:00
2007-05-28 13:49:44 +00:00
draw_box ( button_big_box , tileset , x , y , w , h ) ;
2007-05-27 18:14:24 +00:00
2007-06-01 02:21:46 +00:00
ui_do_label ( x + w / 2 - text_width / 2 , y , text , 46 ) ;
2007-05-27 18:14:24 +00:00
}
2007-05-22 15:03:32 +00:00
struct server_info
{
int version ;
int players ;
int max_players ;
netaddr4 address ;
char name [ 129 ] ;
char map [ 65 ] ;
} ;
struct server_list
{
server_info infos [ 10 ] ;
int active_count , info_count ;
int scroll_index ;
int selected_index ;
} ;
2007-06-01 02:21:46 +00:00
int ui_do_key_reader ( void * id , float x , float y , float w , float h , int key )
{
// process
int inside = ui_mouse_inside ( x , y , w , h ) ;
int new_key = key ;
if ( inside )
{
ui_set_hot_item ( id ) ;
if ( ui_mouse_button ( 0 ) )
ui_set_active_item ( id ) ;
}
if ( ui_active_item ( ) = = id )
{
int k = keys : : last_key ( ) ;
if ( k )
{
new_key = k ;
ui_set_active_item ( 0 ) ;
}
}
// draw
gui_composite_box_enum box_style = screen_info_box ;
draw_box ( box_style , tileset_regular , x , y , w , h ) ;
2007-06-09 16:21:28 +00:00
const char * str = keys : : key_name ( key ) ;
2007-06-01 02:21:46 +00:00
ui_do_label ( x + 10 , y , str , 36 ) ;
if ( ui_active_item ( ) = = id )
{
float w = gfx_pretty_text_width ( 36.0f , str ) ;
ui_do_label ( x + 10 + w , y , " _ " , 36 ) ;
}
return new_key ;
}
int ui_do_combo_box ( void * id , float x , float y , float w , char * lines [ 128 ] , int line_count , int selected_index )
{
float line_height = 36.0f ;
int inside = ( ui_active_item ( ) = = id ) ? ui_mouse_inside ( x , y , w , line_count * line_height ) : ui_mouse_inside ( x , y , w , line_height ) ;
int hover_index = ( ui_mouse_y ( ) - y ) / line_height ;
char resolutions [ ] [ 128 ] =
{
" 400x300 " ,
" 640x480 " ,
" 800x600 " ,
" 1024x768 " ,
" 1280x1024 " ,
} ;
if ( ui_active_item ( ) = = id )
{
for ( int i = 0 ; i < line_count ; i + + )
{
gui_composite_box_enum box_style ;
if ( inside & & hover_index = = i )
box_style = screen_info_box ;
else
box_style = screen_list_box ;
draw_box ( box_style , tileset_regular , x , y + i * line_height , w , line_height ) ;
ui_do_label ( x + 10 + 10 , y + i * line_height , resolutions [ i ] , 36 ) ;
if ( selected_index = = i )
ui_do_label ( x + 10 , y + i * line_height , " - " , 36 ) ;
}
if ( ! ui_mouse_button ( 0 ) )
{
ui_set_active_item ( 0 ) ;
if ( inside )
selected_index = hover_index ;
}
}
else
{
draw_box ( screen_list_box , tileset_regular , x , y , w , line_height ) ;
ui_do_label ( x + 10 , y , resolutions [ selected_index ] , 36 ) ;
if ( inside & & ui_mouse_button ( 0 ) )
ui_set_active_item ( id ) ;
}
return selected_index ;
}
2007-05-22 15:03:32 +00:00
int ui_do_edit_box ( void * id , float x , float y , float w , float h , char * str , int str_size )
{
int inside = ui_mouse_inside ( x , y , w , h ) ;
int r = 0 ;
if ( inside )
{
ui_set_hot_item ( id ) ;
if ( ui_mouse_button ( 0 ) )
ui_set_active_item ( id ) ;
}
if ( ui_active_item ( ) = = id )
{
2007-05-27 10:54:33 +00:00
int c = keys : : last_char ( ) ;
2007-05-22 15:03:32 +00:00
int k = keys : : last_key ( ) ;
int len = strlen ( str ) ;
if ( c > = 32 & & c < 128 )
{
if ( len < str_size - 1 )
{
str [ len ] = c ;
str [ len + 1 ] = 0 ;
}
}
if ( k = = keys : : backspace )
{
if ( len > 0 )
str [ len - 1 ] = 0 ;
}
r = 1 ;
}
2007-05-28 13:49:44 +00:00
draw_box ( screen_textbox_box , tileset_regular , x , y , w , h ) ;
2007-06-01 02:21:46 +00:00
ui_do_label ( x + 10 , y , str , 36 ) ;
2007-05-22 15:03:32 +00:00
if ( ui_active_item ( ) = = id )
{
2007-05-28 13:49:44 +00:00
float w = gfx_pretty_text_width ( 36.0f , str ) ;
2007-06-01 02:21:46 +00:00
ui_do_label ( x + 10 + w , y , " _ " , 36 ) ;
2007-05-22 15:03:32 +00:00
}
return r ;
}
int do_scroll_bar ( void * id , float x , float y , float height , int steps , int last_index )
{
int r = last_index ;
2007-05-28 13:49:44 +00:00
static int up_button ;
static int down_button ;
if ( ui_do_button ( & up_button , " " , 0 , x + 8 , y , 16 , 16 , draw_single_part_button , ( void * ) slider_big_arrow_up ) )
2007-05-22 15:03:32 +00:00
{
if ( r > 0 )
- - r ;
}
2007-06-01 02:21:46 +00:00
if ( ui_do_button ( & down_button , " " , 0 , x + 8 , y + height - 16 , 16 , 16 , draw_single_part_button , ( void * ) slider_big_arrow_down ) )
2007-05-22 15:03:32 +00:00
{
if ( r < steps )
+ + r ;
}
2007-06-01 02:21:46 +00:00
if ( steps > 0 ) // only if there's actually stuff to scroll through
2007-05-22 15:03:32 +00:00
{
2007-05-28 13:49:44 +00:00
int inside = ui_mouse_inside ( x , y + 16 , 16 , height - 32 ) ;
2007-05-22 15:03:32 +00:00
if ( inside & & ( ! ui_active_item ( ) | | ui_active_item ( ) = = id ) )
ui_set_hot_item ( id ) ;
if ( ui_active_item ( ) = = id )
{
if ( ui_mouse_button ( 0 ) )
{
2007-05-28 13:49:44 +00:00
float pos = ui_mouse_y ( ) - y - 16 ;
float perc = pos / ( height - 32 ) ;
2007-05-22 15:03:32 +00:00
2007-05-27 00:47:07 +00:00
r = ( int ) ( ( steps + 1 ) * perc ) ;
2007-05-22 15:03:32 +00:00
if ( r < 0 )
r = 0 ;
else if ( r > steps )
r = steps ;
}
else
ui_set_active_item ( 0 ) ;
}
else if ( ui_hot_item ( ) = = id & & ui_mouse_button ( 0 ) )
ui_set_active_item ( id ) ;
else if ( inside & & ( ! ui_active_item ( ) | | ui_active_item ( ) = = id ) )
ui_set_hot_item ( id ) ;
}
2007-05-28 13:49:44 +00:00
draw_part ( slider_big_vert_begin , tileset_regular , x + 8 , y + 16 , 16 , 16 ) ;
draw_part ( slider_big_vert_mid , tileset_regular , x + 8 , y + 32 , 16 , height - 32 - 32 ) ;
draw_part ( slider_big_vert_end , tileset_regular , x + 8 , y + height - 32 , 16 , 16 ) ;
2007-05-27 18:14:24 +00:00
2007-05-28 13:49:44 +00:00
draw_part ( slider_big_handle_horiz , tileset_regular , x , y + 16 + r * ( ( height - 64 ) / steps ) , 32 , 16 ) ;
2007-05-27 18:14:24 +00:00
2007-05-22 15:03:32 +00:00
return r ;
}
2007-06-01 02:21:46 +00:00
static int do_server_list ( server_list * list , float x , float y , int visible_items )
2007-05-22 15:03:32 +00:00
{
2007-05-28 13:49:44 +00:00
const float spacing = 3.f ;
const float item_height = 28 ;
const float item_width = 728 ;
const float real_width = item_width + 20 ;
2007-05-22 15:03:32 +00:00
const float real_height = item_height * visible_items + spacing * ( visible_items - 1 ) ;
int r = - 1 ;
for ( int i = 0 ; i < visible_items ; i + + )
{
int item_index = i + list - > scroll_index ;
2007-06-01 02:21:46 +00:00
if ( item_index > = list - > active_count ) ;
//ui_do_image(empty_item_texture, x, y + i * item_height + i * spacing, item_width, item_height);
2007-05-22 15:03:32 +00:00
else
{
server_info * item = & list - > infos [ item_index ] ;
bool clicked = false ;
2007-06-01 02:21:46 +00:00
clicked = ui_do_button ( item , item - > name , 0 , x , y + i * item_height + i * spacing , item_width , item_height , draw_menu_button , ( list - > selected_index = = item_index ) ? ( void * ) 1 : 0 ) ;
2007-05-22 15:03:32 +00:00
char temp [ 64 ] ; // plenty of extra room so we don't get sad :o
sprintf ( temp , " %i/%i " , item - > players , item - > max_players ) ;
2007-06-01 02:21:46 +00:00
ui_do_label ( x + 600 , y + i * item_height + i * spacing , temp , item_height ) ;
ui_do_label ( x + 360 , y + i * item_height + i * spacing , item - > map , item_height ) ;
2007-05-22 15:03:32 +00:00
if ( clicked )
{
r = item_index ;
list - > selected_index = item_index ;
}
}
}
2007-05-28 13:49:44 +00:00
list - > scroll_index = do_scroll_bar ( & list - > scroll_index , x + real_width - 16 , y , real_height , list - > active_count - visible_items , list - > scroll_index ) ;
2007-05-22 15:03:32 +00:00
return r ;
}
2007-06-01 02:21:46 +00:00
static char * read_int ( char * buffer , int * value )
2007-05-22 15:03:32 +00:00
{
* value = buffer [ 0 ] < < 24 ;
* value | = buffer [ 1 ] < < 16 ;
* value | = buffer [ 2 ] < < 8 ;
* value | = buffer [ 3 ] ;
return buffer + 4 ;
}
2007-06-01 02:21:46 +00:00
static char * read_netaddr ( char * buffer , netaddr4 * addr )
2007-05-22 15:03:32 +00:00
{
addr - > ip [ 0 ] = * buffer + + ;
addr - > ip [ 1 ] = * buffer + + ;
addr - > ip [ 2 ] = * buffer + + ;
addr - > ip [ 3 ] = * buffer + + ;
int port ;
buffer = read_int ( buffer , & port ) ;
addr - > port = port ;
return buffer ;
}
2007-06-01 02:21:46 +00:00
static void refresh_list ( server_list * list )
2007-05-22 15:03:32 +00:00
{
netaddr4 addr ;
netaddr4 me ( 0 , 0 , 0 , 0 , 0 ) ;
list - > selected_index = - 1 ;
if ( net_host_lookup ( MASTER_SERVER_ADDRESS , MASTER_SERVER_PORT , & addr ) = = 0 )
{
socket_tcp4 sock ;
sock . open ( & me ) ;
//sock.set_non_blocking();
// try and connect with a timeout of 1 second
if ( sock . connect_non_blocking ( & addr ) )
{
char data [ 256 ] ;
int total_received = 0 ;
int received ;
int master_server_version = - 1 ;
int server_count = - 1 ;
// read header
while ( total_received < 12 & & ( received = sock . recv ( data + total_received , 12 - total_received ) ) > 0 )
total_received + = received ;
// see if we have the header
if ( total_received = = 12 )
{
int signature ;
read_int ( data , & signature ) ;
// check signature
2007-05-27 10:54:33 +00:00
if ( signature = = ' TWSL ' )
2007-05-22 15:03:32 +00:00
{
read_int ( data + 4 , & master_server_version ) ;
read_int ( data + 8 , & server_count ) ;
// TODO: handle master server version O.o
const int server_info_size = 212 ;
list - > active_count = 0 ;
for ( int i = 0 ; i < server_count ; i + + )
{
total_received = 0 ;
// read data for a server
while ( sock . is_connected ( ) & & total_received < server_info_size & & ( received = sock . recv ( data + total_received , server_info_size - total_received ) ) > 0 )
total_received + = received ;
// check if we got enough data
if ( total_received = = server_info_size )
{
char * d = data ;
server_info * info = & list - > infos [ i ] ;
d = read_int ( d , & info - > version ) ;
d = read_netaddr ( d , & info - > address ) ;
//dbg_msg("menu/got_serverinfo", "IP: %i.%i.%i.%i:%i", (int)info->address.ip[0], (int)info->address.ip[1], (int)info->address.ip[2], (int)info->address.ip[3], info->address.port);
d = read_int ( d , & info - > players ) ;
d = read_int ( d , & info - > max_players ) ;
memcpy ( info - > name , d , 128 ) ;
d + = 128 ;
memcpy ( info - > map , d , 64 ) ;
// let's be safe.
info - > name [ 128 ] = 0 ;
info - > map [ 64 ] = 0 ;
+ + list - > active_count ;
}
else
break ;
}
if ( list - > scroll_index > = list - > active_count )
list - > scroll_index = list - > active_count - 1 ;
if ( list - > scroll_index < 0 )
list - > scroll_index = 0 ;
}
}
sock . close ( ) ;
}
}
}
2007-06-01 02:21:46 +00:00
static int screen = 0 ;
2007-06-01 11:08:33 +00:00
static configuration config_copy ;
2007-05-22 15:03:32 +00:00
2007-06-01 02:21:46 +00:00
static int main_screen_render ( netaddr4 * server_address )
{
2007-05-22 15:03:32 +00:00
static server_list list ;
static bool inited = false ;
if ( ! inited )
{
list . info_count = 256 ;
list . scroll_index = 0 ;
list . selected_index = - 1 ;
inited = true ;
refresh_list ( & list ) ;
}
2007-05-28 13:49:44 +00:00
do_server_list ( & list , 20 , 160 , 8 ) ;
2007-05-22 15:03:32 +00:00
2007-05-28 13:49:44 +00:00
static int refresh_button , join_button , quit_button ;
if ( ui_do_button ( & refresh_button , " Refresh " , 0 , 440 , 420 , 170 , 48 , draw_teewars_button ) )
2007-05-22 15:03:32 +00:00
{
refresh_list ( & list ) ;
}
if ( list . selected_index = = - 1 )
{
2007-05-28 13:49:44 +00:00
ui_do_button ( & join_button , " Join " , 0 , 620 , 420 , 128 , 48 , draw_teewars_button , ( void * ) 1 ) ;
2007-05-22 15:03:32 +00:00
}
2007-05-28 13:49:44 +00:00
else if ( ui_do_button ( & join_button , " Join " , 0 , 620 , 420 , 128 , 48 , draw_teewars_button ) )
2007-05-22 15:03:32 +00:00
{
* server_address = list . infos [ list . selected_index ] . address ;
dbg_msg ( " menu/join_button " , " IP: %i.%i.%i.%i:%i " , ( int ) server_address - > ip [ 0 ] , ( int ) server_address - > ip [ 1 ] , ( int ) server_address - > ip [ 2 ] , ( int ) server_address - > ip [ 3 ] , server_address - > port ) ;
return 1 ;
}
2007-05-28 13:49:44 +00:00
if ( ui_do_button ( & quit_button , " Quit " , 0 , 620 , 490 , 128 , 48 , draw_teewars_button ) )
2007-05-22 15:03:32 +00:00
return - 1 ;
2007-06-01 02:21:46 +00:00
static int settings_button ;
if ( ui_do_button ( & settings_button , " Settings " , 0 , 20 , 420 , 170 , 48 , draw_teewars_button ) )
2007-06-01 11:08:33 +00:00
{
config_copy = config ;
2007-06-01 02:21:46 +00:00
screen = 1 ;
2007-06-01 11:08:33 +00:00
}
2007-06-01 02:21:46 +00:00
return 0 ;
}
static int settings_screen_render ( )
{
const float column1_x = 20 ;
const float column2_x = column1_x + 150 ;
const float column3_x = column2_x + 170 ;
const float name_y = 160 ;
const float resolution_y = 200 ;
const float keys_y = 240 ;
// NAME
ui_do_label ( column1_x , name_y , " Name: " , 36 ) ;
2007-06-01 11:08:33 +00:00
ui_do_edit_box ( config_copy . player_name , column2_x , name_y , 300 , 36 , config_copy . player_name , sizeof ( config_copy . player_name ) ) ;
2007-06-01 02:21:46 +00:00
// KEYS
ui_do_label ( column1_x , keys_y , " Keys: " , 36 ) ;
ui_do_label ( column2_x , keys_y + 0 , " Move Left: " , 36 ) ;
2007-06-09 16:21:28 +00:00
config_set_key_move_left ( & config_copy , ui_do_key_reader ( & config_copy . key_move_left , column3_x , keys_y + 0 , 150 , 40 , config_copy . key_move_left ) ) ;
2007-06-01 02:21:46 +00:00
ui_do_label ( column2_x , keys_y + 40 , " Move Right: " , 36 ) ;
2007-06-09 16:21:28 +00:00
config_set_key_move_right ( & config_copy , ui_do_key_reader ( & config_copy . key_move_right , column3_x , keys_y + 40 , 150 , 40 , config_copy . key_move_right ) ) ;
2007-06-01 02:21:46 +00:00
ui_do_label ( column2_x , keys_y + 80 , " Jump: " , 36 ) ;
2007-06-09 16:21:28 +00:00
config_set_key_jump ( & config_copy , ui_do_key_reader ( & config_copy . key_jump , column3_x , keys_y + 80 , 150 , 40 , config_copy . key_jump ) ) ;
2007-06-01 02:21:46 +00:00
ui_do_label ( column2_x , keys_y + 120 , " Fire: " , 36 ) ;
2007-06-09 16:21:28 +00:00
config_set_key_fire ( & config_copy , ui_do_key_reader ( & config_copy . key_fire , column3_x , keys_y + 120 , 150 , 40 , config_copy . key_fire ) ) ;
2007-06-01 02:21:46 +00:00
ui_do_label ( column2_x , keys_y + 160 , " Hook: " , 36 ) ;
2007-06-09 16:21:28 +00:00
config_set_key_hook ( & config_copy , ui_do_key_reader ( & config_copy . key_hook , column3_x , keys_y + 160 , 150 , 40 , config_copy . key_hook ) ) ;
2007-06-01 02:21:46 +00:00
// RESOLUTION
static char resolutions [ ] [ 128 ] =
{
" 400x300 " ,
" 640x480 " ,
" 800x600 " ,
" 1024x764 " ,
" 1280x1024 " ,
} ;
2007-06-01 11:08:33 +00:00
static int res [ ] [ 2 ] =
{
{ 400 , 300 } ,
{ 640 , 480 } ,
{ 800 , 600 } ,
{ 1024 , 768 } ,
{ 1280 , 1024 } ,
} ;
2007-06-01 02:21:46 +00:00
static int selected_index = 0 ;
ui_do_label ( column1_x , resolution_y , " Resolution: " , 36 ) ;
2007-06-09 16:21:28 +00:00
selected_index = ui_do_combo_box ( & selected_index , column2_x , resolution_y , 180 , ( char * * ) resolutions , 5 , selected_index ) ;
2007-06-01 02:21:46 +00:00
2007-06-01 11:17:10 +00:00
config_set_screen_width ( & config_copy , res [ selected_index ] [ 0 ] ) ;
config_set_screen_height ( & config_copy , res [ selected_index ] [ 1 ] ) ;
2007-06-01 11:08:33 +00:00
// SAVE BUTTON
static int save_button ;
if ( ui_do_button ( & save_button , " Save " , 0 , 482 , 490 , 128 , 48 , draw_teewars_button ) )
{
config = config_copy ;
2007-06-01 12:02:27 +00:00
config_save ( " teewars.cfg " ) ;
2007-06-01 11:08:33 +00:00
screen = 0 ;
}
// CANCEL BUTTON
static int cancel_button ;
if ( ui_do_button ( & cancel_button , " Cancel " , 0 , 620 , 490 , 150 , 48 , draw_teewars_button ) )
2007-06-01 02:21:46 +00:00
screen = 0 ;
2007-05-22 15:03:32 +00:00
return 0 ;
}
2007-06-01 02:21:46 +00:00
static int menu_render ( netaddr4 * server_address )
{
// background color
gfx_clear ( 89 / 255.f , 122 / 255.f , 0.0 ) ;
// GUI coordsys
gfx_mapscreen ( 0 , 0 , 800.0f , 600.0f ) ;
static int64 start = time_get ( ) ;
float t = double ( time_get ( ) - start ) / double ( time_freq ( ) ) ;
draw_scrolling_background ( background_texture , 800 , 600 , t * 0.01 ) ;
ui_do_image ( teewars_banner_texture , 140 , 20 , 512 , 128 ) ;
ui_do_label ( 20.0f , 600.0f - 40.0f , " Version: " TEEWARS_VERSION , 36 ) ;
if ( screen = = 0 )
return main_screen_render ( server_address ) ;
else
return settings_screen_render ( ) ;
}
2007-05-22 15:03:32 +00:00
void modmenu_init ( )
{
keys : : enable_char_cache ( ) ;
keys : : enable_key_cache ( ) ;
2007-05-27 00:47:07 +00:00
current_font - > font_texture = gfx_load_texture ( " data/big_font.png " ) ;
2007-05-22 15:03:32 +00:00
2007-06-01 02:21:46 +00:00
background_texture = gfx_load_texture ( " data/gui_bg.png " ) ;
2007-05-27 18:14:24 +00:00
gui_tileset_texture = gfx_load_texture ( " data/gui/gui_widgets.png " ) ;
2007-05-27 00:47:07 +00:00
teewars_banner_texture = gfx_load_texture ( " data/gui_logo.png " ) ;
2007-05-22 15:03:32 +00:00
music_menu = snd_load_wav ( " data/audio/Music_Menu.wav " ) ;
}
void modmenu_shutdown ( )
{
}
2007-06-01 02:21:46 +00:00
int modmenu_render ( void * ptr )
2007-05-22 15:03:32 +00:00
{
static int mouse_x = 0 ;
static int mouse_y = 0 ;
if ( music_menu_id = = - 1 )
{
dbg_msg ( " menu " , " no music is playing, so let's play some tunes! " ) ;
music_menu_id = snd_play ( music_menu , SND_LOOP ) ;
}
netaddr4 * server_address = ( netaddr4 * ) ptr ;
// handle mouse movement
float mx , my , mwx , mwy ;
{
int rx , ry ;
inp_mouse_relative ( & rx , & ry ) ;
mouse_x + = rx ;
mouse_y + = ry ;
if ( mouse_x < 0 ) mouse_x = 0 ;
if ( mouse_y < 0 ) mouse_y = 0 ;
if ( mouse_x > gfx_screenwidth ( ) ) mouse_x = gfx_screenwidth ( ) ;
if ( mouse_y > gfx_screenheight ( ) ) mouse_y = gfx_screenheight ( ) ;
// update the ui
2007-05-28 13:49:44 +00:00
mx = ( mouse_x / ( float ) gfx_screenwidth ( ) ) * 800.0f ;
my = ( mouse_y / ( float ) gfx_screenheight ( ) ) * 600.0f ;
2007-05-22 15:03:32 +00:00
mwx = mx * 3.0f ; // adjust to zoom and offset
mwy = mx * 3.0f ; // adjust to zoom and offset
int buttons = 0 ;
if ( inp_mouse_button_pressed ( 0 ) ) buttons | = 1 ;
if ( inp_mouse_button_pressed ( 1 ) ) buttons | = 2 ;
if ( inp_mouse_button_pressed ( 2 ) ) buttons | = 4 ;
ui_update ( mx , my , mx * 3.0f , my * 3.0f , buttons ) ;
}
2007-06-01 02:21:46 +00:00
//int r = menu_render(server_address, str, max_len);
int r = menu_render ( server_address ) ;
2007-05-22 15:03:32 +00:00
// render butt ugly mouse cursor
gfx_texture_set ( - 1 ) ;
gfx_quads_begin ( ) ;
gfx_quads_setcolor ( 0 , 0 , 0 , 1 ) ;
gfx_quads_draw_freeform ( mx , my , mx , my ,
2007-05-28 13:49:44 +00:00
mx + 14 , my ,
mx , my + 14 ) ;
2007-05-22 15:03:32 +00:00
gfx_quads_setcolor ( 1 , 1 , 1 , 1 ) ;
gfx_quads_draw_freeform ( mx + 1 , my + 1 , mx + 1 , my + 1 ,
2007-05-28 13:49:44 +00:00
mx + 10 , my + 1 ,
mx + 1 , my + 10 ) ;
2007-05-22 15:03:32 +00:00
gfx_quads_end ( ) ;
if ( r )
{
snd_stop ( music_menu_id ) ;
music_menu_id = - 1 ;
}
keys : : clear_char ( ) ;
keys : : clear_key ( ) ;
return r ;
}