Created
January 19, 2016 02:22
-
-
Save handsomematt/ca542d2fa7412249e12d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include <time.h> | |
#include <math.h> | |
#include <3ds.h> | |
#include <citro3d.h> | |
#include "vshader_shbin.h" | |
static const u32 SHARED_FONT_SIZE = 0x300000; | |
struct systemfont_header { | |
u32 unk1; | |
u32 unk2; | |
u32 font_size; | |
// rest is 0 | |
}; | |
struct cfnt_header { | |
char signature[4]; | |
u16 endianness; | |
u16 headersize; | |
u32 version; | |
u32 filesize; | |
u32 num_blocks; | |
}; | |
struct finf_header { | |
char signature[4]; | |
u32 sectionsize; | |
u8 fonttype; | |
u8 linefeed; | |
u16 altercharindex; | |
u8 defaultwidth1; | |
u8 defaultwidth2; | |
u8 defaultwidth3; | |
u8 encoding; | |
u32 tglpoffset; | |
u32 cwdhoffset; | |
u32 cmapoffset; | |
u8 height; | |
u8 width; | |
u8 ascent; | |
u8 padding; | |
}; | |
struct tglp_header { | |
char signature[4]; | |
u32 sectionsize; | |
u8 cellwidth; | |
u8 cellheight; | |
u8 baselinepos; | |
u8 maxcharwidth; | |
u32 sheet_size; | |
u16 num_sheets; | |
u16 sheetformat; | |
u16 sheet_num_rows; | |
u16 sheet_num_lines; | |
u16 sheet_width; | |
u16 sheet_height; | |
u32 sheet_data_offset; | |
}; | |
#define CLEAR_COLOR 0x659CEFFF | |
// Used to transfer the final rendered display to the framebuffer | |
#define DISPLAY_TRANSFER_FLAGS \ | |
(GX_TRANSFER_FLIP_VERT(0) | GX_TRANSFER_OUT_TILED(0) | GX_TRANSFER_RAW_COPY(0) | \ | |
GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8) | \ | |
GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO)) | |
// Used to convert textures to 3DS tiled format | |
// Note: vertical flip flag set so 0,0 is top left of texture | |
#define TEXTURE_TRANSFER_FLAGS \ | |
(GX_TRANSFER_FLIP_VERT(1) | GX_TRANSFER_OUT_TILED(1) | GX_TRANSFER_RAW_COPY(0) | \ | |
GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGBA8) | \ | |
GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO)) | |
static DVLB_s* vshader_dvlb; | |
static shaderProgram_s program; | |
static int uLoc_projection; | |
static C3D_Mtx projection; | |
static C3D_Tex sheet_tex; | |
static void sceneInit(void) { | |
int i; | |
// Load the vertex shader, create a shader program and bind it | |
vshader_dvlb = DVLB_ParseFile((u32*)vshader_shbin, vshader_shbin_size); | |
shaderProgramInit(&program); | |
shaderProgramSetVsh(&program, &vshader_dvlb->DVLE[0]); | |
C3D_BindProgram(&program); | |
// Get the location of the uniforms | |
uLoc_projection = shaderInstanceGetUniformLocation(program.vertexShader, "projection"); | |
// Configure attributes for use with the vertex shader | |
// Attribute format and element count are ignored in immediate mode | |
C3D_AttrInfo* attrInfo = C3D_GetAttrInfo(); | |
AttrInfo_Init(attrInfo); | |
AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3); // v0=position | |
AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 2); // v2=texcoord | |
// Compute the projection matrix | |
// Note: we're setting top to 240 here so origin is at top left. | |
Mtx_OrthoTilt(&projection, 0.0, 400.0, 240.0, 0.0, 0.0, 1.0); | |
// Configure buffers | |
C3D_BufInfo* bufInfo = C3D_GetBufInfo(); | |
BufInfo_Init(bufInfo); | |
C3D_TexEnv* env = C3D_GetTexEnv(0); | |
C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, 0, 0); | |
C3D_TexEnvOp(env, C3D_Both, 0, 0, 0); | |
C3D_TexEnvFunc(env, C3D_Both, GPU_REPLACE); | |
} | |
static void sceneRender(int x, int y) { | |
int width = 128; | |
int height = 32; | |
C3D_ImmDrawBegin(GPU_TRIANGLES); | |
C3D_ImmSendAttrib(x, y, 0.5f, 0.0f); // v0=position | |
C3D_ImmSendAttrib( 0.0f, 1.0f, 0.0f, 0.0f); | |
C3D_ImmSendAttrib(x+width, y+height, 0.5f, 0.0f); | |
C3D_ImmSendAttrib( 1.0f, 0.0f, 0.0f, 0.0f); | |
C3D_ImmSendAttrib(x+width, y, 0.5f, 0.0f); | |
C3D_ImmSendAttrib( 1.0f, 1.0f, 0.0f, 0.0f); | |
C3D_ImmSendAttrib(x, y, 0.5f, 0.0f); // v0=position | |
C3D_ImmSendAttrib( 0.0f, 1.0f, 0.0f, 0.0f); | |
C3D_ImmSendAttrib(x, y+height, 0.5f, 0.0f); | |
C3D_ImmSendAttrib( 0.0f, 0.0f, 0.0f, 0.0f); | |
C3D_ImmSendAttrib(x+width, y+height, 0.5f, 0.0f); | |
C3D_ImmSendAttrib( 1.0f, 0.0f, 0.0f, 0.0f); | |
C3D_ImmDrawEnd(); | |
} | |
static void sceneExit(void) { | |
// Free the shader program | |
shaderProgramFree(&program); | |
DVLB_Free(vshader_dvlb); | |
} | |
static bool C3Di_TexInitInVRAM(C3D_Tex* tex, int width, int height, GPU_TEXCOLOR format, void *data, u32 size) | |
{ | |
tex->data = data; | |
tex->width = width; | |
tex->height = height; | |
tex->param = GPU_TEXTURE_MAG_FILTER(GPU_NEAREST) | GPU_TEXTURE_MIN_FILTER(GPU_NEAREST); | |
tex->fmt = format; | |
tex->size = size; | |
return true; | |
} | |
int main() | |
{ | |
aptInit(); | |
gfxInitDefault(); | |
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); | |
consoleInit(GFX_BOTTOM, NULL); | |
Handle apt_handle; | |
srvGetServiceHandle(&apt_handle, "APT:U"); | |
u32* cmdbuf = getThreadCommandBuffer(); | |
cmdbuf[0] = 0x00440000; | |
svcSendSyncRequest(apt_handle); | |
Handle mem_handle = cmdbuf[4]; | |
void* shared_font_addr = reinterpret_cast<void*>(cmdbuf[2]); | |
svcCloseHandle(apt_handle); | |
svcMapMemoryBlock(mem_handle, 0, MEMPERM_READ, MEMPERM_DONTCARE); | |
printf("mem_handle: %p\n", mem_handle); | |
printf("shared_font_addr: %p\n", shared_font_addr); | |
systemfont_header* headertest = (struct systemfont_header*)shared_font_addr; | |
cfnt_header* cfnt = (struct cfnt_header*)(shared_font_addr + 0x80); | |
finf_header* finf = (struct finf_header*)(shared_font_addr + 0x80 + cfnt->headersize); | |
printf("header font_size: %d\n", headertest->font_size); | |
printf("cfntsig: %.*s\n", 4, cfnt->signature); | |
printf("finfsig: %.*s\n", 4, finf->signature); | |
printf("tglpoffset: %p\n", finf->tglpoffset); | |
printf("cwdhoffset: %p\n", finf->cwdhoffset); | |
printf("cmapoffset: %p\n", finf->cmapoffset); | |
tglp_header* tglp = (struct tglp_header*)(finf->tglpoffset - 8); | |
printf("tglpsig: %.*s\n", 4, tglp->signature); | |
printf("tglp format: %d\n", tglp->sheetformat); | |
u32 sheetptr = tglp->sheet_data_offset; | |
u32 sheets[tglp->num_sheets]; | |
for (int i=0; i<tglp->num_sheets; i++) | |
{ | |
sheets[i] = sheetptr; | |
sheetptr += tglp->sheet_size; | |
} | |
printf("loaded %d sheet pointers\n", tglp->num_sheets); | |
printf("sheets[13]: %p\n", sheets[13]); | |
sceneInit(); | |
// Initialize the render target | |
C3D_RenderTarget* target = C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); | |
C3D_RenderTargetSetClear(target, C3D_CLEAR_ALL, CLEAR_COLOR, 0); | |
C3D_RenderTargetSetOutput(target, GFX_TOP, GFX_LEFT, DISPLAY_TRANSFER_FLAGS); | |
printf("texinit: %d, %d\n", tglp->sheet_width, tglp->sheet_height); | |
C3Di_TexInitInVRAM(&sheet_tex, tglp->sheet_width, tglp->sheet_height, (GPU_TEXCOLOR)tglp->sheetformat, (void*)sheets[0], tglp->sheet_size); | |
int row = 0; | |
while (aptMainLoop()) { | |
gfxFlushBuffers(); | |
gfxSwapBuffers(); | |
hidScanInput(); | |
if (hidKeysHeld() & KEY_START) { | |
break; | |
} | |
if (hidKeysHeld() & KEY_DOWN) | |
row++; | |
if (hidKeysHeld() & KEY_UP) | |
row--; | |
if (row < 0) row = 0; | |
if (row > 500) row = 500; | |
C3D_FrameBegin(C3D_FRAME_SYNCDRAW); | |
C3D_FrameDrawOn(target); | |
C3D_TexBind(0, &sheet_tex); | |
// Update the uniforms | |
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, uLoc_projection, &projection); | |
for (int y = 0; y < 9; y++) | |
{ | |
for (int x = 0; x < 3; x++) | |
{ | |
C3Di_TexInitInVRAM(&sheet_tex, tglp->sheet_width, tglp->sheet_height, (GPU_TEXCOLOR)tglp->sheetformat, (void*)sheets[(row*3)+(y*3)+x], tglp->sheet_size); | |
C3D_TexBind(0, &sheet_tex); | |
sceneRender(8 + (x*128), y*32); | |
} | |
} | |
C3D_FrameEnd(0); | |
//draw_sheet((u8*)sheets[0], tglp->sheet_width, tglp->sheet_height); | |
gspWaitForEvent(GSPGPU_EVENT_VBlank0, false); | |
} | |
sceneExit(); | |
C3D_Fini(); | |
gfxExit(); | |
aptExit(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment