UI improvements and sprintf

This commit is contained in:
Lephenixnoir 2021-08-02 21:11:13 +02:00
parent 4e7fa7781e
commit b1f8a97983
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
5 changed files with 231 additions and 77 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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 */

View File

@ -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);

View File

@ -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);