initial commit

This commit is contained in:
Gered 2021-03-06 19:11:23 -05:00
commit de919cd1f7
8 changed files with 708 additions and 0 deletions

6
.gitignore vendored Normal file
View file

@ -0,0 +1,6 @@
obj/
.idea/
*.dol
*.elf
*.map

106
Makefile Normal file
View file

@ -0,0 +1,106 @@
ifeq ($(strip $(DEVKITPRO)),)
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>devkitPro")
endif
ifeq ($(strip $(DEVKITPPC)),)
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC")
endif
# ------------------------------------------------------------------------------
TARGET := gc-gx-fb
# ------------------------------------------------------------------------------
# source file location(s), include/lib dirs, libraries to use
SRC_DIR := src
INCLUDE_DIRS :=
LIB_DIRS = -L$(LIBOGC_LIB_DIR)
LIBS = -ldb $(PLATFORM_LIBS)
# ------------------------------------------------------------------------------
# compiler/linker flags
INCLUDES = -I$(DEVKITPRO)/libogc/include $(foreach dir,$(INCLUDE_DIRS),-I$(dir))
CFLAGS = -g -O0 $(MACHDEP) $(INCLUDES)
CXXFLAGS = $(CFLAGS)
AFLAGS =
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map $(LIB_DIRS) $(LIBS)
# ------------------------------------------------------------------------------
# finding all source files to be compiled and where to place object files
SRC_FILES := $(shell find $(SRC_DIR) -type f)
SRC_FILES := $(filter $(addprefix %, .cpp .c .s), $(SRC_FILES))
OBJ_DIR := obj
OBJ_FILES := $(addprefix $(OBJ_DIR)/, $(addsuffix .o, $(SRC_FILES)))
OBJ_DIRS := $(sort $(dir $(OBJ_FILES)))
DEPS_DIR := $(OBJ_DIR)
DEPENDS := $(OBJ_FILES:.o=.d)
# ------------------------------------------------------------------------------
.SUFFIXES:
.PHONY: clean run
all: $(TARGET).dol
$(TARGET).dol: $(TARGET).elf
$(TARGET).elf: $(OBJ_FILES)
clean:
rm -f $(TARGET).dol
rm -f $(TARGET).elf
rm -f $(TARGET).elf.map
rm -rf $(OBJ_DIR)
run: $(TARGET).dol
$(DEVKITPRO)/tools/bin/wiiload $(TARGET).dol
# ------------------------------------------------------------------------------
# compiler/toolchain related stuff
ifeq ($(PLATFORM),cube)
MACHDEP = -DGEKKO -mogc -mcpu=750 -meabi -mhard-float
LIBOGC_LIB_DIR = $(DEVKITPRO)/libogc/lib/cube
PLATFORM_LIBS = -lfat -logc -lm
else
MACHDEP = -DGEKKO -mrvl -mcpu=750 -meabi -mhard-float
LIBOGC_LIB_DIR = $(DEVKITPRO)/libogc/lib/wii
PLATFORM_LIBS = -lwiiuse -lbte -lfat -logc -lm
endif
CC := $(DEVKITPPC)/bin/powerpc-eabi-gcc
CXX := $(DEVKITPPC)/bin/powerpc-eabi-g++
AS := $(DEVKITPPC)/bin/powerpc-eabi-as
LD := $(DEVKITPPC)/bin/powerpc-eabi-gcc
OBJCOPY := $(DEVKITPPC)/bin/powerpc-eabi-objcopy
ELF2DOL := $(DEVKITPRO)/tools/bin/elf2dol
BIN2S := $(DEVKITPRO)/tools/bin/bin2s
# ------------------------------------------------------------------------------
# standard compilation for the supported source file types, and binary linking
$(OBJ_DIR)/%.cpp.o: %.cpp
@mkdir -p $(dir $@)
$(CXX) -MMD -MP -MF $(DEPS_DIR)/$*.d $(CXXFLAGS) -c $< -o $@
$(OBJ_DIR)/%.c.o: %.c
@mkdir -p $(dir $@)
$(CC) -MMD -MP -MF $(DEPS_DIR)/$*.d $(CFLAGS) -c $< -o $@
$(OBJ_DIR)/%.s.o: %s
@mkdir -p $(dir $@)
$(CC) -MMD -MP -MF $(DEPS_DIR)/$*.d -x assembler-with-cpp $(AFLAGS) -c$< -o $@
%.elf:
$(LD) $^ $(LDFLAGS) -o $@
%.dol: %.elf
$(ELF2DOL) $< $@
# ------------------------------------------------------------------------------
-include $(DEPENDS)

10
README.md Normal file
View file

@ -0,0 +1,10 @@
# Gamecube GX-based RGB Framebuffer Example
Just a simple example of using a GX ARGB-format texture as a means to render a "software" pixel framebuffer
quickly. Most applications won't care about such a thing, but this can be nice if you want low-level per-pixel access
in your code (e.g. MS-DOS Mode 13h style).
If you want to access pixels using RGB, this is significantly better than using the XFB/EFB buffer, where the pixel
data uses YUV color space.
Probably there could be a number of improvements made to this ... I'm not well versed in the GX API.

338
src/gxfb.c Normal file
View file

@ -0,0 +1,338 @@
#include "gxfb.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include "vgafont.h"
#define DEFAULT_FIFO_SIZE 256 * 1024
u32 *framebuffer = NULL;
int framebuffer_width = 0;
int framebuffer_height = 0;
int framebuffer_left;
int framebuffer_top;
int framebuffer_right;
int framebuffer_bottom;
size_t framebuffer_size = 0;
static u32 *xfb[2] = { NULL, NULL };
static int current_xfb = 0;
static void *gpfifo = NULL;
static size_t texture_image_size = 0;
static u32 *texture_image = NULL;
static GXTexObj texture;
static int quad_x_offset = 0;
static int quad_y_offset = 0;
static Mtx44 perspective;
static Mtx modelview;
static char printf_buffer[1024];
static void gx_copyxfb(void) {
GX_CopyDisp(xfb[current_xfb], GX_TRUE);
VIDEO_SetNextFramebuffer(xfb[current_xfb]);
current_xfb ^= 1;
}
static void video_init(GXRModeObj *rmode) {
VIDEO_Init();
xfb[0] = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
xfb[1] = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
VIDEO_Configure(rmode);
VIDEO_SetNextFramebuffer(xfb[0]);
VIDEO_SetBlack(FALSE);
VIDEO_Flush();
VIDEO_WaitVSync();
if (rmode->viTVMode & VI_NON_INTERLACE)
VIDEO_WaitVSync();
current_xfb = 1;
}
static void gx_init(GXRModeObj *rmode, GXColor clearColor) {
gpfifo = aligned_alloc(32, DEFAULT_FIFO_SIZE);
memset(gpfifo, 0, DEFAULT_FIFO_SIZE);
GX_Init(gpfifo, DEFAULT_FIFO_SIZE);
GX_SetCopyClear(clearColor, GX_MAX_Z24);
GX_InvVtxCache();
GX_ClearVtxDesc();
// define various view properties, like the viewport, scissor(clipping), efb/xfb dimensions, filters ...
GX_SetViewport(0, 0, rmode->fbWidth, rmode->efbHeight, 0, 1);
GX_SetDispCopyYScale((f32) rmode->xfbHeight / (f32) rmode->efbHeight);
GX_SetScissor(0, 0, rmode->fbWidth, rmode->efbHeight);
GX_SetDispCopySrc(0, 0, rmode->fbWidth, rmode->efbHeight);
GX_SetDispCopyDst(rmode->fbWidth, rmode->xfbHeight);
GX_SetCopyFilter(rmode->aa, rmode->sample_pattern, GX_TRUE, rmode->vfilter);
GX_SetFieldMode(rmode->field_rendering, ((rmode->viHeight == 2 * rmode->xfbHeight) ? GX_ENABLE : GX_DISABLE));
if (rmode->aa)
GX_SetPixelFmt(GX_PF_RGB565_Z16, GX_ZC_LINEAR);
else
GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
GX_SetCullMode(GX_CULL_NONE);
gx_copyxfb();
GX_SetDispCopyGamma(GX_GM_1_0);
GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
GX_SetColorUpdate(GX_TRUE);
}
static void gx_init_texture(int width, int height) {
texture_image_size = width * height * 4;
texture_image = aligned_alloc(32, texture_image_size);
memset(texture_image, 0, texture_image_size);
GX_InvalidateTexAll();
GX_InitTexObj(&texture, texture_image, width, height, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
GX_InitTexObjFilterMode(&texture, GX_NEAR, GX_NEAR);
GX_LoadTexObj(&texture, GX_TEXMAP0);
}
static void gx_init_vertex_format(void) {
// 2D X/Y + texture coordinates
GX_ClearVtxDesc();
GX_SetVtxDesc(GX_VA_POS, GX_DIRECT);
GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_F32, 0);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
GX_SetNumChans(1);
GX_SetNumTexGens(1);
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
GX_SetTevOp(GX_TEVSTAGE0, GX_REPLACE);
GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
}
static void gx_init_projection(GXRModeObj *rmode) {
// TODO: this is really only going to be appropriate for 240p-equivalent modes ...
guOrtho(perspective, 0, rmode->efbHeight - 1, 0, (rmode->fbWidth / 2) - 1, 0, 300);
GX_LoadProjectionMtx(perspective, GX_ORTHOGRAPHIC);
}
static void copy_framebuffer_to_texture(void) {
// gamecube/wii texture memory is organized in 32-byte tiles. for 32-bit ARGB-format textures, as we are using,
// this means the 32-bit space comprises a 4x4 tile. so we need to copy our contiguous 2d source framebuffer
// and convert it on the fly to this 4x4 tile layout.
// however, one extra wrinkle is that for 32-bit ARGB-format textures, the 32-byte tile size actually only is
// large enough to hold half of a 4x4 tile. so, what the gamecube hardware does instead for 32-bit ARGB format is
// to split the pixels into two halves. the first 32-byte 4x4 tile holds pixel data containing alpha+red only, and
// the second 32-byte 4x4 tile holds pixel data containing green+blue only.
// reading 4 source ARGB-format pixel rows per iteration
u16 *src_1 = (u16*)&framebuffer[0];
u16 *src_2 = (u16*)&framebuffer[framebuffer_width];
u16 *src_3 = (u16*)&framebuffer[framebuffer_width * 2];
u16 *src_4 = (u16*)&framebuffer[framebuffer_width * 3];
// destination 16-bit AR-format (alpha+red) pixel destination rows
u16 *dst_ar_1 = (u16*)&texture_image[0];
u16 *dst_ar_2 = (u16*)&texture_image[8/4];
u16 *dst_ar_3 = (u16*)&texture_image[16/4];
u16 *dst_ar_4 = (u16*)&texture_image[24/4];
// destination 16-bit GB-format (green+blue) pixel destination rows
u16 *dst_gb_1 = (u16*)&texture_image[32/4];
u16 *dst_gb_2 = (u16*)&texture_image[40/4];
u16 *dst_gb_3 = (u16*)&texture_image[48/4];
u16 *dst_gb_4 = (u16*)&texture_image[56/4];
// work through the framebuffer in 4x4 pixel chunks
for (int y = 0; y < framebuffer_height; y += 4) {
for (int x = 0; x < framebuffer_width; x += 4) {
// each loop iteration copies an entire 4x4 pixel chunk
// column 1 for all 4 rows
dst_ar_1[0] = src_1[0]; dst_gb_1[0] = src_1[1];
dst_ar_2[0] = src_2[0]; dst_gb_2[0] = src_2[1];
dst_ar_3[0] = src_3[0]; dst_gb_3[0] = src_3[1];
dst_ar_4[0] = src_4[0]; dst_gb_4[0] = src_4[1];
// column 2 for all 4 rows
dst_ar_1[1] = src_1[2]; dst_gb_1[1] = src_1[3];
dst_ar_2[1] = src_2[2]; dst_gb_2[1] = src_2[3];
dst_ar_3[1] = src_3[2]; dst_gb_3[1] = src_3[3];
dst_ar_4[1] = src_4[2]; dst_gb_4[1] = src_4[3];
// column 3 for all 4 rows
dst_ar_1[2] = src_1[4]; dst_gb_1[2] = src_1[5];
dst_ar_2[2] = src_2[4]; dst_gb_2[2] = src_2[5];
dst_ar_3[2] = src_3[4]; dst_gb_3[2] = src_3[5];
dst_ar_4[2] = src_4[4]; dst_gb_4[2] = src_4[5];
// column 4 for all 4 rows
dst_ar_1[3] = src_1[6]; dst_gb_1[3] = src_1[7];
dst_ar_2[3] = src_2[6]; dst_gb_2[3] = src_2[7];
dst_ar_3[3] = src_3[6]; dst_gb_3[3] = src_3[7];
dst_ar_4[3] = src_4[6]; dst_gb_4[3] = src_4[7];
// move right to the next 4x4 tile for source and dest
src_1 += 8;
src_2 += 8;
src_3 += 8;
src_4 += 8;
dst_ar_1 += 32;
dst_ar_2 += 32;
dst_ar_3 += 32;
dst_ar_4 += 32;
dst_gb_1 += 32;
dst_gb_2 += 32;
dst_gb_3 += 32;
dst_gb_4 += 32;
}
// move down to the next 4x4 tile row for source (dest will be correct already)
src_1 += (framebuffer_width * 2) * 3;
src_2 += (framebuffer_width * 2) * 3;
src_3 += (framebuffer_width * 2) * 3;
src_4 += (framebuffer_width * 2) * 3;
}
}
int fb_init(GXRModeObj *rmode, int width, int height) {
if (framebuffer)
return 1;
if (!rmode)
return 1;
if (width <= 0 || width > (rmode->fbWidth / 2))
return 1;
if (height <= 0 || height > rmode->efbHeight)
return 1;
video_init(rmode);
GXColor clearColor = { .r = 0, .g = 0, .b = 0, .a = 0xff };
gx_init(rmode, clearColor);
gx_init_texture(width, height);
gx_init_vertex_format();
gx_init_projection(rmode);
// allocate application-accessible framebuffer. ARGB-format pixels
framebuffer_size = width * height * 4;
framebuffer = aligned_alloc(32, framebuffer_size);
framebuffer_width = width;
framebuffer_height = height;
framebuffer_left = 0;
framebuffer_top = 0;
framebuffer_right = framebuffer_width - 1;
framebuffer_bottom = framebuffer_height - 1;
memset(framebuffer, 0, framebuffer_size);
// x/y offset for rending the quad.
// this will center it on screen if the framebuffer is smaller than the screen mode
quad_x_offset = ((rmode->fbWidth / 2) - width) / 2;
quad_y_offset = ((rmode->efbHeight) - height) / 2;
// set up constant modelview matrix for rending our quad with
guMtxIdentity(modelview);
guMtxTransApply(modelview, modelview, 0.0, 0.0, -5.0);
GX_LoadPosMtxImm(modelview, GX_PNMTX0);
return 0;
}
void fb_flip(int wait_vsync) {
// update the texture's pixel data with the contents of the application-accessible framebuffer
copy_framebuffer_to_texture();
DCFlushRange(texture_image, texture_image_size);
// render the framebuffer-textured quad
GX_InvVtxCache();
GX_InvalidateTexAll();
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
GX_Position2f32(quad_x_offset, quad_y_offset);
GX_TexCoord2f32(0.0, 0.0);
GX_Position2f32(quad_x_offset + framebuffer_width - 1, quad_y_offset);
GX_TexCoord2f32(1.0, 0.0);
GX_Position2f32(quad_x_offset + framebuffer_width - 1, quad_y_offset + framebuffer_height - 1);
GX_TexCoord2f32(1.0, 1.0);
GX_Position2f32(quad_x_offset, quad_y_offset + framebuffer_height - 1);
GX_TexCoord2f32(0.0, 1.0);
GX_End();
GX_DrawDone();
gx_copyxfb();
GX_Flush();
VIDEO_Flush();
if (wait_vsync) {
VIDEO_WaitVSync();
}
}
void fb_clear(u32 color) {
for (u32 i = 0; i < framebuffer_size; ++i) {
framebuffer[i] = color;
}
}
static void blit_char(char c, int x, int y, u32 color) {
const u8 *work_char;
u8 bit_mask = 0x80;
u32 *ptr;
work_char = &vgafont[(unsigned char)c * 8];
ptr = fb_pixel_ptr(x, y);
for (int yc = 0; yc < 8; ++yc) {
bit_mask = 0x80;
for (int xc = 0; xc < 8; ++xc) {
if ((*work_char & bit_mask))
ptr[xc] = color;
bit_mask = (bit_mask >> 1);
}
ptr += framebuffer_width;
++work_char;
}
}
void fb_printf(int x, int y, u32 color, const char *format, ...) {
va_list args;
va_start(args, format);
vsnprintf(printf_buffer, 1023, format, args);
va_end(args);
printf_buffer[1023] = 0;
int dx = x;
int dy = y;
for (char *c = printf_buffer; *c; ++c) {
switch (*c) {
case '\n':
dx = x;
dy += 8;
break;
case '\r':
break;
case ' ':
dx += 8;
break;
default:
blit_char(*c, dx, dy, color);
dx += 8;
break;
}
}
}

36
src/gxfb.h Normal file
View file

@ -0,0 +1,36 @@
#ifndef GXFB_H_INCLUDED
#define GXFB_H_INCLUDED
#include <gccore.h>
#define RGB(r, g, b) ((255 << 24) | ((r) << 16) | ((g) << 8) | (b))
extern u32 *framebuffer;
extern int framebuffer_width;
extern int framebuffer_height;
extern int framebuffer_left;
extern int framebuffer_top;
extern int framebuffer_right;
extern int framebuffer_bottom;
extern size_t framebuffer_size;
int fb_init(GXRModeObj *rmode, int width, int height);
void fb_flip(int wait_vsync);
void fb_clear(u32 color);
static inline u32* fb_pixel_ptr(int x, int y) {
return framebuffer + (y * framebuffer_width) + x;
}
static inline void fb_pset(int x, int y, u32 color) {
*fb_pixel_ptr(x, y) = color;
}
static inline u32 fb_pget(int x, int y) {
return *fb_pixel_ptr(x, y);
}
void fb_printf(int x, int y, u32 color, const char *format, ...);
#endif

72
src/main.c Normal file
View file

@ -0,0 +1,72 @@
#include <stdio.h>
#include <stdlib.h>
#include <gccore.h>
#include <debug.h>
#include "gxfb.h"
int main(int argc, char *argv[]) {
DEBUG_Init(GDBSTUB_DEVICE_USB, 1);
//_break();
GXRModeObj *rmode;
s32 videoFormat = CONF_GetVideo();
if (videoFormat == CONF_VIDEO_NTSC)
rmode = &TVNtsc240Ds;
else if (videoFormat == CONF_VIDEO_PAL)
rmode = &TVPal264Ds;
else if (videoFormat == CONF_VIDEO_MPAL)
rmode = &TVMpal240Ds;
else
return 1;
if (fb_init(rmode, 320, 240))
return 1;
PAD_Init();
int x = 100, y = 100;
while (1) {
PAD_ScanPads();
u32 pressed = PAD_ButtonsDown(0);
u32 held = PAD_ButtonsHeld(0);
if (pressed & PAD_BUTTON_START) {
exit(0);
}
if (held & PAD_BUTTON_UP) {
--y;
if (y < 0)
y = 0;
}
if (held & PAD_BUTTON_DOWN) {
++y;
if (y > framebuffer_bottom)
y = framebuffer_bottom;
}
if (held & PAD_BUTTON_LEFT) {
--x;
if (x < 0)
x = 0;
}
if (held & PAD_BUTTON_RIGHT) {
++x;
if (x > framebuffer_right)
x = framebuffer_right;
}
fb_clear(RGB(32, 64, 128));
fb_printf(30, 30, RGB(255, 255, 0), "hello, world!");
fb_printf(30, 40, RGB(255, 0, 255), "x = %d, y = %d\n", x, y);
fb_pset(x, y, RGB(255, 255, 255));
fb_flip(true);
}
return 0;
}

133
src/vgafont.c Normal file
View file

@ -0,0 +1,133 @@
const unsigned char vgafont[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e,
0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e, 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00,
0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x38, 0x7c, 0x38, 0xfe, 0xfe, 0x7c, 0x38, 0x7c,
0x10, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x7c, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00,
0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00,
0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78,
0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x70, 0xf0, 0xe0,
0x7f, 0x63, 0x7f, 0x63, 0x63, 0x67, 0xe6, 0xc0, 0x99, 0x5a, 0x3c, 0xe7, 0xe7, 0x3c, 0x5a, 0x99,
0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00, 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00,
0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00,
0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x00, 0x3e, 0x63, 0x38, 0x6c, 0x6c, 0x38, 0xcc, 0x78,
0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff,
0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00,
0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00,
0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00,
0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, 0x78, 0x78, 0x30, 0x00, 0x30, 0x00,
0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00,
0x30, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x30, 0x00, 0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00,
0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00,
0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00,
0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0x7c, 0x00, 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00,
0x78, 0xcc, 0x0c, 0x38, 0x60, 0xcc, 0xfc, 0x00, 0x78, 0xcc, 0x0c, 0x38, 0x0c, 0xcc, 0x78, 0x00,
0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00, 0xfc, 0xc0, 0xf8, 0x0c, 0x0c, 0xcc, 0x78, 0x00,
0x38, 0x60, 0xc0, 0xf8, 0xcc, 0xcc, 0x78, 0x00, 0xfc, 0xcc, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00,
0x78, 0xcc, 0xcc, 0x78, 0xcc, 0xcc, 0x78, 0x00, 0x78, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0x70, 0x00,
0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60,
0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00,
0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00,
0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x78, 0x00, 0x30, 0x78, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0x00,
0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, 0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x00,
0xf8, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x7e, 0x60, 0x60, 0x78, 0x60, 0x60, 0x7e, 0x00,
0x7e, 0x60, 0x60, 0x78, 0x60, 0x60, 0x60, 0x00, 0x3c, 0x66, 0xc0, 0xc0, 0xce, 0x66, 0x3e, 0x00,
0xcc, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0xcc, 0x00, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7e, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00,
0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00,
0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xdc, 0x78, 0x1c, 0x00,
0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00, 0x78, 0xcc, 0xe0, 0x70, 0x1c, 0xcc, 0x78, 0x00,
0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfc, 0x00,
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, 0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00,
0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x78, 0x00,
0xfe, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xfe, 0x00, 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00,
0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00,
0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00,
0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xdc, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x00,
0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00,
0x38, 0x6c, 0x60, 0xf0, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8,
0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00, 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00,
0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0xcc, 0xfe, 0xfe, 0xd6, 0xc6, 0x00,
0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00,
0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e,
0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x00,
0x10, 0x30, 0x7c, 0x30, 0x30, 0x34, 0x18, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00,
0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xfe, 0xfe, 0x6c, 0x00,
0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8,
0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00, 0x1c, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x1c, 0x00,
0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, 0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00,
0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00,
0x7c, 0xc6, 0xc0, 0xc6, 0x7c, 0x0c, 0x06, 0x7c, 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x76, 0x00,
0x1c, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, 0x7e, 0x81, 0x3c, 0x06, 0x3e, 0x66, 0x3b, 0x00,
0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, 0xe0, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00,
0x30, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0x78, 0x0c, 0x38,
0x7e, 0x81, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00, 0xcc, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00,
0xe0, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, 0xcc, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
0x7c, 0x82, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, 0xe0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
0xc6, 0x10, 0x7c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x30, 0x30, 0x00, 0x78, 0xcc, 0xfc, 0xcc, 0x00,
0x1c, 0x00, 0xfc, 0x60, 0x78, 0x60, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0x0c, 0x7f, 0xcc, 0x7f, 0x00,
0x3e, 0x6c, 0xcc, 0xfe, 0xcc, 0xcc, 0xce, 0x00, 0x78, 0x84, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00,
0x00, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0xe0, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00,
0x78, 0x84, 0x00, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0xe0, 0x00, 0xcc, 0xcc, 0xcc, 0x76, 0x00,
0x00, 0xcc, 0x00, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, 0xc3, 0x18, 0x3c, 0x66, 0x66, 0x3c, 0x18, 0x00,
0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x18, 0x18, 0x7e, 0xc0, 0xc0, 0x7e, 0x18, 0x18,
0x38, 0x6c, 0x64, 0xf0, 0x60, 0xe6, 0xfc, 0x00, 0xcc, 0xcc, 0x78, 0x30, 0xfc, 0x30, 0xfc, 0x30,
0xf8, 0xcc, 0xcc, 0xfa, 0xc6, 0xcf, 0xc6, 0xc3, 0x0e, 0x1b, 0x18, 0x3c, 0x18, 0x18, 0xd8, 0x70,
0x1c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
0x00, 0x1c, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x1c, 0x00, 0xcc, 0xcc, 0xcc, 0x76, 0x00,
0x00, 0xf8, 0x00, 0xb8, 0xcc, 0xcc, 0xcc, 0x00, 0xfc, 0x00, 0xcc, 0xec, 0xfc, 0xdc, 0xcc, 0x00,
0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00,
0x18, 0x00, 0x18, 0x18, 0x30, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc0, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x00, 0x00, 0xc6, 0xcc, 0xd8, 0x36, 0x6b, 0xc2, 0x84, 0x0f,
0xc3, 0xc6, 0xcc, 0xdb, 0x37, 0x6d, 0xcf, 0x03, 0x18, 0x00, 0x18, 0x18, 0x3c, 0x3c, 0x18, 0x00,
0x00, 0x33, 0x66, 0xcc, 0x66, 0x33, 0x00, 0x00, 0x00, 0xcc, 0x66, 0x33, 0x66, 0xcc, 0x00, 0x00,
0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
0xdb, 0xf6, 0xdb, 0x6f, 0xdb, 0x7e, 0xd7, 0xed, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18,
0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36,
0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36,
0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00,
0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18,
0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36,
0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36,
0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36,
0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00,
0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36,
0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x76, 0xdc, 0xc8, 0xdc, 0x76, 0x00, 0x00, 0x78, 0xcc, 0xf8, 0xcc, 0xf8, 0xc0, 0xc0,
0x00, 0xfc, 0xcc, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x00,
0xfc, 0xcc, 0x60, 0x30, 0x60, 0xcc, 0xfc, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0x70, 0x00,
0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0xc0, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x00,
0xfc, 0x30, 0x78, 0xcc, 0xcc, 0x78, 0x30, 0xfc, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0x6c, 0x38, 0x00,
0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x6c, 0xee, 0x00, 0x1c, 0x30, 0x18, 0x7c, 0xcc, 0xcc, 0x78, 0x00,
0x00, 0x00, 0x7e, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x06, 0x0c, 0x7e, 0xdb, 0xdb, 0x7e, 0x60, 0xc0,
0x38, 0x60, 0xc0, 0xf8, 0xc0, 0x60, 0x38, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00,
0x00, 0x7e, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x7e, 0x00,
0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xfc, 0x00, 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xfc, 0x00,
0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70,
0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00,
0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x1c,
0x58, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x70, 0x98, 0x30, 0x60, 0xf8, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const int vgafont_size = sizeof(vgafont);

7
src/vgafont.h Normal file
View file

@ -0,0 +1,7 @@
#ifndef VGAFONT_H_INCLUDED
#define VGAFONT_H_INCLUDED
extern const unsigned char vgafont[];
extern const int vgafont_size;
#endif