Example: cmd: --compileOnly -r:off
import jibby/utils/vram import jibby/utils/codegen # {.compile: "gfx.asm".} # Assuming these graphics live in gfx.asm, whereby # they are defined like: # _titleScreenGfx: .incbin "title.2bpp" # _fontGfx: .incbin "font.2bpp" var titleScreenGfx {.importc, asmdefined, noinit.}: uint8 fontGfx {.importc, asmdefined, noinit.}: uint8 turnOffScreen() clearVram() cast[pointer](Tiles1).copyMem(titleScreenGfx.addr, 0x30.tiles) cast[pointer](Tiles2.offset(' '.ord)).copyMem(fontGfx.addr, 0x60.tiles) turnOnScreen()
Types
LcdcFlag = enum BgEnable = 0, ObjEnable, ObjTall, UseBgMap1, UseTiles0, WinEnable, UseWinMap1, LcdOn
StatFlag = enum StatVblank = 0, ## Set during Mode 1 Busy, ## Set during Modes 2 and 3 Coincidence, ## LY == LYC ModeHblankSelect, ## LCD interrupt fires at Hblank ModeVblankSelect, ## LCD interrupt fires at Vblank ModeOamScanSelect, ## LCD interrupt fires at OAM Scan LycSelect ## LCD interrupt fires at LY == LYC
StatModes = enum ModeHblank = 0, ## Mode 0 ModeVblank, ## Mode 1 ModeOamScan, ## Mode 2 ModeActive ## Mode 3
VramTilemap = distinct array[32 * 32, byte]
VramTileset = distinct array[128 * 16, byte]
Consts
BgMap0: ptr VramTilemap = 0x9800'u16
BgMap1: ptr VramTilemap = 0x9C00'u16
BgMapHeight = 32
BgMapWidth = 32
BgPal: ptr byte = 0xFF47'u16
- rBGP
InvertedPalette = 0b00011011'u8
-
An inverted dark -> light palette, use it with the ...Pal constants like:
BgPal[] = InvertedPalette
LcdControl: ptr LcdcFlags = 0xFF40'u16
- rLCDC
LineY: ptr byte = 0xFF44'u16
- rLY
NormalPalette = 0b11100100'u8
-
The normal light -> dark palette, use it with the ...Pal constants like:
BgPal[] = NormalPalette
ObjPal0: ptr byte = 0xFF48'u16
- rOBP0
ObjPal1: ptr byte = 0xFF49'u16
- rOBP1
ScreenHeight = 18
ScreenHeightPx = 144
ScreenWidth = 20
ScreenWidthPx = 160
ScrollX: ptr byte = 0xFF43'u16
- rSCY
ScrollY: ptr byte = 0xFF42'u16
- rSCX
SpritePalette = 0b10010000'u8
-
This is the normal palette but shifted by one lighter, since the first color is transparent. Use it with the ...Pal constants like:
ObjPal0[] = SpritePalette
TileBytes = 16
- Number of bytes needed to represent one 2bpp tile.
Tiles0: ptr VramTileset = 0x8000'u16
Tiles1: ptr VramTileset = 0x8800'u16
Tiles2: ptr VramTileset = 0x9000'u16
TilesAmount = 128
- Number of tiles available in a single tile set.
TileWidthPx = 8
WinX: ptr byte = 0xFF4B'u16
- rWX
WinY: ptr byte = 0xFF4A'u16
- rWY
Procs
proc copy1bppFrom(toAddr: VramPointer; fromAddr: pointer; size: Natural)
-
A special version of VRAM copyMem for copying 2-color (1bpp) tile data. The size parameter should be what the size would have been if copyMem were called instead.
Example: cmd: --compileOnly -r:off
from jibby/utils/codegen import asmDefined import jibby/utils/vram var monochromeFont* {.importc, asmDefined, noinit.}: uint8 Tiles0.offset(0).copy1bppFrom(monochromeFont.addr, 0x10.tiles)
proc copyMem(toAddr: VramPointer; fromAddr: pointer; size: Natural)
-
Copy some data to VRAM even when the screen is still on.Tip: For displaying text to the screen, you should use the print: print function.
Example: cmd: --compileOnly -r:off
import jibby/utils/vram let message = "Hello" BgMap0.offset(0, 0).copyMem(message[0].addr, message.len)
proc setMem(toAddr: VramPointer; value: byte; size: Natural)
-
Fill VRAM locations even when the screen is still on.
Example: cmd: --compileOnly -r:off
import jibby/utils/vram # clear the entire screen BgMap0.setMem(0, sizeof(BgMap0))
proc turnOffScreen(): void {....raises: [], tags: [], forbids: [].}
-
Safely turns off the LCD. According to the Pan Docs, the screen cannot be turned off unless rLY hits V-blank.
Example: cmd: --compileOnly -r:off
from jibby/utils/codegen import asmDefined import jibby/utils/vram var hugeGfx {.importc, asmDefined, noinit.}: array[0x100.tiles, byte] # Copying large graphics. To make this a simple memory-copy operation, # the screen needs to be turned off beforehand. turnOffScreen() copyMem( cast[pointer](Tiles0), # Since the screen is turned off hugeGfx.addr, 0x100.tiles, ) turnOnScreen()
proc waitFrame(): void {....raises: [], tags: [], forbids: [].}
- Waits for the next VBlank interrupt.
Templates
template `[]=`(base: ptr VramTilemap; which: int; val: byte)
-
Convenience for setting a raw value in the background map. Be wary of using it with offset.
Example: cmd: --compileOnly -r:off
import jibby/utils/vram BgMap0[0] = 0x7f'u8 # Be wary of going out of bounds here, since the bounds are # still the same BgMap0.offset(1, 4)[0] = 0x50'u8
template `[]=`(base: ptr VramTileset; which: int; val: byte)
-
Convenience for setting a raw value in the tileset. Be wary of using it with offset.
Example: cmd: --compileOnly -r:off
import jibby/utils/vram Tiles1[0] = 0x7f'u8 # Be wary of going out of bounds here, since the bounds are # still the same Tiles1.offset('J'.ord)[0] = 0x50'u8
template clearVram()
- Clear the entirety of VRAM0. This should be called only when the screen is disabled.
template copyDoubleFrom(toAddr: VramPointer; fromAddr: pointer; size: Natural)
- Alias for copy1bppFrom.
template disableLcdcFeatures(i: LcdcFlags): untyped
-
Disable rLCDC flags. If you try to disable LcdOn (LcdcFlag) using this, this will error out and you would be advised to use turnOffScreen() instead.
Example: cmd: --compileOnly -r:off
import jibby/utils/vram disableLcdcFeatures({WinEnable}) when false: # compiler error! disableLcdcFeatures({LcdOn}) else: turnOffScreen()
template enableLcdcFeatures(i: LcdcFlags): untyped
-
Enable rLCDC flags.
Example: cmd: --compileOnly -r:off
import jibby/utils/vram enableLcdcFeatures( { BgEnable, # Display the background UseWinMap1, # Set window to 0x9C00 LcdOn, # Turn on the screen } )
template offset(base: ptr VramTilemap; x: uint; y: uint): ptr VramTilemap
-
Returns the memory location of some offset into the VRAM tile map address specified in base. All positions are relative to the top left.
Example: cmd: --compileOnly -r:off
import jibby/utils/vram discard BgMap0.offset(1, 1) # 0x9821
template offset(base: ptr VramTileset; tile: uint): ptr VramTileset
-
Returns the memory location of some offset into the VRAM tile set address specified in base. The argument specifies how many tiles to offset it with.
Example: cmd: --compileOnly -r:off
import jibby/utils/vram discard Tiles1.offset(1) # 0x8810, tile #1 of tileset 0x8800
template tiles(i: Natural): int
-
Length of 2bpp tiles in bytes.
Example: cmd: --compileOnly -r:off
import jibby/utils/vram discard 0x60.tiles # 0x600
template turnOnScreen(): untyped
- Convenience for enabling the LCD.
template waitVram()
-
Waits for the next rSTAT interrupt.
Example: cmd: --compileOnly -r:off
import jibby/utils/vram # Writes a single byte to the tileset. waitVram() Tiles0[0] = 11'u8