Skip to content

Instantly share code, notes, and snippets.

View ISSOtm's full-sized avatar
🦀
Rewriting RGBDS... In Rust!

Eldred Habert ISSOtm

🦀
Rewriting RGBDS... In Rust!
View GitHub Profile
@ISSOtm
ISSOtm / cartswap.md
Last active November 25, 2023 12:57
Swapping GB carts from the Game Boy to our advantage

The beauties (and crashes) of CartSwap

CartSwap (Cartridge Swapping) is a technique that allows ACE in any Game Boy game, even before the game has actually booted up! Example applications include :

  • Spoofing consoles (Pokémon Crystal can run on the Gray Brick!)
  • Speedrunning games quicker than a TAS
  • Gaining ACE on games that are otherwise ACE-less
@ISSOtm
ISSOtm / fade.asm
Last active April 4, 2020 15:47
Palette loading and fading routines for the Game Boy Color
Fadeout::
xor a
ld [wFadeCount], a
ld a, [wFadeSpeed]
add a, a
jr c, FadeOutToBlack
FadeOutToWhite:
ld a, [wFadeSpeed]
and $7F
jr z, .maxSpeed
@ISSOtm
ISSOtm / to_c_or_not_to_c.md
Last active June 22, 2021 12:02
Writeup discussing programming toolchains, coding practices, and languages, for GB and GBC dev.

This document is now at https://gbdev.io/guides/tools.html, please go there instead. It's kept here to avoid breaking links and to preserve history.

Previous versions can be checked out by selecting the "Revisions" tab, and selecting "View file" in the three-dot drop-down menu.

@ISSOtm
ISSOtm / vwf.asm
Last active October 9, 2018 20:23
A variable-width font engine for the Game Boy
SECTION "VWF engine",ROM0
; Prints text pointed to by DE
; Text is null-terminated
PrintVWFText::
ld a, 3
jr .startupColorID
@ISSOtm
ISSOtm / conventions.md
Last active April 11, 2021 17:06
My conventions when writing Game Boy ASM (naming / casing, best practices)

Casing

  • Labels use PascalCase. DrawNPCs, GetOffsetFromCamera.
  • Labels in RAM (VRAM, SRAM, WRAM, HRAM; you shouldn't be using Echo RAM or OAM) use the same convention but are prefixed with the initial of the RAM they're in, in lowercase. wCameraOffsetBuffer, hVBlankFlag, vTilesetTiles, sSaveFileChecksum. Rationale: to know in which memory type the label is; this is important because VRAM and SRAM have special access precautions and HRAM can (should (must)) be accessed using the ldh instruction.
  • Local labels use camelCase, regardless of memory type. (.waitVRAM, wPlayer.xCoord)
  • Macro names use snake_case. wait_vram, rst wait_vblank, end_struct.
  • Constants use CAPS_SNAKE. NB_NPCS, OVERWORLD_STAT_LOAD_MAP.
  • Constants posing as labels use the appropriate label convention.

Best practices

@ISSOtm
ISSOtm / my_two_bugs.md
Last active October 31, 2018 19:47
Small writeup about the two most difficult bugs I've ever had to fix.

My Two Bugs

Every programmer has that one bug. That bug that couldn't go away, no matter what you try; that bug whose reason was so obscure it took so long to fix. Even though I am a very young coder, while programming for the Game Boy, I've encountered two of these bugs.

Coincidentally, both of them were caused by the same thing, even though they were completely unrelated. Here are their story.

Overshooting It

I originally started developing Aevilia as a simple RPG for the Game Boy Color, taking inspiration from the Pokémon games' code. That is, use one loop per thing you need to do, and jump between them. This eventually proved to be a disaster, because a lot of code was duplicated, and transitions between loops didn't always go so well.

@ISSOtm
ISSOtm / handler.asm
Created December 20, 2018 17:05
Fast VRAM copy queue code
; Perform fast VRAM copy if asked to
ldh a, [hFastCopyNbReq]
and a
jp z, .dontDoFastTransfer
push de
push hl
; Save sp and set it to source
ld [wSPBuffer], sp
; Get ready to read params
@ISSOtm
ISSOtm / ROM_name_list.asm
Created January 5, 2019 16:33
How the SGB checks for monochrome games (taken from SGB1v2 firmware)
.87:F000 ROMNameList: .BYTE 'ZELDA',0
.87:F006 byte_87F006: .BYTE 0
.87:F007 .BYTE 0
.87:F008 byte_87F008: .BYTE 0
.87:F009 .BYTE 0
.87:F00A byte_87F00A: .BYTE 0
.87:F00B .BYTE 0
.87:F00C byte_87F00C: .BYTE 0
.87:F00D .BYTE 0
.87:F00E byte_87F00E: .BYTE 0
@ISSOtm
ISSOtm / helpers.asm
Last active February 24, 2019 00:40
A documentation-less raster FX lib for the Game Boy (consider this a draft for an upcoming GitHub repo)
; TODO: timings have changed, verify this comment
;
; Be careful with effects on consecutive lines!
; A "double" effect will end a handful of cycles too late if the preceding scanline was really busy
; (approx. 25 M-cycles, HBlank can be as short as 22 cycles plus 1~2 cycles of latency explained below)
; The textbox appears to last up to 22 M-cycles so it should be fine
; The LY=LYC interrupt appears to be unable to trigger in the first (first two?) cycles of a scanline, giving extra leeway
; Anyways, using an effect just after either of the previous conditions may slightly delay it, and repeating the condition will accumulate the delays
; Mode 2 being 20 cycles long, it should be possible to stack the delays somewhat before visible breakage happens, but it's better to avoid it at all
@ISSOtm
ISSOtm / low_byte.asm
Last active February 24, 2021 21:04
Various routines for subpixel positions, primarily intended for 12.4 format. Code licensed under CC0 license.
; Get the low byte of the integer (pixel) part of a 12.4 precision coordinate
; @param hl A pointer to the coordinate
; @return a The pixel part
; @return Carry Clear
; @return Z Set depending on whether `a` is zero or not
GetPixelsLowByte::
ld a, [hli]
xor [hl]
and $0F
xor [hl]