private: No


#!/usr/bin/env octo-run

:alias obtype   v0 #Null entities have no behavior
:alias obx      v1
:alias oby      v2
:alias obanim   v3
:alias obdat1   v4
:alias obdat2   v5
:alias obdat3   v6
:alias obdat4   v7
:alias scratch1 v8
:alias scratch2 v9
:alias scratch3 va
:alias scratch4 vb
:alias param    vc
:alias this     ve

#Scratch aliases for loading a second object to compare or send messages
:alias hitype   v8
:alias hix      v9
:alias hiy      va
:alias hianim   vb
:alias hithis   vd

: panic ;
: breakpoint "panic"
vf += 1

:macro swap A B {
	vf := A
	A  := B
	B  := vf
}

: init
	clear

: main
	this := 0
	sync
	clear
	hires
	hithis := 0 #Otherwise the game will act like it's paused.
	actob
	sync
jump main

#The entity buffer has 32 entries indexed by the receiver register "this."
#At 1000 cycles per frame we get nearly 32 cycles per object if all are active.
#The entity framework consumes half that iterating. If we are under capacity
#you get a little extra headroom.
: actob if this <= 239 then jump0 obtypes ;

: nextob
	this += 8
	if this >= 247 then this := 0
	i := obdata
	i += this
	load obdat3
	return

#We want to push the current object while searching so we can be fast.
#The hiob loses access to the extra data but you still have the param
#register if you need it and you can always overwrite the low obtype
#with hithis+offset if you need anything extra.

: pushob
	i := obdata
	save obdat3
	hithis := this
	this -= 8
	i := obdata
	i += this
	load hianim
	return
: popob  #TODO: this can probably be improved
	this := hithis
	hithis := 8
	i := scratchob
	save hianim
	i := scratchob
	i += hithis
	load obanim
	i := obdata
	i += this
	save obanim
	i := obdata
	i += this
	load obdat4
	hithis := 0
	return

: killme obtype := 0 ;

: spawnob
	i := regscratch
	save this
	this := 0
: spawnloop
	nextob
	if obtype == 0 begin
		i := obproto
		load obdat4
		i := obdata
		i += this
		save obdat4
		jump donespawn
	end
	if this <= 247 then jump spawnloop
: donespawn
	i := regscratch
	load this
	return

: sync
	loop
		vf := delay
		if vf != 0 then
	again
	# delay for up to 1/60th of a second
	# using the fixed-rate delay timer
	vf := 1
	delay := vf
	return

: regscratch 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
: scratchob 0 1 0 0 0 2 0 0x00 2 0 0 0 0 2 0 0x00
: playersprites 0x00 0x00 0x00 0x00 0x00 0x00 0x00
: arrow 0x40 0x20 0x90 0xFE 0x90 0x20 0x40

: explosionsprites 
0x00 0x00 0x00 0x28 0x10 0x04 0x00 0x00
0x00 0x00 0x44 0x04 0x20 0x20 0x16 0x00
0x00 0x02 0x00 0x00 0x00 0x00 0x41 0x00


: bulletsprite
		0b00000000
		0b00000000
		0b00010000
		0b00000000

		0b00000000
		0b00010000
		0b00101000
		0b00010000
		0b00000000


: obproto 0 0 0 0 0 0 0 0
#Object behavior
: actnull
	if hithis != 0 then return
	nextob
	jump actob
: shoot
	swap scratch3 v0
	i := obproto
	v0 := 4
	save v0
	v0 := obx
	v0 += 6
	save v0
	v0 := oby
	save v0
	v0 := param
	save v0
	v0 := 58
	save v0
	spawnob
	swap scratch3 v0
	return

: actavatar
	i := playersprites
	i += obanim
	plane 1
	sprite obx oby 7
	if hithis != 0 then return
	if obanim != 8 then obanim := 8
	scratch1 := OCTO_KEY_S
	if scratch1 key then oby += 1
	scratch1 := OCTO_KEY_W
	if scratch1 key then oby -= 1
	scratch1 := OCTO_KEY_F
	if scratch1 key begin
		if obdat1  == 0 begin
			param := obdat2
			shoot
			obdat1 := 9
			obdat2 += 4
			if obdat2 > 64 then obdat2 := 0
		end
	end
	if obdat1 > 0 then obdat1 -= 1
	i := obdata
	i += this
	save obdat3
	nextob
	jump actob

: findcolbysprite
	pushob
	this := 0
: findcolloop
	nextob
	if obtype != 0 begin
		drawob
		if vf != 0 then jump donefindcolloop
		drawob
	end
#	if this != 0 then jump findcolloop
: donefindcolloop
	param := this
	popob
	return

: actexplosion
	i := explosionsprites
	i += obanim
	plane 2
	sprite obx oby 8
	if hithis != 0 then return
	obdat1 += 1
	if obdat1 >= 7 begin
		obanim += 8
		obdat1 := 1
	end
	if obanim >=  24 then killme
	i := obdata
	i += this
	save obdat3
	nextob
	jump actob

: actbullet
	i := bulletsprite
	plane 3
	sprite obx oby 3
	if hithis != 0 then return
	if vf != 0 then jump bulletdeath
	param := obanim
	param >>= param
	param >>= param
	sincos
	obx += scratch1
	oby += param

	obdat1 -= 1
	if obdat1 == 0 then jump bulletdeath
	jump bulletdone
: bulletdeath
	clear
	i := bulletsprite
	sprite obx oby 3
	findcolbysprite
	obtype := 6
	obanim := 1
	obdat1 := 0
: bulletdone
	i := obdata
	i += this
	save obdat3
	nextob
	jump actob

: sincos
	scratch1 := 0b00001111
	param &= scratch1
	param <<= param
	swap param v0
	swap scratch1 v1
	i := sincostab
	i += v0
	load v1
	swap param v0
	swap scratch1 v1
	return

: sincostab
	 3  0
	 2  1
	 2  2
	 1  2
	 0  3
	-1  2
	-2  2
	-2  1
	-3  0
	-2 -1
	-2 -2
	-1 -2
	 0 -3
	 1 -2
	 2 -2
	 2 -1

#This will crash if not called from a pushed ob
#If called on a null ob you'll leak call stack frames
: drawob jump0 obtypes ;
#The remaining entity tables consume half a kilobyte
#REMEMBER THESE ARE TWO BYTES EACH!!!!
: obtypes #Long jump table
	jump actnull       #0
	jump actavatar     #2
	jump actbullet     #4
	jump actexplosion  #6
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
	jump actnull
#object data buffer
: obdata
0 1 0 0 0 2 0 0x00 2 0 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00 
0 1 0 0 0 2 0 0x00 0 1 0 0 0 2 0 0x00 0 0 0 0 0 0 0 0x00 0 0 0 0 0 0 0 0x00