diff --git a/Source/FreeCS-CE.prj b/Source/FreeCS-CE.prj index 719cb093..f3ffcd11 100755 --- a/Source/FreeCS-CE.prj +++ b/Source/FreeCS-CE.prj @@ -1,5 +1,5 @@ - + @@ -65,6 +65,7 @@ + @@ -110,15 +111,9 @@ - - - - - - - - - - + + + + diff --git a/Source/Menu/Defs.h b/Source/Menu/Defs.h index fcb404ea..85a672fb 100755 --- a/Source/Menu/Defs.h +++ b/Source/Menu/Defs.h @@ -28,6 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. var vector vVideoSize; var vector vMenuOffset; +var vector autocvar_menu_color = '1 0.59 0.19'; var vector vMousePos; var float fInputKeyCode; @@ -35,9 +36,18 @@ var float fInputKeyASCII; var float fInputKeyDown; var float fMouseClick; var float fButtonAlpha[8]; +var float fScrollWheel; + +enum { + SCROLL_NONE, + SCROLL_UP, + SCROLL_DOWN +}; var int iMenuActive; +var int iScrollbarHold; // Because of this, don't put more than one scrollbar per screen :) + float frametime; float fLastTime; @@ -47,6 +57,9 @@ int iMapCount; enum { MENU_MAIN, + MENU_MULTIPLAYER, + MENU_MULTIPLAYER_CREATE, + MENU_MULTIPLAYER_OPTIONS, MENU_QUIT }; @@ -121,4 +134,7 @@ enum { BTN_DEACTIVATE, BTN_SPECTATEGAME, BTN_SPECTATEGAMES -}; \ No newline at end of file +}; + +void Menu_SetClipArea( vector vPosition, vector vRegion ); +void Menu_ResetClipArea( void ); \ No newline at end of file diff --git a/Source/Menu/Draw.c b/Source/Menu/Draw.c index dd236e9a..b2b39608 100755 --- a/Source/Menu/Draw.c +++ b/Source/Menu/Draw.c @@ -36,11 +36,8 @@ Responsible for the fancy menu background ================= */ void m_drawback( void ) { - if ( clientstate() == 2 ) { - drawfill( '0 0', vVideoSize, '0 0 0', 0.75f ); - } else { - drawpic( vMenuOffset, "gfx/shell/splash", '640 480', '1 1 1', 1.0f, 0 ); - } + drawfill( '0 0', vVideoSize, '0 0 0', 0.75f ); + drawpic( vMenuOffset, "gfx/shell/splash", '640 480', '1 1 1', 1.0f, 0 ); } /* @@ -59,6 +56,7 @@ void m_draw( vector vScreenSize ) { vVideoSize = vScreenSize; vMenuOffset_x = vVideoSize_x / 2 - 320; vMenuOffset_y = vVideoSize_y / 2 - 240; + Menu_ResetClipArea(); } // we have to create frametime ourselves because menuqc is primitive @@ -73,6 +71,10 @@ void m_draw( vector vScreenSize ) { if ( iMenu == MENU_MAIN ) { Menu_Main(); + } else if ( iMenu == MENU_MULTIPLAYER ) { + Menu_Multiplayer(); + } else if ( iMenu == MENU_MULTIPLAYER_CREATE ) { + Menu_Multiplayer_Create(); } else if ( iMenu == MENU_QUIT ) { Menu_Quit(); } diff --git a/Source/Menu/Init.c b/Source/Menu/Init.c index c1e8a6ae..7f1ae0b3 100755 --- a/Source/Menu/Init.c +++ b/Source/Menu/Init.c @@ -38,6 +38,8 @@ void m_init( void ) { } search_end( shMaps ); + + Menu_ResetClipArea(); } /* diff --git a/Source/Menu/Input.c b/Source/Menu/Input.c index ba8501ed..2496db90 100755 --- a/Source/Menu/Input.c +++ b/Source/Menu/Input.c @@ -18,6 +18,10 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +// Temporary state +var vector vMenuClickMins; +var vector vMenuClickMaxs; + /* ================= Menu_InputCheckMouse @@ -25,26 +29,48 @@ Menu_InputCheckMouse Checks a specified region and returns TRUE if the mouse is above it. ================= */ -int Menu_InputCheckMouse( vector vPos, vector vReg ) { +int Menu_InputCheckMouse( vector vPosition, vector vRegion ) { vector vSMins, vSMaxs; - vSMins = vPos; - vSMaxs = vPos; - vSMins_x = vPos_x; - vSMaxs_y = vPos_y - 1; - - vSMaxs_x = vPos_x + vReg_x; - vSMaxs_y = vPos_y + vReg_y; - - if ( vMousePos_x >= vSMins_x && vMousePos_x <= vSMaxs_x ) { - if ( vMousePos_y >= vSMins_y && vMousePos_y <= vSMaxs_y ) { - return TRUE; + // Some elements will be blocked (scrolling lists) outside of this region + if ( vMousePos_x >= vMenuClickMins_x && vMousePos_x <= vMenuClickMaxs_x ) { + if ( vMousePos_y >= vMenuClickMins_y && vMousePos_y <= vMenuClickMaxs_y ) { + vSMins = vSMaxs = vPosition; + vSMaxs_y = vPosition_y - 1; + + vSMaxs_x = vPosition_x + vRegion_x; + vSMaxs_y = vPosition_y + vRegion_y; + + if ( vMousePos_x >= vSMins_x && vMousePos_x <= vSMaxs_x ) { + if ( vMousePos_y >= vSMins_y && vMousePos_y <= vSMaxs_y ) { + return TRUE; + } + } } } return FALSE; } +void Menu_SetClipArea( vector vPosition, vector vRegion ) { + vPosition += vMenuOffset; + vMenuClickMins = vPosition; + vMenuClickMaxs = vPosition; + vMenuClickMins_x = vPosition_x; + vMenuClickMaxs_y = vPosition_y - 1; + + vMenuClickMaxs_x = vPosition_x + vRegion_x; + vMenuClickMaxs_y = vPosition_y + vRegion_y; + + drawsetcliparea( vPosition_x, vPosition_y, vRegion_x, vRegion_y ); +} + +void Menu_ResetClipArea( void ) { + vMenuClickMins = vMenuOffset; + vMenuClickMaxs = vMenuOffset + '640 480'; + drawresetcliparea(); +} + /* ================= Menu_InputEvent @@ -64,11 +90,18 @@ float Menu_InputEvent( float fEventType, float fKey, float fCharacter, float fDe fInputKeyDown = 1; } + if ( fKey == K_MWHEELDOWN ) { + fScrollWheel = SCROLL_DOWN; + } else if ( fKey == K_MWHEELUP ) { + fScrollWheel = SCROLL_UP; + } + fInputKeyCode = fKey; fInputKeyASCII = fCharacter; } else if ( fEventType == IE_KEYUP ) { if ( fKey == K_MOUSE1 ) { fMouseClick = 0; + iScrollbarHold = FALSE; } else { fInputKeyDown = 0; } diff --git a/Source/Menu/MenuMain.c b/Source/Menu/MenuMain.c index 09aff56b..139e8858 100755 --- a/Source/Menu/MenuMain.c +++ b/Source/Menu/MenuMain.c @@ -22,6 +22,9 @@ void Menu_Main( void ) { static void Main_ButtonConsole( void ) { localcmd( "toggleconsole\n" ); } + static void Main_ButtonMultiplayer( void ) { + iMenu = MENU_MULTIPLAYER; + } static void Main_ButtonQuit( void ) { iMenu = MENU_QUIT; } @@ -29,7 +32,7 @@ void Menu_Main( void ) { Object_Button( '72 188', BTN_CONSOLE, Main_ButtonConsole, fButtonAlpha[0] ); Object_Button( '72 272', BTN_CONFIG, __NULL__, fButtonAlpha[1] ); - Object_Button( '72 328', BTN_MULTIPLAYER, __NULL__, fButtonAlpha[2] ); + Object_Button( '72 328', BTN_MULTIPLAYER, Main_ButtonMultiplayer, fButtonAlpha[2] ); Object_Button( '72 356', BTN_CUSTOMGAME, __NULL__, fButtonAlpha[3] ); Object_Button( '72 384', BTN_README, __NULL__, fButtonAlpha[4] ); Object_Button( '72 412', BTN_VISITWEB, __NULL__, fButtonAlpha[5] ); @@ -46,7 +49,7 @@ void Menu_Quit( void ) { } Object_Frame( '192 192', '256 96' ); - drawstring( vMenuOffset + '200 216', "FREECS_QUITMSG", '8 8', MENU_FGCOLOR, 1.0f, 0 ); + Object_Label( '200 216', "FREECS_QUITMSG", '8 8' ); Object_Button( '200 248', BTN_QUIT, Quit_Exit, fButtonAlpha[0] ); Object_Button_Right( '440 248', BTN_CANCEL, Quit_Cancel, fButtonAlpha[1] ); diff --git a/Source/Menu/MenuMultiplayer.c b/Source/Menu/MenuMultiplayer.c new file mode 100755 index 00000000..5d37144d --- /dev/null +++ b/Source/Menu/MenuMultiplayer.c @@ -0,0 +1,207 @@ +/* +FreeCS Project +Copyright (C) 2016, 2017 Marco "eukara" Hladik + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +// Server fields! +float fldName; +float fldAddress; +float fldPing; +float fldPlayers; +float fldMaxplayers; +float fldMap; +float fldTimelimit; +float fldFraglimit; +float fServerClickTime; + +void Menu_Multiplayer_Connect( int iServerID ) { + if ( gethostcachenumber( fldMaxplayers, iServerID ) <= 0 ) { + return; + } + + if ( iServerID >= 0 ) { + localcmd( sprintf( "connect %s\n", gethostcachestring( fldAddress, iServerID ) ) ); + m_hide(); + } +} + +int Menu_Multiplayer_Find_Item( vector vPosition, int i, __inout int iSelected ) { + float fItemAlpha = 1.0f; + + vPosition += vMenuOffset; + + if ( Menu_InputCheckMouse( [ vPosition_x, vPosition_y ], [ 397, 8 ] ) == TRUE ) { + if ( fMouseClick == TRUE ) { + if ( iSelected != i ) { + iSelected = i; + fInputKeyCode = 0; + fMouseClick = FALSE; + fServerClickTime = time + 0.2; + } else { + if ( fServerClickTime > time ) { + Menu_Multiplayer_Connect( i ); + } + iSelected = -2; + fInputKeyCode = 0; + fMouseClick = FALSE; + } + } + } else { + fItemAlpha = 0.8; + } + + if ( gethostcachenumber( fldPing, i ) == -1 ) { + return FALSE; + } + + if ( iSelected == i ) { + drawfill( [ vPosition_x, vPosition_y - 1 ], [ 397, 10 ], '1 1 1', 0.5, 2 ); + drawstring( [vPosition_x + 8, vPosition_y], sprintf( "%.25s", gethostcachestring( fldName, i ) ), '8 8 0', '1 1 1', 1.0f, FALSE ); + drawstring( [vPosition_x + 218, vPosition_y], sprintf( "%.10s", gethostcachestring( fldMap, i ) ), '8 8 0', '1 1 1', 1.0f, FALSE ); + drawstring( [vPosition_x + 298, vPosition_y], sprintf( "%d/%d", gethostcachenumber( fldPlayers, i ), gethostcachenumber( fldMaxplayers, i ) ), '8 8 0', '1 1 1', 1.0f, FALSE ); + drawstring( [vPosition_x + 362, vPosition_y], sprintf( "%.3s", ftos( gethostcachenumber( fldPing, i ) ) ), '8 8 0', '1 1 1', 1.0f, FALSE ); + } else { + drawstring( [vPosition_x + 8, vPosition_y], sprintf( "^3%.25s", gethostcachestring( fldName, i ) ), '8 8 0', '1 1 1', fItemAlpha, FALSE ); + drawstring( [vPosition_x + 218, vPosition_y], sprintf( "%.10s", gethostcachestring( fldMap, i ) ), '8 8 0', '1 1 1', fItemAlpha, FALSE ); + drawstring( [vPosition_x + 298, vPosition_y], sprintf( "%d/%d", gethostcachenumber( fldPlayers, i ), gethostcachenumber( fldMaxplayers, i ) ), '8 8 0', '1 1 1', fItemAlpha, FALSE ); + drawstring( [vPosition_x + 362, vPosition_y], sprintf( "%.3s", ftos( gethostcachenumber( fldPing, i ) ) ), '8 8 0', '1 1 1', fItemAlpha, FALSE ); + } + + return TRUE; +} + +void Menu_Multiplayer( void ) { + static int iSelectedServer = -1; + static int iScrollServer; + static int iServersTotal; + + static void Multiplayer_ButtonCreate( void ) { + iMenu = MENU_MULTIPLAYER_CREATE; + } + static void Multiplayer_ButtonRefresh( void ) { + refreshhostcache(); + resorthostcache(); + } + static void Multiplayer_ButtonDone( void ) { + iMenu = MENU_MAIN; + } + + // Initialize it on the first run + if ( iSelectedServer == -1 ) { + localcmd( "com_protocolname FTE-Quake\n" ); + //clear the filter + resethostcachemasks(); + //sethostcachemaskstring( 0, gethostcacheindexforkey( "gamedir" ), "freecs", SLIST_TEST_EQUAL ); + sethostcachesort( gethostcacheindexforkey( "ping" ), FALSE ); + refreshhostcache(); + resorthostcache(); + iSelectedServer = 0; + } + + fldName = gethostcacheindexforkey("name"); + fldAddress = gethostcacheindexforkey("cname"); + fldPing = gethostcacheindexforkey("ping"); + fldPlayers = gethostcacheindexforkey("numhumans"); + fldMaxplayers = gethostcacheindexforkey("maxplayers"); + fldMap = gethostcacheindexforkey("map"); + fldTimelimit = gethostcacheindexforkey("timelimit"); + fldFraglimit = gethostcacheindexforkey("fraglimit"); + + iServersTotal = gethostcachevalue( SLIST_HOSTCACHEVIEWCOUNT ); + + Menu_SetClipArea( '32 148', '164 160' ); + Object_Button( '32 148', BTN_JOINGAME, __NULL__, fButtonAlpha[0] ); + Object_Button( '32 180', BTN_CREATE, Multiplayer_ButtonCreate, fButtonAlpha[1] ); + Object_Button( '32 212', BTN_GAMEINFO, __NULL__, fButtonAlpha[2] ); + Object_Button( '32 244', BTN_REFRESHLIST, Multiplayer_ButtonRefresh, fButtonAlpha[3] ); + Object_Button( '32 276', BTN_DONE, Multiplayer_ButtonDone, fButtonAlpha[4] ); + Menu_ResetClipArea(); + + Object_Frame( '196 140', '404 308' ); + Object_Scrollbar( '604 140', 308, iScrollServer ); + + Object_Label( '208 124', "Game", '8 8' ); + Object_Label( '418 124', "Map", '8 8' ); + Object_Label( '498 124', "Players", '8 8' ); + Object_Label( '562 124', "Ping", '8 8' ); + + Menu_SetClipArea( '196 141', '404 306' ); + vector vListPos = '200 145'; + vListPos_y -= fabs( ( ( iServersTotal - 8 ) * 10 ) * ( iScrollServer / 308 ) ); + for ( float i = 0; i < iServersTotal; i++ ) { + if ( Menu_Multiplayer_Find_Item( vListPos, i, iSelectedServer ) == TRUE ) { + vListPos_y += 10; + } else { + break; + } + } + Menu_ResetClipArea(); +} + +void Menu_Multiplayer_Create( void ) { + static int iSelectedMap; + static int iScrollMap; + + static void Create_ListMap( vector vPosition, int iIndex ) { + float fAlpha = 0.8; + vPosition += vMenuOffset; + + if ( Menu_InputCheckMouse( vPosition, '182 10' ) == TRUE ) { + if ( fMouseClick == TRUE ) { + iSelectedMap = iIndex; + fMouseClick = FALSE; + } + fAlpha = 1.0f; + } + + if ( iSelectedMap == iIndex ) { + drawstring( vPosition, sMapList[ iIndex ], '8 8', '1 1 1', 1.0f, 0 ); + } else { + drawstring( vPosition, sMapList[ iIndex ], '8 8', '0.9 0.9 0.9', fAlpha, 0 ); + } + } + static void Create_ButtonAdvanced( void ) { + // Advanced options + iMenu = MENU_MULTIPLAYER_OPTIONS; + } + static void Create_ButtonOK( void ) { + // Start server + localcmd( sprintf( "map %s\n", sMapList[ iSelectedMap ] ) ); + } + static void Create_ButtonCancel( void ) { + iMenu = MENU_MULTIPLAYER; + } + + Object_Button( '32 148', BTN_ADVOPTIONS, Create_ButtonAdvanced, fButtonAlpha[0] ); + Object_Button( '32 180', BTN_OK, Create_ButtonOK, fButtonAlpha[1] ); + Object_Button( '32 212', BTN_CANCEL, Create_ButtonCancel, fButtonAlpha[2] ); + + Object_Label( '384 148', "Maps:", '8 8' ); + Object_Frame( '384 164', '190 288' ); + Object_Scrollbar( '576 164', 288, iScrollMap ); + + // Maplist + vector vListPos = '392 172'; + Menu_SetClipArea( '386 166', '188 286' ); + vListPos_y -= fabs( ( ( iMapCount - 21 ) * 10 ) * ( iScrollMap / 288 ) ); + for ( int i = 0; i < iMapCount; i++ ) { + Create_ListMap( vListPos, i ); + vListPos_y += 10; + } + Menu_ResetClipArea(); +} \ No newline at end of file diff --git a/Source/Menu/Objects.c b/Source/Menu/Objects.c index eb8868ea..f05ae3bf 100755 --- a/Source/Menu/Objects.c +++ b/Source/Menu/Objects.c @@ -90,16 +90,15 @@ string sButtonLabels[ MENU_BUTTONS ] = { "BTN_SPECTATEGAMES" }; -#define MENU_FGCOLOR '1 0.59 0.19' +#define autocvar_menu_color '1 0.59 0.19' /* ================= -drawmenupic +Object_Button -Wrapper for drawpic that cares about resolution and scales. +Used for the (used to be) bitmap buttons in the menu ================= */ - void Object_Button( vector vPosition, int iButtonID, void() vFunction, __inout float fAlpha ) { static int iLastButton = -1; @@ -127,25 +126,102 @@ void Object_Button( vector vPosition, int iButtonID, void() vFunction, __inout f } } - drawstring( vPosition, sButtonLabels[ iButtonID ], '16 16', MENU_FGCOLOR, 1.0f, 0 ); + drawstring( vPosition, sButtonLabels[ iButtonID ], '16 16', autocvar_menu_color, 1.0f, 0 ); drawstring( vPosition, sButtonLabels[ iButtonID ], '16 16', '1 1 1', fAlpha, 0 ); } +/* +================= +Object_Button_Right + +A right-aligned version of Object_Button +================= +*/ void Object_Button_Right( vector vPosition, int iButtonID, void() vFunction, __inout float fAlpha ) { vPosition_x -= stringwidth( sButtonLabels[ iButtonID ], TRUE, '16 16' ); Object_Button( vPosition, iButtonID, vFunction, fAlpha ); } -// Draws window with outline, border and title -void Object_Frame( vector vPos, vector vSize ) { - vPos += vMenuOffset; +/* +================= +Object_Frame + +A filled "window" of sorts +================= +*/ +void Object_Frame( vector vPosition, vector vSize ) { + vPosition += vMenuOffset; // Draw the background - drawfill( vPos, vSize, '0 0 0', 1.0f ); + drawfill( vPosition, vSize, '0 0 0', 1.0f ); - drawfill( vPos, [vSize_x, 1], MENU_FGCOLOR, 1.0f ); // Top - drawfill( [vPos_x, vPos_y + vSize_y], [vSize_x, 1], MENU_FGCOLOR, 1.0f ); // Bottom + drawfill( vPosition, [vSize_x, 1], autocvar_menu_color, 1.0f ); // Top + drawfill( [vPosition_x, vPosition_y + vSize_y], [vSize_x, 1], autocvar_menu_color, 1.0f ); // Bottom - drawfill( vPos, [1, vSize_y], MENU_FGCOLOR, 1.0f ); // Left - drawfill( [vPos_x + vSize_x, vPos_y], [1, vSize_y], MENU_FGCOLOR, 1.0f ); // Right + drawfill( vPosition, [1, vSize_y], autocvar_menu_color, 1.0f ); // Left + drawfill( [vPosition_x + vSize_x, vPosition_y], [1, vSize_y + 1], autocvar_menu_color, 1.0f ); // Right } + +/* +================= +Object_Label + +A label in a cvar driven color scheme +================= +*/ +void Object_Label( vector vPosition, string sLabel, vector vSize ) { + vPosition += vMenuOffset; + drawstring( vPosition, sLabel, vSize, autocvar_menu_color, 1.0f, 0 ); +} + +/* +================= +Object_Label_Right + +A right-aligned version of Object_Label +================= +*/ +void Object_Label_Right( vector vPosition, string sLabel, vector vSize ) { + vPosition_x -= stringwidth( sLabel, TRUE, vSize ); + Object_Label( vPosition, sLabel, vSize ); +} + +/* +================= +Object_Scrollbar + +A scrollbar, for different types of purposes. +Note: Only have one at a time. +================= +*/ +void Object_Scrollbar( vector vPosition, int iHeight, __inout int iProgress ) { + Object_Frame( vPosition, [ 16, iHeight ] ); + + vPosition += vMenuOffset; + iHeight -= 16; + if ( ( iScrollbarHold == TRUE ) || ( Menu_InputCheckMouse( [vPosition_x, vPosition_y + iProgress ], '16 16' ) == TRUE ) ) { + if ( fMouseClick == TRUE ) { + iProgress = ( vMousePos_y - vPosition_y ) - 8; + iScrollbarHold = TRUE; + } + } + + if ( fScrollWheel == SCROLL_DOWN ) { + iProgress += 2; + fScrollWheel = SCROLL_NONE; + } else if ( fScrollWheel == SCROLL_UP ) { + iProgress -= 2; + fScrollWheel = SCROLL_NONE; + } + + if ( iProgress < 0 ) { + iProgress = 0; + } else if ( iProgress > iHeight ) { + iProgress = iHeight; + } + + iHeight += 16; + + drawfill( [vPosition_x, vPosition_y + iProgress], [ 16, 16 ], autocvar_menu_color, 1.0f ); +} + diff --git a/Source/Menu/progs.src b/Source/Menu/progs.src index 642847f3..6e041de3 100755 --- a/Source/Menu/progs.src +++ b/Source/Menu/progs.src @@ -12,5 +12,6 @@ Init.c Input.c Objects.c MenuMain.c +MenuMultiplayer.c Draw.c #endlist diff --git a/freecs/csprogs.dat b/freecs/csprogs.dat index 95e928e5..27a21aa7 100644 Binary files a/freecs/csprogs.dat and b/freecs/csprogs.dat differ diff --git a/freecs/default.cfg b/freecs/default.cfg index b8fd4783..2863d15a 100755 --- a/freecs/default.cfg +++ b/freecs/default.cfg @@ -60,13 +60,13 @@ hostname "FreeCS Server" seta vid_conautoscale "1" seta snd_device "sdl" -seta r_polygonoffset_submodel_offset 0 -seta r_polygonoffset_submodel_factor 0 -seta r_fullbrightSkins 0 -seta r_fb_models 0 -seta con_logcenterprint 0 -seta v_contentblend 0 -seta com_nogamedirnativecode 0 - +seta r_polygonoffset_submodel_offset "0" +seta r_polygonoffset_submodel_factor "0" +seta r_fullbrightSkins "0" +seta r_fb_models "0" +seta con_logcenterprint "0" +seta v_contentblend "0" +seta com_nogamedirnativecode "0" +seta cl_cursor_scale "1" seta r_shadow_realtime_world_shadows "0" seta r_shadow_realtime_dlight_shadows "0" diff --git a/freecs/gfx/menuchars.tga b/freecs/gfx/menuchars.tga new file mode 100755 index 00000000..b68b86d5 Binary files /dev/null and b/freecs/gfx/menuchars.tga differ diff --git a/freecs/menu.dat b/freecs/menu.dat index adaf0364..f539d25e 100755 Binary files a/freecs/menu.dat and b/freecs/menu.dat differ diff --git a/freecs/progs.dat b/freecs/progs.dat index 6a4c2b88..af809926 100644 Binary files a/freecs/progs.dat and b/freecs/progs.dat differ