UI improvements and sprintf
This commit is contained in:
parent
4e7fa7781e
commit
b1f8a97983
|
@ -73,4 +73,12 @@
|
|||
#define ASSERT(x)
|
||||
#define InitFlashSimu(filename)
|
||||
|
||||
/* Description of a WAD file selectable by user. */
|
||||
typedef struct
|
||||
{
|
||||
char name[16];
|
||||
uint16_t path[23];
|
||||
int size;
|
||||
} WADFileInfo;
|
||||
|
||||
#endif //#ifndef PLATFORM_H
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "cgdoom-ui.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/* gint's font in a PrizmSDK-friendly (though ugly) form */
|
||||
static uint8_t const font_width[96] = {
|
||||
|
@ -68,7 +69,7 @@ static void Font_RenderChar(int *x, int y, int c, int fg)
|
|||
for(int dy = 0; dy < 11; dy++)
|
||||
for(int dx = 0; dx < font_width[g]; dx++)
|
||||
{
|
||||
int b = font_glyphs[offset + (bit >> 5)] & (0x80000000 >> (bit & 31));
|
||||
int b = font_glyphs[offset + (bit>>5)] & (0x80000000 >> (bit&31));
|
||||
if (b)
|
||||
Bdisp_SetPoint_VRAM(*x+dx, y+dy, fg);
|
||||
bit++;
|
||||
|
@ -89,13 +90,7 @@ static int Font_StringLength(char const *text)
|
|||
return w - 1;
|
||||
}
|
||||
|
||||
enum {
|
||||
UI_LEFT = 0,
|
||||
UI_CENTER = 1,
|
||||
UI_RIGHT = 2,
|
||||
};
|
||||
|
||||
void UI_Print(int x, int y, char const *text, int fg, int align)
|
||||
void UI_Print(int x, int y, int fg, int align, char const *text)
|
||||
{
|
||||
if(align == UI_CENTER)
|
||||
x -= (Font_StringLength(text) + 1) / 2;
|
||||
|
@ -106,6 +101,21 @@ void UI_Print(int x, int y, char const *text, int fg, int align)
|
|||
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);
|
||||
}
|
||||
|
||||
void UI_Printf(int x, int y, int fg, int align, char const *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
UI_Vprintf(x, y, fg, align, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void UI_AreaReverse(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
uint16_t *VRAM = (uint16_t *)GetVRAMAddress() + WIDTH * y1;
|
||||
|
@ -131,59 +141,6 @@ void UI_Checkbox(int x, int y, int checked)
|
|||
}
|
||||
}
|
||||
|
||||
int UI_Main(char const wad_files[][32], int wad_file_count, int *dev_info)
|
||||
{
|
||||
int key=0, cursor=0;
|
||||
|
||||
while(key != KEY_CTRL_EXIT)
|
||||
{
|
||||
int l=60, r=WIDTH-l, y=34, cursor_max=0, play_max=0;
|
||||
|
||||
Bdisp_AllClr_VRAM();
|
||||
UI_Print(WIDTH / 2, 12, "CGDOOM for fx-CG 50 and Graph 90+E",
|
||||
0x0000, UI_CENTER);
|
||||
|
||||
for(int i = 0; i < wad_file_count; i++)
|
||||
{
|
||||
char const *action = "Play other WAD";
|
||||
if(!strcmp(wad_files[i], "doom.wad"))
|
||||
action = "Play DOOM";
|
||||
else if(!strcmp(wad_files[i], "doomu.wad"))
|
||||
action = "Play Ultimate DOOM";
|
||||
|
||||
char name[34] = "";
|
||||
strcat(name, "(");
|
||||
strcat(name, wad_files[i]);
|
||||
strcat(name, ")");
|
||||
|
||||
UI_Print(l, y, action, 0x0000, UI_LEFT);
|
||||
UI_Print(r, y, name, 0x0000, UI_RIGHT);
|
||||
y += 14;
|
||||
}
|
||||
play_max = cursor_max = wad_file_count;
|
||||
|
||||
UI_Print(l, y, "Developer info:", 0x0000, UI_LEFT);
|
||||
UI_Checkbox(r-7, y+1, *dev_info);
|
||||
y += 14;
|
||||
cursor_max++;
|
||||
|
||||
UI_AreaReverse(0, 32+14*cursor, WIDTH-1, 32+14*cursor+13);
|
||||
Bdisp_PutDisp_DD();
|
||||
|
||||
GetKey(&key);
|
||||
if(key == KEY_CTRL_UP && cursor > 0)
|
||||
cursor--;
|
||||
if(key == KEY_CTRL_DOWN && cursor < cursor_max - 1)
|
||||
cursor++;
|
||||
if(key == KEY_CTRL_EXE && cursor < play_max)
|
||||
return cursor;
|
||||
if(key == KEY_CTRL_EXE && cursor == cursor_max - 1)
|
||||
*dev_info ^= 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void UI_FileMappingProgressBar(int size_mapped, int size_total)
|
||||
{
|
||||
const int w=192, h=5;
|
||||
|
@ -201,3 +158,130 @@ void UI_FileMappingProgressBar(int size_mapped, int size_total)
|
|||
}
|
||||
Bdisp_PutDisp_DD();
|
||||
}
|
||||
|
||||
/* Layout functions. */
|
||||
|
||||
#define LAYOUT_LEFT 40
|
||||
#define LAYOUT_RIGHT (WIDTH-40)
|
||||
|
||||
void Layout_Init(Layout *l)
|
||||
{
|
||||
l->focus = -1;
|
||||
Layout_StartFrame(l);
|
||||
}
|
||||
|
||||
void Layout_StartFrame(Layout *l)
|
||||
{
|
||||
l->focus_count = 0;
|
||||
l->y = 12;
|
||||
}
|
||||
|
||||
void Layout_EndFrame(Layout *l)
|
||||
{
|
||||
if(l->focus < 0)
|
||||
return;
|
||||
int y = l->focus_y[l->focus];
|
||||
UI_AreaReverse(0, y, WIDTH-1, y+13);
|
||||
}
|
||||
|
||||
static void Layout_AddFocus(Layout *l)
|
||||
{
|
||||
if(l->focus < 0)
|
||||
l->focus = 0;
|
||||
if(l->focus_count >= 16)
|
||||
return;
|
||||
l->focus_y[l->focus_count++] = l->y - 2;
|
||||
}
|
||||
|
||||
void Layout_CenteredText(Layout *l, const char *text)
|
||||
{
|
||||
UI_Print(WIDTH / 2, l->y, 0x0000, UI_CENTER, text);
|
||||
l->y += 14;
|
||||
}
|
||||
|
||||
void Layout_Text(Layout *l, const char *label, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
Layout_AddFocus(l);
|
||||
UI_Print(LAYOUT_LEFT, l->y, 0x0000, UI_LEFT, label);
|
||||
UI_Vprintf(LAYOUT_RIGHT, l->y, 0x0000, UI_RIGHT, fmt, args);
|
||||
l->y += 14;
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void Layout_Checkbox(Layout *l, const char *label, int checked)
|
||||
{
|
||||
Layout_AddFocus(l);
|
||||
UI_Print(LAYOUT_LEFT, l->y, 0x0000, UI_LEFT, label);
|
||||
UI_Checkbox(LAYOUT_RIGHT-7, l->y+1, checked);
|
||||
l->y += 14;
|
||||
}
|
||||
|
||||
void Layout_Spacing(Layout *l, int spacing)
|
||||
{
|
||||
l->y += spacing;
|
||||
}
|
||||
|
||||
int Layout_Event(Layout *l, int key)
|
||||
{
|
||||
if(key == KEY_CTRL_UP)
|
||||
{
|
||||
l->focus--;
|
||||
if(l->focus < 0)
|
||||
l->focus += l->focus_count;
|
||||
return 1;
|
||||
}
|
||||
if(key == KEY_CTRL_DOWN)
|
||||
{
|
||||
l->focus++;
|
||||
if(l->focus >= l->focus_count)
|
||||
l->focus -= l->focus_count;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int UI_Main(WADFileInfo *wads, int wad_count, int *dev_info)
|
||||
{
|
||||
Layout l;
|
||||
Layout_Init(&l);
|
||||
|
||||
while(1)
|
||||
{
|
||||
Bdisp_AllClr_VRAM();
|
||||
Layout_StartFrame(&l);
|
||||
Layout_CenteredText(&l, "CGDOOM for fx-CG 50 and Graph 90+E");
|
||||
Layout_Spacing(&l, 12);
|
||||
|
||||
for(int i = 0; i < wad_count; i++)
|
||||
{
|
||||
char const *action = "Play other WAD";
|
||||
if(!strcmp(wads[i].name, "doom.wad"))
|
||||
action = "Play DOOM";
|
||||
else if(!strcmp(wads[i].name, "doomu.wad"))
|
||||
action = "Play Ultimate DOOM";
|
||||
|
||||
Layout_Text(&l, action, "%s (%d.%dM)",
|
||||
wads[i].name, wads[i].size / 1000000,
|
||||
(wads[i].size % 1000000) / 100000);
|
||||
}
|
||||
|
||||
Layout_Spacing(&l, 12);
|
||||
Layout_Checkbox(&l, "Developer info:", *dev_info);
|
||||
Layout_EndFrame(&l);
|
||||
Bdisp_PutDisp_DD();
|
||||
|
||||
int key;
|
||||
GetKey(&key);
|
||||
if(Layout_Event(&l, key))
|
||||
continue;
|
||||
|
||||
if(key == KEY_CTRL_EXE && l.focus < wad_count)
|
||||
return l.focus;
|
||||
if(key == KEY_CTRL_EXE && l.focus == l.focus_count - 1)
|
||||
*dev_info ^= 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -2,11 +2,53 @@
|
|||
#define CGDOOM_UI_H
|
||||
|
||||
#include "platform.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
/* Show the program's main screen; returns index of selected WAD file. */
|
||||
int UI_Main(char const wad_files[][32], int wad_file_count, int *dev_info);
|
||||
/* Basic rendering functions. */
|
||||
|
||||
/* Show a progress bar of file mapping. */
|
||||
enum {
|
||||
UI_LEFT = 0,
|
||||
UI_CENTER = 1,
|
||||
UI_RIGHT = 2,
|
||||
};
|
||||
|
||||
/* Show a progress bar of file mapping at the bottom of the screen. */
|
||||
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);
|
||||
/* 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);
|
||||
|
||||
/* A simple immediate-mode layout system. */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int y, focus, focus_count;
|
||||
int16_t focus_y[16];
|
||||
} Layout;
|
||||
|
||||
void Layout_Init(Layout *l);
|
||||
|
||||
void Layout_StartFrame(Layout *l);
|
||||
void Layout_EndFrame(Layout *l);
|
||||
|
||||
/* Add a centered text. */
|
||||
void Layout_CenteredText(Layout *l, const char *text);
|
||||
/* Add a labeled field with printf-formatted contents. */
|
||||
void Layout_Text(Layout *l, const char *label, const char *fmt, ...);
|
||||
/* Add a checkbox. */
|
||||
void Layout_Checkbox(Layout *l, const char *label, int checked);
|
||||
/* Add spacing. */
|
||||
void Layout_Spacing(Layout *l, int spacing);
|
||||
|
||||
/* Handle a key press; returns non-zero if event is caught. */
|
||||
int Layout_Event(Layout *l, int key);
|
||||
|
||||
/* Larger-scale functions. */
|
||||
|
||||
/* Show the program's main screen; returns index of selected WAD file. */
|
||||
int UI_Main(WADFileInfo *wads, int wad_count, int *dev_info);
|
||||
|
||||
#endif /* CGDOOM_UI_H */
|
||||
|
|
|
@ -318,6 +318,7 @@ typedef struct
|
|||
|
||||
}FileMapping;
|
||||
|
||||
/* Bfile's file info structure returned by filesystem search functions. */
|
||||
typedef struct
|
||||
{
|
||||
unsigned short id, type;
|
||||
|
@ -334,9 +335,9 @@ void ResetData(FileMapping *pMap)
|
|||
}
|
||||
|
||||
/* Find WAD files in the filesystem. */
|
||||
int FindWADs(char filenames[][32], int max)
|
||||
int FindWADs(WADFileInfo *files, int max)
|
||||
{
|
||||
uint16_t path[32];
|
||||
uint16_t path[16];
|
||||
Bfile_FileInfo info;
|
||||
|
||||
int sd, rc, total=0;
|
||||
|
@ -344,7 +345,10 @@ int FindWADs(char filenames[][32], int max)
|
|||
|
||||
while(rc != -16 && total < max)
|
||||
{
|
||||
Bfile_NameToStr_ncpy(filenames[total], path, 32);
|
||||
memcpy(files[total].path, u"\\\\fls0\\", 14);
|
||||
memcpy(files[total].path+7, path, 16*2);
|
||||
Bfile_NameToStr_ncpy(files[total].name, path, 16);
|
||||
files[total].size = info.fsize;
|
||||
total++;
|
||||
|
||||
rc = Bfile_FindNext(sd, path, &info);
|
||||
|
@ -376,6 +380,10 @@ int Flash_ReadFile(void *buf, int size, int readpos)
|
|||
static FileMapping *gpWADMap = 0;
|
||||
static SectorIndexInfo *gIndex = NULL;
|
||||
|
||||
/* Developer info */
|
||||
static int gDevFragments = 0;
|
||||
static int gDevIndexHits = 0;
|
||||
|
||||
/* Read next sector from file, while caching into a buffer. */
|
||||
const void *ReadNextSector(FileAccessCache *fc, int *size)
|
||||
{
|
||||
|
@ -438,13 +446,17 @@ int FindSectorInFlash(const void *buf, int size)
|
|||
typeof(&memcmp) memcmp_fun = &memcmp;
|
||||
if(size == FLASH_PAGE_SIZE) memcmp_fun = &CGD_sector_memcmp;
|
||||
|
||||
gDevFragments++;
|
||||
|
||||
#ifdef FLASH_INDEX
|
||||
/* If an index has been built, search in it */
|
||||
int lo, hi;
|
||||
IndexSearchSector(gIndex, buf, &lo, &hi);
|
||||
for(int i = lo; i < hi; i++) {
|
||||
if(!memcmp_fun(buf, gIndex[i].sector, size))
|
||||
if(!memcmp_fun(buf, gIndex[i].sector, size)) {
|
||||
gDevIndexHits++;
|
||||
return (gIndex[i].sector - FLASH_START) / FLASH_PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -602,17 +614,14 @@ int main(void){
|
|||
EnableColor(1);
|
||||
EnableStatusArea(3);
|
||||
|
||||
char wad_files[16][32];
|
||||
int wad_file_count = FindWADs(wad_files, 16);
|
||||
uint16_t wad_path[39] = u"\\\\fls0\\";
|
||||
WADFileInfo wads[16];
|
||||
int wad_count = FindWADs(wads, 16);
|
||||
|
||||
int dev_info = 0;
|
||||
int choice = UI_Main(wad_files, wad_file_count, &dev_info);
|
||||
int choice = UI_Main(wads, wad_count, &dev_info);
|
||||
if(choice < 0)
|
||||
return 1;
|
||||
|
||||
Bfile_StrToName_ncpy(wad_path+7, wad_files[choice], 32);
|
||||
|
||||
unsigned tmp=((unsigned)getSecondaryVramAddress()+3)&(~3);
|
||||
SaveVRAMBuffer = (unsigned char*)tmp;
|
||||
/* Graph 90+E: RAM starts at 0x0c000000 in physical memory */
|
||||
|
@ -622,7 +631,7 @@ int main(void){
|
|||
|
||||
/* Setup access to WAD file */
|
||||
#ifdef CGDOOM_WAD_BFILE
|
||||
gWADfd = Bfile_OpenFile_OS(wad_path, 0, 0);
|
||||
gWADfd = Bfile_OpenFile_OS(wads[choice].path, 0, 0);
|
||||
#else
|
||||
#ifdef FLASH_INDEX
|
||||
/* Index most likely flash sectors into a sorted array, so that sectors
|
||||
|
@ -640,7 +649,7 @@ int main(void){
|
|||
|
||||
gpWADMap = (FileMapping *)(SaveVRAMBuffer + 2*65536);
|
||||
ASSERT(2*65536 + sizeof(FileMapping) < SAVE_VRAM_SIZE);
|
||||
int fd = Bfile_OpenFile_OS(wad_path,0,0);
|
||||
int fd = Bfile_OpenFile_OS(wads[choice].path,0,0);
|
||||
int size = CreateFileMapping(fd, gpWADMap);
|
||||
Bfile_CloseFile_OS(fd);
|
||||
UI_FileMappingProgressBar(1, 1);
|
||||
|
@ -657,6 +666,18 @@ int main(void){
|
|||
I_Error ("File too fragmented");
|
||||
return 1;
|
||||
}
|
||||
else if(dev_info) {
|
||||
Layout l;
|
||||
Layout_Init(&l);
|
||||
Bdisp_AllClr_VRAM();
|
||||
Layout_CenteredText(&l, "Developer info");
|
||||
Layout_Text(&l, "Fragments:", "%d", gDevFragments);
|
||||
Layout_Text(&l, "Index hits:", "%d (%d%%)", gDevIndexHits,
|
||||
(gDevIndexHits * 100 / gDevFragments));
|
||||
Bdisp_PutDisp_DD();
|
||||
int key;
|
||||
GetKey(&key);
|
||||
}
|
||||
#endif
|
||||
|
||||
memset(VRAM,0,WIDTH*HEIGHT*2);
|
||||
|
|
|
@ -40,7 +40,6 @@ void I_ErrorI(const char *str, int i1, int i2, int i3, int i4);
|
|||
#define strnicmp 22
|
||||
#define strncmp 27
|
||||
#define strcmp 33
|
||||
#define sprintf 212
|
||||
|
||||
//return ptr to flash
|
||||
int FindInFlash(const void **buf, int size, int readpos);
|
||||
|
|
Loading…
Reference in New Issue