initial commit
This commit is contained in:
commit
de919cd1f7
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
obj/
|
||||||
|
.idea/
|
||||||
|
*.dol
|
||||||
|
*.elf
|
||||||
|
*.map
|
||||||
|
|
106
Makefile
Normal file
106
Makefile
Normal 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
10
README.md
Normal 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
338
src/gxfb.c
Normal 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
36
src/gxfb.h
Normal 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
72
src/main.c
Normal 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
133
src/vgafont.c
Normal 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
7
src/vgafont.h
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#ifndef VGAFONT_H_INCLUDED
|
||||||
|
#define VGAFONT_H_INCLUDED
|
||||||
|
|
||||||
|
extern const unsigned char vgafont[];
|
||||||
|
extern const int vgafont_size;
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue