The struct components are just offsets from the start of the struct. If the size of the struct is less than 255, we can use the y register as an indexer for a pointer in the zero page.
The gist of this example is that you can set the pointer of an instance in the zero page ($02) and then index the struct members (ie Vector3::_X) in the y register (lda (r0l),y) .
Short Example:
Code: Select all
; fetch the Z axis
ldy #Vector3::_Z
lda ($02),y
; do stuff to it
;...
; store back in
sta ($02),y
A list of vectors in contiguous memory lets us iterate over the list using the size of the vector3 struct as a stride. A pseudo code version of this would be:
foreach vec in ListOfVects: vec = vec + Vec3(2, 14, 200)
Iterating over an array of structs example:
Code: Select all
; r0 is the zero page address low / high bytes
.define r0l $02
.define r0h $03
.struct Vector3
_X .byte
_Y .byte
_Z .byte
.endstruct
.DEFINE NUM_VECS 10
.struct ListOfVecs
.byte NUM_VECS * .sizeof(Vector3)
.endstruct
.macro Vec3_add_axis Axis, Value
ldy #Axis
lda (r0l),y
clc
adc #Value
sta (r0l),y
.endmacro
.macro Vec3_add nX, nY, nZ
Vec3_add_axis Vector3::_X, nX
Vec3_add_axis Vector3::_Y, nY
Vec3_add_axis Vector3::_Z, nZ
.endmacro
; allocate the list
Vlist: .tag ListOfVecs
FunWithStructs:
; foreach vec in ListOfVects:
; vec = vec + Vec3(2, 14, 200)
; set the pointer: r0 = &Vlist
lda #<Vlist
sta r0l
lda #>Vlist
sta r0h
ldx #NUM_VECS
foreach:
Vec3_add 2, 14, 200
; advance the pointer: r0 += sizeof(Vec3)
clc
lda r0l
adc #.sizeof(Vector3)
sta r0l
lda r0h ; add the carry
adc #$00
sta r0h
; Next
dex
bne foreach
rts