2006-04-13 20:47:06 +00:00
// On-screen Display (ie. console)
// for the Build Engine
// by Jonathon Fowler (jonof@edgenetwk.com)
# include "build.h"
# include "osd.h"
# include "compat.h"
# include "baselayer.h"
2008-06-30 07:30:48 +00:00
# include "cache1d.h"
2006-04-13 20:47:06 +00:00
2008-06-30 00:18:59 +00:00
symbol_t * symbols = NULL ;
2006-04-13 20:47:06 +00:00
static symbol_t * addnewsymbol ( const char * name ) ;
static symbol_t * findsymbol ( const char * name , symbol_t * startingat ) ;
static symbol_t * findexactsymbol ( const char * name ) ;
2008-03-23 00:06:42 +00:00
// static int _validate_osdlines(void *);
2006-04-13 20:47:06 +00:00
static int _internal_osdfunc_listsymbols ( const osdfuncparm_t * ) ;
static int _internal_osdfunc_help ( const osdfuncparm_t * ) ;
2008-06-29 22:37:30 +00:00
static int _internal_osdfunc_alias ( const osdfuncparm_t * ) ;
2008-03-23 00:06:42 +00:00
// static int _internal_osdfunc_dumpbuildinfo(const osdfuncparm_t *);
// static int _internal_osdfunc_setrendermode(const osdfuncparm_t *);
2006-04-13 20:47:06 +00:00
static int white = - 1 ; // colour of white (used by default display routines)
static void _internal_drawosdchar ( int , int , char , int , int ) ;
static void _internal_drawosdstr ( int , int , char * , int , int , int ) ;
static void _internal_drawosdcursor ( int , int , int , int ) ;
static int _internal_getcolumnwidth ( int ) ;
static int _internal_getrowheight ( int ) ;
static void _internal_clearbackground ( int , int ) ;
static int _internal_gettime ( void ) ;
static void _internal_onshowosd ( int ) ;
2007-03-04 19:52:57 +00:00
# define TEXTSIZE 32768
2006-04-13 20:47:06 +00:00
// history display
static char osdtext [ TEXTSIZE ] ;
2006-12-11 04:38:10 +00:00
static char osdversionstring [ 32 ] ;
static int osdversionstringlen ;
2007-04-17 05:54:12 +00:00
static int osdversionstringshade ;
static int osdversionstringpal ;
2006-04-13 20:47:06 +00:00
static int osdpos = 0 ; // position next character will be written at
static int osdlines = 1 ; // # lines of text in the buffer
static int osdrows = 20 ; // # lines of the buffer that are visible
2006-12-11 21:18:21 +00:00
static int osdrowscur = - 1 ;
2006-12-11 03:06:49 +00:00
static int osdscroll = 0 ;
2006-04-13 20:47:06 +00:00
static int osdcols = 60 ; // width of onscreen display in text columns
static int osdmaxrows = 20 ; // maximum number of lines which can fit on the screen
static int osdmaxlines = TEXTSIZE / 60 ; // maximum lines which can fit in the buffer
static char osdvisible = 0 ; // onscreen display visible?
2006-12-11 03:32:43 +00:00
static char osdinput = 0 ; // capture input?
2006-04-13 20:47:06 +00:00
static int osdhead = 0 ; // topmost visible line number
static BFILE * osdlog = NULL ; // log filehandle
2008-02-24 00:46:57 +00:00
static char osdinited = 0 ; // text buffer initialized?
2006-12-11 03:06:49 +00:00
static int osdkey = 0x29 ; // tilde shows the osd
2006-04-13 20:47:06 +00:00
static int keytime = 0 ;
2007-12-12 17:42:14 +00:00
static int osdscrtime = 0 ;
2006-04-13 20:47:06 +00:00
// command prompt editing
# define EDITLENGTH 512
static int osdovertype = 0 ; // insert (0) or overtype (1)
static char osdeditbuf [ EDITLENGTH + 1 ] ; // editing buffer
static char osdedittmp [ EDITLENGTH + 1 ] ; // editing buffer temporary workspace
static int osdeditlen = 0 ; // length of characters in edit buffer
static int osdeditcursor = 0 ; // position of cursor in edit buffer
static int osdeditshift = 0 ; // shift state
static int osdeditcontrol = 0 ; // control state
static int osdeditcaps = 0 ; // capslock
static int osdeditwinstart = 0 ;
static int osdeditwinend = 60 - 1 - 3 ;
# define editlinewidth (osdcols-1-3)
// command processing
# define HISTORYDEPTH 16
static int osdhistorypos = - 1 ; // position we are at in the history buffer
static int osdhistorybuf [ HISTORYDEPTH ] [ EDITLENGTH + 1 ] ; // history strings
static int osdhistorysize = 0 ; // number of entries in history
// execution buffer
// the execution buffer works from the command history
static int osdexeccount = 0 ; // number of lines from the head of the history buffer to execute
2008-07-01 10:31:03 +00:00
static int osdcompletionstyle = 0 ;
2006-04-13 20:47:06 +00:00
2008-01-04 01:04:35 +00:00
// maximal log line count
int logcutoff = 120000 ;
int linecnt ;
2008-06-30 07:30:48 +00:00
int osdexecscript = 0 ;
2008-01-04 01:04:35 +00:00
2006-04-13 20:47:06 +00:00
// presentation parameters
static int osdpromptshade = 0 ;
static int osdpromptpal = 0 ;
static int osdeditshade = 0 ;
static int osdeditpal = 0 ;
static int osdtextshade = 0 ;
static int osdtextpal = 0 ;
2008-03-23 00:06:42 +00:00
/* static int osdcursorshade=0;
static int osdcursorpal = 0 ; */
2006-04-13 20:47:06 +00:00
// application callbacks
static void ( * drawosdchar ) ( int , int , char , int , int ) = _internal_drawosdchar ;
static void ( * drawosdstr ) ( int , int , char * , int , int , int ) = _internal_drawosdstr ;
static void ( * drawosdcursor ) ( int , int , int , int ) = _internal_drawosdcursor ;
static int ( * getcolumnwidth ) ( int ) = _internal_getcolumnwidth ;
static int ( * getrowheight ) ( int ) = _internal_getrowheight ;
static void ( * clearbackground ) ( int , int ) = _internal_clearbackground ;
static int ( * gettime ) ( void ) = _internal_gettime ;
static void ( * onshowosd ) ( int ) = _internal_onshowosd ;
2008-06-30 07:30:48 +00:00
const char * stripcolorcodes ( const char * t )
{
int i = 0 ;
static char colstrip [ 1024 ] ;
while ( * t )
{
if ( * t = = ' ^ ' & & isdigit ( * ( t + 1 ) ) )
{
t + = 2 ;
if ( isdigit ( * t ) )
t + + ;
continue ;
}
colstrip [ i ] = * t ;
i + + , t + + ;
}
colstrip [ i ] = ' \0 ' ;
return ( colstrip ) ;
}
int OSD_Exec ( const char * szScript )
{
FILE * fp = fopenfrompath ( szScript , " r " ) ;
if ( fp ! = NULL )
{
char line [ 255 ] ;
OSD_Printf ( " Executing \" %s \" \n " , szScript ) ;
osdexecscript + + ;
while ( fgets ( line , sizeof ( line ) - 1 , fp ) ! = NULL )
OSD_Dispatch ( strtok ( line , " \r \n " ) ) ;
osdexecscript - - ;
fclose ( fp ) ;
return 0 ;
}
return 1 ;
}
static int _internal_osdfunc_exec ( const osdfuncparm_t * parm )
{
char fn [ BMAX_PATH ] ;
if ( parm - > numparms ! = 1 ) return OSDCMD_SHOWHELP ;
Bstrcpy ( fn , parm - > parms [ 0 ] ) ;
if ( OSD_Exec ( fn ) )
{
OSD_Printf ( " exec: file \" %s \" not found. \n " , fn ) ;
return OSDCMD_OK ;
}
return OSDCMD_OK ;
}
2006-04-13 20:47:06 +00:00
static void _internal_drawosdchar ( int x , int y , char ch , int shade , int pal )
{
2006-04-24 19:04:22 +00:00
int i , j , k ;
char st [ 2 ] = { 0 , 0 } ;
2008-03-23 00:06:42 +00:00
UNREFERENCED_PARAMETER ( shade ) ;
UNREFERENCED_PARAMETER ( pal ) ;
2006-04-24 19:04:22 +00:00
st [ 0 ] = ch ;
2007-12-12 17:42:14 +00:00
if ( white < 0 )
{
2006-04-24 19:04:22 +00:00
// find the palette index closest to white
k = 0 ;
2006-11-13 23:12:47 +00:00
for ( i = 0 ; i < 256 ; i + + )
2006-04-24 19:04:22 +00:00
{
j = ( ( int ) curpalette [ i ] . r ) + ( ( int ) curpalette [ i ] . g ) + ( ( int ) curpalette [ i ] . b ) ;
if ( j > k ) { k = j ; white = i ; }
}
}
printext256 ( 4 + ( x < < 3 ) , 4 + ( y < < 3 ) , white , - 1 , st , 0 ) ;
2006-04-13 20:47:06 +00:00
}
static void _internal_drawosdstr ( int x , int y , char * ch , int len , int shade , int pal )
{
2006-04-24 19:04:22 +00:00
int i , j , k ;
char st [ 1024 ] ;
2008-03-23 00:06:42 +00:00
UNREFERENCED_PARAMETER ( shade ) ;
UNREFERENCED_PARAMETER ( pal ) ;
2006-04-24 19:04:22 +00:00
if ( len > 1023 ) len = 1023 ;
memcpy ( st , ch , len ) ;
st [ len ] = 0 ;
2007-12-12 17:42:14 +00:00
if ( white < 0 )
{
2006-04-24 19:04:22 +00:00
// find the palette index closest to white
k = 0 ;
2006-11-13 23:12:47 +00:00
for ( i = 0 ; i < 256 ; i + + )
2006-04-24 19:04:22 +00:00
{
j = ( ( int ) curpalette [ i ] . r ) + ( ( int ) curpalette [ i ] . g ) + ( ( int ) curpalette [ i ] . b ) ;
if ( j > k ) { k = j ; white = i ; }
}
}
printext256 ( 4 + ( x < < 3 ) , 4 + ( y < < 3 ) , white , - 1 , st , 0 ) ;
2006-04-13 20:47:06 +00:00
}
static void _internal_drawosdcursor ( int x , int y , int type , int lastkeypress )
{
2006-04-24 19:04:22 +00:00
int i , j , k ;
char st [ 2 ] = { ' _ ' , 0 } ;
2008-03-23 00:06:42 +00:00
UNREFERENCED_PARAMETER ( lastkeypress ) ;
2006-04-24 19:04:22 +00:00
if ( type ) st [ 0 ] = ' # ' ;
2007-12-12 17:42:14 +00:00
if ( white < 0 )
{
2006-04-24 19:04:22 +00:00
// find the palette index closest to white
k = 0 ;
2006-11-13 23:12:47 +00:00
for ( i = 0 ; i < 256 ; i + + )
2006-04-24 19:04:22 +00:00
{
j = ( ( int ) palette [ i * 3 ] ) + ( ( int ) palette [ i * 3 + 1 ] ) + ( ( int ) palette [ i * 3 + 2 ] ) ;
if ( j > k ) { k = j ; white = i ; }
}
}
printext256 ( 4 + ( x < < 3 ) , 4 + ( y < < 3 ) + 2 , white , - 1 , st , 0 ) ;
2006-04-13 20:47:06 +00:00
}
static int _internal_getcolumnwidth ( int w )
{
2006-04-24 19:04:22 +00:00
return w / 8 - 1 ;
2006-04-13 20:47:06 +00:00
}
static int _internal_getrowheight ( int w )
{
2006-04-24 19:04:22 +00:00
return w / 8 ;
2006-04-13 20:47:06 +00:00
}
static void _internal_clearbackground ( int cols , int rows )
{
2008-03-23 00:06:42 +00:00
UNREFERENCED_PARAMETER ( cols ) ;
UNREFERENCED_PARAMETER ( rows ) ;
2006-04-13 20:47:06 +00:00
}
static int _internal_gettime ( void )
{
2006-04-24 19:04:22 +00:00
return 0 ;
2006-04-13 20:47:06 +00:00
}
static void _internal_onshowosd ( int a )
{
2008-03-23 00:06:42 +00:00
UNREFERENCED_PARAMETER ( a ) ;
2006-04-13 20:47:06 +00:00
}
////////////////////////////
2008-06-29 22:37:30 +00:00
static int _internal_osdfunc_alias ( const osdfuncparm_t * parm )
{
symbol_t * i ;
if ( parm - > numparms < 1 )
{
OSD_Printf ( " Alias listing: \n " ) ;
for ( i = symbols ; i ! = NULL ; i = i - > next )
2008-06-30 00:18:59 +00:00
if ( i - > func = = ( void * ) OSD_ALIAS )
2008-06-30 07:30:48 +00:00
OSD_Printf ( " %s \" %s \" \n " , i - > name , i - > help ) ;
2008-06-29 22:37:30 +00:00
return OSDCMD_OK ;
}
2008-06-30 00:18:59 +00:00
for ( i = symbols ; i ! = NULL ; i = i - > next )
2008-06-29 22:37:30 +00:00
{
2008-06-30 00:32:05 +00:00
if ( ! Bstrcasecmp ( parm - > parms [ 0 ] , i - > name ) )
2008-06-30 00:18:59 +00:00
{
2008-06-30 00:32:05 +00:00
if ( parm - > numparms < 2 )
2008-06-30 00:18:59 +00:00
{
if ( i - > func = = ( void * ) OSD_ALIAS )
OSD_Printf ( " alias %s \" %s \" \n " , i - > name , i - > help ) ;
else OSD_Printf ( " %s is a function, not an alias \n " , i - > name ) ;
2008-06-30 00:32:05 +00:00
return OSDCMD_OK ;
}
2008-06-30 01:03:51 +00:00
if ( i - > func ! = ( void * ) OSD_ALIAS & & i - > func ! = ( void * ) OSD_UNALIASED )
2008-06-30 00:32:05 +00:00
{
OSD_Printf ( " Cannot override function \" %s \" with alias \n " , i - > name ) ;
return OSDCMD_OK ;
2008-06-30 00:18:59 +00:00
}
}
2008-06-29 22:37:30 +00:00
}
2008-06-30 00:18:59 +00:00
OSD_RegisterFunction ( Bstrdup ( parm - > parms [ 0 ] ) , Bstrdup ( parm - > parms [ 1 ] ) , ( void * ) OSD_ALIAS ) ;
2008-06-30 07:30:48 +00:00
if ( ! osdexecscript )
OSD_Printf ( " %s \n " , parm - > raw ) ;
2008-06-29 22:37:30 +00:00
return OSDCMD_OK ;
}
2008-06-30 01:03:51 +00:00
static int _internal_osdfunc_unalias ( const osdfuncparm_t * parm )
{
symbol_t * i ;
if ( parm - > numparms < 1 )
return OSDCMD_SHOWHELP ;
for ( i = symbols ; i ! = NULL ; i = i - > next )
{
if ( ! Bstrcasecmp ( parm - > parms [ 0 ] , i - > name ) )
{
if ( parm - > numparms < 2 )
{
if ( i - > func = = ( void * ) OSD_ALIAS )
{
2008-06-30 07:30:48 +00:00
OSD_Printf ( " Removed alias %s ( \" %s \" ) \n " , i - > name , i - > help ) ;
2008-06-30 01:03:51 +00:00
i - > func = ( void * ) OSD_UNALIASED ;
}
else OSD_Printf ( " Invalid alias %s \n " , i - > name ) ;
return OSDCMD_OK ;
}
}
}
OSD_Printf ( " Invalid alias %s \n " , parm - > parms [ 0 ] ) ;
return OSDCMD_OK ;
}
2006-04-13 20:47:06 +00:00
static int _internal_osdfunc_vars ( const osdfuncparm_t * parm )
{
2006-04-24 19:04:22 +00:00
int showval = ( parm - > numparms < 1 ) ;
2007-12-12 17:42:14 +00:00
if ( ! Bstrcasecmp ( parm - > name , " osdrows " ) )
{
2006-04-24 19:04:22 +00:00
if ( showval ) { OSD_Printf ( " osdrows is %d \n " , osdrows ) ; return OSDCMD_OK ; }
2007-12-12 17:42:14 +00:00
else
{
2006-04-24 19:04:22 +00:00
osdrows = atoi ( parm - > parms [ 0 ] ) ;
if ( osdrows < 1 ) osdrows = 1 ;
else if ( osdrows > osdmaxrows ) osdrows = osdmaxrows ;
2008-05-10 01:29:37 +00:00
if ( osdrowscur ! = - 1 ) osdrowscur = osdrows ;
2008-07-01 10:31:03 +00:00
OSD_Printf ( " %s \n " , parm - > raw ) ;
return OSDCMD_OK ;
}
}
if ( ! Bstrcasecmp ( parm - > name , " osdcompletionstyle " ) )
{
if ( showval ) { OSD_Printf ( " osdcompletionstyle is %d \n " , osdcompletionstyle ) ; return OSDCMD_OK ; }
else
{
osdcompletionstyle = atoi ( parm - > parms [ 0 ] ) ;
if ( osdcompletionstyle < 0 ) osdcompletionstyle = 0 ;
else if ( osdcompletionstyle > 1 ) osdcompletionstyle = 1 ;
OSD_Printf ( " %s \n " , parm - > raw ) ;
2006-04-24 19:04:22 +00:00
return OSDCMD_OK ;
}
}
2008-05-10 01:29:37 +00:00
else
if ( ! Bstrcasecmp ( parm - > name , " logcutoff " ) )
{
if ( showval ) { OSD_Printf ( " logcutoff is %d \n " , logcutoff ) ; return OSDCMD_OK ; }
else
{
logcutoff = atoi ( parm - > parms [ 0 ] ) ;
2008-07-01 10:31:03 +00:00
OSD_Printf ( " %s \n " , parm - > raw ) ;
2008-05-10 01:29:37 +00:00
return OSDCMD_OK ;
}
}
2006-04-24 19:04:22 +00:00
return OSDCMD_SHOWHELP ;
2006-04-13 20:47:06 +00:00
}
static int _internal_osdfunc_listsymbols ( const osdfuncparm_t * parm )
{
2006-04-24 19:04:22 +00:00
symbol_t * i ;
2008-06-30 07:30:48 +00:00
int maxwidth = 0 ;
2006-04-13 20:47:06 +00:00
2008-03-23 00:06:42 +00:00
UNREFERENCED_PARAMETER ( parm ) ;
2006-04-24 19:04:22 +00:00
for ( i = symbols ; i ! = NULL ; i = i - > next )
2008-06-30 01:03:51 +00:00
if ( i - > func ! = ( void * ) OSD_UNALIASED )
2008-06-30 07:30:48 +00:00
maxwidth = max ( ( unsigned ) maxwidth , Bstrlen ( i - > name ) ) ;
if ( maxwidth > 0 )
{
int x = 0 ;
maxwidth + = 3 ;
OSD_Printf ( " Symbol listing: \n " ) ;
for ( i = symbols ; i ! = NULL ; i = i - > next )
{
if ( i - > func ! = ( void * ) OSD_UNALIASED )
{
OSD_Printf ( " %-*s " , maxwidth , i - > name ) ;
x + = maxwidth ;
}
if ( x > osdcols - maxwidth )
{
x = 0 ;
OSD_Printf ( " \n " ) ;
}
}
if ( x )
OSD_Printf ( " \n " ) ;
}
2006-04-24 19:04:22 +00:00
return OSDCMD_OK ;
2006-04-13 20:47:06 +00:00
}
static int _internal_osdfunc_help ( const osdfuncparm_t * parm )
{
2006-04-24 19:04:22 +00:00
symbol_t * symb ;
if ( parm - > numparms ! = 1 ) return OSDCMD_SHOWHELP ;
symb = findexactsymbol ( parm - > parms [ 0 ] ) ;
2007-12-12 17:42:14 +00:00
if ( ! symb )
{
2006-04-24 19:04:22 +00:00
OSD_Printf ( " Help Error: \" %s \" is not a defined variable or function \n " , parm - > parms [ 0 ] ) ;
2007-12-12 17:42:14 +00:00
}
else
{
2006-04-24 19:04:22 +00:00
OSD_Printf ( " %s \n " , symb - > help ) ;
}
return OSDCMD_OK ;
2006-04-13 20:47:06 +00:00
}
2007-01-04 07:15:17 +00:00
static int _internal_osdfunc_clear ( const osdfuncparm_t * parm )
{
2008-03-23 00:06:42 +00:00
UNREFERENCED_PARAMETER ( parm ) ;
2007-01-04 07:15:17 +00:00
Bmemset ( osdtext , 0 , sizeof ( osdtext ) ) ;
osdlines = 1 ;
return OSDCMD_OK ;
}
2006-04-13 20:47:06 +00:00
////////////////////////////
//
// OSD_Cleanup() -- Cleans up the on-screen display
//
void OSD_Cleanup ( void )
{
2006-04-24 19:04:22 +00:00
symbol_t * s ;
2006-04-13 20:47:06 +00:00
2007-12-12 17:42:14 +00:00
for ( ; symbols ; symbols = s )
{
2006-04-24 19:04:22 +00:00
s = symbols - > next ;
Bfree ( symbols ) ;
}
2006-04-13 20:47:06 +00:00
2006-04-24 19:04:22 +00:00
if ( osdlog ) Bfclose ( osdlog ) ;
osdlog = NULL ;
2006-04-24 18:52:29 +00:00
2006-04-24 19:04:22 +00:00
osdinited = 0 ;
2006-04-13 20:47:06 +00:00
}
//
2008-02-24 00:46:57 +00:00
// OSD_Init() -- Initializes the on-screen display
2006-04-13 20:47:06 +00:00
//
void OSD_Init ( void )
{
2006-04-24 19:04:22 +00:00
Bmemset ( osdtext , 32 , TEXTSIZE ) ;
osdlines = 1 ;
2006-04-13 20:47:06 +00:00
2006-04-24 19:04:22 +00:00
osdinited = 1 ;
2006-04-13 20:47:06 +00:00
2006-04-24 19:04:22 +00:00
OSD_RegisterFunction ( " listsymbols " , " listsymbols: lists all the recognized symbols " , _internal_osdfunc_listsymbols ) ;
OSD_RegisterFunction ( " help " , " help: displays help on the named symbol " , _internal_osdfunc_help ) ;
OSD_RegisterFunction ( " osdrows " , " osdrows: sets the number of visible lines of the OSD " , _internal_osdfunc_vars ) ;
2008-01-04 01:04:35 +00:00
OSD_RegisterFunction ( " logcutoff " , " logcutoff: sets the maximal line count of the log file " , _internal_osdfunc_vars ) ;
2007-01-04 07:15:17 +00:00
OSD_RegisterFunction ( " clear " , " clear: clears the console text buffer " , _internal_osdfunc_clear ) ;
2008-06-29 22:37:30 +00:00
OSD_RegisterFunction ( " alias " , " alias: creates an alias for calling multiple commands " , _internal_osdfunc_alias ) ;
2008-06-30 01:03:51 +00:00
OSD_RegisterFunction ( " unalias " , " unalias: removes an alias created with \" alias \" " , _internal_osdfunc_unalias ) ;
2008-06-30 07:30:48 +00:00
OSD_RegisterFunction ( " exec " , " exec <scriptfile>: executes a script " , _internal_osdfunc_exec ) ;
2008-07-01 10:31:03 +00:00
OSD_RegisterFunction ( " osdcompletionstyle " , " osdcompletionstyle: sets the type of tab completion to be used in the OSD; 0 (default) = bash style, 1 = cycling style " , _internal_osdfunc_vars ) ;
2006-04-13 20:47:06 +00:00
2006-04-24 19:04:22 +00:00
atexit ( OSD_Cleanup ) ;
2006-04-13 20:47:06 +00:00
}
//
// OSD_SetLogFile() -- Sets the text file where printed text should be echoed
//
void OSD_SetLogFile ( char * fn )
{
2006-04-24 19:04:22 +00:00
if ( osdlog ) Bfclose ( osdlog ) ;
osdlog = NULL ;
if ( fn ) osdlog = Bfopen ( fn , " w " ) ;
if ( osdlog ) setvbuf ( osdlog , ( char * ) NULL , _IONBF , 0 ) ;
2006-04-13 20:47:06 +00:00
}
//
// OSD_SetFunctions() -- Sets some callbacks which the OSD uses to understand its world
//
void OSD_SetFunctions (
2006-04-24 19:04:22 +00:00
void ( * drawchar ) ( int , int , char , int , int ) ,
void ( * drawstr ) ( int , int , char * , int , int , int ) ,
void ( * drawcursor ) ( int , int , int , int ) ,
int ( * colwidth ) ( int ) ,
int ( * rowheight ) ( int ) ,
void ( * clearbg ) ( int , int ) ,
int ( * gtime ) ( void ) ,
void ( * showosd ) ( int )
)
2006-04-13 20:47:06 +00:00
{
2006-04-24 19:04:22 +00:00
drawosdchar = drawchar ;
drawosdstr = drawstr ;
drawosdcursor = drawcursor ;
getcolumnwidth = colwidth ;
getrowheight = rowheight ;
clearbackground = clearbg ;
gettime = gtime ;
onshowosd = showosd ;
if ( ! drawosdchar ) drawosdchar = _internal_drawosdchar ;
if ( ! drawosdstr ) drawosdstr = _internal_drawosdstr ;
if ( ! drawosdcursor ) drawosdcursor = _internal_drawosdcursor ;
if ( ! getcolumnwidth ) getcolumnwidth = _internal_getcolumnwidth ;
if ( ! getrowheight ) getrowheight = _internal_getrowheight ;
if ( ! clearbackground ) clearbackground = _internal_clearbackground ;
if ( ! gettime ) gettime = _internal_gettime ;
if ( ! onshowosd ) onshowosd = _internal_onshowosd ;
2006-04-13 20:47:06 +00:00
}
//
// OSD_SetParameters() -- Sets the parameters for presenting the text
//
void OSD_SetParameters (
2006-04-24 19:04:22 +00:00
int promptshade , int promptpal ,
int editshade , int editpal ,
int textshade , int textpal
)
2006-04-13 20:47:06 +00:00
{
2006-04-24 19:04:22 +00:00
osdpromptshade = promptshade ;
osdpromptpal = promptpal ;
osdeditshade = editshade ;
osdeditpal = editpal ;
osdtextshade = textshade ;
osdtextpal = textpal ;
2006-04-13 20:47:06 +00:00
}
//
// OSD_CaptureKey() -- Sets the scancode for the key which activates the onscreen display
//
void OSD_CaptureKey ( int sc )
{
2006-04-24 19:04:22 +00:00
osdkey = sc ;
2006-04-13 20:47:06 +00:00
}
2008-07-01 10:31:03 +00:00
//
// OSD_FindDiffPoint() -- Finds the length of the longest common prefix of 2 strings, stolen from ZDoom
//
static int OSD_FindDiffPoint ( const char * str1 , const char * str2 )
{
int i ;
for ( i = 0 ; Btolower ( str1 [ i ] ) = = Btolower ( str2 [ i ] ) ; i + + )
if ( str1 [ i ] = = 0 | | str2 [ i ] = = 0 )
break ;
return i ;
}
2006-04-13 20:47:06 +00:00
//
// OSD_HandleKey() -- Handles keyboard input when capturing input.
// Returns 0 if the key was handled internally, or the scancode if it should
// be passed on to the game.
//
int OSD_HandleKey ( int sc , int press )
{
2006-04-24 19:04:22 +00:00
char ch ;
int i , j ;
symbol_t * tabc = NULL ;
static symbol_t * lastmatch = NULL ;
if ( ! osdinited ) return sc ;
2007-12-12 17:42:14 +00:00
if ( sc = = osdkey )
{
if ( press )
{
2006-12-11 03:06:49 +00:00
osdscroll = - osdscroll ;
2006-12-11 21:18:21 +00:00
if ( osdrowscur = = - 1 )
2006-12-11 03:06:49 +00:00
osdscroll = 1 ;
else if ( osdrowscur = = osdrows )
osdscroll = - 1 ;
2007-12-12 17:42:14 +00:00
osdrowscur + = osdscroll ;
2006-12-11 03:32:43 +00:00
OSD_CaptureInput ( osdscroll = = 1 ) ;
2007-01-02 02:27:31 +00:00
osdscrtime = getticks ( ) ;
2006-04-24 19:04:22 +00:00
}
return 0 ; //sc;
2007-12-12 17:42:14 +00:00
}
else if ( ! osdinput )
{
2006-04-24 19:04:22 +00:00
return sc ;
}
2007-12-12 17:42:14 +00:00
if ( ! press )
{
2006-04-24 19:04:22 +00:00
if ( sc = = 42 | | sc = = 54 ) // shift
osdeditshift = 0 ;
if ( sc = = 29 | | sc = = 157 ) // control
osdeditcontrol = 0 ;
return 0 ; //sc;
}
keytime = gettime ( ) ;
if ( sc ! = 15 ) lastmatch = NULL ; // tab
2007-12-12 17:42:14 +00:00
while ( ( ch = bgetchar ( ) ) )
{
if ( ch = = 1 ) // control a. jump to beginning of line
{
}
else if ( ch = = 2 ) // control b, move one character left
{
}
else if ( ch = = 5 ) // control e, jump to end of line
{
}
else if ( ch = = 6 ) // control f, move one character right
{
}
else if ( ch = = 8 | | ch = = 127 ) // control h, backspace
{
2006-04-24 19:04:22 +00:00
if ( ! osdeditcursor | | ! osdeditlen ) return 0 ;
2007-12-12 17:42:14 +00:00
if ( ! osdovertype )
{
2006-04-24 19:04:22 +00:00
if ( osdeditcursor < osdeditlen )
Bmemmove ( osdeditbuf + osdeditcursor - 1 , osdeditbuf + osdeditcursor , osdeditlen - osdeditcursor ) ;
osdeditlen - - ;
}
osdeditcursor - - ;
if ( osdeditcursor < osdeditwinstart ) osdeditwinstart - - , osdeditwinend - - ;
2007-12-12 17:42:14 +00:00
}
else if ( ch = = 9 ) // tab
{
2008-07-01 10:31:03 +00:00
int commonsize = 512 ;
2007-12-12 17:42:14 +00:00
if ( ! lastmatch )
{
2006-04-24 19:04:22 +00:00
for ( i = osdeditcursor ; i > 0 ; i - - ) if ( osdeditbuf [ i - 1 ] = = ' ' ) break ;
for ( j = 0 ; osdeditbuf [ i ] ! = ' ' & & i < osdeditlen ; j + + , i + + )
osdedittmp [ j ] = osdeditbuf [ i ] ;
osdedittmp [ j ] = 0 ;
if ( j > 0 )
2006-12-11 03:06:49 +00:00
{
2006-04-24 19:04:22 +00:00
tabc = findsymbol ( osdedittmp , NULL ) ;
2007-12-12 17:42:14 +00:00
2007-01-26 21:12:05 +00:00
if ( tabc )
2006-12-11 03:06:49 +00:00
{
2007-01-26 21:12:05 +00:00
if ( tabc - > next )
2006-12-11 03:06:49 +00:00
{
2007-01-26 21:12:05 +00:00
if ( findsymbol ( osdedittmp , tabc - > next ) )
{
symbol_t * symb = tabc ;
2008-06-30 07:30:48 +00:00
int maxwidth = 0 , x = 0 ;
2007-01-26 21:12:05 +00:00
2008-06-30 07:30:48 +00:00
OSD_Printf ( " Completions for '%s': \n " , osdedittmp ) ;
while ( symb & & symb ! = lastmatch )
{
2008-07-01 10:31:03 +00:00
int diffpt ;
if ( lastmatch )
{
diffpt = OSD_FindDiffPoint ( symb - > name , lastmatch - > name ) ;
if ( diffpt < commonsize )
{
commonsize = diffpt ;
// OSD_Printf("commonsize %d\n",commonsize);
}
}
2008-06-30 07:30:48 +00:00
maxwidth = max ( ( unsigned ) maxwidth , Bstrlen ( symb - > name ) ) ;
lastmatch = symb ;
symb = findsymbol ( osdedittmp , lastmatch - > next ) ;
}
maxwidth + = 3 ;
symb = tabc ;
OSD_Printf ( " " ) ;
2007-01-26 21:12:05 +00:00
while ( symb & & symb ! = lastmatch )
{
2008-06-30 07:30:48 +00:00
OSD_Printf ( " %-*s " , maxwidth , symb - > name ) ;
x + = maxwidth ;
2007-01-26 21:12:05 +00:00
lastmatch = symb ;
2007-12-12 17:42:14 +00:00
symb = findsymbol ( osdedittmp , lastmatch - > next ) ;
2008-06-30 07:30:48 +00:00
if ( x > osdcols - maxwidth )
{
x = 0 ;
OSD_Printf ( " \n " ) ;
2008-07-01 10:31:03 +00:00
if ( symb & & symb ! = lastmatch )
OSD_Printf ( " " ) ;
2008-06-30 07:30:48 +00:00
}
2007-01-26 21:12:05 +00:00
}
2008-06-30 07:30:48 +00:00
if ( x )
OSD_Printf ( " \n " ) ;
2007-01-26 21:12:05 +00:00
}
2006-12-11 03:06:49 +00:00
}
}
}
2007-12-12 17:42:14 +00:00
}
else
{
2008-07-01 10:31:03 +00:00
if ( osdcompletionstyle = = 1 )
{
tabc = findsymbol ( osdedittmp , lastmatch - > next ) ;
if ( ! tabc & & lastmatch )
tabc = findsymbol ( osdedittmp , NULL ) ; // wrap */
}
2006-04-24 19:04:22 +00:00
}
2007-12-12 17:42:14 +00:00
if ( tabc )
{
2006-04-24 19:04:22 +00:00
for ( i = osdeditcursor ; i > 0 ; i - - ) if ( osdeditbuf [ i - 1 ] = = ' ' ) break ;
osdeditlen = i ;
2008-07-01 10:31:03 +00:00
for ( j = 0 ; tabc - > name [ j ] & & osdeditlen < = EDITLENGTH
& & ( ! osdcompletionstyle ? osdeditlen < commonsize : 1 ) ; i + + , j + + , osdeditlen + + )
2006-04-24 19:04:22 +00:00
osdeditbuf [ i ] = tabc - > name [ j ] ;
osdeditcursor = osdeditlen ;
osdeditwinend = osdeditcursor ;
osdeditwinstart = osdeditwinend - editlinewidth ;
2007-12-12 17:42:14 +00:00
if ( osdeditwinstart < 0 )
{
2006-04-24 19:04:22 +00:00
osdeditwinstart = 0 ;
osdeditwinend = editlinewidth ;
}
lastmatch = tabc ;
}
2007-12-12 17:42:14 +00:00
}
else if ( ch = = 11 ) // control k, delete all to end of line
{
}
else if ( ch = = 12 ) // control l, clear screen
{
2007-01-04 07:15:17 +00:00
Bmemset ( osdtext , 0 , sizeof ( osdtext ) ) ;
osdlines = 1 ;
2007-12-12 17:42:14 +00:00
}
else if ( ch = = 13 ) // control m, enter
{
if ( osdeditlen > 0 )
{
2006-04-24 19:04:22 +00:00
osdeditbuf [ osdeditlen ] = 0 ;
Bmemmove ( osdhistorybuf [ 1 ] , osdhistorybuf [ 0 ] , HISTORYDEPTH * ( EDITLENGTH + 1 ) ) ;
Bmemmove ( osdhistorybuf [ 0 ] , osdeditbuf , EDITLENGTH + 1 ) ;
if ( osdhistorysize < HISTORYDEPTH ) osdhistorysize + + ;
if ( osdexeccount = = HISTORYDEPTH )
OSD_Printf ( " Command Buffer Warning: Failed queueing command "
" for execution. Buffer full. \n " ) ;
else
osdexeccount + + ;
osdhistorypos = - 1 ;
}
osdeditlen = 0 ;
osdeditcursor = 0 ;
osdeditwinstart = 0 ;
osdeditwinend = editlinewidth ;
2007-12-12 17:42:14 +00:00
}
else if ( ch = = 16 ) // control p, previous (ie. up arrow)
{
}
else if ( ch = = 20 ) // control t, swap previous two chars
{
}
else if ( ch = = 21 ) // control u, delete all to beginning
{
if ( osdeditcursor > 0 & & osdeditlen )
{
2006-04-24 19:04:22 +00:00
if ( osdeditcursor < osdeditlen )
Bmemmove ( osdeditbuf , osdeditbuf + osdeditcursor , osdeditlen - osdeditcursor ) ;
osdeditlen - = osdeditcursor ;
osdeditcursor = 0 ;
osdeditwinstart = 0 ;
osdeditwinend = editlinewidth ;
}
2007-12-12 17:42:14 +00:00
}
else if ( ch = = 23 ) // control w, delete one word back
{
if ( osdeditcursor > 0 & & osdeditlen > 0 )
{
2006-04-24 19:04:22 +00:00
i = osdeditcursor ;
while ( i > 0 & & osdeditbuf [ i - 1 ] = = 32 ) i - - ;
while ( i > 0 & & osdeditbuf [ i - 1 ] ! = 32 ) i - - ;
if ( osdeditcursor < osdeditlen )
Bmemmove ( osdeditbuf + i , osdeditbuf + osdeditcursor , osdeditlen - osdeditcursor ) ;
osdeditlen - = ( osdeditcursor - i ) ;
osdeditcursor = i ;
2007-12-12 17:42:14 +00:00
if ( osdeditcursor < osdeditwinstart )
{
2006-04-24 19:04:22 +00:00
osdeditwinstart = osdeditcursor ;
osdeditwinend = osdeditwinstart + editlinewidth ;
}
}
2007-12-12 17:42:14 +00:00
}
else if ( ch > = 32 ) // text char
{
2006-04-24 19:04:22 +00:00
if ( ! osdovertype & & osdeditlen = = EDITLENGTH ) // buffer full, can't insert another char
return 0 ;
2007-12-12 17:42:14 +00:00
if ( ! osdovertype )
{
2006-04-24 19:04:22 +00:00
if ( osdeditcursor < osdeditlen )
Bmemmove ( osdeditbuf + osdeditcursor + 1 , osdeditbuf + osdeditcursor , osdeditlen - osdeditcursor ) ;
osdeditlen + + ;
2007-12-12 17:42:14 +00:00
}
else
{
2006-04-24 19:04:22 +00:00
if ( osdeditcursor = = osdeditlen )
osdeditlen + + ;
}
osdeditbuf [ osdeditcursor ] = ch ;
osdeditcursor + + ;
if ( osdeditcursor > osdeditwinend ) osdeditwinstart + + , osdeditwinend + + ;
}
}
2007-12-12 17:42:14 +00:00
if ( sc = = 15 ) // tab
{
}
else if ( sc = = 1 ) // escape
2007-12-20 19:14:38 +00:00
{
2007-12-12 17:42:14 +00:00
// OSD_ShowDisplay(0);
osdscroll = - 1 ;
osdrowscur + = osdscroll ;
OSD_CaptureInput ( 0 ) ;
osdscrtime = getticks ( ) ;
}
else if ( sc = = 201 ) // page up
{
2006-04-24 19:04:22 +00:00
if ( osdhead < osdlines - 1 )
osdhead + + ;
2007-12-12 17:42:14 +00:00
}
else if ( sc = = 209 ) // page down
{
2006-04-24 19:04:22 +00:00
if ( osdhead > 0 )
osdhead - - ;
2007-12-12 17:42:14 +00:00
}
else if ( sc = = 199 ) // home
{
if ( osdeditcontrol )
{
2006-04-24 19:04:22 +00:00
osdhead = osdlines - 1 ;
2007-12-12 17:42:14 +00:00
}
else
{
2006-04-24 19:04:22 +00:00
osdeditcursor = 0 ;
osdeditwinstart = osdeditcursor ;
osdeditwinend = osdeditwinstart + editlinewidth ;
}
2007-12-12 17:42:14 +00:00
}
else if ( sc = = 207 ) // end
{
if ( osdeditcontrol )
{
2006-04-24 19:04:22 +00:00
osdhead = 0 ;
2007-12-12 17:42:14 +00:00
}
else
{
2006-04-24 19:04:22 +00:00
osdeditcursor = osdeditlen ;
osdeditwinend = osdeditcursor ;
osdeditwinstart = osdeditwinend - editlinewidth ;
2007-12-12 17:42:14 +00:00
if ( osdeditwinstart < 0 )
{
2006-04-24 19:04:22 +00:00
osdeditwinstart = 0 ;
osdeditwinend = editlinewidth ;
}
}
2007-12-12 17:42:14 +00:00
}
else if ( sc = = 210 ) // insert
{
2006-04-24 19:04:22 +00:00
osdovertype ^ = 1 ;
2007-12-12 17:42:14 +00:00
}
else if ( sc = = 203 ) // left
{
if ( osdeditcursor > 0 )
{
if ( osdeditcontrol )
{
while ( osdeditcursor > 0 )
{
2006-04-24 19:04:22 +00:00
if ( osdeditbuf [ osdeditcursor - 1 ] ! = 32 ) break ;
osdeditcursor - - ;
}
2007-12-12 17:42:14 +00:00
while ( osdeditcursor > 0 )
{
2006-04-24 19:04:22 +00:00
if ( osdeditbuf [ osdeditcursor - 1 ] = = 32 ) break ;
osdeditcursor - - ;
}
2007-12-12 17:42:14 +00:00
}
else osdeditcursor - - ;
2006-04-24 19:04:22 +00:00
}
if ( osdeditcursor < osdeditwinstart )
osdeditwinend - = ( osdeditwinstart - osdeditcursor ) ,
osdeditwinstart - = ( osdeditwinstart - osdeditcursor ) ;
2007-12-12 17:42:14 +00:00
}
else if ( sc = = 205 ) // right
{
if ( osdeditcursor < osdeditlen )
{
if ( osdeditcontrol )
{
while ( osdeditcursor < osdeditlen )
{
2006-04-24 19:04:22 +00:00
if ( osdeditbuf [ osdeditcursor ] = = 32 ) break ;
osdeditcursor + + ;
}
2007-12-12 17:42:14 +00:00
while ( osdeditcursor < osdeditlen )
{
2006-04-24 19:04:22 +00:00
if ( osdeditbuf [ osdeditcursor ] ! = 32 ) break ;
osdeditcursor + + ;
}
2007-12-12 17:42:14 +00:00
}
else osdeditcursor + + ;
2006-04-24 19:04:22 +00:00
}
if ( osdeditcursor > = osdeditwinend )
osdeditwinstart + = ( osdeditcursor - osdeditwinend ) ,
osdeditwinend + = ( osdeditcursor - osdeditwinend ) ;
2007-12-12 17:42:14 +00:00
}
else if ( sc = = 200 ) // up
{
if ( osdhistorypos < osdhistorysize - 1 )
{
2006-04-24 19:04:22 +00:00
osdhistorypos + + ;
memcpy ( osdeditbuf , osdhistorybuf [ osdhistorypos ] , EDITLENGTH + 1 ) ;
osdeditlen = osdeditcursor = 0 ;
while ( osdeditbuf [ osdeditcursor ] ) osdeditlen + + , osdeditcursor + + ;
2007-12-12 17:42:14 +00:00
if ( osdeditcursor < osdeditwinstart )
{
2006-04-24 19:04:22 +00:00
osdeditwinend = osdeditcursor ;
osdeditwinstart = osdeditwinend - editlinewidth ;
if ( osdeditwinstart < 0 )
osdeditwinend - = osdeditwinstart ,
osdeditwinstart = 0 ;
2007-12-12 17:42:14 +00:00
}
else if ( osdeditcursor > = osdeditwinend )
2006-04-24 19:04:22 +00:00
osdeditwinstart + = ( osdeditcursor - osdeditwinend ) ,
osdeditwinend + = ( osdeditcursor - osdeditwinend ) ;
}
2007-12-12 17:42:14 +00:00
}
else if ( sc = = 208 ) // down
{
if ( osdhistorypos > = 0 )
{
if ( osdhistorypos = = 0 )
{
2006-04-24 19:04:22 +00:00
osdeditlen = 0 ;
osdeditcursor = 0 ;
osdeditwinstart = 0 ;
osdeditwinend = editlinewidth ;
osdhistorypos = - 1 ;
2007-12-12 17:42:14 +00:00
}
else
{
2006-04-24 19:04:22 +00:00
osdhistorypos - - ;
memcpy ( osdeditbuf , osdhistorybuf [ osdhistorypos ] , EDITLENGTH + 1 ) ;
osdeditlen = osdeditcursor = 0 ;
while ( osdeditbuf [ osdeditcursor ] ) osdeditlen + + , osdeditcursor + + ;
2007-12-12 17:42:14 +00:00
if ( osdeditcursor < osdeditwinstart )
{
2006-04-24 19:04:22 +00:00
osdeditwinend = osdeditcursor ;
osdeditwinstart = osdeditwinend - editlinewidth ;
if ( osdeditwinstart < 0 )
osdeditwinend - = osdeditwinstart ,
osdeditwinstart = 0 ;
2007-12-12 17:42:14 +00:00
}
else if ( osdeditcursor > = osdeditwinend )
2006-04-24 19:04:22 +00:00
osdeditwinstart + = ( osdeditcursor - osdeditwinend ) ,
osdeditwinend + = ( osdeditcursor - osdeditwinend ) ;
}
}
2007-12-12 17:42:14 +00:00
}
else if ( sc = = 42 | | sc = = 54 ) // shift
{
2006-04-24 19:04:22 +00:00
osdeditshift = 1 ;
2007-12-12 17:42:14 +00:00
}
else if ( sc = = 29 | | sc = = 157 ) // control
{
2006-04-24 19:04:22 +00:00
osdeditcontrol = 1 ;
2007-12-12 17:42:14 +00:00
}
else if ( sc = = 58 ) // capslock
{
2006-04-24 19:04:22 +00:00
osdeditcaps ^ = 1 ;
2007-12-12 17:42:14 +00:00
}
else if ( sc = = 28 | | sc = = 156 ) // enter
{
}
else if ( sc = = 14 ) // backspace
{
}
else if ( sc = = 211 ) // delete
{
2006-04-24 19:04:22 +00:00
if ( osdeditcursor = = osdeditlen | | ! osdeditlen ) return 0 ;
if ( osdeditcursor < = osdeditlen - 1 ) Bmemmove ( osdeditbuf + osdeditcursor , osdeditbuf + osdeditcursor + 1 , osdeditlen - osdeditcursor - 1 ) ;
osdeditlen - - ;
}
return 0 ;
2006-04-13 20:47:06 +00:00
}
//
// OSD_ResizeDisplay() -- Handles readjustment of the display when the screen resolution
// changes on us.
//
void OSD_ResizeDisplay ( int w , int h )
{
2006-04-24 19:04:22 +00:00
int newcols ;
int newmaxlines ;
char newtext [ TEXTSIZE ] ;
int i , j , k ;
newcols = getcolumnwidth ( w ) ;
newmaxlines = TEXTSIZE / newcols ;
j = min ( newmaxlines , osdmaxlines ) ;
k = min ( newcols , osdcols ) ;
memset ( newtext , 32 , TEXTSIZE ) ;
2007-12-12 17:42:14 +00:00
for ( i = 0 ; i < j ; i + + )
{
2006-04-24 19:04:22 +00:00
memcpy ( newtext + newcols * i , osdtext + osdcols * i , k ) ;
}
memcpy ( osdtext , newtext , TEXTSIZE ) ;
osdcols = newcols ;
osdmaxlines = newmaxlines ;
osdmaxrows = getrowheight ( h ) - 2 ;
if ( osdrows > osdmaxrows ) osdrows = osdmaxrows ;
osdpos = 0 ;
osdhead = 0 ;
osdeditwinstart = 0 ;
osdeditwinend = editlinewidth ;
white = - 1 ;
2006-04-13 20:47:06 +00:00
}
//
2006-12-11 03:32:43 +00:00
// OSD_CaptureInput()
2006-04-13 20:47:06 +00:00
//
2006-12-11 03:32:43 +00:00
void OSD_CaptureInput ( int cap )
2006-04-13 20:47:06 +00:00
{
2006-12-11 03:32:43 +00:00
osdinput = ( cap ! = 0 ) ;
2006-04-24 19:04:22 +00:00
osdeditcontrol = 0 ;
osdeditshift = 0 ;
2006-04-13 20:47:06 +00:00
2006-12-11 03:32:43 +00:00
grabmouse ( osdinput = = 0 ) ;
onshowosd ( osdinput ) ;
if ( osdinput ) releaseallbuttons ( ) ;
2006-12-11 21:18:21 +00:00
bflushchars ( ) ;
2006-12-11 03:32:43 +00:00
}
//
// OSD_ShowDisplay() -- Shows or hides the onscreen display
//
void OSD_ShowDisplay ( int onf )
{
osdvisible = ( onf ! = 0 ) ;
OSD_CaptureInput ( osdvisible ) ;
2006-04-13 20:47:06 +00:00
}
//
// OSD_Draw() -- Draw the onscreen display
//
2007-01-02 02:27:31 +00:00
2006-04-13 20:47:06 +00:00
void OSD_Draw ( void )
{
2006-04-24 19:04:22 +00:00
unsigned topoffs ;
int row , lines , x , len ;
2006-12-11 03:06:49 +00:00
if ( ! osdinited ) return ;
2006-12-11 21:18:21 +00:00
if ( osdrowscur = = 0 )
2006-12-11 03:06:49 +00:00
OSD_ShowDisplay ( osdvisible ^ 1 ) ;
if ( osdrowscur = = osdrows )
osdscroll = 0 ;
else
{
2007-01-12 05:05:19 +00:00
int j ;
2007-12-12 17:42:14 +00:00
2006-12-11 21:18:21 +00:00
if ( ( osdrowscur < osdrows & & osdscroll = = 1 ) | | osdrowscur < - 1 )
2007-01-06 09:50:02 +00:00
{
2007-01-12 05:05:19 +00:00
j = ( getticks ( ) - osdscrtime ) ;
2007-01-06 09:50:02 +00:00
while ( j > - 1 )
{
osdrowscur + + ;
2008-01-04 01:04:35 +00:00
j - = 200 / osdrows ;
2007-01-06 09:50:02 +00:00
if ( osdrowscur > osdrows - 1 )
break ;
}
}
2007-01-02 02:27:31 +00:00
if ( ( osdrowscur > - 1 & & osdscroll = = - 1 ) | | osdrowscur > osdrows )
2007-01-06 09:50:02 +00:00
{
2007-01-12 05:05:19 +00:00
j = ( getticks ( ) - osdscrtime ) ;
2007-01-06 09:50:02 +00:00
while ( j > - 1 )
{
osdrowscur - - ;
2008-01-04 01:04:35 +00:00
j - = 200 / osdrows ;
2007-01-06 09:50:02 +00:00
if ( osdrowscur < 1 )
break ;
}
}
osdscrtime = getticks ( ) ;
2007-01-02 02:27:31 +00:00
}
2007-12-12 17:42:14 +00:00
2006-12-11 03:06:49 +00:00
if ( ! osdvisible | | ! osdrowscur ) return ;
2006-04-24 19:04:22 +00:00
topoffs = osdhead * osdcols ;
2006-12-11 03:06:49 +00:00
row = osdrowscur - 1 ;
2007-12-12 17:42:14 +00:00
lines = min ( osdlines - osdhead , osdrowscur ) ;
2006-04-24 19:04:22 +00:00
begindrawing ( ) ;
2006-12-11 03:06:49 +00:00
clearbackground ( osdcols , osdrowscur + 1 ) ;
2007-12-12 17:42:14 +00:00
2006-12-11 04:38:10 +00:00
if ( osdversionstring [ 0 ] )
2007-04-17 05:54:12 +00:00
drawosdstr ( osdcols - osdversionstringlen , osdrowscur , osdversionstring , osdversionstringlen , osdversionstringshade , osdversionstringpal ) ;
2007-12-12 17:42:14 +00:00
for ( ; lines > 0 ; lines - - , row - - )
{
2006-04-24 19:04:22 +00:00
drawosdstr ( 0 , row , osdtext + topoffs , osdcols , osdtextshade , osdtextpal ) ;
topoffs + = osdcols ;
}
2006-12-11 03:06:49 +00:00
drawosdchar ( 2 , osdrowscur , ' > ' , osdpromptshade , osdpromptpal ) ;
if ( osdeditcaps ) drawosdchar ( 0 , osdrowscur , ' C ' , osdpromptshade , osdpromptpal ) ;
if ( osdeditshift ) drawosdchar ( 1 , osdrowscur , ' H ' , osdpromptshade , osdpromptpal ) ;
2006-04-24 19:04:22 +00:00
len = min ( osdcols - 1 - 3 , osdeditlen - osdeditwinstart ) ;
for ( x = 0 ; x < len ; x + + )
2006-12-11 03:06:49 +00:00
drawosdchar ( 3 + x , osdrowscur , osdeditbuf [ osdeditwinstart + x ] , osdeditshade , osdeditpal ) ;
2006-04-24 19:04:22 +00:00
2006-12-11 03:06:49 +00:00
drawosdcursor ( 3 + osdeditcursor - osdeditwinstart , osdrowscur , osdovertype , keytime ) ;
2007-12-12 17:42:14 +00:00
2006-04-24 19:04:22 +00:00
enddrawing ( ) ;
2006-04-13 20:47:06 +00:00
}
//
// OSD_Printf() -- Print a string to the onscreen display
// and write it to the log file
//
static inline void linefeed ( void )
{
2006-04-24 19:04:22 +00:00
Bmemmove ( osdtext + osdcols , osdtext , TEXTSIZE - osdcols ) ;
Bmemset ( osdtext , 32 , osdcols ) ;
2006-04-13 20:47:06 +00:00
2006-04-24 19:04:22 +00:00
if ( osdlines < osdmaxlines ) osdlines + + ;
2006-04-13 20:47:06 +00:00
}
void OSD_Printf ( const char * fmt , . . . )
{
2006-04-24 19:04:22 +00:00
char tmpstr [ 1024 ] , * chp ;
va_list va ;
if ( ! osdinited ) OSD_Init ( ) ;
va_start ( va , fmt ) ;
Bvsnprintf ( tmpstr , 1024 , fmt , va ) ;
va_end ( va ) ;
2008-05-10 01:29:37 +00:00
if ( linecnt < logcutoff )
2008-01-04 01:04:35 +00:00
{
if ( osdlog & & ( ! logcutoff | | linecnt < logcutoff ) )
Bfputs ( tmpstr , osdlog ) ;
}
2008-05-10 01:29:37 +00:00
else if ( linecnt = = logcutoff )
2008-01-04 01:04:35 +00:00
{
Bfputs ( " \n Maximal log size reached. Logging stopped. \n Set the \" logcutoff \" console variable to a higher value if you need a longer log. \n " , osdlog ) ;
linecnt = logcutoff + 1 ;
}
2006-04-24 19:04:22 +00:00
2007-12-12 17:42:14 +00:00
for ( chp = tmpstr ; * chp ; chp + + )
{
2006-04-24 19:04:22 +00:00
if ( * chp = = ' \r ' ) osdpos = 0 ;
2007-12-12 17:42:14 +00:00
else if ( * chp = = ' \n ' )
{
2006-04-24 19:04:22 +00:00
osdpos = 0 ;
2008-01-04 01:04:35 +00:00
linecnt + + ;
2006-04-24 19:04:22 +00:00
linefeed ( ) ;
2007-12-12 17:42:14 +00:00
}
else
{
2006-04-24 19:04:22 +00:00
osdtext [ osdpos + + ] = * chp ;
2007-12-12 17:42:14 +00:00
if ( osdpos = = osdcols )
{
2006-04-24 19:04:22 +00:00
osdpos = 0 ;
linefeed ( ) ;
}
}
}
2006-04-13 20:47:06 +00:00
}
//
// OSD_DispatchQueued() -- Executes any commands queued in the buffer
//
void OSD_DispatchQueued ( void )
{
2006-04-24 19:04:22 +00:00
int cmd ;
2006-04-13 20:47:06 +00:00
2006-04-24 19:04:22 +00:00
if ( ! osdexeccount ) return ;
2006-04-13 20:47:06 +00:00
2006-04-24 19:04:22 +00:00
cmd = osdexeccount - 1 ;
osdexeccount = 0 ;
2007-12-12 17:42:14 +00:00
for ( ; cmd > = 0 ; cmd - - )
{
2006-04-24 19:04:22 +00:00
OSD_Dispatch ( ( const char * ) osdhistorybuf [ cmd ] ) ;
}
2006-04-13 20:47:06 +00:00
}
//
// OSD_Dispatch() -- Executes a command string
//
static char * strtoken ( char * s , char * * ptrptr , int * restart )
{
2006-04-24 19:04:22 +00:00
char * p , * p2 , * start ;
* restart = 0 ;
if ( ! ptrptr ) return NULL ;
// if s != NULL, we process from the start of s, otherwise
// we just continue with where ptrptr points to
if ( s ) p = s ;
else p = * ptrptr ;
if ( ! p ) return NULL ;
// eat up any leading whitespace
while ( * p ! = 0 & & * p ! = ' ; ' & & * p = = ' ' ) p + + ;
// a semicolon is an end of statement delimiter like a \0 is, so we signal
// the caller to 'restart' for the rest of the string pointed at by *ptrptr
2007-12-12 17:42:14 +00:00
if ( * p = = ' ; ' )
{
2006-04-24 19:04:22 +00:00
* restart = 1 ;
* ptrptr = p + 1 ;
return NULL ;
}
// or if we hit the end of the input, signal all done by nulling *ptrptr
2007-12-12 17:42:14 +00:00
else if ( * p = = 0 )
{
2006-04-24 19:04:22 +00:00
* ptrptr = NULL ;
return NULL ;
}
2007-12-12 17:42:14 +00:00
if ( * p = = ' \" ' )
{
2006-04-24 19:04:22 +00:00
// quoted string
start = + + p ;
p2 = p ;
2007-12-12 17:42:14 +00:00
while ( * p ! = 0 )
{
if ( * p = = ' \" ' )
{
2006-04-24 19:04:22 +00:00
p + + ;
break ;
2007-12-12 17:42:14 +00:00
}
else if ( * p = = ' \\ ' )
{
switch ( * ( + + p ) )
{
2006-11-13 23:12:47 +00:00
case ' n ' :
* p2 = ' \n ' ; break ;
case ' r ' :
* p2 = ' \r ' ; break ;
default :
* p2 = * p ; break ;
2006-04-24 19:04:22 +00:00
}
2007-12-12 17:42:14 +00:00
}
else
{
2006-04-24 19:04:22 +00:00
* p2 = * p ;
}
p2 + + , p + + ;
}
* p2 = 0 ;
2007-12-12 17:42:14 +00:00
}
else
{
2006-04-24 19:04:22 +00:00
start = p ;
while ( * p ! = 0 & & * p ! = ' ; ' & & * p ! = ' ' ) p + + ;
}
// if we hit the end of input, signal all done by nulling *ptrptr
2007-12-12 17:42:14 +00:00
if ( * p = = 0 )
{
2006-04-24 19:04:22 +00:00
* ptrptr = NULL ;
}
// or if we came upon a semicolon, signal caller to restart with the
// string at *ptrptr
2007-12-12 17:42:14 +00:00
else if ( * p = = ' ; ' )
{
2006-04-24 19:04:22 +00:00
* p = 0 ;
* ptrptr = p + 1 ;
* restart = 1 ;
}
// otherwise, clip off the token and carry on
2007-12-12 17:42:14 +00:00
else
{
2006-04-24 19:04:22 +00:00
* ( p + + ) = 0 ;
* ptrptr = p ;
}
return start ;
2006-04-13 20:47:06 +00:00
}
# define MAXPARMS 512
int OSD_Dispatch ( const char * cmd )
{
2006-04-24 19:04:22 +00:00
char * workbuf , * wp , * wtp , * state ;
char * parms [ MAXPARMS ] ;
int numparms , restart = 0 ;
osdfuncparm_t ofp ;
symbol_t * symb ;
//int i;
workbuf = state = Bstrdup ( cmd ) ;
if ( ! workbuf ) return - 1 ;
2007-12-12 17:42:14 +00:00
do
{
2006-04-24 19:04:22 +00:00
numparms = 0 ;
Bmemset ( parms , 0 , sizeof ( parms ) ) ;
wp = strtoken ( state , & wtp , & restart ) ;
2007-12-12 17:42:14 +00:00
if ( ! wp )
{
2006-04-24 19:04:22 +00:00
state = wtp ;
continue ;
}
2008-06-29 12:53:18 +00:00
if ( wp [ 0 ] = = ' / ' & & wp [ 1 ] = = ' / ' ) // cheap hack
{
free ( workbuf ) ;
return - 1 ;
}
2006-04-24 19:04:22 +00:00
symb = findexactsymbol ( wp ) ;
2007-12-12 17:42:14 +00:00
if ( ! symb )
{
2006-04-24 19:04:22 +00:00
OSD_Printf ( " Error: \" %s \" is not defined \n " , wp ) ;
free ( workbuf ) ;
return - 1 ;
}
ofp . name = wp ;
2007-12-12 17:42:14 +00:00
while ( wtp & & ! restart )
{
2006-04-24 19:04:22 +00:00
wp = strtoken ( NULL , & wtp , & restart ) ;
if ( wp & & numparms < MAXPARMS ) parms [ numparms + + ] = wp ;
}
ofp . numparms = numparms ;
ofp . parms = ( const char * * ) parms ;
ofp . raw = cmd ;
2008-06-30 00:18:59 +00:00
if ( symb - > func = = ( void * ) OSD_ALIAS )
2008-06-29 22:37:30 +00:00
OSD_Dispatch ( symb - > help ) ;
2008-06-30 01:03:51 +00:00
else if ( symb - > func ! = ( void * ) OSD_UNALIASED )
2007-12-12 17:42:14 +00:00
{
2008-06-30 00:18:59 +00:00
switch ( symb - > func ( & ofp ) )
{
case OSDCMD_OK :
break ;
case OSDCMD_SHOWHELP :
OSD_Printf ( " %s \n " , symb - > help ) ;
break ;
}
2006-04-24 19:04:22 +00:00
}
state = wtp ;
2007-12-12 17:42:14 +00:00
}
while ( wtp & & restart ) ;
2006-04-24 19:04:22 +00:00
free ( workbuf ) ;
return 0 ;
2006-04-13 20:47:06 +00:00
}
//
// OSD_RegisterFunction() -- Registers a new function
//
int OSD_RegisterFunction ( const char * name , const char * help , int ( * func ) ( const osdfuncparm_t * ) )
{
2006-04-24 19:04:22 +00:00
symbol_t * symb ;
const char * cp ;
if ( ! osdinited ) OSD_Init ( ) ;
2007-12-12 17:42:14 +00:00
if ( ! name )
{
2008-06-29 22:37:30 +00:00
OSD_Printf ( " OSD_RegisterFunction(): may not register a function with a null name \n " ) ;
2006-04-24 19:04:22 +00:00
return - 1 ;
}
2007-12-12 17:42:14 +00:00
if ( ! name [ 0 ] )
{
2008-06-29 22:37:30 +00:00
OSD_Printf ( " OSD_RegisterFunction(): may not register a function with no name \n " ) ;
2006-04-24 19:04:22 +00:00
return - 1 ;
}
// check for illegal characters in name
2007-12-12 17:42:14 +00:00
for ( cp = name ; * cp ; cp + + )
{
if ( ( cp = = name ) & & ( * cp > = ' 0 ' ) & & ( * cp < = ' 9 ' ) )
{
2008-06-29 22:37:30 +00:00
OSD_Printf ( " OSD_RegisterFunction(): first character of function name \" %s \" must not be a numeral \n " , name ) ;
2006-04-24 19:04:22 +00:00
return - 1 ;
}
if ( ( * cp < ' 0 ' ) | |
( * cp > ' 9 ' & & * cp < ' A ' ) | |
( * cp > ' Z ' & & * cp < ' a ' & & * cp ! = ' _ ' ) | |
2007-12-12 17:42:14 +00:00
( * cp > ' z ' ) )
{
2008-06-29 22:37:30 +00:00
OSD_Printf ( " OSD_RegisterFunction(): illegal character in function name \" %s \" \n " , name ) ;
2006-04-24 19:04:22 +00:00
return - 1 ;
}
}
if ( ! help ) help = " (no description for this function) " ;
2007-12-12 17:42:14 +00:00
if ( ! func )
{
2008-06-29 22:37:30 +00:00
OSD_Printf ( " OSD_RegisterFunction(): may not register a null function \n " ) ;
2006-04-24 19:04:22 +00:00
return - 1 ;
}
symb = findexactsymbol ( name ) ;
2008-06-29 22:37:30 +00:00
if ( symb ) // allow this now for reusing an alias name
2007-12-12 17:42:14 +00:00
{
2008-06-30 01:03:51 +00:00
if ( symb - > func ! = ( void * ) OSD_ALIAS & & symb - > func ! = ( void * ) OSD_UNALIASED )
2008-06-30 00:18:59 +00:00
{
OSD_Printf ( " OSD_RegisterFunction(): \" %s \" is already defined \n " , name ) ;
return - 1 ;
}
2008-06-30 00:32:05 +00:00
Bfree ( ( char * ) symb - > help ) ;
2008-06-29 22:37:30 +00:00
symb - > help = help ;
2008-06-30 01:03:51 +00:00
symb - > func = func ;
2008-06-30 00:32:05 +00:00
return 0 ;
2006-04-24 19:04:22 +00:00
}
symb = addnewsymbol ( name ) ;
2007-12-12 17:42:14 +00:00
if ( ! symb )
{
2008-06-29 22:37:30 +00:00
OSD_Printf ( " OSD_RegisterFunction(): Failed registering function \" %s \" \n " , name ) ;
2006-04-24 19:04:22 +00:00
return - 1 ;
}
symb - > name = name ;
symb - > help = help ;
symb - > func = func ;
return 0 ;
2006-04-13 20:47:06 +00:00
}
2006-12-11 04:38:10 +00:00
//
// OSD_SetVersionString()
//
2007-04-17 05:54:12 +00:00
void OSD_SetVersionString ( const char * version , int shade , int pal )
2006-12-11 04:38:10 +00:00
{
if ( ! osdinited ) OSD_Init ( ) ;
2007-04-17 05:54:12 +00:00
Bstrcpy ( osdversionstring , version ) ;
osdversionstringlen = Bstrlen ( osdversionstring ) ;
osdversionstringshade = shade ;
osdversionstringpal = pal ;
2006-12-11 04:38:10 +00:00
}
2006-04-13 20:47:06 +00:00
//
// addnewsymbol() -- Allocates space for a new symbol and attaches it
// appropriately to the lists, sorted.
//
static symbol_t * addnewsymbol ( const char * name )
{
2006-04-24 19:04:22 +00:00
symbol_t * newsymb , * s , * t ;
newsymb = ( symbol_t * ) Bmalloc ( sizeof ( symbol_t ) ) ;
if ( ! newsymb ) { return NULL ; }
Bmemset ( newsymb , 0 , sizeof ( symbol_t ) ) ;
// link it to the main chain
2007-12-12 17:42:14 +00:00
if ( ! symbols )
{
2006-04-24 19:04:22 +00:00
symbols = newsymb ;
2007-12-12 17:42:14 +00:00
}
else
{
if ( Bstrcasecmp ( name , symbols - > name ) < = 0 )
{
2006-04-24 19:04:22 +00:00
t = symbols ;
symbols = newsymb ;
symbols - > next = t ;
2007-12-12 17:42:14 +00:00
}
else
{
2006-04-24 19:04:22 +00:00
s = symbols ;
2007-12-12 17:42:14 +00:00
while ( s - > next )
{
2006-04-24 19:04:22 +00:00
if ( Bstrcasecmp ( s - > next - > name , name ) > 0 ) break ;
s = s - > next ;
}
t = s - > next ;
s - > next = newsymb ;
newsymb - > next = t ;
}
}
return newsymb ;
2006-04-13 20:47:06 +00:00
}
//
// findsymbol() -- Finds a symbol, possibly partially named
2006-04-24 19:04:22 +00:00
//
2006-04-13 20:47:06 +00:00
static symbol_t * findsymbol ( const char * name , symbol_t * startingat )
{
2006-04-24 19:04:22 +00:00
if ( ! startingat ) startingat = symbols ;
if ( ! startingat ) return NULL ;
2006-04-13 20:47:06 +00:00
2006-04-24 19:04:22 +00:00
for ( ; startingat ; startingat = startingat - > next )
2008-06-30 01:03:51 +00:00
if ( startingat - > func ! = ( void * ) OSD_UNALIASED & & ! Bstrncasecmp ( name , startingat - > name , Bstrlen ( name ) ) ) return startingat ;
2006-04-13 20:47:06 +00:00
2006-04-24 19:04:22 +00:00
return NULL ;
2006-04-13 20:47:06 +00:00
}
//
// findexactsymbol() -- Finds a symbol, complete named
2006-04-24 19:04:22 +00:00
//
2006-04-13 20:47:06 +00:00
static symbol_t * findexactsymbol ( const char * name )
{
2006-04-24 19:04:22 +00:00
symbol_t * startingat ;
if ( ! symbols ) return NULL ;
2006-04-13 20:47:06 +00:00
2006-04-24 19:04:22 +00:00
startingat = symbols ;
2006-04-13 20:47:06 +00:00
2006-04-24 19:04:22 +00:00
for ( ; startingat ; startingat = startingat - > next )
if ( ! Bstrcasecmp ( name , startingat - > name ) ) return startingat ;
2006-04-13 20:47:06 +00:00
2006-04-24 19:04:22 +00:00
return NULL ;
2006-04-13 20:47:06 +00:00
}