├── .gitignore ├── src ├── custom │ ├── soundtest_helper.s │ ├── soundtest.c │ └── drawing.c └── patches │ ├── dma_code.s │ └── header.s ├── LICENSE ├── README.md ├── include └── macro.inc ├── Makefile ├── NSUE.ld └── tools └── n64cksum.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.elf 2 | *.z64 3 | .vscode 4 | build/ 5 | -------------------------------------------------------------------------------- /src/custom/soundtest_helper.s: -------------------------------------------------------------------------------- 1 | #include 2 | .set noat 3 | .set noreorder 4 | .section .text 5 | 6 | function soundtest_helper 7 | .helper_call_no_args soundtest func_8006C39C 8 | 9 | -------------------------------------------------------------------------------- /src/patches/dma_code.s: -------------------------------------------------------------------------------- 1 | #include 2 | .set noat 3 | .set noreorder 4 | .section .text 5 | 6 | function dma_code 7 | jal create_scheduler # Replacement for the instruction that was overwritten 8 | nop 9 | 10 | addiu $sp, $sp, -0x20 11 | sw $a2, 0x18($sp) 12 | sw $a1, 0x14($sp) 13 | sw $a0, 0x10($sp) 14 | 15 | la $a0, _baseromSegmentRomEnd 16 | la $a1, _customSegmentStart 17 | lui $a2, %hi(_customSegmentSize) 18 | jal do_dma_read 19 | addiu $a2, $a2, %lo(_customSegmentSize) 20 | 21 | lw $a2, 0x18($sp) 22 | lw $a1, 0x14($sp) 23 | lw $a0, 0x10($sp) 24 | j dma_hook + 2 * 4 25 | addiu $sp, $sp, -0x20 26 | -------------------------------------------------------------------------------- /src/patches/header.s: -------------------------------------------------------------------------------- 1 | .section .data 2 | 3 | .word 0x80371240 /* PI BSB Domain 1 register */ 4 | .word 0x0000000F /* Clockrate setting */ 5 | .word 0x80000400 /* Entrypoint address */ 6 | .word 0x00001444 /* Revision */ 7 | .word 0x0C5EE085 /* Checksum 1 */ 8 | .word 0xA167DD3E /* Checksum 2 */ 9 | .word 0x00000000 /* Unknown 1 */ 10 | .word 0x00000000 /* Unknown 2 */ 11 | .ascii "RROW SOUNDTEST " /* Internal name */ 12 | .word 0x00000000 /* Unknown 3 */ 13 | .word 0x0000004E /* Cartridge */ 14 | .ascii "ED" /* Cartridge ID */ 15 | .ascii "E" /* Country code */ 16 | .byte 0x11 /* Version */ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # N64 Precomp Example 2 | 3 | This is an example repo of showing how to do what I refer to as precomp, which is using an in-progress decomp project as a source of symbols for traditional binary hacking. 4 | 5 | The process involves taking the elf file generated from an in-progress decomp and using it in conjunction with ld to be able to write assembly and C (and C++ for the especially brave) that references symbols from the decomp. It also allows you to write jump hooks that reference offsets from decomp symbols/segments, allowing you to specify instructions to overwrite without needing to deal with converting between RAM and ROM addresses. Using ld also ensures that source files are linked against the correct RAM address. 6 | 7 | This example is that of a hack for "Rocket: Robot On Wheels" that adds a simple sound test to the game. Press left or right on the D-Pad to swap between sounds, press up to play the selected sound and press down to stop a currently running sound. 8 | 9 | This repo targets the modern N64 SDK by CrashOveride95 (https://crashoveride95.github.io/n64hbrew/modernsdk/startoff.html) but can easily be modified to use the regular mips-linux-gnu if you prefer by changing `CROSS` in the makefile and setting up the right flags for gcc. 10 | 11 | To build this, you will need to build the corresponding decomp (https://github.com/RocketRet/Rocket-Robot-On-Wheels). Place the elf file generated by that project into a folder named `elf` in the root of this project, then run `make`. 12 | -------------------------------------------------------------------------------- /include/macro.inc: -------------------------------------------------------------------------------- 1 | # Assembly Macros 2 | 3 | .set gp=64 4 | 5 | .set K0BASE, 0x80000000 6 | .set K1BASE, 0xA0000000 7 | .set K2BASE, 0xC0000000 8 | 9 | .macro glabel label 10 | .global \label 11 | .balign 4 12 | \label: 13 | .endm 14 | 15 | .macro function label 16 | .global \label 17 | .type \label @function 18 | .balign 4 19 | \label: 20 | .endm 21 | 22 | .macro .helper_start 23 | addiu $sp, $sp, -0x28 24 | sw $ra, 0x10($sp) 25 | sw $a0, 0x14($sp) 26 | sw $a1, 0x18($sp) 27 | sw $a2, 0x1C($sp) 28 | sw $a3, 0x20($sp) 29 | .endm 30 | 31 | .macro .helper_end old_func 32 | lw $ra, 0x10($sp) 33 | lw $a0, 0x14($sp) 34 | lw $a1, 0x18($sp) 35 | lw $a2, 0x1C($sp) 36 | lw $a3, 0x20($sp) 37 | j \old_func 38 | addiu $sp, $sp, 0x28 39 | .endm 40 | 41 | .macro .helper_call_no_args new_func old_func 42 | addiu $sp, $sp, -0x28 43 | sw $ra, 0x10($sp) 44 | sw $a0, 0x14($sp) 45 | sw $a1, 0x18($sp) 46 | sw $a2, 0x1C($sp) 47 | jal \new_func 48 | sw $a3, 0x20($sp) 49 | lw $ra, 0x10($sp) 50 | lw $a0, 0x14($sp) 51 | lw $a1, 0x18($sp) 52 | lw $a2, 0x1C($sp) 53 | lw $a3, 0x20($sp) 54 | j \old_func 55 | addiu $sp, $sp, 0x28 56 | .endm 57 | 58 | # TODO does not work? 59 | .macro .helper_call_no_args_no_saves new_func old_func 60 | addiu $sp, $sp, -0x18 61 | jal \new_func 62 | sw $ra, 0x10($sp) 63 | lw $ra, 0x10($sp) 64 | j \old_func 65 | addiu $sp, $sp, 0x18 66 | .endm 67 | -------------------------------------------------------------------------------- /src/custom/soundtest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void drawSmallString(Gfx **dl, int x, int y, const char* string); 6 | void drawSmallStringCol(Gfx **dl, int x, int y, const char* string, unsigned char r, unsigned char g, unsigned char b); 7 | 8 | extern struct ControllerData gControllerData; 9 | extern struct GfxContext gGfxContext; 10 | 11 | musHandle play_sound(u32 number, s32 arg1, s32 volume, s32 pan); 12 | 13 | s32 sound = 0x0D; 14 | musHandle handle = 0; 15 | 16 | void soundtest() 17 | { 18 | if (gControllerData.buttonPressed & L_JPAD) 19 | { 20 | sound--; 21 | if (sound < 0) sound = 0; 22 | } 23 | if (gControllerData.buttonPressed & R_JPAD) 24 | { 25 | sound++; 26 | if (sound > 0xa1) sound = 0xa1; 27 | } 28 | if (gControllerData.buttonPressed & U_JPAD) 29 | { 30 | MusHandleStop(handle, 0); 31 | handle = play_sound(sound, 0x00, 0x80, 0x80); 32 | } 33 | if (gControllerData.buttonPressed & D_JPAD) 34 | { 35 | MusHandleStop(handle, 0); 36 | } 37 | } 38 | 39 | s32 hex_char_from_nibble(s32 val) 40 | { 41 | if (val >= 0x0A) 42 | { 43 | return val + ('A' - 0x0A); 44 | } 45 | else 46 | { 47 | return val + '0'; 48 | } 49 | } 50 | 51 | void schedule_gfx_task(); 52 | 53 | void soundtest_draw() 54 | { 55 | Gfx *dlHead = gGfxContext.dlHead; 56 | char text[9]; 57 | text[0] = 'S'; 58 | text[1] = 'o'; 59 | text[2] = 'u'; 60 | text[3] = 'n'; 61 | text[4] = 'd'; 62 | text[5] = ':'; 63 | text[6] = hex_char_from_nibble((sound >> 4) & 0xF); 64 | text[7] = hex_char_from_nibble((sound >> 0) & 0xF); 65 | text[8] = '\0'; 66 | 67 | gDPSetCycleType(dlHead++, G_CYC_1CYCLE); 68 | gDPSetRenderMode(dlHead++, G_RM_TEX_EDGE, G_RM_TEX_EDGE2); 69 | gDPSetTexturePersp(dlHead++, G_TP_NONE); 70 | gDPSetTextureFilter(dlHead++, G_TF_POINT); 71 | gDPSetTextureLUT(dlHead++, G_TT_NONE); 72 | drawSmallStringCol(&dlHead, 100, 30, text, 255, 255, 255); 73 | 74 | gGfxContext.dlHead = dlHead; 75 | 76 | schedule_gfx_task(); 77 | } 78 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | TARGET := NSUE 2 | 3 | # Directories 4 | SRC_DIR := src 5 | BUILD_DIR := build 6 | 7 | SRC_DIRS := $(shell find $(SRC_DIR)/ -type d) 8 | BUILD_SRC_DIRS := $(addprefix $(BUILD_DIR)/,$(SRC_DIRS)) 9 | 10 | # Tools 11 | CROSS := mips-n64- 12 | 13 | CC := $(CROSS)gcc 14 | AS := $(CROSS)gcc 15 | LD := $(CROSS)ld 16 | CPP := $(CROSS)cpp 17 | OBJCOPY := $(CROSS)objcopy 18 | MKDIR := mkdir -p 19 | RMDIR := rm -rf 20 | CKSUM := $(PYTHON) tools/n64cksum.py 21 | 22 | # Inputs/outputs 23 | ELF := $(BUILD_DIR)/$(TARGET).elf 24 | Z64 := $(ELF:.elf=.z64) 25 | ELF_IN := elf/NSUE.elf 26 | Z64_IN := $(BUILD_DIR)/NSUE_in.z64 27 | Z64_IN_OBJ := $(Z64_IN:.z64=.o) 28 | 29 | C_SRCS := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.c)) 30 | C_OBJS := $(addprefix $(BUILD_DIR)/, $(C_SRCS:.c=.o)) 31 | A_SRCS := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.s)) 32 | A_OBJS := $(addprefix $(BUILD_DIR)/, $(A_SRCS:.s=.o)) 33 | 34 | OBJS := $(C_OBJS) $(A_OBJS) $(Z64_IN_OBJ) 35 | 36 | # Flags 37 | CFLAGS := -c -mabi=32 -ffreestanding -mfix4300 -G 0 -fno-zero-initialized-in-bss -Wall -Wextra -Wpedantic 38 | CPPFLAGS := -Iinclude -I../rrow/include -I../rrow/include/2.0I -DF3DEX_GBI_2 -D_LANGUAGE_C 39 | OPTFLAGS := -Os 40 | ASFLAGS := -c -x assembler-with-cpp -mabi=32 -ffreestanding -mfix4300 -G 0 -O -Iinclude 41 | LD_SCRIPT := NSUE.ld 42 | LDFLAGS := -T $(BUILD_DIR)/$(LD_SCRIPT) -mips3 --accept-unknown-input-arch --no-check-sections 43 | CPP_LDFLAGS := -P -Wno-trigraphs -DBUILD_DIR=$(BUILD_DIR) -Umips -DBASEROM=$(Z64_IN_OBJ) 44 | BINOFLAGS := -I binary -O elf32-big 45 | Z64OFLAGS := -O binary 46 | 47 | # Rules 48 | all: $(Z64) 49 | 50 | $(BUILD_DIR) $(BUILD_SRC_DIRS) : 51 | $(MKDIR) $@ 52 | 53 | $(BUILD_DIR)/%.o : %.c | $(BUILD_SRC_DIRS) 54 | $(CC) $(CPPFLAGS) $(CFLAGS) $(OPTFLAGS) $< -o $@ 55 | 56 | $(BUILD_DIR)/%.o : %.s | $(BUILD_SRC_DIRS) 57 | $(AS) $(ASFLAGS) $< -o $@ 58 | 59 | $(BUILD_DIR)/$(LD_SCRIPT) : $(LD_SCRIPT) 60 | $(CPP) $(CPP_LDFLAGS) $< -o $@ 61 | 62 | $(ELF) : $(OBJS) $(BUILD_DIR)/$(LD_SCRIPT) $(ELF_IN) 63 | $(LD) -R $(ELF_IN) $(LDFLAGS) -Map $(@:.elf=.map) -o $@ 64 | 65 | $(Z64_IN) : $(ELF_IN) | $(BUILD_DIR) 66 | $(OBJCOPY) $(Z64OFLAGS) $< $@ 67 | 68 | $(Z64_IN_OBJ) : $(Z64_IN) | $(BUILD_DIR) 69 | $(OBJCOPY) $(BINOFLAGS) $< $@ 70 | 71 | $(Z64) : $(ELF) 72 | $(OBJCOPY) $(Z64OFLAGS) $< $@ 73 | $(CKSUM) $@ 74 | 75 | clean: 76 | $(RMDIR) $(BUILD_DIR) 77 | 78 | .PHONY: all clean 79 | 80 | print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true 81 | 82 | -------------------------------------------------------------------------------- /NSUE.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_ARCH (mips) 2 | 3 | #define BEGIN_SEG(name, addr) \ 4 | _##name##SegmentStart = ADDR(.name); \ 5 | _##name##SegmentRomStart = __romPos; \ 6 | .name addr : AT(__romPos) 7 | 8 | #define END_SEG(name) \ 9 | _##name##SegmentEnd = ADDR(.name) + SIZEOF(.name); \ 10 | _##name##SegmentRomEnd = __romPos + SIZEOF(.name); \ 11 | _##name##SegmentSize = _##name##SegmentEnd - _##name##SegmentStart; \ 12 | __romPos += SIZEOF(.name); 13 | 14 | #define BEGIN_NOLOAD(name) \ 15 | _##name##SegmentNoloadStart = ADDR(.name.noload); \ 16 | .name.noload (NOLOAD) : 17 | 18 | #define END_NOLOAD(name) \ 19 | _##name##SegmentNoloadEnd = ADDR(.name.noload) + SIZEOF(.name.noload); 20 | 21 | #define PATCH(segment, symbol, offset) \ 22 | .segment##symbol##offset##_patch symbol + offset : AT(_##segment##SegmentRomStart + symbol - _##segment##SegmentStart + offset) 23 | 24 | #define CODE_PATCH(segment, symbol, offset) \ 25 | .segment##symbol##offset##_patch symbol + offset : AT(code_##segment##_ROM_START + symbol - code_##segment##_VRAM + offset) 26 | 27 | #define JAL_HOOK(segment, symbol, offset, helper, name) \ 28 | .segment##symbol##offset##_patch symbol + offset : AT(code_##segment##_ROM_START + symbol - code_##segment##_VRAM + offset) \ 29 | { \ 30 | name = .; \ 31 | BYTE(0x0C); \ 32 | BYTE((helper >> 18) & 0xFF); \ 33 | BYTE((helper >> 10) & 0xFF); \ 34 | BYTE((helper >> 2) & 0xFF); \ 35 | } 36 | 37 | #define ROM_PATCH(address) \ 38 | .rom##address##_patch : AT(address) 39 | 40 | SECTIONS 41 | { 42 | __romPos = 0; 43 | 44 | BEGIN_SEG(baserom, 0) 45 | { 46 | BASEROM; 47 | } 48 | END_SEG(baserom) 49 | baseromEnd = __romPos; 50 | extRamStart = 0xFFFFFFFF80400000; 51 | . = extRamStart; 52 | BEGIN_SEG(custom, .) 53 | { 54 | BUILD_DIR/src/custom/soundtest_helper.o(.text); 55 | BUILD_DIR/src/custom/soundtest.o(.text); 56 | BUILD_DIR/src/custom/drawing.o(.text); 57 | BUILD_DIR/src/custom/soundtest.o(.*data*); 58 | BUILD_DIR/src/custom/drawing.o(.*data*); 59 | } 60 | END_SEG(custom) 61 | 62 | CODE_PATCH(codesegs0_1, osLeoDiskInit, 0x0) 63 | { 64 | BUILD_DIR/src/patches/dma_code.o(.text); 65 | } 66 | 67 | /* Replace a call to create_scheduler with a call to DMA custom code into ext ram */ 68 | JAL_HOOK(codesegs0_1, thread6_unk, 40, dma_code, dma_hook) 69 | 70 | /* Replace a call so that soundtest_helper is called instead */ 71 | JAL_HOOK(codeseg2, func_8005AAE0, 44, soundtest_helper, soundtest_hook) 72 | 73 | /* Replace a call so that soundtest_helper is called instead */ 74 | JAL_HOOK(codeseg2, func_80046B40, 0x148, soundtest_draw, schedule_gfx_hook_1) 75 | 76 | /* Replace a call so that soundtest_helper is called instead */ 77 | JAL_HOOK(codeseg2, func_8007F22C, 0x100, soundtest_draw, schedule_gfx_hook_2) 78 | 79 | ROM_PATCH(0x000000) 80 | { 81 | BUILD_DIR/src/patches/header.o(.data); 82 | } 83 | 84 | /* Discard everything not specifically mentioned above. */ 85 | /DISCARD/ : 86 | { 87 | *(*); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /tools/n64cksum.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import sys 4 | import struct 5 | 6 | # Original code from: https://gist.github.com/dkosmari/ee7bb471ea12c21b008d0ecffebd6384 7 | # Modified to not print 8 | 9 | # tool to recalculate N64 rom checksums 10 | # reference code: 11 | # https://github.com/queueRAM/sm64tools/blob/master/n64cksum.c 12 | # https://github.com/queueRAM/sm64tools/blob/master/libsm64.c 13 | 14 | mask32 = 0xffffffff 15 | 16 | 17 | def read_u32_be(buffer : bytearray, offset): 18 | return struct.unpack_from(">I", buffer, offset)[0] 19 | 20 | 21 | def write_u32_be(buffer : bytearray, offset, value): 22 | struct.pack_into(">I", buffer, offset, value) 23 | 24 | 25 | def sm64_calc_checksums(buf : bytearray): 26 | #local t0, t1, t2, t3, t4, t5, t6, t7, t8, t9 27 | #local s0, s6 28 | #local a0, a1, a2, a3, at 29 | #local lo 30 | #local v0, v1 31 | #local ra 32 | 33 | # derived from the SM64 boot code 34 | s6 = 0x3f 35 | a0 = 0x1000 # 59c: 8d640008 lw a0,8(t3) 36 | a1 = s6 # 5a0: 02c02825 move a1,s6 37 | at = 0x5d588b65 # 5a4: 3c015d58 lui at,0x5d58 38 | # 5a8: 34218b65 ori at,at,0x8b65 39 | lo = (a1 * at) & mask32 # 5ac: 00a10019 multu a1,at 16 F8CA 4DDB 40 | 41 | ra = 0x100000 # 5bc: 3c1f0010 lui ra,0x10 42 | v1 = 0 # 5c0: 00001825 move v1,zero 43 | t0 = 0 # 5c4: 00004025 move t0,zero 44 | t1 = a0 # 5c8: 00804825 move t1,a0 45 | t5 = 32 # 5cc: 240d0020 li t5,32 46 | v0 = lo # 5d0: 00001012 mflo v0 47 | v0 = (v0 + 1) & mask32 # 5d4: 24420001 addiu v0,v0,1 48 | a3 = v0 # 5d8: 00403825 move a3,v0 49 | t2 = v0 # 5dc: 00405025 move t2,v0 50 | t3 = v0 # 5e0: 00405825 move t3,v0 51 | s0 = v0 # 5e4: 00408025 move s0,v0 52 | a2 = v0 # 5e8: 00403025 move a2,v0 53 | t4 = v0 # 5ec: 00406025 move t4,v0 54 | 55 | while t0 != ra: 56 | v0 = read_u32_be(buf, t1) # 5f0: 8d220000 lw v0,0(t1) 57 | v1 = (a3 + v0) & mask32 # 5f4: 00e21821 addu v1,a3,v0 58 | at = v1 < a3 # 5f8: 0067082b sltu at,v1,a3 59 | a1 = v1 # 600: 00602825 move a1,v1 branch delay slot 60 | if at: # 5fc: 10200002 beqz at,0x608 61 | t2 = (t2 + 1) & mask32 # 604: 254a0001 addiu t2,t2,1 62 | 63 | v1 = v0 & 0x1F # 608: 3043001f andi v1,v0,0x1f 64 | t7 = (t5 - v1) & mask32 # 60c: 01a37823 subu t7,t5,v1 65 | t8 = v0 >> t7 # 610: 01e2c006 srlv t8,v0,t7 66 | t6 = (v0 << v1) & mask32 # 614: 00627004 sllv t6,v0,v1 67 | a0 = t6 | t8 # 618: 01d82025 or a0,t6,t8 68 | at = a2 < v0 # 61c: 00c2082b sltu at,a2,v0 69 | a3 = a1 # 620: 00a03825 move a3,a1 70 | t3 = (t3 ^ v0) & mask32 # 624: 01625826 xor t3,t3,v0 71 | s0 = (s0 + a0) & mask32 # 62c: 02048021 addu s0,s0,a0 branch delay slot 72 | if at: # 628: 10200004 beqz at,0x63c 73 | t9 = (a3 ^ v0) & mask32 # 630: 00e2c826 xor t9,a3,v0 74 | # 634: 10000002 b 0x640 75 | a2 = (a2 ^ t9) & mask32 # 638: 03263026 xor a2,t9,a2 branch delay 76 | else: 77 | a2 = (a2 ^ a0) & mask32 # 63c: 00c43026 xor a2,a2,a0 78 | 79 | t0 += 4 # 640: 25080004 addiu t0,t0,4 80 | t7 = (v0 ^ s0) & mask32 # 644: 00507826 xor t7,v0,s0 81 | t1 += 4 # 648: 25290004 addiu t1,t1,4 82 | t4 = (t4 + t7) & mask32 # 650: 01ec6021 addu t4,t7,t4 branch delay 83 | # 64c: 151fffe8 bne t0,ra,0x5f0 84 | 85 | t6 = (a3 ^ t2) & mask32 # 654: 00ea7026 xor t6,a3,t2 86 | a3 = (t6 ^ t3) & mask32 # 658: 01cb3826 xor a3,t6,t3 87 | t8 = (s0 ^ a2) & mask32 # 65c: 0206c026 xor t8,s0,a2 88 | s0 = (t8 ^ t4) & mask32 # 660: 030c8026 xor s0,t8,t4 89 | 90 | return a3, s0 91 | 92 | 93 | def sm64_update_checksums(buf: bytearray): 94 | cksum_offsets = [0x10, 0x14] 95 | read_cksum = [0, 0] 96 | calc_cksum = [0, 0] 97 | 98 | # assume CIC-NUS-6102 99 | # print("BootChip: CIC-NUS-6102"); 100 | 101 | # calculate new N64 header checksum 102 | calc_cksum = sm64_calc_checksums(buf) 103 | 104 | # mimic the n64sums output 105 | for i in range(2): 106 | read_cksum[i] = read_u32_be(buf, cksum_offsets[i]) 107 | # print("CRC{}: 0x{:08X} ".format(i+1, read_cksum[i]), end="") 108 | # print("Calculated: 0x{:08X} ".format(calc_cksum[i]), end="") 109 | 110 | # write checksums into header 111 | # print("Writing back calculated Checksum") 112 | write_u32_be(buf, cksum_offsets[0], calc_cksum[0]) 113 | write_u32_be(buf, cksum_offsets[1], calc_cksum[1]) 114 | 115 | 116 | 117 | def print_usage(): 118 | print("TODO: show help") 119 | 120 | 121 | def read_file(fname): 122 | with open(fname, "rb") as f: 123 | return bytearray(f.read()) 124 | 125 | 126 | def write_file(fname, data): 127 | with open(fname, "wb") as f: 128 | f.write(data) 129 | 130 | 131 | 132 | 133 | if len(sys.argv) < 2: 134 | print_usage() 135 | sys.exit(1) 136 | 137 | 138 | input_name = sys.argv[1] 139 | output_name = input_name 140 | if len(sys.argv) > 2: 141 | output_name = sys.argv[2] 142 | 143 | 144 | rom_data = read_file(input_name) 145 | 146 | sm64_update_checksums(rom_data) 147 | 148 | write_file(output_name, rom_data) -------------------------------------------------------------------------------- /src/custom/drawing.c: -------------------------------------------------------------------------------- 1 | // This file originally from https://github.com/danbolt/n64-jam-1 and is licensed under the MPL-2.0 License 2 | // See the original repo for more details. 3 | 4 | #include 5 | 6 | #define TEX_ASCII_START 0 7 | 8 | #define G_CC_TEXT 0, 0, 0, PRIMITIVE, 0, 0, 0, TEXEL0 9 | 10 | unsigned char font_8px_bin[] __attribute__((aligned(8))) = { 11 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 12 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 14 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 15 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 16 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 17 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 18 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 19 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 20 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 21 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 22 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 23 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 24 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 25 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 26 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 27 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 28 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 29 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 30 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 31 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 32 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 33 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 34 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 35 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 36 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 37 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 38 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 39 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 40 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 41 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 42 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 43 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 44 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 45 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 46 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 47 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 48 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 49 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 50 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 51 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 52 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 53 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 54 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 55 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 56 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 57 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 58 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 59 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 60 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 61 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 62 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 63 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 64 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 65 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 66 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 67 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 68 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 69 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 70 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 71 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 72 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 73 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 74 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 75 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 76 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 77 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 78 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 79 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 80 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 81 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 82 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 83 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 84 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 85 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 86 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 87 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 88 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 89 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 90 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 91 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 92 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 93 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 94 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 95 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 96 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 97 | 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0x00, 98 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 99 | 0x00, 0x00, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 100 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 101 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 102 | 0x00, 0x00, 0xf0, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 103 | 0x00, 0x0f, 0xff, 0xf0, 0x0f, 0xf0, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x00, 104 | 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x0f, 0x00, 0x00, 105 | 0x00, 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 106 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 107 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xf0, 0x0f, 0x00, 108 | 0x0f, 0xff, 0xff, 0xf0, 0x00, 0xf0, 0xf0, 0x00, 0x0f, 0xf0, 0x0f, 0x00, 109 | 0x0f, 0x00, 0xf0, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 110 | 0x00, 0x00, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0xf0, 0x00, 111 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 112 | 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 113 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x0f, 0xff, 0x00, 114 | 0x00, 0x00, 0xf0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 115 | 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xff, 0xff, 0xf0, 116 | 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 117 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 118 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 119 | 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0xf0, 0xf0, 120 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 121 | 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 122 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 123 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 124 | 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xf0, 0x0f, 0xf0, 125 | 0x0f, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 126 | 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0x00, 127 | 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 128 | 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 129 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0x00, 130 | 0x0f, 0x00, 0x0f, 0xf0, 0x00, 0xff, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 131 | 0x00, 0x00, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 132 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 133 | 0x00, 0x0f, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 134 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 135 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 136 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 137 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 138 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 139 | 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 140 | 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0f, 0xff, 0xff, 0xf0, 141 | 0x00, 0x0f, 0xff, 0x00, 0x0f, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 142 | 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 143 | 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 144 | 0x00, 0xff, 0xff, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x0f, 0xf0, 0x00, 145 | 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xff, 0x00, 146 | 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x0f, 0x00, 0x00, 0xf0, 147 | 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 148 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 149 | 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 150 | 0x00, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xf0, 151 | 0x00, 0x0f, 0x0f, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x0f, 0x00, 0x00, 0x00, 152 | 0x00, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 153 | 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xf0, 0x00, 0x00, 154 | 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, 155 | 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0x00, 156 | 0x00, 0x00, 0xff, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, 157 | 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 158 | 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 159 | 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 160 | 0x00, 0x00, 0xff, 0x00, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xf0, 0x00, 161 | 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0xff, 0xff, 0xf0, 162 | 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 163 | 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 164 | 0x00, 0x00, 0xf0, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 165 | 0x00, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 166 | 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0xf0, 167 | 0x00, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 168 | 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x0f, 0x00, 169 | 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x0f, 0x00, 0x00, 170 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 171 | 0x00, 0x0f, 0xf0, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xf0, 172 | 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x00, 173 | 0x00, 0xff, 0xff, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 174 | 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 175 | 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 176 | 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 177 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 178 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 179 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 180 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 181 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 182 | 0x00, 0x0f, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xff, 0x00, 183 | 0x0f, 0xff, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xf0, 184 | 0x00, 0x0f, 0xff, 0x00, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0xff, 0x00, 185 | 0x00, 0x00, 0xff, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, 186 | 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0xff, 0xff, 0x00, 187 | 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0xf0, 188 | 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x0f, 0x00, 0x0f, 0x00, 0x00, 0x00, 189 | 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 190 | 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00, 191 | 0x0f, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0xf0, 192 | 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 193 | 0x00, 0xf0, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xf0, 194 | 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 195 | 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x0f, 0x00, 196 | 0x0f, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0xf0, 0xf0, 197 | 0x0f, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x0f, 0x0f, 0xf0, 198 | 0x0f, 0xff, 0xff, 0xf0, 0x00, 0xff, 0xff, 0x00, 0x0f, 0x00, 0x00, 0x00, 199 | 0x00, 0xf0, 0x00, 0xf0, 0x0f, 0xff, 0xf0, 0x00, 0x0f, 0xff, 0xf0, 0x00, 200 | 0x0f, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0xf0, 0x00, 201 | 0x00, 0x00, 0x0f, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 202 | 0x0f, 0x0f, 0xf0, 0xf0, 0x0f, 0x00, 0xf0, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 203 | 0x0f, 0x00, 0xff, 0x00, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 204 | 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, 205 | 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0xff, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 206 | 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf0, 0x00, 207 | 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x0f, 0xf0, 208 | 0x0f, 0x00, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0x00, 0x0f, 0x00, 0x00, 0xf0, 209 | 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x0f, 0x00, 210 | 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xf0, 211 | 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x0f, 0x00, 212 | 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0xf0, 213 | 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0xff, 0xf0, 214 | 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xff, 0x00, 215 | 0x0f, 0xff, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x0f, 0x00, 0x00, 0x00, 216 | 0x00, 0x0f, 0xff, 0x00, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0xff, 0x00, 217 | 0x00, 0xff, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0xff, 0xff, 0xf0, 218 | 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0xff, 0xff, 0x00, 219 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 220 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 221 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 222 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 223 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 224 | 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 225 | 0x0f, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xf0, 226 | 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 227 | 0x0f, 0x00, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x0f, 0xff, 0xff, 0xf0, 228 | 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 229 | 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0xf0, 230 | 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 231 | 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 232 | 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 233 | 0x00, 0x00, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 234 | 0x00, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 235 | 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 236 | 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0xf0, 237 | 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0xf0, 0x0f, 0x00, 238 | 0x00, 0xf0, 0x00, 0xf0, 0x00, 0x00, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x00, 239 | 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0xf0, 240 | 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x0f, 0x00, 0x00, 0xf0, 241 | 0x0f, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xf0, 0x00, 242 | 0x0f, 0x00, 0x00, 0xf0, 0x00, 0xf0, 0x0f, 0x00, 0x0f, 0x0f, 0xf0, 0xf0, 243 | 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 244 | 0x00, 0xf0, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 245 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 246 | 0x0f, 0x00, 0xf0, 0xf0, 0x0f, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xf0, 247 | 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0xf0, 0x0f, 0x00, 248 | 0x0f, 0x0f, 0xf0, 0xf0, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0x00, 249 | 0x00, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 250 | 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 251 | 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00, 252 | 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0xf0, 253 | 0x00, 0x0f, 0xf0, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 254 | 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 255 | 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 256 | 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0xf0, 257 | 0x0f, 0x00, 0x00, 0xf0, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xf0, 0x00, 258 | 0x00, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0xf0, 259 | 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xf0, 260 | 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xff, 0xff, 0x00, 261 | 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 262 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 263 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 264 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 265 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 266 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 267 | 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 268 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 269 | 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 270 | 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0x00, 271 | 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 272 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 273 | 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 274 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 275 | 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 276 | 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 277 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 278 | 0x00, 0xff, 0xff, 0x00, 0x0f, 0x0f, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 279 | 0x00, 0xff, 0xf0, 0xf0, 0x00, 0xff, 0xff, 0x00, 0x00, 0x0f, 0x00, 0x00, 280 | 0x00, 0xff, 0x0f, 0x00, 0x0f, 0x0f, 0xff, 0x00, 0x00, 0x0f, 0xf0, 0x00, 281 | 0x00, 0x0f, 0xf0, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0x00, 282 | 0x0f, 0xff, 0x0f, 0xff, 0x0f, 0x0f, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 283 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0f, 0xf0, 0x00, 0xf0, 284 | 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x0f, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 285 | 0x0f, 0xff, 0xff, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0xf0, 286 | 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0xf0, 0x00, 287 | 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0xf0, 0x0f, 0x0f, 0xf0, 0x00, 0xf0, 288 | 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 289 | 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0xf0, 290 | 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0xff, 0x00, 291 | 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 292 | 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0xf0, 0x0f, 293 | 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 294 | 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0xf0, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 295 | 0x0f, 0x00, 0x0f, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 296 | 0x00, 0xff, 0x0f, 0x00, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xf0, 0x00, 297 | 0x00, 0x00, 0xf0, 0x00, 0x0f, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 298 | 0x0f, 0x00, 0xf0, 0x0f, 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 299 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0xf0, 0x0f, 0x0f, 0xff, 0x00, 300 | 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xf0, 0xf0, 0x00, 0xff, 0xff, 0x00, 301 | 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x00, 0xf0, 302 | 0x00, 0x0f, 0xff, 0x00, 0x0f, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x0f, 0x00, 303 | 0x00, 0x0f, 0xff, 0x00, 0x0f, 0x00, 0xf0, 0x0f, 0x0f, 0x00, 0x00, 0xf0, 304 | 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 305 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 306 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 307 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 308 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 309 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 310 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 311 | 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 312 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 313 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 314 | 0x0f, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 315 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 316 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 317 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 318 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 319 | 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0xff, 0x00, 320 | 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0xff, 0x00, 0x00, 0xff, 0xf0, 0xf0, 321 | 0x0f, 0x0f, 0xff, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0x00, 322 | 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 323 | 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0xff, 0xff, 0xf0, 324 | 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 325 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0xf0, 326 | 0x0f, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, 327 | 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 328 | 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0x0f, 0x00, 0x00, 0xf0, 329 | 0x00, 0x00, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 330 | 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 331 | 0x0f, 0xf0, 0x00, 0xf0, 0x0f, 0x00, 0x0f, 0xf0, 0x0f, 0x00, 0x00, 0x00, 332 | 0x00, 0xff, 0xff, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0x00, 0xf0, 333 | 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0x0f, 0xf0, 0x00, 334 | 0x0f, 0x00, 0x0f, 0xf0, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x0f, 0x00, 0x00, 335 | 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 336 | 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0xff, 0x00, 0x00, 0xff, 0xf0, 0xf0, 337 | 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0xf0, 338 | 0x0f, 0x00, 0x0f, 0xf0, 0x00, 0xf0, 0x0f, 0x00, 0x0f, 0x00, 0xf0, 0x0f, 339 | 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xff, 0xf0, 0xf0, 0x00, 0xf0, 0x00, 0x00, 340 | 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00, 341 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 342 | 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 343 | 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xf0, 0xf0, 0x00, 0x0f, 0xf0, 0x00, 344 | 0x00, 0xff, 0x0f, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xf0, 345 | 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0xf0, 0x00, 346 | 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 347 | 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 348 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 349 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 350 | 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 351 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 352 | 0x00, 0x00, 0x00, 0x00 353 | }; 354 | 355 | // Naive strlen copied from 356 | // https://stackoverflow.com/questions/22520413/c-strlen-implementation-in-one-line-of-code 357 | void my_strlen(const char *str, u32 *len) 358 | { 359 | for (*len = 0; str[*len]; (*len)++); 360 | } 361 | 362 | void computeST(u8* s, u8* t, unsigned char letter) { 363 | const unsigned char offsetLetter = letter - TEX_ASCII_START; 364 | 365 | *s = (offsetLetter % 16) * 8; 366 | *t = (offsetLetter / 16) * 8; 367 | } 368 | 369 | void drawSmallString_impl(Gfx **dl, int x, int y, const char* string, unsigned char r, unsigned char g, unsigned char b) { 370 | int i = 0; 371 | int xPos = x; 372 | int yPos = y; 373 | u8 s = 0; 374 | u8 t = 0; 375 | Gfx *dlHead = *dl; 376 | 377 | gDPLoadTextureBlock_4b(dlHead++, font_8px_bin, G_IM_FMT_IA, 128, 64, 0, G_TX_MIRROR | G_TX_WRAP, G_TX_MIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); 378 | gDPSetPrimColor(dlHead++, 0, 0, r, g, b, 255); 379 | gDPSetCombineMode(dlHead++, G_CC_TEXT, G_CC_TEXT); 380 | gDPPipeSync(dlHead++); 381 | while (string[i] != '\0') { 382 | if (string[i] == '\n') { 383 | xPos = x; 384 | yPos += 8; 385 | i++; 386 | continue; 387 | } 388 | 389 | computeST(&s, &t, string[i]); 390 | gSPTextureRectangle(dlHead++, (xPos + 0) << 2, (yPos + 0) << 2, (xPos + 8) << 2, (yPos + 8) << 2, 0, s << 5, t << 5, 1 << 10, 1 << 10); 391 | 392 | xPos += 8; 393 | i++; 394 | } 395 | gDPSetPrimColor(dlHead++, 0, 0, 255, 255, 255, 255); 396 | gDPPipeSync(dlHead++); 397 | 398 | *dl = dlHead; 399 | } 400 | 401 | void drawSmallString(Gfx **dl, int x, int y, const char* string) { 402 | drawSmallString_impl(dl, x, y, string, 255, 255, 255); 403 | } 404 | 405 | void drawSmallStringCol(Gfx **dl, int x, int y, const char* string, unsigned char r, unsigned char g, unsigned char b) { 406 | drawSmallString_impl(dl, x, y, string, r, g, b); 407 | } 408 | --------------------------------------------------------------------------------