Skip to content

Instantly share code, notes, and snippets.

@Heath123
Created December 3, 2022 16:40
Show Gist options
  • Save Heath123/64f88eb4894739bf3d672b6409e71082 to your computer and use it in GitHub Desktop.
Save Heath123/64f88eb4894739bf3d672b6409e71082 to your computer and use it in GitHub Desktop.
Assembly code
.global _draw3DLine
.type _draw3DLine, @function
_draw3DLine: # (r4: x, r5: y, r6: dx, r7: dy) -> r0
# vramLine is stored in a global because I don't want to deal with loading it from the stack
# Save registers
mov.l r8,@-r15
mov.l r9,@-r15
mov.l r10,@-r15
mov.l r11,@-r15
mov.l r12,@-r15
mov.l r13,@-r15
mov.l r14,@-r15
# Copy dx and dy into r13 and r14 (otherwise they get overwritten)
mov r6, r13
mov r7, r14
# Load vramLine into r8
mov.l .vramLine, r8
mov.l @r8, r8
# Load xOffset into r12
mov.l .xOffset, r12
mov.w @r12, r12
# Load yOffset into r2
mov.l .yOffset, r2
mov.w @r2, r2
# Use r9 as the loop counter
# Load 198 into it and go backwards
# Counting down is better because we only have to load the value of 198 once
mov.w .halfWidth, r9
.loop:
# Set r10 to x >> 16
swap.w r4, r10
exts.w r10, r10
# Set r11 to y >> 16
swap.w r5, r11
exts.w r11, r11
# Call samplePixel
# START: INLINED VERSION OF samplePixel
# (though I made some changes to it to optimize it)
# add xOffset to xPos
add r12, r10
# add yOffset to yPos
add r2, r11
# divide by 4
shlr2 r10
shlr2 r11
# get the position of the pixel in the tile
# copy them into other registers so we can use the original ones for the tileID
mov r10, r6
mov #0b111, r0
and r0, r6
mov r11, r7
and r0, r7
# get the colour of the pixel in the tile
# get the tile ID by calling getTileID
# START: INLINED VERSION OF getTileID
# (also with some changes to optimize it)
mov r10, r0
or r11, r0
shlr8 r0
tst #0b11111000, r0
# T is now 0 if we want to return 0
bf.s .endv2
mov #0, r0
# otherwise, continue
mov #-3, r1
shad r1, r10
shad r1, r11
# multiply r11 by 256
shll8 r11
add r11, r10
# read from the tilemap
mov.l .tilemap, r0
# now r0 = _tilemap symbol = address of the variable, which is an array
# shll2 r10
mov.b @(r0, r10), r0
bra .endv2
extu.b r0, r0
.endv2:
# END: INLINED VERSION OF getTileID
# r0 now contains the tile ID
# multiply r7 by 8
# Happens in branch delay slot
shll2 r7
add r7, r7
# add r6 to r7
add r6, r7
# multiply r0 by 64
shll8 r0
shlr2 r0
# add r0 to r7
add r0, r7
# read from the tileset
mov.l .tileset, r0
# now r0 = _tileset symbol = address of the variable, which is an array
mov.b @(r0, r7), r0
extu.b r0, r0
# read from the palette
mov.l .palette, r1
# now r1 = _palette symbol = address of the variable, which is an array
# multiply r0 by 2
add r0, r0
# read from the palette
mov.w @(r0, r1), r0
extu.w r0, r0
# END: INLINED VERSION OF samplePixel
# Set r1 to the result
mov r0, r1
# Shift r1 left by 16
shll16 r1
# OR r1 with r0
or r0, r1
# Store r12 in vramLine
mov.l r1, @r8
# Increment vramLine
add #4, r8
# Increment x and y by dx and dy
add r13, r4
add r14, r5
# Decrement the loop counter and check if it's 0
dt r9
bf .loop
# Restore registers
mov.l @r15+,r14
mov.l @r15+,r13
mov.l @r15+,r12
mov.l @r15+,r11
mov.l @r15+,r10
mov.l @r15+,r9
rts
mov.l @r15+,r8
.align 2
.halfWidth:
.word 198
.align 4
.vramLine:
.long _vramLine
.align 4
.xOffset:
.long _xOffset
.align 4
.yOffset:
.long _yOffset
.align 4
.tilemap:
.long _tilemap
.align 4
.tileset:
.long _tileset
.align 4
.palette:
.long _palette
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment