mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-01-22 09:01:57 -05:00
WIP on very basic platform independent system font backend
This commit is contained in:
parent
0c2b52efe7
commit
b07f6575ba
4 changed files with 271 additions and 8 deletions
41
misc/bitmap_font_gen.cs
Normal file
41
misc/bitmap_font_gen.cs
Normal file
|
@ -0,0 +1,41 @@
|
|||
void Main()
|
||||
{
|
||||
Console.WriteLine("static cc_uint8 font_bitmap[][8] = {");
|
||||
using (Bitmap bmp = new Bitmap(@"C:\classicube-dev\default.png"))
|
||||
{
|
||||
for (int CY = 0; CY < 16; CY++)
|
||||
for (int CX = 0; CX < 16; CX++)
|
||||
DecodeTile(bmp, CX, CY);
|
||||
}
|
||||
Console.WriteLine("}");
|
||||
}
|
||||
|
||||
static void DecodeTile(Bitmap bmp, int cx, int cy) {
|
||||
int c = (cy << 4) | cx;
|
||||
if (c <= 32 || c >= 127) return;
|
||||
|
||||
int X = cx * 8, Y = cy * 8;
|
||||
|
||||
Console.Write("\t{ ");
|
||||
|
||||
for (int y = Y; y < Y + 8; y++) {
|
||||
uint mask = 0;
|
||||
int shift = 0;
|
||||
|
||||
for (int x = X; x < X + 8; x++, shift++) {
|
||||
Color P = bmp.GetPixel(x, y);
|
||||
|
||||
if (P.A == 0) {
|
||||
mask |= 0u << shift;
|
||||
} else if (P.R == 255 && P.G == 255 && P.B == 255 && P.A == 255) {
|
||||
mask |= 1u << shift;
|
||||
} else {
|
||||
throw new InvalidOperationException("unsupported colour" + P);
|
||||
}
|
||||
}
|
||||
|
||||
string suffix = y == Y + 7 ? " " : ",";
|
||||
Console.Write("0x" + mask.ToString("X2") + suffix);
|
||||
}
|
||||
Console.WriteLine("}, /* " + (char)c + " */");
|
||||
}
|
|
@ -4,8 +4,10 @@ SOURCE_DIRS := src third_party/bearssl/src
|
|||
C_FILES := $(foreach dir,$(SOURCE_DIRS),$(wildcard $(dir)/*.c))
|
||||
OBJS := $(addprefix $(BUILD_DIR)/, $(notdir $(C_FILES:%.c=%.o)))
|
||||
CFLAGS :=-g -O1 -pipe -fno-math-errno -Ithird_party/bearssl/inc
|
||||
|
||||
GLDC_LIB=third_party/gldc/libGLdc.a
|
||||
LDFLAGS=-g
|
||||
LIBS=-lm
|
||||
LIBS=-lm $(GLDC_LIB)
|
||||
|
||||
TARGET := ClassiCube-dc
|
||||
|
||||
|
@ -13,10 +15,13 @@ ifeq ($(strip $(KOS_BASE)),)
|
|||
$(error "Please set KOS variables in your environment.")
|
||||
endif
|
||||
|
||||
default: $(BUILD_DIR) $(TARGET).cdi
|
||||
default: $(GLDC_LIB) $(BUILD_DIR) $(TARGET).cdi
|
||||
|
||||
$(BUILD_DIR):
|
||||
mkdir -p $(BUILD_DIR)
|
||||
|
||||
$(GLDC_LIB):
|
||||
$(MAKE) -C third_party/gldc
|
||||
|
||||
$(BUILD_DIR)/%.o: src/%.c
|
||||
kos-cc $(CFLAGS) -c $< -o $@
|
||||
|
|
|
@ -1419,4 +1419,223 @@ void SysFont_DrawText(struct DrawTextArgs* args, struct Bitmap* bmp, int x, int
|
|||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
#define SysFont_ValidChar(c) ((c) > 32 && (c) < 127)
|
||||
#define SysFont_ToIndex(c) ((c) - 33) /* First valid char is ! */
|
||||
#define SPACE_WIDTH 2
|
||||
#define CELL_SIZE 8
|
||||
|
||||
#define SysFont_GetRows(c) (SysFont_ValidChar(c) ? font_bitmap[SysFont_ToIndex(c)] : missing_cell)
|
||||
|
||||
static cc_uint8 missing_cell[CELL_SIZE] = {
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
|
||||
};
|
||||
|
||||
/* 8x8 font bitmap, represented with 1 bit for each pixel */
|
||||
/* Source: Goodly's texture pack for ClassiCube */
|
||||
static cc_uint8 font_bitmap[][CELL_SIZE] = {
|
||||
{ 0x01,0x01,0x01,0x01,0x01,0x00,0x01,0x00 }, /* ! */
|
||||
{ 0x05,0x05,0x05,0x00,0x00,0x00,0x00,0x00 }, /* " */
|
||||
{ 0x0A,0x0A,0x1F,0x0A,0x1F,0x0A,0x0A,0x00 }, /* # */
|
||||
{ 0x04,0x1F,0x01,0x1F,0x10,0x1F,0x04,0x00 }, /* $ */
|
||||
{ 0x00,0x21,0x11,0x08,0x04,0x22,0x21,0x00 }, /* % */
|
||||
{ 0x0C,0x12,0x0C,0x2E,0x19,0x11,0x2E,0x00 }, /* & */
|
||||
{ 0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00 }, /* ' */
|
||||
{ 0x04,0x02,0x01,0x01,0x01,0x02,0x04,0x00 }, /* ( */
|
||||
{ 0x01,0x02,0x04,0x04,0x04,0x02,0x01,0x00 }, /* ) */
|
||||
{ 0x00,0x02,0x07,0x02,0x05,0x00,0x00,0x00 }, /* * */
|
||||
{ 0x00,0x04,0x04,0x1F,0x04,0x04,0x00,0x00 }, /* + */
|
||||
{ 0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x01 }, /* , */
|
||||
{ 0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00 }, /* - */
|
||||
{ 0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00 }, /* . */
|
||||
{ 0x08,0x08,0x04,0x04,0x02,0x02,0x01,0x00 }, /* / */
|
||||
{ 0x06,0x09,0x0D,0x0B,0x09,0x09,0x06,0x00 }, /* 0 */
|
||||
{ 0x02,0x03,0x02,0x02,0x02,0x02,0x07,0x00 }, /* 1 */
|
||||
{ 0x06,0x09,0x08,0x04,0x02,0x09,0x0F,0x00 }, /* 2 */
|
||||
{ 0x06,0x09,0x08,0x06,0x08,0x09,0x06,0x00 }, /* 3 */
|
||||
{ 0x05,0x05,0x05,0x0F,0x04,0x04,0x04,0x00 }, /* 4 */
|
||||
{ 0x0F,0x01,0x07,0x08,0x08,0x09,0x06,0x00 }, /* 5 */
|
||||
{ 0x06,0x09,0x01,0x07,0x09,0x09,0x06,0x00 }, /* 6 */
|
||||
{ 0x0F,0x08,0x08,0x04,0x04,0x02,0x02,0x00 }, /* 7 */
|
||||
{ 0x06,0x09,0x09,0x06,0x09,0x09,0x06,0x00 }, /* 8 */
|
||||
{ 0x06,0x09,0x09,0x0E,0x08,0x09,0x06,0x00 }, /* 9 */
|
||||
{ 0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00 }, /* : */
|
||||
{ 0x00,0x02,0x02,0x00,0x00,0x02,0x02,0x01 }, /* ; */
|
||||
{ 0x00,0x04,0x02,0x01,0x02,0x04,0x00,0x00 }, /* < */
|
||||
{ 0x00,0x00,0x1F,0x00,0x00,0x1F,0x00,0x00 }, /* = */
|
||||
{ 0x00,0x01,0x02,0x04,0x02,0x01,0x00,0x00 }, /* > */
|
||||
{ 0x07,0x09,0x08,0x04,0x02,0x00,0x02,0x00 }, /* ? */
|
||||
{ 0x0E,0x11,0x1D,0x1D,0x1D,0x01,0x0E,0x00 }, /* @ */
|
||||
{ 0x06,0x09,0x09,0x0F,0x09,0x09,0x09,0x00 }, /* A */
|
||||
{ 0x07,0x09,0x09,0x07,0x09,0x09,0x07,0x00 }, /* B */
|
||||
{ 0x06,0x09,0x01,0x01,0x01,0x09,0x06,0x00 }, /* C */
|
||||
{ 0x07,0x09,0x09,0x09,0x09,0x09,0x07,0x00 }, /* D */
|
||||
{ 0x0F,0x01,0x01,0x07,0x01,0x01,0x0F,0x00 }, /* E */
|
||||
{ 0x0F,0x01,0x01,0x07,0x01,0x01,0x01,0x00 }, /* F */
|
||||
{ 0x06,0x09,0x01,0x0D,0x09,0x09,0x06,0x00 }, /* G */
|
||||
{ 0x09,0x09,0x09,0x0F,0x09,0x09,0x09,0x00 }, /* H */
|
||||
{ 0x07,0x02,0x02,0x02,0x02,0x02,0x07,0x00 }, /* I */
|
||||
{ 0x08,0x08,0x08,0x08,0x08,0x09,0x07,0x00 }, /* J */
|
||||
{ 0x09,0x09,0x05,0x03,0x05,0x09,0x09,0x00 }, /* K */
|
||||
{ 0x01,0x01,0x01,0x01,0x01,0x01,0x0F,0x00 }, /* L */
|
||||
{ 0x11,0x1B,0x15,0x11,0x11,0x11,0x11,0x00 }, /* M */
|
||||
{ 0x09,0x0B,0x0D,0x09,0x09,0x09,0x09,0x00 }, /* N */
|
||||
{ 0x06,0x09,0x09,0x09,0x09,0x09,0x06,0x00 }, /* O */
|
||||
{ 0x07,0x09,0x09,0x07,0x01,0x01,0x01,0x00 }, /* P */
|
||||
{ 0x06,0x09,0x09,0x09,0x09,0x05,0x0E,0x00 }, /* Q */
|
||||
{ 0x07,0x09,0x09,0x07,0x09,0x09,0x09,0x00 }, /* R */
|
||||
{ 0x06,0x09,0x01,0x06,0x08,0x09,0x06,0x00 }, /* S */
|
||||
{ 0x07,0x02,0x02,0x02,0x02,0x02,0x02,0x00 }, /* T */
|
||||
{ 0x09,0x09,0x09,0x09,0x09,0x09,0x06,0x00 }, /* U */
|
||||
{ 0x11,0x11,0x11,0x11,0x11,0x0A,0x04,0x00 }, /* V */
|
||||
{ 0x11,0x11,0x11,0x11,0x15,0x1B,0x11,0x00 }, /* W */
|
||||
{ 0x11,0x11,0x0A,0x04,0x0A,0x11,0x11,0x00 }, /* X */
|
||||
{ 0x11,0x11,0x0A,0x04,0x04,0x04,0x04,0x00 }, /* Y */
|
||||
{ 0x0F,0x08,0x04,0x02,0x01,0x01,0x0F,0x00 }, /* Z */
|
||||
{ 0x07,0x01,0x01,0x01,0x01,0x01,0x07,0x00 }, /* [ */
|
||||
{ 0x01,0x01,0x02,0x02,0x04,0x04,0x08,0x00 }, /* \ */
|
||||
{ 0x07,0x04,0x04,0x04,0x04,0x04,0x07,0x00 }, /* ] */
|
||||
{ 0x04,0x0A,0x11,0x00,0x00,0x00,0x00,0x00 }, /* ^ */
|
||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F }, /* _ */
|
||||
{ 0x01,0x01,0x02,0x00,0x00,0x00,0x00,0x00 }, /* ` */
|
||||
{ 0x00,0x00,0x0E,0x09,0x09,0x0D,0x0B,0x00 }, /* a */
|
||||
{ 0x01,0x01,0x07,0x09,0x09,0x09,0x07,0x00 }, /* b */
|
||||
{ 0x00,0x00,0x06,0x09,0x01,0x09,0x06,0x00 }, /* c */
|
||||
{ 0x08,0x08,0x0E,0x09,0x09,0x09,0x0E,0x00 }, /* d */
|
||||
{ 0x00,0x00,0x06,0x09,0x0F,0x01,0x0E,0x00 }, /* e */
|
||||
{ 0x06,0x01,0x07,0x01,0x01,0x01,0x01,0x00 }, /* f */
|
||||
{ 0x00,0x00,0x0E,0x09,0x09,0x0E,0x08,0x07 }, /* g */
|
||||
{ 0x01,0x01,0x07,0x09,0x09,0x09,0x09,0x00 }, /* h */
|
||||
{ 0x01,0x00,0x01,0x01,0x01,0x01,0x01,0x00 }, /* i */
|
||||
{ 0x08,0x00,0x08,0x08,0x08,0x08,0x09,0x06 }, /* j */
|
||||
{ 0x01,0x01,0x09,0x05,0x03,0x05,0x09,0x00 }, /* k */
|
||||
{ 0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x00 }, /* l */
|
||||
{ 0x00,0x00,0x0B,0x15,0x15,0x11,0x11,0x00 }, /* m */
|
||||
{ 0x00,0x00,0x07,0x09,0x09,0x09,0x09,0x00 }, /* n */
|
||||
{ 0x00,0x00,0x06,0x09,0x09,0x09,0x06,0x00 }, /* o */
|
||||
{ 0x00,0x00,0x07,0x09,0x09,0x07,0x01,0x01 }, /* p */
|
||||
{ 0x00,0x00,0x0E,0x09,0x09,0x0E,0x08,0x08 }, /* q */
|
||||
{ 0x00,0x00,0x05,0x03,0x01,0x01,0x01,0x00 }, /* r */
|
||||
{ 0x00,0x00,0x0E,0x01,0x06,0x08,0x07,0x00 }, /* s */
|
||||
{ 0x02,0x02,0x07,0x02,0x02,0x02,0x02,0x00 }, /* t */
|
||||
{ 0x00,0x00,0x09,0x09,0x09,0x09,0x0E,0x00 }, /* u */
|
||||
{ 0x00,0x00,0x09,0x09,0x09,0x05,0x03,0x00 }, /* v */
|
||||
{ 0x00,0x00,0x11,0x11,0x15,0x15,0x1A,0x00 }, /* w */
|
||||
{ 0x00,0x00,0x05,0x05,0x02,0x05,0x05,0x00 }, /* x */
|
||||
{ 0x00,0x00,0x09,0x09,0x09,0x0E,0x08,0x07 }, /* y */
|
||||
{ 0x00,0x00,0x0F,0x08,0x04,0x02,0x0F,0x00 }, /* z */
|
||||
{ 0x04,0x02,0x02,0x01,0x02,0x02,0x04,0x00 }, /* { */
|
||||
{ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 }, /* | */
|
||||
{ 0x01,0x02,0x02,0x04,0x02,0x02,0x01,0x00 }, /* } */
|
||||
{ 0x00,0x00,0x26,0x19,0x00,0x00,0x00,0x00 }, /* ~ */
|
||||
};
|
||||
|
||||
|
||||
void SysFonts_Register(const cc_string* path) { }
|
||||
|
||||
const cc_string* SysFonts_UNSAFE_GetDefault(void) { return &String_Empty; }
|
||||
|
||||
void SysFonts_GetNames(struct StringsBuffer* buffer) { }
|
||||
|
||||
cc_result SysFont_Make(struct FontDesc* desc, const cc_string* fontName, int size, int flags) {
|
||||
desc->size = size;
|
||||
desc->flags = flags;
|
||||
desc->height = Drawer2D_AdjHeight(size);
|
||||
|
||||
desc->handle = (void*)1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SysFont_MakeDefault(struct FontDesc* desc, int size, int flags) {
|
||||
SysFont_Make(desc, NULL, size, flags);
|
||||
}
|
||||
|
||||
void SysFont_Free(struct FontDesc* desc) {
|
||||
}
|
||||
|
||||
static int CellWidth(cc_uint8* rows) {
|
||||
int y, widest = 0;
|
||||
|
||||
for (y = 0; y < CELL_SIZE; y++)
|
||||
{
|
||||
widest = max(widest, rows[y]);
|
||||
}
|
||||
return Math_Log2(widest) + 2; /* add padding for next character */
|
||||
}
|
||||
|
||||
int SysFont_TextWidth(struct DrawTextArgs* args) {
|
||||
int width = 0;
|
||||
cc_string left = args->text, part;
|
||||
char colorCode = 'f';
|
||||
int i;
|
||||
|
||||
while (Drawer2D_UNSAFE_NextPart(&left, &part, &colorCode))
|
||||
{
|
||||
for (i = 0; i < part.length; i++)
|
||||
{
|
||||
cc_uint8 c = part.buffer[i];
|
||||
if (c == ' ') {
|
||||
width += SPACE_WIDTH;
|
||||
} else {
|
||||
width += CellWidth(SysFont_GetRows(c));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
width = max(1, width);
|
||||
if (args->useShadow) width++;
|
||||
return width;
|
||||
}
|
||||
|
||||
static void DrawCell(struct Bitmap* bmp, int x, int y, cc_uint8* rows, BitmapCol color) {
|
||||
int srcX, srcY, dstX, dstY;
|
||||
cc_uint8 row;
|
||||
|
||||
for (srcY = 0; srcY < CELL_SIZE; srcY++)
|
||||
{
|
||||
dstY = y + srcY;
|
||||
if (dstY < 0 || dstY >= bmp->height) continue;
|
||||
|
||||
row = rows[srcY];
|
||||
for (srcX = 0; srcX < CELL_SIZE; srcX++)
|
||||
{
|
||||
dstX = x + srcX;
|
||||
if (dstX < 0 || dstX >= bmp->width) continue;
|
||||
|
||||
if (row & (1 << srcX)) {
|
||||
Bitmap_GetPixel(bmp, dstX, dstY) = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SysFont_DrawText(struct DrawTextArgs* args, struct Bitmap* bmp, int x, int y, cc_bool shadow) {
|
||||
cc_string left = args->text, part;
|
||||
char colorCode = 'f';
|
||||
cc_uint8* rows;
|
||||
BitmapCol color;
|
||||
int i;
|
||||
|
||||
if (shadow) { x++; y++; }
|
||||
|
||||
while (Drawer2D_UNSAFE_NextPart(&left, &part, &colorCode))
|
||||
{
|
||||
color = Drawer2D_GetColor(colorCode);
|
||||
if (shadow) color = GetShadowColor(color);
|
||||
|
||||
for (i = 0; i < part.length; i++)
|
||||
{
|
||||
cc_uint8 c = part.buffer[i];
|
||||
if (c == ' ') {
|
||||
x += SPACE_WIDTH;
|
||||
} else {
|
||||
rows = SysFont_GetRows(c);
|
||||
|
||||
DrawCell(bmp, x, y, rows, color);
|
||||
x += CellWidth(rows);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
10
third_party/gldc/Makefile
vendored
10
third_party/gldc/Makefile
vendored
|
@ -3,12 +3,10 @@ SOURCE_DIRS := src src/yalloc
|
|||
C_FILES := $(foreach dir,$(SOURCE_DIRS),$(wildcard $(dir)/*.c))
|
||||
OBJS := $(notdir $(C_FILES:%.c=%.o))
|
||||
|
||||
C_FLAGS = -O3 -DNDEBUG -mfsrra -mfsca -ffp-contract=fast -ffast-math -O3 -mpretend-cmove -fexpensive-optimizations -fomit-frame-pointer -finline-functions -flto -fno-fat-lto-objects -ml -m4-single-only -ffunction-sections -fdata-sections -std=gnu99
|
||||
C_FLAGS = -O3 -DNDEBUG -mfsrra -mfsca -ffp-contract=fast -ffast-math -O3 -mpretend-cmove -fexpensive-optimizations -fomit-frame-pointer -finline-functions -flto -fno-fat-lto-objects -ml -m4-single-only -ffunction-sections -fdata-sections -std=gnu99
|
||||
|
||||
C_DEFINES = -DDREAMCAST -DNDEBUG -D__DREAMCAST__ -D__arch_dreamcast -D_arch_dreamcast -D_arch_sub_pristine
|
||||
|
||||
C_INCLUDES = -I/opt/toolchains/dc/kos/include -I/opt/toolchains/dc/kos/kernel/arch/dreamcast/include -I/opt/toolchains/dc/kos/addons/include
|
||||
|
||||
TARGET := libGLdc.a
|
||||
|
||||
ifeq ($(strip $(KOS_BASE)),)
|
||||
|
@ -18,11 +16,11 @@ endif
|
|||
default: $(TARGET)
|
||||
|
||||
%.o: src/%.c
|
||||
kos-cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -c $< -o $@
|
||||
kos-cc $(C_DEFINES) $(C_FLAGS) -c $< -o $@
|
||||
|
||||
%.o: src/yalloc/%.c
|
||||
kos-cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -c $< -o $@
|
||||
kos-cc $(C_DEFINES) $(C_FLAGS) -c $< -o $@
|
||||
|
||||
$(TARGET): $(OBJS)
|
||||
kos-ar cr $@ $^
|
||||
kos-ranlib $@
|
||||
kos-ranlib $@
|
Loading…
Reference in a new issue