2004-08-23 00:15:46 +00:00
//DMW
/*
F1 will return to progs . src
F2 will try to open a file with the name of which is on that line . ( excluding comments / tabs ) . Needs conditions .
F3 will give a prompt for typing in a value name to see the value .
F4 will save
F5 will run ( unbreak ) .
F6 will list the stack .
F7 will compile .
F8 will move execution
F9 will set a break point .
F10 will apply code changes .
F11 will step through .
*/
# include "quakedef.h"
# ifdef TEXTEDITOR
2006-02-11 02:09:43 +00:00
cvar_t alloweditor = SCVAR ( " alloweditor " , " 1 " ) ; //disallow loading editor for stepbystep debugging.
cvar_t editstripcr = SCVAR ( " edit_stripcr " , " 1 " ) ; //remove \r from eols (on load).
cvar_t editaddcr = SCVAR ( " edit_addcr " , " 1 " ) ; //make sure that each line ends with a \r (on save).
cvar_t edittabspacing = SCVAR ( " edit_tabsize " , " 4 " ) ;
2004-08-23 00:15:46 +00:00
# undef pr_trace
progfuncs_t * editprogfuncs ;
typedef struct fileblock_s {
struct fileblock_s * next ;
struct fileblock_s * prev ;
int allocatedlength ;
int datalength ;
int flags ;
char * data ;
} fileblock_t ;
# define FB_BREAK 1
2009-07-11 20:56:09 +00:00
static fileblock_t * cursorblock , * firstblock , * executionblock , * viewportystartblock ;
2004-08-23 00:15:46 +00:00
void * E_Malloc ( int size )
{
char * mem ;
mem = Z_Malloc ( size ) ;
if ( ! mem )
Sys_Error ( " Failed to allocate enough mem for editor \n " ) ;
return mem ;
}
void E_Free ( void * mem )
{
Z_Free ( mem ) ;
}
# define GETBLOCK(s, ret) ret = (void *)E_Malloc(sizeof(fileblock_t) + s);ret->allocatedlength = s;ret->data = (char *)ret + sizeof(fileblock_t)
char OpenEditorFile [ 256 ] ;
qboolean editoractive ; //(export)
qboolean editormodal ; //doesn't return. (export)
qboolean editorblocking ;
qboolean madechanges ;
2006-03-10 03:50:23 +00:00
qboolean insertkeyhit = true ;
2004-08-23 00:15:46 +00:00
qboolean useeval ;
char evalstring [ 256 ] ;
int executionlinenum ; //step by step debugger
int cursorlinenum , cursorx ;
int viewportx ;
int viewporty ;
2005-12-21 03:07:33 +00:00
static int VFS_GETC ( vfsfile_t * fp )
{
unsigned char c ;
VFS_READ ( fp , & c , 1 ) ;
return c ;
}
2004-08-23 00:15:46 +00:00
//newsize = number of chars, EXCLUDING terminator.
void MakeNewSize ( fileblock_t * block , int newsize ) //this is used to resize a block. It allocates a new one, copys the data frees the old one and links it into the right place
//it is called when the user is typing
{
fileblock_t * newblock ;
newsize = ( newsize + 4 ) & ~ 3 ; //We allocate a bit extra, so we don't need to keep finding a new block for each and every character.
if ( block - > allocatedlength > = newsize )
return ; //Ignore. This block is too large already. Don't bother resizeing, cos that's pretty much pointless.
GETBLOCK ( newsize , newblock ) ;
memcpy ( newblock - > data , block - > data , block - > datalength ) ;
newblock - > prev = block - > prev ;
newblock - > next = block - > next ;
if ( newblock - > prev )
newblock - > prev - > next = newblock ;
if ( newblock - > next )
newblock - > next - > prev = newblock ;
newblock - > datalength = block - > datalength ;
newblock - > flags = block - > flags ;
E_Free ( block ) ;
if ( firstblock = = block )
firstblock = newblock ;
if ( cursorblock = = block )
cursorblock = newblock ;
}
int positionacross ;
void GetCursorpos ( void )
{
int a ;
char * s ;
int ts = edittabspacing . value ;
if ( ts < 1 )
ts = 4 ;
for ( a = 0 , positionacross = 0 , s = cursorblock - > data ; a < cursorx & & * s ; s + + , a + + )
{
if ( * s = = ' \t ' )
{
positionacross + = ts ;
positionacross - = cursorx % ts ;
}
else
positionacross + + ;
}
// positionacross = cursorofs;
}
void SetCursorpos ( void )
{
int a = 0 ;
char * s ;
int ts = edittabspacing . value ;
if ( ts < 1 )
ts = 4 ;
for ( cursorx = 0 , s = cursorblock - > data ; cursorx < positionacross & & * s ; s + + , a + + )
2005-12-21 03:07:33 +00:00
{
2004-08-23 00:15:46 +00:00
if ( * s = = ' \t ' )
{
cursorx + = ts ;
cursorx - = cursorx % ts ;
}
else
cursorx + + ;
}
cursorx = a ;
//just in case
if ( cursorx > cursorblock - > datalength )
cursorx = cursorblock - > datalength ;
}
void CloseEditor ( void )
{
fileblock_t * b ;
key_dest = key_console ;
editoractive = false ;
if ( ! firstblock )
return ;
OpenEditorFile [ 0 ] = ' \0 ' ;
for ( b = firstblock ; b ; )
{
firstblock = b ;
b = b - > next ;
E_Free ( firstblock ) ;
}
madechanges = false ;
2005-05-26 12:55:34 +00:00
editormodal = false ;
2004-08-23 00:15:46 +00:00
firstblock = NULL ;
executionlinenum = - 1 ;
}
qboolean EditorSaveFile ( char * s ) //returns true if succesful
{
// FILE *F;
fileblock_t * b ;
int len = 0 ;
int pos = 0 ;
char * data ;
for ( b = firstblock ; b ; b = b - > next ) //find total length required.
{
len + = b - > datalength ;
len + = 2 ; //extra for \n
}
data = Hunk_TempAlloc ( len ) ;
for ( b = firstblock ; b ; b = b - > next ) //find total length required.
{
memcpy ( data + pos , b - > data , b - > datalength ) ;
pos + = b - > datalength ;
if ( editaddcr . value )
{
data [ pos ] = ' \r ' ;
pos + + ;
}
data [ pos ] = ' \n ' ;
pos + + ;
}
COM_WriteFile ( s , data , len ) ;
/*
F = fopen ( s , " wt " ) ;
if ( ! F )
return false ;
for ( b = firstblock ; b ; b = b - > next )
{
fprintf ( F , " %s \n " , b - > data ) ;
}
fclose ( F ) ;
*/
madechanges = false ;
executionlinenum = - 1 ;
return true ;
}
void EditorNewFile ( )
{
2005-12-21 03:07:33 +00:00
GETBLOCK ( 64 , firstblock ) ;
2004-08-23 00:15:46 +00:00
GETBLOCK ( 64 , firstblock - > next ) ;
firstblock - > next - > prev = firstblock ;
cursorblock = firstblock ;
cursorlinenum = 0 ;
cursorx = 0 ;
viewportystartblock = NULL ;
madechanges = true ;
executionlinenum = - 1 ;
2005-12-21 03:07:33 +00:00
key_dest = key_editor ;
2004-08-23 00:15:46 +00:00
editoractive = true ;
}
void EditorOpenFile ( char * name )
{
int i ;
char line [ 8192 ] ;
int len , flen , pos = 0 ;
2005-12-21 03:07:33 +00:00
vfsfile_t * F ;
fileblock_t * b ;
2004-08-23 00:15:46 +00:00
2005-12-21 03:07:33 +00:00
CloseEditor ( ) ;
2004-08-23 00:15:46 +00:00
strcpy ( OpenEditorFile , name ) ;
2005-12-21 03:07:33 +00:00
if ( ! ( F = FS_OpenVFS ( OpenEditorFile , " rb " , FS_GAME ) ) )
2004-08-23 00:15:46 +00:00
{
sprintf ( OpenEditorFile , " src/%s " , name ) ;
2005-12-21 03:07:33 +00:00
if ( ! ( F = FS_OpenVFS ( OpenEditorFile , " rb " , FS_GAME ) ) )
2004-08-23 00:15:46 +00:00
{
2005-12-21 03:07:33 +00:00
Con_Printf ( " Couldn't open file \" %s \" \n A new file will be created \n " , name ) ;
strcpy ( OpenEditorFile , name ) ;
key_dest = key_console ;
EditorNewFile ( ) ;
return ;
2004-08-23 00:15:46 +00:00
}
}
i = 1 ;
2005-12-21 03:07:33 +00:00
flen = VFS_GETLEN ( F ) ;
2004-08-23 00:15:46 +00:00
while ( pos < flen )
{
len = 0 ;
for ( ; ; )
{
2006-03-10 03:50:23 +00:00
if ( pos + len > = flen | | len > sizeof ( line ) - 16 )
2004-08-23 00:15:46 +00:00
break ;
2005-12-21 03:07:33 +00:00
line [ len ] = VFS_GETC ( F ) ;
2004-08-23 00:15:46 +00:00
if ( line [ len ] = = ' \n ' )
break ;
len + + ;
}
pos + = len ;
pos + + ; //and a \n
if ( editstripcr . value )
{
if ( line [ len - 1 ] = = ' \r ' )
len - - ;
}
b = firstblock ;
GETBLOCK ( len + 1 , firstblock ) ;
firstblock - > prev = b ;
if ( b )
b - > next = firstblock ;
firstblock - > datalength = len ;
memcpy ( firstblock - > data , line , len ) ;
2005-08-03 23:14:59 +00:00
if ( editprogfuncs )
{
2009-04-01 22:03:56 +00:00
if ( editprogfuncs - > ToggleBreak ( editprogfuncs , OpenEditorFile , i , 3 ) )
2005-08-03 23:14:59 +00:00
{
2005-12-21 03:07:33 +00:00
firstblock - > flags | = FB_BREAK ;
2005-08-03 23:14:59 +00:00
}
}
else
2004-08-23 00:15:46 +00:00
{
2005-08-03 23:14:59 +00:00
if ( svprogfuncs )
{
2009-04-01 22:03:56 +00:00
if ( svprogfuncs - > ToggleBreak ( svprogfuncs , OpenEditorFile , i , 3 ) )
2005-08-03 23:14:59 +00:00
{
2005-12-21 03:07:33 +00:00
firstblock - > flags | = FB_BREAK ;
2005-08-03 23:14:59 +00:00
}
}
2004-08-23 00:15:46 +00:00
}
i + + ;
}
if ( firstblock = = NULL )
{
2005-12-21 03:07:33 +00:00
GETBLOCK ( 10 , firstblock ) ;
}
2004-08-23 00:15:46 +00:00
else
for ( ; firstblock - > prev ; firstblock = firstblock - > prev ) ;
2005-12-21 03:07:33 +00:00
VFS_CLOSE ( F ) ;
2004-08-23 00:15:46 +00:00
cursorblock = firstblock ;
cursorx = 0 ;
viewportystartblock = NULL ;
madechanges = false ;
executionlinenum = - 1 ;
2005-12-21 03:07:33 +00:00
key_dest = key_editor ;
2004-08-23 00:15:46 +00:00
editoractive = true ;
}
2009-07-25 11:05:06 +00:00
void Editor_Key ( int key , int unicode )
2004-08-23 00:15:46 +00:00
{
int i ;
if ( keybindings [ key ] [ 0 ] )
if ( ! strcmp ( keybindings [ key ] [ 0 ] , " toggleconsole " ) )
{
key_dest = key_console ;
return ;
}
/* if (CmdAfterSave)
{
switch ( key )
{
case ' Y ' :
case ' y ' :
if ( ! EditorSaveFile ( OpenEditorFile ) )
{
Con_Printf ( " Couldn't save file \" %s \" \n " , OpenEditorFile ) ;
key_dest = key_console ;
}
else if ( ! CmdAfterSaveCalled )
{
CmdAfterSaveCalled = true ;
( * CmdAfterSave ) ( ) ;
CmdAfterSaveCalled = false ;
}
CmdAfterSave = NULL ;
break ;
case ' N ' :
2005-12-21 03:07:33 +00:00
case ' n ' :
2004-08-23 00:15:46 +00:00
( * CmdAfterSave ) ( ) ;
CmdAfterSave = NULL ;
break ;
case ' C ' :
case ' c ' :
CmdAfterSave = NULL ;
break ;
}
return ;
}
*/
if ( key = = K_SHIFT )
return ;
2006-09-18 22:52:33 +00:00
if ( useeval & & key ! = K_F11 & & key ! = K_F5 )
2004-08-23 00:15:46 +00:00
{
switch ( key )
{
case K_ESCAPE :
2005-05-26 12:55:34 +00:00
if ( editprogfuncs )
* editprogfuncs - > pr_trace = 0 ;
useeval = false ;
break ;
case K_F3 :
2004-08-23 00:15:46 +00:00
useeval = false ;
break ;
case K_DEL :
evalstring [ 0 ] = ' \0 ' ;
break ;
case K_BACKSPACE :
i = strlen ( evalstring ) ;
if ( i < 1 )
break ;
evalstring [ i - 1 ] = ' \0 ' ;
break ;
default :
2009-07-25 11:05:06 +00:00
if ( unicode )
{
i = strlen ( evalstring ) ;
evalstring [ i ] = unicode ;
evalstring [ i + 1 ] = ' \0 ' ;
}
2004-08-23 00:15:46 +00:00
break ;
}
return ;
}
/* if (ctrl_down && (key == 'c' || key == K_INS))
key = K_F9 ;
if ( ( ctrl_down & & key = = ' v ' ) | | ( shift_down & & key = = K_INS ) )
key = K_F10 ;
*/
switch ( key )
{
case K_SHIFT :
break ;
case K_ALT :
break ;
case K_CTRL :
break ;
case K_PGUP :
GetCursorpos ( ) ;
{ int a = ( vid . height / 8 ) / 2 ;
while ( a ) { a - - ;
if ( cursorblock - > prev )
{
cursorblock = cursorblock - > prev ;
cursorlinenum - - ;
}
2005-12-21 03:07:33 +00:00
}
2004-08-23 00:15:46 +00:00
}
SetCursorpos ( ) ;
break ;
case K_PGDN :
GetCursorpos ( ) ;
{ int a = ( vid . height / 8 ) / 2 ;
while ( a )
{
a - - ;
if ( cursorblock - > next )
{
cursorblock = cursorblock - > next ;
cursorlinenum + + ;
}
}
}
SetCursorpos ( ) ;
break ;
// case K_BACK:
case K_F1 :
// Editor_f();
break ;
// case K_FORWARD:
case K_F2 :
{
char file [ 1024 ] ;
char * s ;
Q_strncpyz ( file , cursorblock - > data , sizeof ( file ) ) ;
s = file ;
while ( * s )
{
if ( ( * s = = ' / ' & & s [ 1 ] = = ' / ' ) | | ( * s = = ' \t ' ) )
{
* s = ' \0 ' ;
break ;
2005-12-21 03:07:33 +00:00
}
2004-08-23 00:15:46 +00:00
s + + ;
}
if ( * file )
EditorOpenFile ( file ) ;
}
break ;
case K_F3 :
2006-03-10 03:50:23 +00:00
if ( editprogfuncs )
useeval = true ;
2004-08-23 00:15:46 +00:00
break ;
case K_F4 :
EditorSaveFile ( OpenEditorFile ) ;
break ;
2005-12-21 03:07:33 +00:00
case K_F5 :
2004-08-23 00:15:46 +00:00
editormodal = false ;
if ( editprogfuncs )
* editprogfuncs - > pr_trace = false ;
break ;
case K_F6 :
if ( editprogfuncs )
2005-12-21 03:07:33 +00:00
PR_StackTrace ( editprogfuncs ) ;
2004-08-23 00:15:46 +00:00
break ;
case K_F7 :
EditorSaveFile ( OpenEditorFile ) ;
2006-03-10 03:50:23 +00:00
if ( editprogfuncs )
Cbuf_AddText ( " compile \n " , RESTRICT_LOCAL ) ;
2004-08-23 00:15:46 +00:00
break ;
case K_F8 :
executionlinenum = cursorlinenum ;
executionblock = cursorblock ;
break ;
case K_F9 :
{
int f = 0 ;
2006-03-10 03:50:23 +00:00
if ( editprogfuncs )
{
if ( editprogfuncs - > ToggleBreak ( editprogfuncs , OpenEditorFile + 4 , cursorlinenum , 2 ) )
f | = 1 ;
else
f | = 2 ;
}
2005-08-03 23:14:59 +00:00
# ifndef CLIENTONLY
2006-03-10 03:50:23 +00:00
else if ( svprogfuncs )
{
if ( svprogfuncs - > ToggleBreak ( svprogfuncs , OpenEditorFile + 4 , cursorlinenum , 2 ) )
f | = 1 ;
else
f | = 2 ;
}
2004-08-23 00:15:46 +00:00
# endif
2006-03-10 03:50:23 +00:00
if ( f & 1 )
cursorblock - > flags | = FB_BREAK ;
else
cursorblock - > flags & = ~ FB_BREAK ;
2004-08-23 00:15:46 +00:00
}
break ;
case K_F10 :
EditorSaveFile ( OpenEditorFile ) ;
Cbuf_AddText ( " applycompile \n " , RESTRICT_LOCAL ) ;
break ;
case K_F11 :
editormodal = false ;
break ;
// case K_STOP:
case K_ESCAPE :
2006-09-18 22:52:33 +00:00
if ( editprogfuncs )
editprogfuncs - > AbortStack ( editprogfuncs ) ;
2004-08-23 00:15:46 +00:00
CloseEditor ( ) ;
break ;
case K_HOME :
cursorx = 0 ;
break ;
case K_END :
cursorx = cursorblock - > datalength ;
break ;
case K_LEFTARROW :
cursorx - - ;
if ( cursorx < 0 )
cursorx = 0 ;
break ;
case K_RIGHTARROW :
cursorx + + ;
if ( cursorx > cursorblock - > datalength )
cursorx = cursorblock - > datalength ;
break ;
case K_MWHEELUP :
case K_UPARROW :
GetCursorpos ( ) ;
if ( cursorblock - > prev )
{
cursorblock = cursorblock - > prev ;
cursorlinenum - - ;
}
SetCursorpos ( ) ;
break ;
case K_MWHEELDOWN :
case K_DOWNARROW :
GetCursorpos ( ) ;
if ( cursorblock - > next )
{
cursorblock = cursorblock - > next ;
cursorlinenum + + ;
}
SetCursorpos ( ) ;
break ;
case K_BACKSPACE :
cursorx - - ;
if ( cursorx < 0 )
{
fileblock_t * b = cursorblock ;
if ( b = = firstblock ) //no line above to remove to
{
cursorx = 0 ;
break ;
}
cursorlinenum - = 1 ;
madechanges = true ;
cursorblock = b - > prev ;
MakeNewSize ( cursorblock , b - > datalength + cursorblock - > datalength + 5 ) ;
cursorx = cursorblock - > datalength ;
memcpy ( cursorblock - > data + cursorblock - > datalength , b - > data , b - > datalength ) ;
2006-03-10 03:50:23 +00:00
cursorblock - > datalength + = b - > datalength ;
2004-08-23 00:15:46 +00:00
cursorblock - > next = b - > next ;
if ( b - > next )
b - > next - > prev = cursorblock ;
// cursorblock->prev->next = cursorblock->next;
// cursorblock->next->prev = cursorblock->prev;
E_Free ( b ) ;
2005-12-21 03:07:33 +00:00
// cursorblock = b;
2004-08-23 00:15:46 +00:00
break ;
}
case K_DEL : //bksp falls through.
{
int a ;
fileblock_t * b ;
cursorlinenum = - 1 ;
madechanges = true ;
//FIXME: does this work right?
if ( ! cursorblock - > datalength & & cursorblock - > next & & cursorblock - > prev ) //blank line
2005-12-21 03:07:33 +00:00
{
2004-08-23 00:15:46 +00:00
b = cursorblock ;
2005-12-21 03:07:33 +00:00
if ( b - > next )
2004-08-23 00:15:46 +00:00
b - > next - > prev = b - > prev ;
if ( b - > prev )
2005-12-21 03:07:33 +00:00
b - > prev - > next = b - > next ;
2004-08-23 00:15:46 +00:00
if ( cursorblock - > next )
cursorblock = cursorblock - > next ;
else
cursorblock = cursorblock - > prev ;
E_Free ( b ) ;
}
else
{
for ( a = cursorx ; a < cursorblock - > datalength ; a + + )
cursorblock - > data [ a ] = cursorblock - > data [ a + 1 ] ;
cursorblock - > datalength - - ;
}
2006-03-10 03:50:23 +00:00
if ( cursorx > cursorblock - > datalength )
cursorx = cursorblock - > datalength ;
2004-08-23 00:15:46 +00:00
}
break ;
2005-12-21 03:07:33 +00:00
case K_ENTER :
2004-08-23 00:15:46 +00:00
{
fileblock_t * b = cursorblock ;
cursorlinenum = - 1 ;
madechanges = true ;
2006-03-10 03:50:23 +00:00
GETBLOCK ( b - > datalength - cursorx , cursorblock ) ;
2004-08-23 00:15:46 +00:00
cursorblock - > next = b - > next ;
cursorblock - > prev = b ;
b - > next = cursorblock ;
if ( cursorblock - > next )
cursorblock - > next - > prev = cursorblock ;
if ( cursorblock - > prev )
cursorblock - > prev - > next = cursorblock ;
2006-03-10 03:50:23 +00:00
cursorblock - > datalength = b - > datalength - cursorx ;
memcpy ( cursorblock - > data , b - > data + cursorx , cursorblock - > datalength ) ;
b - > datalength = cursorx ;
2004-08-23 00:15:46 +00:00
cursorx = 0 ;
}
break ;
case K_INS :
insertkeyhit = insertkeyhit ? false : true ;
break ;
default :
2009-07-25 11:05:06 +00:00
if ( unicode < ' ' & & unicode ! = ' \t ' ) //we deem these as unprintable
2004-08-23 00:15:46 +00:00
break ;
if ( insertkeyhit ) //insert a char
{
char * s ;
madechanges = true ;
MakeNewSize ( cursorblock , cursorblock - > datalength + 5 ) ; //allocate a bit extra, so we don't need to keep resizing it and shifting loads a data about
s = cursorblock - > data + cursorblock - > datalength ;
while ( s > = cursorblock - > data + cursorx )
{
s [ 1 ] = s [ 0 ] ;
s - - ;
}
cursorx + + ;
cursorblock - > datalength + + ;
2009-07-25 11:05:06 +00:00
* ( s + 1 ) = unicode ;
2004-08-23 00:15:46 +00:00
}
else //over write a char
2005-12-21 03:07:33 +00:00
{
2004-08-23 00:15:46 +00:00
MakeNewSize ( cursorblock , cursorblock - > datalength + 5 ) ; //not really needed
2005-12-21 03:07:33 +00:00
2009-07-25 11:05:06 +00:00
cursorblock - > data [ cursorx ] = unicode ;
2004-08-23 00:15:46 +00:00
cursorx + + ;
2006-03-10 03:50:23 +00:00
if ( cursorx > cursorblock - > datalength )
cursorblock - > datalength = cursorx ;
2004-08-23 00:15:46 +00:00
}
break ;
}
}
void Draw_CursorLine ( int ox , int y , fileblock_t * b )
{
int x = 0 ;
qbyte * d = b - > data ;
int cx ;
int a = 0 , i ;
2005-10-01 03:09:17 +00:00
int colour = COLOR_BLUE ;
2004-08-23 00:15:46 +00:00
int ts = edittabspacing . value ;
if ( ts < 1 )
ts = 4 ;
ts * = 8 ;
if ( b - > flags & ( FB_BREAK ) )
2005-12-21 03:07:33 +00:00
colour = COLOR_RED ; //red
2004-08-23 00:15:46 +00:00
if ( executionblock = = b )
{
if ( colour ) //break point too
2005-01-04 07:27:50 +00:00
colour = COLOR_GREEN ; //green
2004-08-23 00:15:46 +00:00
else
2005-01-04 07:27:50 +00:00
colour = COLOR_YELLOW ; //yellow
2004-08-23 00:15:46 +00:00
}
2006-09-18 22:52:33 +00:00
if ( cursorx < = strlen ( d ) + 1 & & ( int ) ( Sys_DoubleTime ( ) * 4.0 ) & 1 )
2004-08-23 00:15:46 +00:00
cx = - 1 ;
else
cx = cursorx ;
for ( i = 0 ; i < b - > datalength ; i + + )
{
if ( * d = = ' \t ' )
{
if ( a = = cx )
2006-01-01 09:01:15 +00:00
Draw_ColouredCharacter ( x + ox , y , 11 | CON_WHITEMASK ) ;
2004-08-23 00:15:46 +00:00
x + = ts ;
x - = x % ts ;
d + + ;
a + + ;
continue ;
}
if ( x + ox < vid . width )
{
if ( a = = cx )
2006-01-01 09:01:15 +00:00
Draw_ColouredCharacter ( x + ox , y , 11 | CON_WHITEMASK ) ;
2004-08-23 00:15:46 +00:00
else
2006-01-01 09:01:15 +00:00
Draw_ColouredCharacter ( x + ox , y , ( int ) * d | ( colour < < CON_FGSHIFT ) ) ;
2004-08-23 00:15:46 +00:00
}
d + + ;
x + = 8 ;
a + + ;
}
if ( a = = cx )
2006-03-10 03:50:23 +00:00
Draw_ColouredCharacter ( x + ox , y , 11 | CON_WHITEMASK ) ;
2004-08-23 00:15:46 +00:00
}
void Draw_NonCursorLine ( int x , int y , fileblock_t * b )
{
int nx = 0 ;
qbyte * d = b - > data ;
int i ;
2005-01-04 07:27:50 +00:00
int colour = COLOR_WHITE ;
2004-08-23 00:15:46 +00:00
int ts = edittabspacing . value ;
if ( ts < 1 )
ts = 4 ;
ts * = 8 ;
if ( b - > flags & ( FB_BREAK ) )
2005-12-21 03:07:33 +00:00
colour = COLOR_RED ; //red
2004-08-23 00:15:46 +00:00
if ( executionblock = = b )
{
if ( colour ) //break point too
2005-01-04 07:27:50 +00:00
colour = COLOR_GREEN ; //green
2004-08-23 00:15:46 +00:00
else
2005-01-04 07:27:50 +00:00
colour = COLOR_YELLOW ; //yellow
2004-08-23 00:15:46 +00:00
}
for ( i = 0 ; i < b - > datalength ; i + + )
{
if ( * d = = ' \t ' )
{
nx + = ts ;
nx - = nx % ts ;
2005-12-21 03:07:33 +00:00
d + + ;
continue ;
2004-08-23 00:15:46 +00:00
}
if ( x + nx < vid . width )
2006-01-01 09:01:15 +00:00
Draw_ColouredCharacter ( x + nx , y , ( int ) * d | ( colour < < CON_FGSHIFT ) ) ;
2004-08-23 00:15:46 +00:00
d + + ;
2005-12-21 03:07:33 +00:00
nx + = 8 ;
}
2004-08-23 00:15:46 +00:00
}
fileblock_t * firstline ( void )
{
int lines ;
fileblock_t * b ;
lines = ( vid . height / 8 ) / 2 - 1 ;
b = cursorblock ;
if ( ! b )
return NULL ;
while ( 1 )
{
if ( ! b - > prev )
return b ;
b = b - > prev ;
lines - - ;
if ( lines < = 0 )
return b ;
}
return NULL ;
}
void Editor_Draw ( void )
{
int x ;
int y ;
fileblock_t * b ;
if ( key_dest ! = key_console )
key_dest = key_editor ;
if ( ( editoractive & & cls . state = = ca_disconnected ) | | editormodal )
Draw_EditorBackground ( vid . height ) ;
if ( cursorlinenum < 0 ) //look for the cursor line num
{
cursorlinenum = 0 ;
for ( b = firstblock ; b ; b = b - > next )
{
cursorlinenum + + ;
if ( b = = cursorblock )
break ;
2005-12-21 03:07:33 +00:00
}
2004-08-23 00:15:46 +00:00
}
if ( ! viewportystartblock ) //look for the cursor line num
{
y = 0 ;
for ( viewportystartblock = firstblock ; viewportystartblock ; viewportystartblock = viewportystartblock - > prev )
{
y + + ;
if ( y = = viewporty )
break ;
2005-12-21 03:07:33 +00:00
}
2004-08-23 00:15:46 +00:00
}
x = 0 ;
for ( y = 0 ; y < cursorx ; y + + )
{
if ( cursorblock - > data [ y ] = = ' \0 ' )
break ;
else if ( cursorblock - > data [ y ] = = ' \t ' )
{
x + = 32 ;
x & = ~ 31 ;
}
else
x + = 8 ;
}
x = - x + vid . width / 2 ;
if ( x > 0 )
x = 0 ;
2005-12-21 03:07:33 +00:00
2004-08-23 00:15:46 +00:00
if ( madechanges )
2006-01-01 09:01:15 +00:00
Draw_Character ( vid . width - 8 , 0 , ' ! ' | CON_HIGHCHARSMASK ) ;
2004-08-23 00:15:46 +00:00
if ( ! insertkeyhit )
2006-01-01 09:01:15 +00:00
Draw_Character ( vid . width - 16 , 0 , ' O ' | CON_HIGHCHARSMASK ) ;
2004-08-23 00:15:46 +00:00
Draw_String ( 0 , 0 , va ( " %6i:%4i:%s " , cursorlinenum , cursorx + 1 , OpenEditorFile ) ) ;
if ( useeval )
{
if ( ! editprogfuncs )
useeval = false ;
else
{
2006-09-18 22:52:33 +00:00
char * eq ;
2004-08-23 00:15:46 +00:00
Draw_String ( 0 , 8 , evalstring ) ;
2006-09-18 22:52:33 +00:00
eq = strchr ( evalstring , ' = ' ) ;
if ( eq )
{
if ( strchr ( eq , ' ; ' ) )
{
* strchr ( eq , ' ; ' ) = ' \0 ' ;
eq = NULL ;
}
else
* eq = ' \0 ' ;
}
2004-08-23 00:15:46 +00:00
Draw_String ( vid . width / 2 , 8 , editprogfuncs - > EvaluateDebugString ( editprogfuncs , evalstring ) ) ;
2006-09-18 22:52:33 +00:00
if ( eq )
* eq = ' = ' ;
2004-08-23 00:15:46 +00:00
}
y = 16 ;
}
else
y = 8 ;
b = firstline ( ) ;
for ( ; b ; b = b - > next )
{
if ( b = = cursorblock )
Draw_CursorLine ( x , y , b ) ;
2005-12-21 03:07:33 +00:00
else
2004-08-23 00:15:46 +00:00
Draw_NonCursorLine ( x , y , b ) ;
y + = 8 ;
if ( y > vid . height )
break ;
}
2005-12-21 03:07:33 +00:00
2004-08-23 00:15:46 +00:00
/* if (CmdAfterSave)
{
if ( madechanges )
{
M_DrawTextBox ( 0 , 0 , 36 , 5 ) ;
M_PrintWhite ( 16 , 12 , OpenEditorFile ) ;
M_PrintWhite ( 16 , 28 , " Do you want to save the open file? " ) ;
M_PrintWhite ( 16 , 36 , " [Y]es/[N]o/[C]ancel " ) ;
}
else
{
if ( ! CmdAfterSaveCalled )
{
CmdAfterSaveCalled = true ;
( * CmdAfterSave ) ( ) ;
CmdAfterSaveCalled = false ;
}
CmdAfterSave = NULL ;
}
}
*/
}
2005-08-03 23:14:59 +00:00
int QCLibEditor ( progfuncs_t * prfncs , char * filename , int line , int nump , char * * parms )
2004-08-23 00:15:46 +00:00
{
if ( editormodal | | ! developer . value )
return line ; //whoops
2004-10-01 22:16:01 +00:00
if ( ! qrenderer )
{
int i ;
char buffer [ 8192 ] ;
char * r ;
2005-12-21 03:07:33 +00:00
vfsfile_t * f ;
2004-10-01 22:16:01 +00:00
if ( line = = - 1 )
return - 1 ;
2005-12-21 03:07:33 +00:00
f = FS_OpenVFS ( filename , " rb " , FS_GAME ) ;
2004-10-01 22:16:01 +00:00
if ( ! f )
Con_Printf ( " %s - %i \n " , filename , line ) ;
else
{
for ( i = 0 ; i < line ; i + + )
{
2005-12-21 03:07:33 +00:00
VFS_GETS ( f , buffer , sizeof ( buffer ) ) ;
2004-10-01 22:16:01 +00:00
}
if ( ( r = strchr ( buffer , ' \r ' ) ) )
{ r [ 0 ] = ' \n ' ; r [ 1 ] = ' \0 ' ; }
Con_Printf ( " %s " , buffer ) ;
2005-12-21 03:07:33 +00:00
VFS_CLOSE ( f ) ;
2004-10-01 22:16:01 +00:00
}
//PF_break(NULL);
return line ;
}
2005-08-03 23:14:59 +00:00
editprogfuncs = prfncs ;
2004-08-23 00:15:46 +00:00
if ( ! strncmp ( OpenEditorFile , " src/ " , 4 ) )
{
if ( ! editoractive | | strcmp ( OpenEditorFile + 4 , filename ) )
{
if ( editoractive )
EditorSaveFile ( OpenEditorFile ) ;
EditorOpenFile ( filename ) ;
}
}
else
{
if ( ! editoractive | | strcmp ( OpenEditorFile , filename ) )
{
if ( editoractive )
EditorSaveFile ( OpenEditorFile ) ;
EditorOpenFile ( filename ) ;
}
}
for ( cursorlinenum = 1 , cursorblock = firstblock ; cursorlinenum < line & & cursorblock - > next ; cursorlinenum + + )
cursorblock = cursorblock - > next ;
executionblock = cursorblock ;
if ( ! parms )
{
editormodal = true ;
2005-05-26 12:55:34 +00:00
while ( editormodal & & editoractive & & editprogfuncs )
2004-08-23 00:15:46 +00:00
{
2005-08-03 23:14:59 +00:00
// key_dest = key_editor;
2004-08-23 00:15:46 +00:00
scr_disabled_for_loading = false ;
SCR_UpdateScreen ( ) ;
Sys_SendKeyEvents ( ) ;
2006-09-18 22:52:33 +00:00
S_ExtraUpdate ( ) ;
2004-08-23 00:15:46 +00:00
NET_Sleep ( 100 , false ) ; //any os.
}
editormodal = false ;
}
return line ;
}
void Editor_f ( void )
{
2005-08-14 03:55:08 +00:00
if ( Cmd_Argc ( ) ! = 2 )
{
Con_Printf ( " edit <filename> \n " ) ;
return ;
}
2006-03-10 03:50:23 +00:00
editprogfuncs = NULL ;
useeval = false ;
2004-08-23 00:15:46 +00:00
if ( editoractive )
EditorSaveFile ( OpenEditorFile ) ;
EditorOpenFile ( Cmd_Argv ( 1 ) ) ;
// EditorNewFile();
}
void Editor_Init ( void )
{
Cmd_AddCommand ( " edit " , Editor_f ) ;
2005-12-21 03:07:33 +00:00
2004-08-23 00:15:46 +00:00
Cvar_Register ( & alloweditor , " Text editor " ) ;
Cvar_Register ( & editstripcr , " Text editor " ) ;
Cvar_Register ( & editaddcr , " Text editor " ) ;
Cvar_Register ( & edittabspacing , " Text editor " ) ;
}
# endif