diff --git a/cgdoom/cgdoom-ui.c b/cgdoom/cgdoom-ui.c index 019b05e..d71100f 100644 --- a/cgdoom/cgdoom-ui.c +++ b/cgdoom/cgdoom-ui.c @@ -54,7 +54,8 @@ static uint32_t const font_glyphs[263] = { static inline void SetPixel(int x, int y, int color) { - VRAM[WIDTH * y + x] = color; + if ((unsigned)x < 384 && (unsigned)y < 216) + VRAM[WIDTH * y + x] = color; } static void Font_RenderChar(int *x, int y, int c, int fg) @@ -96,22 +97,41 @@ static int Font_StringLength(char const *text) return w - 1; } -void UI_Print(int x, int y, int fg, int align, char const *text) +static int Font_ReverseStringLength(char const *text, int width) +{ + int i = 0; + for(; text[i]; i++) { + if(text[i] < 32) + continue; + + int cw = font_width[text[i]-32] + 1; + if(cw > width) + break; + + width -= cw; + } + return i; +} + +void UI_Print(int x, int y, int fg, int align, char const *text, int length) { if(align == UI_CENTER) x -= (Font_StringLength(text) + 1) / 2; if(align == UI_RIGHT) x -= Font_StringLength(text); - for(int i = 0; text[i]; i++) + for(int i = 0; text[i]; i++) { + if (length >= 0 && i >= length) + break; Font_RenderChar(&x, y, text[i], fg); + } } void UI_Vprintf(int x, int y, int fg, int align, char const *fmt, va_list args) { char str[256]; - vsprintf(str, fmt, args); - UI_Print(x, y, fg, align, str); + vsnprintf(str, 256, fmt, args); + UI_Print(x, y, fg, align, str, -1); } void UI_Printf(int x, int y, int fg, int align, char const *fmt, ...) @@ -237,7 +257,7 @@ static void Layout_EndInput(Layout *l) void Layout_CenteredText(Layout *l, const char *text) { - UI_Print(WIDTH / 2, l->y, 0x0000, UI_CENTER, text); + UI_Print(WIDTH / 2, l->y, 0x0000, UI_CENTER, text, -1); l->y += 14; } @@ -246,7 +266,7 @@ void Layout_Text(Layout *l, const char *label, const char *fmt, ...) va_list args; va_start(args, fmt); Layout_AddFocus(l, FOCUS_NOTHING, NULL); - UI_Print(LAYOUT_LEFT, l->y, 0x0000, UI_LEFT, label); + UI_Print(LAYOUT_LEFT, l->y, 0x0000, UI_LEFT, label, -1); UI_Vprintf(LAYOUT_RIGHT, l->y, 0x0000, UI_RIGHT, fmt, args); l->y += 14; va_end(args); @@ -255,7 +275,7 @@ void Layout_Text(Layout *l, const char *label, const char *fmt, ...) void Layout_Checkbox(Layout *l, const char *label, int *checked) { Layout_AddFocus(l, FOCUS_CHECKBOX, checked); - UI_Print(LAYOUT_LEFT, l->y, 0x0000, UI_LEFT, label); + UI_Print(LAYOUT_LEFT, l->y, 0x0000, UI_LEFT, label, -1); UI_Checkbox(LAYOUT_RIGHT-7, l->y+1, *checked); l->y += 14; } @@ -263,9 +283,9 @@ void Layout_Checkbox(Layout *l, const char *label, int *checked) void Layout_Integer(Layout *l, const char *label, int *value) { Layout_AddFocus(l, FOCUS_INTEGER, value); - UI_Print(LAYOUT_LEFT, l->y, 0x0000, UI_LEFT, label); + UI_Print(LAYOUT_LEFT, l->y, 0x0000, UI_LEFT, label, -1); if(l->active && l->focus == l->focus_count - 1) - UI_Print(LAYOUT_RIGHT, l->y, 0x0000, UI_RIGHT, l->text); + UI_Print(LAYOUT_RIGHT, l->y, 0x0000, UI_RIGHT, l->text, -1); else UI_Printf(LAYOUT_RIGHT, l->y, 0x0000, UI_RIGHT, "%d", *value); l->y += 14; @@ -427,3 +447,42 @@ int UI_Main(WADFileInfo *wads, int wad_count, int *dev_info, int *use_mmap, return -1; } + +static int isspace_(int c) +{ + return (c == ' ' || c == '\t' || c == '\n'); +} + +void UI_Error(const char *fmt, va_list args) +{ + char message[256], *str=message; + vsnprintf(message, 256, fmt, args); + + int y = 12; + Bdisp_AllClr_VRAM(); + UI_Print(192, y, 0x0000, UI_CENTER, "Error!", -1); + y += 14 + 12; + + while(*str) { + int len = Font_ReverseStringLength(str, LAYOUT_RIGHT - LAYOUT_LEFT); + + /* Try to stop at previous word boundary */ + int wordb = len; + while(wordb > 0 && str[wordb] && !isspace_(str[wordb])) wordb--; + if(wordb > 0) len = wordb; + + UI_Print(LAYOUT_LEFT, y, 0x0000, UI_LEFT, str, len); + y += 14; + + /* Skip spacing */ + str += len; + while(*str && isspace_(*str)) str++; + } + + Bdisp_FrameAndColor(3, 16); + Bdisp_FrameAndColor(1, 0); + Bdisp_PutDisp_DD(); + + int key; + GetKey(&key); +} diff --git a/cgdoom/cgdoom-ui.h b/cgdoom/cgdoom-ui.h index 060492c..5b0e0a4 100644 --- a/cgdoom/cgdoom-ui.h +++ b/cgdoom/cgdoom-ui.h @@ -18,7 +18,7 @@ enum { void UI_FileMappingProgressBar(int size_mapped, int size_total); /* Print text with a cleaner font. */ -void UI_Print(int x, int y, int fg, int halign, char const *text); +void UI_Print(int x, int y, int fg, int halign, char const *text, int length); /* Like UI_Print, but applies printf() formatting. */ void UI_Printf(int x, int y, int fg, int halign, char const *fmt, ...); void UI_Vprintf(int x, int y, int fg, int halign, char const *fmt, va_list args); @@ -72,4 +72,7 @@ int UI_Main(WADFileInfo *wads, int wad_count, int *enabledemos /* Enable demos on the title screen */ ); +/* Show an error with custom formatting. */ +void UI_Error(const char *fmt, va_list args); + #endif /* CGDOOM_UI_H */ diff --git a/cgdoom/cgdoom.c b/cgdoom/cgdoom.c index 98a2754..d88fa3b 100644 --- a/cgdoom/cgdoom.c +++ b/cgdoom/cgdoom.c @@ -594,7 +594,8 @@ int Flash_ReadFile(void *buf, int size, int readpos) { int i = FindInFlash(&pSrc,size, readpos); if(i<0) { - I_ErrorI ("Flash_ReadFile", size, readpos, 0, i); + I_Error ("Flash_ReadFile: cannot find position %d (size %d)", readpos, + size); return i; } memcpy(buf,pSrc,i); diff --git a/cgdoom/i_system.c b/cgdoom/i_system.c index 33821c0..cc938ca 100644 --- a/cgdoom/i_system.c +++ b/cgdoom/i_system.c @@ -25,6 +25,7 @@ #include "platform.h" #include "cgdoom.h" #include "cgdoom-alloc.h" +#include "cgdoom-ui.h" #include #include "doomdef.h" @@ -195,52 +196,21 @@ int toupper_int(int i) // // I_Error // -static int key = 31; -void I_ErrorI (const char *error, int i1,int i2,int i3,int i4) -{ - #ifndef CG_EMULATOR - - char buf[21]; - Bdisp_AllClr_VRAM(); - locate_OS( 1, 1 ); - PrintLine( "ERROR:", 21 ); - locate_OS( 1, 2 ); - PrintLine( error, 21 ); - locate_OS( 1, 3 );CGDAppendHex32("i1:",i1,8,buf);PrintLine( buf, 21 ); - locate_OS( 1, 4 );CGDAppendHex32("i2:",i2,8,buf);PrintLine( buf, 21 ); - locate_OS( 1, 5 );CGDAppendHex32("i3:",i3,8,buf);PrintLine( buf, 21 ); - locate_OS( 1, 6 );CGDAppendHex32("i4:",i4,8,buf);PrintLine( buf, 21 ); - GetKey( &key ); - I_ReinitAfterError(); -#else - I_Error (error,i1,i2,i3,i4); -#endif -} - void I_Error (const char *error, ...) { + va_list args; + va_start(args, error); + #ifdef CG_EMULATOR - /*// Message first. - va_start (argptr,error); - printf ("Error: "); - printf (error,argptr); - printf ("\n"); - sprintf(ferror,error,argptr); - va_end (argptr); - */ - printf ("Error: %s",error); - //Inform the user something bad had occured - //Exit function here + printf("Error: "); + vprintf(error, args); #else - I_ShutdownGraphics(); - Bdisp_AllClr_VRAM(); - locate_OS( 1, 1 ); - PrintLine( "ERROR:", 21 ); - locate_OS( 1, 2 ); - PrintLine( error, 21 ); - GetKey( &key ); + I_ShutdownGraphics(); + UI_Error(error, args); I_ReinitAfterError(); -#endif //#ifdef CG_EMULATOR +#endif + + va_end(args); //I_Quit(); } diff --git a/cgdoom/i_system.h b/cgdoom/i_system.h index 8f5a294..8f368e5 100644 --- a/cgdoom/i_system.h +++ b/cgdoom/i_system.h @@ -94,9 +94,6 @@ int toupper_int(int i); //void I_GetMainDir(char* dir); void I_Error (const char *error, ...); -//CGD bastl/hack -void I_ErrorI (const char *error, int i1,int i2,int i3,int i4); - //Set by I_Error() extern boolean fuck; diff --git a/cgdoom/i_video.c b/cgdoom/i_video.c index b343982..164a6b6 100644 --- a/cgdoom/i_video.c +++ b/cgdoom/i_video.c @@ -215,6 +215,10 @@ void I_ReinitAfterError(void) /* Redraw status bar over help message */ extern boolean st_firsttime; st_firsttime = true; + + /* Restore full black screen */ + memset(GetVRAMAddress(), 0, 384*216*2); + Bdisp_PutDisp_DD(); } #endif diff --git a/cgdoom/os.h b/cgdoom/os.h index 53fbf83..ebf1688 100644 --- a/cgdoom/os.h +++ b/cgdoom/os.h @@ -31,7 +31,6 @@ void CGDAppendHex32(const char *pszText,int iNum, int iDigits,char *pszBuf); int abs(int x); void I_Error (const char *error, ...); -void I_ErrorI(const char *str, int i1, int i2, int i3, int i4); //force compiler error on use following: #define strcpy 12 diff --git a/cgdoom/w_wad.c b/cgdoom/w_wad.c index 9945c26..9d47339 100644 --- a/cgdoom/w_wad.c +++ b/cgdoom/w_wad.c @@ -124,7 +124,8 @@ static int W_AddFile () } if (!lumpinfo) - I_ErrorI ("CGDrealloc lumpinfo", (int)lumpinfo, numlumps, numlumps*sizeof(lumpinfo_t), 0); + I_Error ("CGDrealloc(lumpinfo) failed (%d lumps, %d bytes)", numlumps, + numlumps * sizeof(lumpinfo_t)); lump_p = &lumpinfo[startlump]; @@ -293,7 +294,7 @@ void W_ReadLump(int lump, void* dest ) if (c < l->size) { - I_ErrorI ("W_ReadLump: only read %i of %i on lump %i", c,l->size,lump,0);//CGD HACK + I_Error ("W_ReadLump: only read %i of %i on lump %i", c,l->size,lump); } } @@ -373,7 +374,8 @@ static void* W_CacheLumpNumCommon( int lump, int tag,int iEnableFlash) } if(lumpcache[lump] == NULL) - I_ErrorI("W_CacheLumpNumCommon", (int)lumpcache[lump], lump, 0, 0); + I_Error ("W_CacheLumpNumCommon: Loading lump %d failed (%p)", lump, + lumpcache[lump]); return lumpcache[lump]; } diff --git a/cgdoom/z_zone.c b/cgdoom/z_zone.c index 2f34815..ec92662 100644 --- a/cgdoom/z_zone.c +++ b/cgdoom/z_zone.c @@ -142,7 +142,7 @@ void Z_Free (const void* ptr) memblock_t* block; memblock_t* other; - if (PTR_TO_FLASH(ptr)) + if (PTR_TO_FLASH(ptr) || ptr == NULL) return; memzone_t* zone = NULL; @@ -156,7 +156,7 @@ void Z_Free (const void* ptr) } if (zone == NULL) { - I_ErrorI ("Z_Free: Out of zone", (int)ptr, 0, 0, 0); + I_Error ("Z_Free: %p is out of zone", ptr); return; } @@ -314,7 +314,7 @@ void* Z_Malloc( int size, int tag, void* user ) { if (zone_no == zone_count - 1) { - I_ErrorI ("Z_Malloc failure", size, 0, 0, 0); + I_Error ("Z_Malloc(%d) failure", size); prof_leave(CGD_Perf.DynamicAllocation); return NULL; } @@ -461,16 +461,15 @@ void Z_CheckHeap (void) void Z_ChangeTag2(const void* ptr,int tag ) { memblock_t* block; - if(PTR_TO_FLASH(ptr)) - { + + if(PTR_TO_FLASH(ptr) || ptr == NULL) return; - } block = (memblock_t *) ( (byte *)ptr - sizeof(memblock_t)); if (block->id != ZONEID) { - I_ErrorI ("Z_ChangeTag: freed a pointer without ZONEID", (int)ptr, 0, 0, 0); + I_Error ("Z_ChangeTag: freed a pointer without ZONEID: %p", ptr); } if (tag >= PU_PURGELEVEL && (unsigned)block->user < 0x100)