Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Switch to GitLab Next
Sign in / Register
Toggle navigation
Open sidebar
IRQsome Software
Ventilator software archive
Commits
809cdf45
Commit
809cdf45
authored
Jan 04, 2021
by
Ada Gottensträter
Browse files
Add StarBlaster
Not exactly the most exciting game.
parent
76fa895b
Changes
7
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
751 additions
and
0 deletions
+751
-0
games/starblaster/.gitignore
games/starblaster/.gitignore
+1
-0
games/starblaster/build.sh
games/starblaster/build.sh
+6
-0
games/starblaster/original/87288.zip
games/starblaster/original/87288.zip
+0
-0
games/starblaster/source/Fk_NESDriver_001.spin
games/starblaster/source/Fk_NESDriver_001.spin
+68
-0
games/starblaster/source/Fk_graphics_drv_010.spin
games/starblaster/source/Fk_graphics_drv_010.spin
+0
-0
games/starblaster/source/Fk_starblaster_010.spin
games/starblaster/source/Fk_starblaster_010.spin
+675
-0
games/starblaster/source/TV.spin
games/starblaster/source/TV.spin
+1
-0
No files found.
games/starblaster/.gitignore
0 → 100644
View file @
809cdf45
/sdbins
games/starblaster/build.sh
0 → 100644
View file @
809cdf45
mkdir
-p
sdbins
cd source
rm
../sdbins/STBLST.BIN
bstc
-e
-o
../sdbins/STBLST Fk_starblaster_010.spin
mv
../sdbins/STBLST.eeprom ../sdbins/STBLST.BIN
cd
..
\ No newline at end of file
games/starblaster/original/87288.zip
0 → 100644
View file @
809cdf45
File added
games/starblaster/source/Fk_NESDriver_001.spin
0 → 100644
View file @
809cdf45
' /////////////////////////////////////////////////////////////////////////////
' NES Controller Driver
' AUTHOR: Frank Korf
' LAST MODIFIED: 1.29.09
' VERSION 0.1
' /////////////////////////////////////////////////////////////////////////////
CON
JOY_CLK = 16
JOY_LCH = 17
JOY_DATAOUT0 = 19
JOY_DATAOUT1 = 18
' NES bit encodings for NES gamepad 0
NES0_RIGHT = %00000000_00000001
NES0_LEFT = %00000000_00000010
NES0_DOWN = %00000000_00000100
NES0_UP = %00000000_00001000
NES0_START = %00000000_00010000
NES0_SELECT = %00000000_00100000
NES0_B = %00000000_01000000
NES0_A = %00000000_10000000
VAR
long nespad0
PUB Update
nespad0 := Read_Gamepad_0
PUB Up : nesbits
nesbits := ( (nespad0 & NES0_UP) <> 0 )
PUB Down : nesbits
nesbits := ( (nespad0 & NES0_DOWN) <> 0 )
PUB Left : nesbits
nesbits := ( (nespad0 & NES0_LEFT) <> 0 )
PUB Right : nesbits
nesbits := ( (nespad0 & NES0_RIGHT) <> 0 )
PUB Start : nesbits
nesbits := ( (nespad0 & NES0_START) <> 0 )
PUB Select : nesbits
nesbits := ( (nespad0 & NES0_SELECT) <> 0 )
PUB A : nesbits
nesbits := ( (nespad0 & NES0_A) <> 0 )
PUB B : nesbits
nesbits := ( (nespad0 & NES0_B) <> 0 )
PUB Read_Gamepad_0 : nes_bits | i
DIRA [JOY_CLK] := 1 ' output
DIRA [JOY_LCH] := 1 ' output
DIRA [25] := 0 ' input
DIRA [26] := 0 ' input
OUTA [JOY_CLK] := 0 ' JOY_CLK = 0
OUTA [JOY_LCH] := 0 ' JOY_SH/LDn = 0
OUTA [JOY_LCH] := 1 ' JOY_SH/LDn = 1
OUTA [JOY_LCH] := 0 ' JOY_SH/LDn = 0
nes_bits := 0
nes_bits := INA[JOY_DATAOUT0] | (INA[JOY_DATAOUT1] << 8)
repeat i from 0 to 6
OUTA [JOY_CLK] := 1 ' JOY_CLK = 1
OUTA [JOY_CLK] := 0 ' JOY_CLK = 0
nes_bits := (nes_bits << 1)
nes_bits := nes_bits | INA[JOY_DATAOUT0] | (INA[JOY_DATAOUT1] << 8)
nes_bits := (!nes_bits & $FFFF)
DAT
\ No newline at end of file
games/starblaster/source/Fk_graphics_drv_010.spin
0 → 100644
View file @
809cdf45
B
''***************************** ''* Graphics Driver v1.0 * ''* (C) 2005 Parallax, Inc. * ''***************************** '' '' Theory of Operation: '' '' A cog is launched which processes commands via the PUB routines. '' '' Points, lines, arcs, sprites, text, and polygons are rasterized into '' a specified stretch of memory which serves as a generic bitmap buffer. '' '' The bitmap can be displayed by the TV.SRC or VGA.SRC driver. '' '' See GRAPHICS_DEMO_010.SPIN for usage example. '' CON #1, _setup, _color, _width, _plot, _line, _arc, _vec, _vecarc, _pix, _pixarc, _text, _textarc, _textmode, _fill, _loop VAR long cogon, cog long command long bitmap_base 'bitmap data long bitmap_longs word bases[32] long pixel_width 'pixel data long slices[8] long text_xs, text_ys, text_sp, text_just 'text data (these 4 must be contiguous) PUB start : okay '' Start graphics driver - starts a cog '' returns false if no cog available fontptr := @font 'set font pointer (same for all instances) stop okay := cogon := (cog := cognew(@loop, @command)) > 0 PUB stop '' Stop graphics driver - frees a cog if cogon~ cogstop(cog) command~ PUB setup(x_tiles, y_tiles, x_origin, y_origin, base_ptr) | bases_ptr, slices_ptr '' Set bitmap parameters '' '' x_tiles - number of x tiles (tiles are 16x16 pixels each) '' y_tiles - number of y tiles '' x_origin - relative-x center pixel '' y_origin - relative-y center pixel '' base_ptr - base address of bitmap setcommand(_loop, 0) 'make sure last command finished repeat bases_ptr from 0 to x_tiles - 1 <# 31 'write bases bases[bases_ptr] := base_ptr + bases_ptr * y_tiles << 6 y_tiles <<= 4 'adjust arguments and do setup command y_origin := y_tiles - y_origin - 1 bases_ptr := @bases slices_ptr := @slices setcommand(_setup, @x_tiles) bitmap_base := base_ptr 'retain high-level bitmap data bitmap_longs := x_tiles * y_tiles PUB clear '' Clear bitmap setcommand(_loop, 0) 'make sure last command finished longfill(bitmap_base, 0, bitmap_longs) 'clear bitmap PUB copy(dest_ptr) '' Copy bitmap '' use for double-buffered display (flicker-free) '' '' dest_ptr - base address of destination bitmap setcommand(_loop, 0) 'make sure last command finished longmove(dest_ptr, bitmap_base, bitmap_longs) 'copy bitmap PUB color(c) '' Set pixel color to two-bit pattern '' '' c - color code in bits[1..0] setcommand(_color, @colors[c & 3]) 'set color PUB width(w) | pixel_passes, round_pix, i, p '' Set pixel width '' actual width is w[3..0] + 1 '' '' w - 0..15 for round pixels, 16..31 for square pixels round_pix := not w & $10 'determine pixel shape/width w &= $F pixel_width := w pixel_passes := w >> 1 + 1 setcommand(_width, @w) 'do width command now to avoid updating slices when busy p := w ^ $F 'update slices to new shape/width repeat i from 0 to w >> 1 slices[i] := true >> (p << 1) << (p & $E) if round_pix and pixels[w] & |< i p += 2 if round_pix and i == pixel_passes - 2 p += 2 PUB colorwidth(c, w) '' Set pixel color and width color(c) width(w) PUB plot(x, y) '' Plot point '' '' x,y - point setcommand(_plot, @x) PUB line(x, y) '' Draw a line to point '' '' x,y - endpoint setcommand(_line, @x) { PUB arc(x, y, xr, yr, angle, anglestep, steps, arcmode) '' Draw an arc '' '' x,y - center of arc '' xr,yr - radii of arc '' angle - initial angle in bits[12..0] (0..$1FFF = 0?..359.956?) '' anglestep - angle step in bits[12..0] '' steps - number of steps (0 just leaves (x,y) at initial arc position) '' arcmode - 0: plot point(s) '' 1: line to point(s) '' 2: line between points '' 3: line from point(s) to center setcommand(_arc, @x) } PUB vec(x, y, vecscale, vecangle, vecdef_ptr) '' Draw a vector sprite '' '' x,y - center of vector sprite '' vecscale - scale of vector sprite ($100 = 1x) '' vecangle - rotation angle of vector sprite in bits[12..0] '' vecdef_ptr - address of vector sprite definition '' '' '' Vector sprite definition: '' '' word $8000 | $4000 + angle 'vector mode + 13-bit angle (mode: $4000=plot, $8000=line) '' ' where angle is a 13 bit value bits[12..0] mapping (0..$1FFF = 0?..359.956?) '' word length 'vector length '' ... 'more vectors '' ... '' word 0 'end of definition setcommand(_vec, @x) PUB vecarc(x, y, xr, yr, angle, vecscale, vecangle, vecdef_ptr) '' Draw a vector sprite at an arc position '' '' x,y - center of arc '' xr,yr - radii of arc '' angle - angle in bits[12..0] (0..$1FFF = 0?..359.956?) '' vecscale - scale of vector sprite ($100 = 1x) '' vecangle - rotation angle of vector sprite in bits[12..0] '' vecdef_ptr - address of vector sprite definition setcommand(_vecarc, @x) PUB pix(x, y, pixrot, pixdef_ptr) '' Draw a pixel sprite '' '' x,y - center of vector sprite '' pixrot - 0: 0?, 1: 90?, 2: 180?, 3: 270?, +4: mirror '' pixdef_ptr - address of pixel sprite definition '' '' '' Pixel sprite definition: '' '' word 'word align, express dimensions and center, define pixels '' byte xwords, ywords, xorigin, yorigin '' word %%xxxxxxxx,%%xxxxxxxx '' word %%xxxxxxxx,%%xxxxxxxx '' word %%xxxxxxxx,%%xxxxxxxx '' ... setcommand(_pix, @x) { PUB pixarc(x, y, xr, yr, angle, pixrot, pixdef_ptr) '' Draw a pixel sprite at an arc position '' '' x,y - center of arc '' xr,yr - radii of arc '' angle - angle in bits[12..0] (0..$1FFF = 0?..359.956?) '' pixrot - 0: 0?, 1: 90?, 2: 180?, 3: 270?, +4: mirror '' pixdef_ptr - address of pixel sprite definition setcommand(_pixarc, @x) } PUB text(x, y, string_ptr) | justx, justy '' Draw text '' '' x,y - text position (see textmode for sizing and justification) '' string_ptr - address of zero-terminated string (it may be necessary to call .finish '' immediately afterwards to prevent subsequent code from clobbering the '' string as it is being drawn justify(string_ptr, @justx) 'justify string and draw text setcommand(_text, @x) { PUB textarc(x, y, xr, yr, angle, string_ptr) | justx, justy '' Draw text at an arc position '' '' x,y - center of arc '' xr,yr - radii of arc '' angle - angle in bits[12..0] (0..$1FFF = 0?..359.956?) '' string_ptr - address of zero-terminated string (it may be necessary to call .finish '' immediately afterwards to prevent subsequent code from clobbering the '' string as it is being drawn justify(string_ptr, @justx) 'justify string and draw text setcommand(_textarc, @x) } PUB textmode(x_scale, y_scale, spacing, justification) '' Set text size and justification '' '' x_scale - x character scale, should be 1+ '' y_scale - y character scale, should be 1+ '' spacing - character spacing, 6 is normal '' justification - bits[1..0]: 0..3 = left, center, right, left '' bits[3..2]: 0..3 = bottom, center, top, bottom longmove(@text_xs, @x_scale, 4) 'retain high-level text data setcommand(_textmode, @x_scale) 'set text mode { PUB box(x, y, box_width, box_height) | x2, y2, pmin, pmax '' Draw a box with round/square corners, according to pixel width '' '' x,y - box left, box bottom if box_width > pixel_width and box_height > pixel_width pmax := pixel_width - (pmin := pixel_width >> 1) 'get pixel-half-min and pixel-half-max x += pmin 'adjust coordinates to accomodate width y += pmin x2 := x + box_width - 1 - pixel_width y2 := y + box_height - 1 - pixel_width plot(x, y) 'plot round/square corners plot(x, y2) plot(x2, y) plot(x2, y2) fill(x, y2 + pmax, 0, (x2 - x) << 16, 0, 0, pmax) 'fill gaps fill(x, y, 0, (x2 - x) << 16, 0, 0, pmin) fill(x - pmin, y2, 0, (x2 - x + pixel_width) << 16, 0, 0, y2 - y) PUB quad(x1, y1, x2, y2, x3, y3, x4, y4) '' Draw a solid quadrilateral '' vertices must be ordered clockwise or counter-clockwise tri(x1, y1, x2, y2, x3, y3) 'draw two triangle to make 4-sides polygon tri(x3, y3, x4, y4, x1, y1) PUB tri(x1, y1, x2, y2, x3, y3) | xy[2] '' Draw a solid triangle ' reorder vertices by descending y case (y1 => y2) & %100 | (y2 => y3) & %010 | (y1 => y3) & %001 %000: longmove(@xy, @x1, 2) longmove(@x1, @x3, 2) longmove(@x3, @xy, 2) %010: longmove(@xy, @x1, 2) longmove(@x1, @x2, 4) longmove(@x3, @xy, 2) %011: longmove(@xy, @x1, 2) longmove(@x1, @x2, 2) longmove(@x2, @xy, 2) %100: longmove(@xy, @x3, 2) longmove(@x2, @x1, 4) longmove(@x1, @xy, 2) %101: longmove(@xy, @x2, 2) longmove(@x2, @x3, 2) longmove(@x3, @xy, 2) ' draw triangle fill(x1, y1, (x3 - x1) << 16 / (y1 - y3 + 1), (x2 - x1) << 16 / (y1 - y2 + 1), (x3 - x2) << 16 / (y2 - y3 + 1), y1 - y2, y1 - y3) } PUB finish '' Wait for any current graphics command to finish '' use this to insure that it is safe to manually manipulate the bitmap setcommand(_loop, 0) 'make sure last command finished PRI fill(x, y, da, db, db2, linechange, lines_minus_1) setcommand(_fill, @x) PRI justify(string_ptr, justptr) | x x := (strsize(string_ptr) - 1) * text_xs * text_sp + text_xs * 5 - 1 long[justptr] := -lookupz(text_just >> 2 & 3: 0, x >> 1, x, 0) long[justptr][1] := -lookupz(text_just & 3: 0, text_ys << 3, text_ys << 4, 0) PRI setcommand(cmd, argptr) command := cmd << 16 + argptr 'write command and pointer repeat while command 'wait for command to be cleared, signifying receipt CON ' Vector font primitives xa0 = %000 << 0 'x line start / arc center xa1 = %001 << 0 xa2 = %010 << 0 xa3 = %011 << 0 xa4 = %100 << 0 xa5 = %101 << 0 xa6 = %110 << 0 xa7 = %111 << 0 ya0 = %0000 << 3 'y line start / arc center ya1 = %0001 << 3 ya2 = %0010 << 3 ya3 = %0011 << 3 ya4 = %0100 << 3 ya5 = %0101 << 3 ya6 = %0110 << 3 ya7 = %0111 << 3 ya8 = %1000 << 3 ya9 = %1001 << 3 yaA = %1010 << 3 yaB = %1011 << 3 yaC = %1100 << 3 yaD = %1101 << 3 yaE = %1110 << 3 yaF = %1111 << 3 xb0 = %000 << 7 'x line end xb1 = %001 << 7 xb2 = %010 << 7 xb3 = %011 << 7 xb4 = %100 << 7 xb5 = %101 << 7 xb6 = %110 << 7 xb7 = %111 << 7 yb0 = %0000 << 10 'y line end yb1 = %0001 << 10 yb2 = %0010 << 10 yb3 = %0011 << 10 yb4 = %0100 << 10 yb5 = %0101 << 10 yb6 = %0110 << 10 yb7 = %0111 << 10 yb8 = %1000 << 10 yb9 = %1001 << 10 ybA = %1010 << 10 ybB = %1011 << 10 ybC = %1100 << 10 ybD = %1101 << 10 ybE = %1110 << 10 ybF = %1111 << 10 ax1 = %0 << 7 'x arc radius ax2 = %1 << 7 ay1 = %00 << 8 'y arc radius ay2 = %01 << 8 ay3 = %10 << 8 ay4 = %11 << 8 a0 = %0000 << 10 'arc start/length a1 = %0001 << 10 'bits[1..0] = start (0..3 = 0?, 90?, 180?, 270?) a2 = %0010 << 10 'bits[3..2] = length (0..3 = 360?, 270?, 180?, 90?) a3 = %0011 << 10 a4 = %0100 << 10 a5 = %0101 << 10 a6 = %0110 << 10 a7 = %0111 << 10 a8 = %1000 << 10 a9 = %1001 << 10 aA = %1010 << 10 aB = %1011 << 10 aC = %1100 << 10 aD = %1101 << 10 aE = %1110 << 10 aF = %1111 << 10 fline = %0 << 14 'line command farc = %1 << 14 'arc command more = %1 << 15 'another arc/line DAT ' Color codes colors long %%0000000000000000 long %%1111111111111111 long %%2222222222222222 long %%3333333333333333 ' Round pixel recipes pixels byte %00000000,%00000000,%00000000,%00000000 '0,1,2,3 byte %00000000,%00000000,%00000010,%00000101 '4,5,6,7 byte %00001010,%00001010,%00011010,%00011010 '8,9,A,B byte %00110100,%00111010,%01110100,%01110100 'C,D,E,F ' Vector font - standard ascii characters ($21-$7E) font word fline + xa2 + yaC + xb2 + yb7 + more '! word fline + xa2 + ya5 + xb2 + yb4 word fline + xa1 + yaD + xb1 + ybC + more '" word fline + xa3 + yaD + xb3 + ybC word fline + xa1 + yaA + xb1 + yb6 + more '# word fline + xa3 + yaA + xb3 + yb6 + more word fline + xa0 + ya9 + xb4 + yb9 + more word fline + xa0 + ya7 + xb4 + yb7 word farc + xa2 + ya9 + a9 + ax2 + ay1 + more '$ word farc + xa2 + ya7 + aB + ax2 + ay1 + more word fline + xa0 + ya6 + xb2 + yb6 + more word fline + xa2 + yaA + xb4 + ybA + more word fline + xa2 + yaA + xb2 + ybB + more word fline + xa2 + ya6 + xb2 + yb5 word farc + xa1 + yaA + a0 + ax1 + ay1 + more '% word farc + xa3 + ya6 + a0 + ax1 + ay1 + more word fline + xa0 + ya6 + xb4 + ybA word farc + xa2 + yaA + a7 + ax1 + ay1 + more '& word farc + xa2 + ya7 + a5 + ax2 + ay2 + more word fline + xa1 + yaA + xb4 + yb5 word fline + xa2 + yaD + xb2 + ybC ' ' word farc + xa3 + ya9 + aD + ax1 + ay4 + more '( word farc + xa3 + ya7 + aE + ax1 + ay4 + more word fline + xa2 + ya7 + xb2 + yb9 word farc + xa1 + ya9 + aC + ax1 + ay4 + more ') word farc + xa1 + ya7 + aF + ax1 + ay4 + more word fline + xa2 + ya7 + xb2 + yb9 word fline + xa4 + ya6 + xb0 + ybA + more '* word fline + xa0 + ya6 + xb4 + ybA + more word fline + xa2 + yaB + xb2 + yb5 word fline + xa0 + ya8 + xb4 + yb8 + more '+ word fline + xa2 + yaA + xb2 + yb6 word fline + xa2 + ya4 + xb1 + yb3 ', word fline + xa0 + ya8 + xb4 + yb8 '- word fline + xa2 + ya5 + xb2 + yb4 '. word fline + xa0 + ya4 + xb4 + ybC '/ word farc + xa2 + ya8 + a0 + ax2 + ay4 '0 word fline + xa0 + ya4 + xb4 + yb4 + more '1 word fline + xa2 + ya4 + xb2 + ybC + more word fline + xa0 + yaA + xb2 + ybC word farc + xa2 + yaA + a8 + ax2 + ay2 + more '2 word farc + xa2 + yaA + aF + ax2 + ay2 + more word farc + xa2 + ya6 + aD + ax2 + ay2 + more word fline + xa0 + ya4 + xb0 + yb6 + more word fline + xa0 + ya4 + xb4 + yb4 word farc + xa2 + yaA + a7 + ax2 + ay2 + more '3 word farc + xa2 + ya6 + a6 + ax2 + ay2 word fline + xa2 + yaC + xb0 + yb7 + more '4 word fline + xa0 + ya7 + xb4 + yb7 + more word fline + xa3 + ya4 + xb3 + yb8 word farc + xa2 + ya6 + aB + ax2 + ay2 + more '5 word fline + xa4 + yaC + xb0 + ybC + more word fline + xa0 + yaC + xb0 + yb8 + more word fline + xa0 + ya8 + xb2 + yb8 + more word fline + xa0 + ya4 + xb2 + yb4 word farc + xa2 + ya6 + a0 + ax2 + ay2 + more '6 word farc + xa2 + ya8 + aD + ax2 + ay4 + more word fline + xa0 + ya6 + xb0 + yb8 + more word fline + xa2 + yaC + xb3 + ybC word fline + xa0 + yaC + xb4 + ybC + more '7 word fline + xa1 + ya4 + xb4 + ybC word farc + xa2 + ya6 + a0 + ax2 + ay2 + more '8 word farc + xa2 + yaA + a0 + ax2 + ay2 word farc + xa2 + yaA + a0 + ax2 + ay2 + more '9 word farc + xa2 + ya8 + aF + ax2 + ay4 + more word fline + xa4 + ya8 + xb4 + ybA + more word fline + xa1 + ya4 + xb2 + yb4 word fline + xa2 + ya6 + xb2 + yb7 + more ': word fline + xa2 + yaA + xb2 + yb9 word fline + xa2 + ya4 + xb1 + yb3 + more '; word fline + xa2 + ya8 + xb2 + yb7 word fline + xa0 + ya8 + xb4 + ybA + more '< word fline + xa0 + ya8 + xb4 + yb6 word fline + xa0 + yaA + xb4 + ybA + more '= word fline + xa0 + ya6 + xb4 + yb6 word fline + xa4 + ya8 + xb0 + ybA + more '> word fline + xa4 + ya8 + xb0 + yb6 word farc + xa2 + yaB + a8 + ax2 + ay1 + more '? word farc + xa3 + yaB + aF + ax1 + ay2 + more word farc + xa3 + ya7 + aD + ax1 + ay2 + more word fline + xa2 + ya5 + xb2 + yb4 word farc + xa2 + ya8 + a0 + ax1 + ay1 + more '@ word farc + xa2 + ya8 + a4 + ax2 + ay3 + more word farc + xa3 + ya8 + aF + ax1 + ay1 + more word farc + xa2 + ya6 + aF + ax2 + ay1 + more word fline + xa3 + ya7 + xb3 + yb9 word farc + xa2 + yaA + a8 + ax2 + ay2 + more 'A word fline + xa0 + ya4 + xb0 + ybA + more word fline + xa4 + ya4 + xb4 + ybA + more word fline + xa0 + ya8 + xb4 + yb8 word farc + xa2 + yaA + aB + ax2 + ay2 + more 'B word farc + xa2 + ya6 + aB + ax2 + ay2 + more word fline + xa0 + ya4 + xb0 + ybC + more word fline + xa0 + ya4 + xb2 + yb4 + more word fline + xa0 + ya8 + xb2 + yb8 + more word fline + xa0 + yaC + xb2 + ybC word farc + xa2 + yaA + a8 + ax2 + ay2 + more 'C word farc + xa2 + ya6 + aA + ax2 + ay2 + more word fline + xa0 + ya6 + xb0 + ybA word farc + xa2 + yaA + aC + ax2 + ay2 + more 'D word farc + xa2 + ya6 + aF + ax2 + ay2 + more word fline + xa0 + ya4 + xb0 + ybC + more word fline + xa4 + ya6 + xb4 + ybA + more word fline + xa0 + ya4 + xb2 + yb4 + more word fline + xa0 + yaC + xb2 + ybC word fline + xa0 + ya4 + xb0 + ybC + more 'E word fline + xa0 + ya4 + xb4 + yb4 + more word fline + xa0 + ya8 + xb3 + yb8 + more word fline + xa0 + yaC + xb4 + ybC word fline + xa0 + ya4 + xb0 + ybC + more 'F word fline + xa0 + ya8 + xb3 + yb8 + more word fline + xa0 + yaC + xb4 + ybC word farc + xa2 + yaA + a8 + ax2 + ay2 + more 'G word farc + xa2 + ya6 + aA + ax2 + ay2 + more word fline + xa0 + ya6 + xb0 + ybA + more word fline + xa4 + ya4 + xb4 + yb7 + more word fline + xa3 + ya7 + xb4 + yb7 word fline + xa0 + ya4 + xb0 + ybC + more 'H word fline + xa4 + ya4 + xb4 + ybC + more word fline + xa0 + ya8 + xb4 + yb8 word fline + xa2 + ya4 + xb2 + ybC + more 'I word fline + xa0 + ya4 + xb4 + yb4 + more word fline + xa0 + yaC + xb4 + ybC word farc + xa2 + ya6 + aA + ax2 + ay2 + more 'J word fline + xa4 + ya6 + xb4 + ybC word fline + xa0 + ya4 + xb0 + ybC + more 'K word fline + xa4 + yaC + xb0 + yb8 + more word fline + xa4 + ya4 + xb0 + yb8 word fline + xa0 + ya4 + xb0 + ybC + more 'L word fline + xa0 + ya4 + xb4 + yb4 word fline + xa0 + ya4 + xb0 + ybC + more 'M word fline + xa4 + ya4 + xb4 + ybC + more word fline + xa2 + ya8 + xb0 + ybC + more word fline + xa2 + ya8 + xb4 + ybC word fline + xa0 + ya4 + xb0 + ybC + more 'N word fline + xa4 + ya4 + xb4 + ybC + more word fline + xa4 + ya4 + xb0 + ybC word farc + xa2 + yaA + a8 + ax2 + ay2 + more '0 word farc + xa2 + ya6 + aA + ax2 + ay2 + more word fline + xa0 + ya6 + xb0 + ybA + more word fline + xa4 + ya6 + xb4 + ybA word farc + xa2 + yaA + aB + ax2 + ay2 + more 'P word fline + xa0 + ya4 + xb0 + ybC + more word fline + xa0 + ya8 + xb2 + yb8 + more word fline + xa0 + yaC + xb2 + ybC word farc + xa2 + yaA + a8 + ax2 + ay2 + more 'Q word farc + xa2 + ya6 + aA + ax2 + ay2 + more word fline + xa0 + ya6 + xb0 + ybA + more word fline + xa4 + ya6 + xb4 + ybA + more word fline + xa2 + ya6 + xb4 + yb3 word farc + xa2 + yaA + aB + ax2 + ay2 + more 'R word fline + xa0 + ya4 + xb0 + ybC + more word fline + xa0 + ya8 + xb2 + yb8 + more word fline + xa0 + yaC + xb2 + ybC + more word fline + xa4 + ya4 + xb2 + yb8 word farc + xa2 + yaA + a4 + ax2 + ay2 + more 'S word farc + xa2 + ya6 + a6 + ax2 + ay2 word fline + xa2 + ya4 + xb2 + ybC + more 'T word fline + xa0 + yaC + xb4 + ybC word farc + xa2 + ya6 + aA + ax2 + ay2 + more 'U word fline + xa0 + ya6 + xb0 + ybC + more word fline + xa4 + ya6 + xb4 + ybC word fline + xa2 + ya4 + xb0 + ybC + more 'V word fline + xa2 + ya4 + xb4 + ybC word fline + xa0 + yaC + xb0 + yb4 + more 'W word fline + xa4 + yaC + xb4 + yb4 + more word fline + xa2 + ya8 + xb0 + yb4 + more word fline + xa2 + ya8 + xb4 + yb4 word fline + xa4 + ya4 + xb0 + ybC + more 'X word fline + xa0 + ya4 + xb4 + ybC word fline + xa0 + yaC + xb2 + yb8 + more 'Y word fline + xa4 + yaC + xb2 + yb8 + more word fline + xa2 + ya4 + xb2 + yb8 word fline + xa0 + yaC + xb4 + ybC + more 'Z word fline + xa0 + ya4 + xb4 + ybC + more word fline + xa0 + ya4 + xb4 + yb4 word fline + xa2 + yaD + xb2 + yb3 + more '[ word fline + xa2 + yaD + xb4 + ybD + more word fline + xa2 + ya3 + xb4 + yb3 word fline + xa4 + ya4 + xb0 + ybC '\ word fline + xa2 + yaD + xb2 + yb3 + more '[ word fline + xa2 + yaD + xb0 + ybD + more word fline + xa2 + ya3 + xb0 + yb3 word fline + xa2 + yaA + xb0 + yb6 + more '^ word fline + xa2 + yaA + xb4 + yb6 word fline + xa0 + ya1 + xa4 + yb1 '_ word fline + xa1 + ya9 + xb3 + yb7 '` word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'a word fline + xa4 + ya4 + xb4 + yb8 word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'b word fline + xa0 + ya4 + xb0 + ybC word farc + xa2 + ya6 + a9 + ax2 + ay2 + more 'c word fline + xa2 + ya4 + xb4 + yb4 + more word fline + xa2 + ya8 + xb4 + yb8 word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'd word fline + xa4 + ya4 + xb4 + ybC word farc + xa2 + ya6 + a4 + ax2 + ay2 + more 'e word fline + xa0 + ya6 + xb4 + yb6 + more word fline + xa2 + ya4 + xb4 + yb4 word farc + xa4 + yaA + aD + ax2 + ay2 + more 'f word fline + xa0 + ya8 + xb4 + yb8 + more word fline + xa2 + ya4 + xb2 + ybA word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'g word farc + xa2 + ya3 + aF + ax2 + ay2 + more word fline + xa4 + ya3 + xb4 + yb8 + more word fline + xa1 + ya1 + xb2 + yb1 word farc + xa2 + ya6 + a8 + ax2 + ay2 + more 'h word fline + xa0 + ya4 + xb0 + ybC + more word fline + xa4 + ya4 + xb4 + yb6 word fline + xa1 + ya4 + xb3 + yb4 + more 'i word fline + xa2 + ya4 + xb2 + yb8 + more word fline + xa1 + ya8 + xb2 + yb8 + more word fline + xa2 + yaB + xb2 + ybA word farc + xa0 + ya3 + aF + ax2 + ay2 + more 'j word fline + xa2 + ya3 + xb2 + yb8 + more word fline + xa1 + ya8 + xb2 + yb8 + more word fline + xa2 + yaB + xb2 + ybA word fline + xa0 + ya4 + xb0 + ybC + more 'k word fline + xa0 + ya6 + xb2 + yb6 + more word fline + xa2 + ya6 + xb4 + yb8 + more word fline + xa2 + ya6 + xb4 + yb4 word fline + xa1 + ya4 + xb3 + yb4 + more 'l word fline + xa2 + ya4 + xb2 + ybC + more word fline + xa1 + yaC + xb2 + ybC word farc + xa1 + ya7 + a8 + ax1 + ay1 + more 'm word farc + xa3 + ya7 + a8 + ax1 + ay1 + more word fline + xa0 + ya4 + xb0 + yb8 + more word fline + xa2 + ya4 + xb2 + yb7 + more word fline + xa4 + ya4 + xb4 + yb7 word farc + xa2 + ya6 + a8 + ax2 + ay2 + more 'n word fline + xa0 + ya4 + xb0 + yb8 + more word fline + xa4 + ya4 + xb4 + yb6 word farc + xa2 + ya6 + a0 + ax2 + ay2 'o word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'p word fline + xa0 + ya1 + xb0 + yb8 word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'q word fline + xa4 + ya1 + xb4 + yb8 word farc + xa2 + ya7 + a8 + ax2 + ay1 + more 'r word fline + xa0 + ya4 + xb0 + yb8 word farc + xa2 + ya7 + a9 + ax2 + ay1 + more 's word farc + xa2 + ya5 + aB + ax2 + ay1 + more word fline + xa0 + ya4 + xb2 + yb4 + more word fline + xa2 + ya8 + xb4 + yb8 word farc + xa4 + ya6 + aE + ax2 + ay2 + more 't word fline + xa0 + ya8 + xb4 + yb8 + more word fline + xa2 + ya6 + xb2 + ybA word farc + xa2 + ya6 + aA + ax2 + ay2 + more 'u word fline + xa0 + ya6 + xb0 + yb8 + more word fline + xa4 + ya4 + xb4 + yb8 word fline + xa0 + ya8 + xb2 + yb4 + more 'v word fline + xa4 + ya8 + xb2 + yb4 word farc + xa1 + ya5 + aA + ax1 + ay1 + more 'w word farc + xa3 + ya5 + aA + ax1 + ay1 + more word fline + xa0 + ya5 + xb0 + yb8 + more word fline + xa2 + ya5 + xb2 + yb6 + more word fline + xa4 + ya5 + xb4 + yb8 word fline + xa0 + ya8 + xb4 + yb4 + more 'x word fline + xa0 + ya4 + xb4 + yb8 word farc + xa2 + ya6 + aA + ax2 + ay2 + more 'y word farc + xa2 + ya3 + aF + ax2 + ay2 + more word fline + xa4 + ya3 + xb4 + yb8 + more word fline + xa0 + ya6 + xb0 + yb8 + more word fline + xa1 + ya1 + xb2 + yb1 word fline + xa0 + ya8 + xb4 + yb8 + more 'z word fline + xa4 + ya8 + xb0 + yb4 + more word fline + xa0 + ya4 + xb4 + yb4 word farc + xa3 + yaA + aD + ax1 + ay3 + more '{ word farc + xa1 + ya6 + aC + ax1 + ay2 + more word farc + xa1 + yaA + aF + ax1 + ay2 + more word farc + xa3 + ya6 + aE + ax1 + ay3 word fline + xa2 + ya3 + xb2 + ybD '| word farc + xa1 + yaA + aC + ax1 + ay3 + more '} word farc + xa3 + ya6 + aD + ax1 + ay2 + more word farc + xa3 + yaA + aE + ax1 + ay2 + more word farc + xa1 + ya6 + aF + ax1 + ay3 word farc + xa1 + ya8 + a8 + ax1 + ay1 + more '~ word farc + xa3 + ya8 + aA + ax1 + ay1 ' Vector font - custom characters ($7F+) word fline + xa2 + ya9 + xb0 + yb4 + more 'delta word fline + xa2 + ya9 + xb4 + yb4 + more word fline + xa0 + ya4 + xb4 + yb4 word farc + xa2 + ya7 + a8 + ax2 + ay2 + more 'omega word farc + xa1 + ya7 + aE + ax1 + ay2 + more word farc + xa3 + ya7 + aF + ax1 + ay2 + more word fline + xa1 + ya5 + xb1 + yb4 + more word fline + xa3 + ya5 + xb3 + yb4 + more word fline + xa0 + ya4 + xb1 + yb4 + more word fline + xa4 + ya4 + xb3 + yb4 word farc + xa2 + ya8 + a0 + ax1 + ay1 'bullet CON fx = 3 'number of custom characters DAT '************************************* '* Assembly language graphics driver * '************************************* org ' ' ' Graphics driver - main loop ' loop rdlong t1,par wz 'wait for command if_z jmp #loop movd :arg,#arg0 'get 8 arguments mov t2,t1 mov t3,#8 :arg rdlong arg0,t2 add :arg,d0 add t2,#4 djnz t3,#:arg wrlong zero,par 'zero command to signify received call #setd 'set dx,dy from arg0,arg1 ror t1,#16+2 'lookup command address add t1,#jumps movs :table,t1 rol t1,#2 shl t1,#3 :table mov t2,0 shr t2,t1 and t2,#$FF jmp t2 'jump to command jumps byte 0 '0 byte setup_ '1 byte color_ '2 byte width_ '3 byte plot_ '4 byte line_ '5 byte arc_ '6 byte vec_ '7 byte vecarc_ '8 byte pix_ '9 byte pixarc_ 'A byte text_ 'B byte textarc_ 'C byte textmode_ 'D byte fill_ 'E byte loop 'F ' ' ' setup(x_tiles, y_tiles*16, x_origin, y_origin, base_ptr) bases_ptr, slices_ptr ' setup_ mov xlongs,arg0 'set xlongs, ylongs mov ylongs,arg1 mov xorigin,arg2 'set xorigin, yorigin mov yorigin,arg3 mov basesptr,arg5 'set pointers mov slicesptr,arg6 jmp #loop ' ' ' color(c) ' color_ mov pcolor,arg0 'set pixel color jmp #loop ' ' ' width(w) pixel_passes ' width_ mov pwidth,arg0 'set pixel width mov passes,arg1 'set pixel passes jmp #loop ' ' ' plot(x, y) ' plot_ call #plotd jmp #loop ' ' ' line(x, y) ' line_ call #linepd jmp #loop ' ' ' arc(x, y, xr, yr, angle, anglestep, iterations, mode) ' arc_ and arg7,#3 'limit mode :loop call #arca 'get arc dx,dy cmp arg7,#1 wz 'if not mode 1, set px,py if_nz mov px,dx if_nz mov py,dy tjz arg6,#loop 'if no points exit with new px,py cmp arg7,#3 wz 'if mode 3, set center if_z call #setd test arg7,#1 wz 'if mode 0 or 2, plot point if_z call #plotp test arg7,#1 wz 'if mode 1 or 3, plot line if_nz call #linepd cmp arg7,#2 wz 'if mode 2, set mode 1 if_z mov arg7,#1 add arg4,arg5 'step angle djnz arg6,#:loop 'loop if more iterations jmp #loop ' ' ' vec(x, y, vecscale, vecangle, vecdef_ptr) ' vecarc(x, y, xr, yr, angle, vecscale, vecangle, vecdef_ptr) ' ' vecdef: word $8000/$4000+angle 'vector mode + 13-bit angle (mode: $4000=plot, $8000=line) ' word length 'vector length ' ... 'more vectors ' ... ' word 0 'end of definition ' vecarc_ call #arcmod vec_ tjz arg2,#loop 'if scale 0, exit :loop rdword t7,arg4 wz 'get vector mode+angle add arg4,#2 if_z jmp #loop 'if mode+angle 0, exit rdword t1,arg4 'get vector length add arg4,#2 abs t2,arg2 wc 'add/sub vector angle to/from angle mov t6,arg3 sumc t6,t7 call #multiply 'multiply length by scale add t1,#$80 'round up 1/2 lsb shr t1,#8 mov t4,t1 'get arc dx,dy mov t5,t1 call #arcd test t7,h8000 wc 'plot pixel or draw line? if_nc call #plotd test t7,h8000 wc if_c call #linepd jmp #:loop 'get next vector ' ' ' pix(x, y, pixrot, pixdef_ptr) ' pixarc(x, y, xr, yr, angle, pixrot, pixdef_ptr) ' ' pixdef: word ' byte xwords, ywords, xorigin, yorigin ' word %%xxxxxxxx,%%xxxxxxxx ' word %%xxxxxxxx,%%xxxxxxxx ' word %%xxxxxxxx,%%xxxxxxxx ' ... ' pixarc_ call #arcmod pix_ mov t6,pcolor 'save color mov px,dx 'get center into px,py mov py,dy mov sy,pwidth 'get actual pixel width add sy,#1 rdbyte dx,arg3 'get dimensions into dx,dy add arg3,#1 rdbyte dy,arg3 add arg3,#1 rdbyte t1,arg3 'get origin and adjust px,py add arg3,#1 rdbyte t2,arg3 add arg3,#1 neg t2,t2 sub t2,#1 add t2,dy mov t3,sy :adjust test arg2,#%001 wz test arg2,#%110 wc if_z sumnc px,t1 if_nz sumc py,t1 test arg2,#%010 wc if_nz sumnc px,t2 if_z sumnc py,t2 djnz t3,#:adjust :yline mov sx,#0 'plot entire pix mov t3,dx :xword rdword t4,arg3 'read next pix word add arg3,#2 shl t4,#16 mov t5,#8 :xpixel rol t4,#2 'plot pixel within word test t4,#1 wc 'set color muxc pcolor,color1 test t4,#2 wc muxc pcolor,color2 wz '(z=1 if color=0) if_nz call #plotp test arg2,#%001 wz 'update px,py for next x test arg2,#%110 wc if_z sumc px,sy if_nz sumnc py,sy add sx,sy djnz t5,#:xpixel 'another x pixel? djnz t3,#:xword 'another x word? if_z sumnc px,sx 'update px,py for next y if_nz sumc py,sx test arg2,#%010 wc if_nz sumc px,sy if_z sumc py,sy djnz dy,#:yline 'another y line? mov pcolor,t6 'restore color jmp #loop ' ' ' text(x, y, @string) justx, justy ' textarc(x, y, xr, yr, angle, @string) justx, justy ' textarc_ call #arcmod text_ add arg3,arg0 'add x into justx add arg4,arg1 'add y into justy :chr rdbyte t1,arg2 wz 'get chr add arg2,#1 if_z jmp #loop 'if 0, done sub t1,#$21 'if chr out of range, skip cmp t1,#$7F-$21+fx wc if_nc jmp #:skip mov arg5,fontptr 'scan font for chr definition :scan tjz t1,#:def rdword t2,arg5 add arg5,#2 test t2,h8000 wc if_nc sub t1,#1 jmp #:scan :def rdword t7,arg5 'get font definition word add arg5,#2 call #fontxy 'extract initial x,y test t7,#$80 wc 'arc or line? if_nc jmp #:line mov t2,textsx 'arc, extract x radius mov t3,#%0001_0001_1 call #fontb mov t4,t1 mov t2,textsy 'extract y radius mov t3,#%0010_0011_1 call #fontb mov t5,t1 mov t2,#1 'extract starting angle mov t3,#%0010_0011_0 call #fontb shl t1,#11 mov t6,t1 'extract angle sweep mov t3,#%0010_0011_0 call #fontb neg arg6,t1 shl arg6,#4 add arg6,#65 call #arcd 'plot initial arc point call #plotd :arc call #arcd 'connect subsequent arc points with lines call #linepd add t6,#$80 djnz arg6,#:arc jmp #:more :line call #plotd 'line, plot initial x,y call #fontxy 'extract terminal x,y call #linepd 'draw line :more test t7,#$02 wc 'more font definition? if_c jmp #:def :skip mov t1,textsp 'advance x to next chr position mov t2,textsx call #multiply add arg3,t1 jmp #:chr 'get next chr fontxy mov t2,textsx 'extract x mov t3,#%0011_0111_0 call #fontb mov arg0,t1 add arg0,arg3 mov t2,textsy 'extract y mov t3,#%0100_1111_0 call #fontb mov arg1,t1 add arg1,arg4 setd mov dx,xorigin 'set dx,dy from arg0,arg1 add dx,arg0 mov dy,yorigin sub dy,arg1 setd_ret fontxy_ret ret fontb mov t1,t7 'extract bitrange from font word shr t3,#1 wc and t1,t3 if_c add t1,#1 shr t3,#4 shr t7,t3 shl t1,#32-4 'multiply t1[3..0] by t2 mov t3,#4 :loop shl t1,#1 wc if_c add t1,t2 djnz t3,#:loop fontb_ret ret ' ' ' textmode(x_scale, y_scale, spacing, justification) ' textmode_ mov textsx,arg0 'set text x scale mov textsy,arg1 'set text y scale mov textsp,arg2 'set text spacing jmp #loop ' ' ' fill(x, y, da, db, db2, linechange, lines_minus_1) ' fill_ shl dx,#16 'get left and right fractions or dx,h8000 mov t1,dx mov t2,xlongs 'get x pixels shl t2,#4 add arg6,#1 'pre-increment line counter :yloop add dx,arg2 'adjust left and right fractions add t1,arg3 cmps dx,t1 wc 'get left and right integers if_c mov base0,dx if_c mov base1,t1 if_nc mov base0,t1 if_nc mov base1,dx sar base0,#16 sar base1,#16 cmps base0,t2 wc 'left out of range? if_c cmps hFFFFFFFF,base1 wc 'right out of range? if_c cmp dy,ylongs wc 'y out of range? if_nc jmp #:skip 'if any, skip mins base0,#0 'limit left and right maxs base1,t2 wc if_nc sub base1,#1 shl base0,#1 'make left mask neg mask0,#1 shl mask0,base0 shr base0,#5 shl base1,#1 'make right mask xor base1,#$1E neg mask1,#1 shr mask1,base1 shr base1,#5 sub base1,base0 wz 'ready long count add base1,#1 if_z and mask0,mask1 'if single long, merge masks shl base0,#1 'get long base add base0,basesptr rdword base0,base0 shl dy,#2 add base0,dy shr dy,#2 mov bits0,mask0 'ready left mask :xloop mov bits1,pcolor 'make color mask and bits1,bits0 rdlong pass,base0 'read-modify-write long andn pass,bits0 or pass,bits1 wrlong pass,base0 shl ylongs,#2 'advance to next long add base0,ylongs shr ylongs,#2 cmp base1,#2 wz 'one more? if_nz neg bits0,#1 'if not, ready full mask if_z mov bits0,mask1 'if one more, ready right mask djnz base1,#:xloop 'loop if more longs :skip sub arg5,#1 wc 'delta change? if_c mov arg3,arg4 'if so, set new deltas :same add dy,#1 'adjust y djnz arg6,#:yloop 'another y? jmp #loop ' ' ' Plot line from px,py to dx,dy ' linepd cmps dx,px wc, wr 'get x difference negc sx,#1 'set x direction cmps dy,py wc, wr 'get y difference negc sy,#1 'set y direction abs dx,dx 'make differences absolute abs dy,dy cmp dx,dy wc 'determine dominant axis if_nc tjz dx,#:last 'if both differences 0, plot single pixel if_nc mov count,dx 'set pixel count if_c mov count,dy mov ratio,count 'set initial ratio shr ratio,#1 if_c jmp #:yloop 'x or y dominant? :xloop call #plotp 'dominant x line add px,sx sub ratio,dy wc if_c add ratio,dx if_c add py,sy djnz count,#:xloop jmp #:last 'plot last pixel :yloop call #plotp 'dominant y line add py,sy sub ratio,dx wc if_c add ratio,dy if_c add px,sx djnz count,#:yloop :last call #plotp 'plot last pixel linepd_ret ret ' ' ' Plot pixel at px,py ' plotd mov px,dx 'set px,py to dx,dy mov py,dy plotp tjnz pwidth,#wplot 'if width > 0, do wide plot mov t1,px 'compute pixel mask shl t1,#1 mov mask0,#%11 shl mask0,t1 shr t1,#5 cmp t1,xlongs wc 'if x or y out of bounds, exit if_c cmp py,ylongs wc if_nc jmp #plotp_ret mov bits0,pcolor 'compute pixel bits and bits0,mask0 shl t1,#1 'get address of pixel long add t1,basesptr mov t2,py rdword t1,t1 shl t2,#2 add t1,t2 rdlong t2,t1 'write pixel andn t2,mask0 or t2,bits0 wrlong t2,t1 plotp_ret plotd_ret ret ' ' ' Plot wide pixel ' wplot mov t1,py 'if y out of bounds, exit add t1,#7 mov t2,ylongs add t2,#7+8 cmp t1,t2 wc if_nc jmp #plotp_ret mov t1,px 'determine x long pair sub t1,#8 sar t1,#4 cmp t1,xlongs wc muxc jumps,#%01 '(use jumps[1..0] to store writes) add t1,#1 cmp t1,xlongs wc muxc jumps,#%10 test jumps,#%11 wz 'if x out of bounds, exit if_z jmp #plotp_ret shl t1,#1 'get base pair add t1,basesptr rdword base1,t1 sub t1,#2 rdword base0,t1 mov t1,px 'determine pair shifts shl t1,#1 movs :shift1,t1 xor :shift1,#7<<1 add t1,#9<<1 movs :shift0,t1 test t1,#$F<<1 wz '(account for special case) if_z andn jumps,#%01 mov pass,#0 'ready to plot slices mov slice,slicesptr :loop rdlong mask0,slice 'get next slice mov mask1,mask0 :shift0 shl mask0,#0 'position slice :shift1 shr mask1,#0 mov bits0,pcolor 'colorize slice and bits0,mask0 mov bits1,pcolor and bits1,mask1 mov t1,py 'plot lower slice add t1,pass cmp t1,ylongs wc if_c call #wslice mov t1,py 'plot upper slice test pwidth,#1 wc subx t1,pass cmp t1,ylongs wc if_c call #wslice add slice,#4 'next slice add pass,#1 cmp pass,passes wz if_nz jmp #:loop jmp #plotp_ret ' ' ' Plot wide pixel slice ' wslice shl t1,#2 'ready long offset add base0,t1 'plot left slice test jumps,#%01 wc if_c rdlong t2,base0 if_c andn t2,mask0 if_c or t2,bits0 if_c wrlong t2,base0 add base1,t1 'plot right slice test jumps,#%10 wc if_c rdlong t2,base1 if_c andn t2,mask1 if_c or t2,bits1 if_c wrlong t2,base1 sub base0,t1 'restore bases sub base1,t1 wslice_ret ret ' ' ' Get arc point from args and then move args 5..7 to 2..4 ' arcmod call #arca 'get arc using first 5 args mov arg0,dx 'set arg0,arg1 sub arg0,xorigin mov arg1,yorigin sub arg1,dy mov arg2,arg5 'move args 5..7 to 2..4 mov arg3,arg6 mov arg4,arg7 arcmod_ret ret ' ' ' Get arc dx,dy from arg0,arg1 ' ' in: arg0,arg1 = center x,y ' arg2/t4 = x length ' arg3/t5 = y length ' arg4/t6 = 13-bit angle ' ' out: dx,dy = arc point ' arca mov t4,arg2 'use args mov t5,arg3 mov t6,arg4 arcd call #setd 'reset dx,dy to arg0,arg1 mov t1,t6 'get arc dx mov t2,t4 call #polarx add dx,t1 mov t1,t6 'get arc dy mov t2,t5 call #polary sub dy,t1 arcd_ret arca_ret ret ' ' ' Polar to cartesian ' ' in: t1 = 13-bit angle ' t2 = 16-bit length ' ' out: t1 = x|y ' polarx add t1,sine_90 'cosine, add 90? for sine lookup polary test t1,sine_180 wz 'get sine quadrant 3|4 into nz test t1,sine_90 wc 'get sine quadrant 2|4 into c negc t1,t1 'if sine quadrant 2|4, negate table offset or t1,sine_table 'or in sine table address >> 1 shl t1,#1 'shift left to get final word address rdword t1,t1 'read sine/cosine word call #multiply 'multiply sine/cosine by length to get x|y add t1,h8000 'add 1/2 lsb to round up x|y fraction shr t1,#16 'justify x|y integer negnz t1,t1 'if sine quadrant 3|4, negate x|y polary_ret polarx_ret ret sine_90 long $0800 '90? bit sine_180 long $1000 '180? bit sine_table long $E000 >> 1 'sine table address shifted right ' ' ' Multiply ' ' in: t1 = 16-bit multiplicand (t1[31..16] must be 0) ' t2 = 16-bit multiplier ' ' out: t1 = 32-bit product ' multiply mov t3,#16 shl t2,#16 shr t1,#1 wc :loop if_c add t1,t2 wc rcr t1,#1 wc djnz t3,#:loop multiply_ret ret ' ' ' Defined data ' zero long 0 'constants d0 long $200 h8000 long $8000 hFFFFFFFF long $FFFFFFFF color1 long %%1111111111111111 color2 long %%2222222222222222 fontptr long 0 'font pointer (set before cognew command) pcolor long %%1111111111111111 'pixel color pwidth long 0 'pixel width passes long 1 'pixel passes textsx long 1 'text scale x textsy long 1 'text scale y textsp long 6 'text spacing ' ' ' Undefined data ' t1 res 1 'temps t2 res 1 t3 res 1 t4 res 1 t5 res 1 t6 res 1 t7 res 1 arg0 res 1 'arguments passed from high-level arg1 res 1 arg2 res 1 arg3 res 1 arg4 res 1 arg5 res 1 arg6 res 1 arg7 res 1 basesptr res 1 'pointers slicesptr res 1 xlongs res 1 'bitmap metrics ylongs res 1 xorigin res 1 yorigin res 1 dx res 1 'line/plot coordinates dy res 1 px res 1 py res 1 sx res 1 'line sy res 1 count res 1 ratio res 1 pass res 1 'plot slice res 1 base0 res 1 base1 res 1 mask0 res 1 mask1 res 1 bits0 res 1 bits1 res 1
games/starblaster/source/Fk_starblaster_010.spin
0 → 100644
View file @
809cdf45
' /////////////////////////////////////////////////////////////////////////////
' StarBlaster Game
' AUTHOR: Frank Korf
' LAST MODIFIED: 1.29.12
' VERSION 1.0
' COMMENTS: Simple space shooter
' Special thanks to Andre' LaMothe and the Hydra team
'
' CONTROLS: gamepad (must be plugged in)
' Start = "Start"
' Move = "Dpad"
' Shoot = "A"
' /////////////////////////////////////////////////////////////////////////////
'///////////////////////////////////////////////////////////////////////
' CONSTANTS SECTION ////////////////////////////////////////////////////
'///////////////////////////////////////////////////////////////////////
CON
_clkmode = xtal1 + pll16x ' enable external clock and pll times 8
_xinfreq = 5_000_000 ' set frequency to 10 MHZ plus some error
_stack = ($3000 + $3000 + 64) >> 2 'accomodate display memory and stack
' graphics driver and screen constants
PARAMCOUNT = 14
OFFSCREEN_BUFFER = $2000 ' offscreen buffer
ONSCREEN_BUFFER = $5000 ' onscreen buffer
' size of graphics tile map
X_TILES = 16
Y_TILES = 12
SCREEN_WIDTH = 256
SCREEN_HEIGHT = 192
' text position constants
SCORE_X_POS = -SCREEN_WIDTH/2 + 10
SCORE_Y_POS = SCREEN_HEIGHT/2 - 1*14
HISCORE_X_POS = -24
HISCORE_Y_POS = SCREEN_HEIGHT/2 - 1*14
SHIPS_X_POS = SCREEN_WIDTH/2 - 10/2*12
SHIPS_Y_POS = SCREEN_HEIGHT/2 - 1*14
' angular constants to make object declarations easier
ANG_0 = $0000
ANG_360 = $2000
ANG_240 = ($2000*2/3)
ANG_180 = ($2000/2)
ANG_120 = ($2000/3)
ANG_90 = ($2000/4)
ANG_60 = ($2000/6)
ANG_45 = ($2000/8)
ANG_30 = ($2000/12)
ANG_22_5 = ($2000/16)
ANG_15 = ($2000/24)
ANG_10 = ($2000/36)
ANG_5 = ($2000/72)
' game states
GAME_STATE_INIT = 0
GAME_STATE_MENU = 1
GAME_STATE_START = 2
GAME_STATE_RUN = 3
GAME_STATE_OVER = 4
'Object Contstants
OBJECT_SIZE = 3
_POSITION 'long
_X = $0 'word
_Y = $1 'word
_VEL = $2 'word
_VEL_X = $4 'byte
_VEL_Y = $5 'byte
_LIFETIME = $3 'word
'Player Constants
PLAYER_SIZE = OBJECT_SIZE
PLAYER_SPEED = 3
RELOAD_TIME = 15
'Bullet Constants
MAX_BULLETS = 3
BULLET_SIZE = OBJECT_SIZE + 1
BULLET_SPEED = 4
BULLET_LIFETIME = 30
'Mob Constants
MOB_SIZE = OBJECT_SIZE + 2
MAX_MOBS = 8
_AI = $4
_AI_COUNT = $8
_AI_STEP = $9
'Explosion Constants
_EXPLOSION_LIFE = $2
'///////////////////////////////////////////////////////////////////////
' VARIABLES SECTION ////////////////////////////////////////////////////
'///////////////////////////////////////////////////////////////////////
VAR
long tv_status '0/1/2 = off/visible/invisible read-only
long tv_enable '0/? = off/on write-only
long tv_pins '%ppmmm = pins write-only
long tv_mode '%ccinp = chroma,interlace,ntsc/pal,swap write-only
long tv_screen 'pointer to screen (words) write-only
long tv_colors 'pointer to colors (longs) write-only
long tv_hc 'horizontal cells write-only
long tv_vc 'vertical cells write-only
long tv_hx 'horizontal cell expansion write-only
long tv_vx 'vertical cell expansion write-only
long tv_ho 'horizontal offset write-only
long tv_vo 'vertical offset write-only
long tv_broadcast 'broadcast frequency (Hz) write-only
long tv_auralcog 'aural fm cog write-only
word screen[X_TILES * Y_TILES] ' storage for screen tile map
long colors[64] ' color look up table
word map_height[64]
word seed
byte game_state
byte restart_timer
word score
word high_score
'two words per star: x and y pos
word star_list[64]
word camera_x
word camera_y
'four words for the character
word player[PLAYER_SIZE]
word num_ships
'four words per bullet: x and y pos, direction, lifetime
word bullet_list[ MAX_BULLETS * BULLET_SIZE ]
word num_bullets
word bullet_timer
'four words per mob: x and y pos, direction, ai state
word mob_list[ MAX_MOBS * MOB_SIZE ]
word num_mobs
word mob_timer
'
word explosion_list[ MAX_MOBS * OBJECT_SIZE ]
'///////////////////////////////////////////////////////////////////////
' OBJECT DECLARATION SECTION ///////////////////////////////////////////
'///////////////////////////////////////////////////////////////////////
OBJ
tv : "tv.spin" ' instantiate a tv object
gr : "Fk_graphics_drv_010.spin" ' instantiate a graphics object
nes : "Fk_NESDriver_001.spin"
'///////////////////////////////////////////////////////////////////////
' PUBLIC FUNCTIONS /////////////////////////////////////////////////////
'///////////////////////////////////////////////////////////////////////
PUB start | i, dx, dy
game_state := GAME_STATE_INIT
'start tv
longmove(@tv_status, @tvparams, paramcount)
tv_screen := @screen
tv_colors := @colors
tv.start(@tv_status)
'init colors
repeat i from 0 to 64
colors[i] := $00001010 * (i+4) & $F + $FB060C02
'init tile screen
repeat dx from 0 to tv_hc - 1
repeat dy from 0 to tv_vc - 1
screen[dy * tv_hc + dx] := onscreen_buffer >> 6 + dy + dx * tv_vc + ((dy & $3F) << 10)
'start and setup graphics 256x192, with orgin (0,0) at bottom left of screen
gr.start
gr.setup(X_TILES, Y_TILES, SCREEN_WIDTH/2, SCREEN_HEIGHT/2, offscreen_buffer)
' BEGIN GAME LOOP ////////////////////////////////////////////////////
' infinite loop
repeat while TRUE
case game_state
GAME_STATE_INIT:
GameInit
game_state := GAME_STATE_START
GAME_STATE_START:
GameStart
game_state := GAME_STATE_MENU
i := 0
GAME_STATE_RUN,GAME_STATE_MENU,GAME_STATE_OVER:
'clear the offscreen buffer
gr.clear
camera_x++
nes.Update
if( game_state == GAME_STATE_RUN )
GameUpdate
else
if( nes.Start )
game_state := GAME_STATE_RUN
i := 0
' RENDERING SECTION (render to offscreen buffer always//////////////
RenderMap(camera_x,camera_y)
if( game_state == GAME_STATE_RUN )
GameRender
else
' draw start game text
gr.textmode(3,1,6,5)
gr.colorwidth(2,0)
if (i > 200)
if (++i & $8)
gr.text(0,0,@start_string)
else
i++
if ( game_state == GAME_STATE_MENU )
gr.text(0,0,@title_string)
else
gr.text(0,0,@over_string)
HudRender
'copy bitmap to display offscreen -> onscreen
gr.copy(onscreen_buffer)
' synchronize to frame rate would go here...
' END RENDERING SECTION ///////////////////////////////////////////////
' END MAIN GAME LOOP REPEAT BLOCK //////////////////////////////////
'//////Game Functions
PUB GameInit
restart_timer := $FF
seed := 1234
high_score := 0
PUB GameStart
camera_x := 80
camera_y := 90
PrepPlayer
PrepMap
PrepBullets
PrepMobs
PrepExplosions
PUB GameUpdate
UpdatePlayer
UpdateBullets
UpdateMobs
UpdateExplosions
ProcessCollisions
PUB GameRender
RenderBullets(camera_x,camera_y)
RenderMobs(camera_x,camera_y)
RenderExplosions( camera_x, camera_y )
if( restart_timer == $FF )
gr.colorwidth(2, 0)
gr.pix( player.WORD[_X] - camera_x, player.WORD[_Y] - camera_y, 0, @pix_player )
PUB HudRender | i
gr.colorwidth(2, 0)
' draw score and num players
gr.textmode( 2,1,6,0 )
gr.text(SCORE_X_POS, SCORE_Y_POS, @score_string)
gr.text(HISCORE_X_POS, HISCORE_Y_POS, @hiscore_string)
gr.text(SHIPS_X_POS, SHIPS_Y_POS, @ships_string)
PrintScore( score, SCORE_X_POS + 10, SCORE_Y_POS - 13 )
PrintScore( high_score, HISCORE_X_POS + 5, HISCORE_Y_POS - 13 )
' draw players ships left
gr.colorwidth(3,0)
repeat i from 0 to num_ships
gr.pix( SHIPS_X_POS + i << 4 + 12, SHIPS_Y_POS - 10, 1, @pix_player )
PUB PrintScore( i, x, y ) | t, str
str := 5
gr.colorwidth(2,0)
gr.textmode( 1,1,6,0 )
repeat t from 0 to 6
BYTE[ @score_number + str ] := 48 + (i // 10)
i /= 10
str--
gr.text( x,y, @score_number )
'////Player Code
PUB PrepPlayer
player.WORD[_X] := 0
player.WORD[_Y] := 100
player.WORD[_VEL] := $00_00
num_ships := 2
score := 0
PUB UpdatePlayer
if( restart_timer == $FF )
player.WORD[_VEL] := $00_00
if( nes.Right )
player.BYTE[_VEL_X] := 2
if( nes.Left )
player.BYTE[_VEL_X] := -1
if( nes.Up )
player.BYTE[_VEL_Y] := 2
if( nes.Down )
player.BYTE[_VEL_Y] := -2
if( nes.A )
AddBullet( player.WORD[_X], player.WORD[_Y] )
player.WORD[_X]++
if( player.WORD[_X] > camera_x )
player.WORD[_X] := camera_x
if( camera_x - player.WORD[_X] > 100 )
player.WORD[_X] := camera_x - 100
if( player.WORD[_Y] < 20 )
player.WORD[_Y] := 20
if( player.WORD[_Y] > 180 )
player.WORD[_Y] := 180
UpdatePos( @player )
elseif( restart_timer == 0 )
' if we're out of ships, game over
restart_timer := $FF
if( num_ships == 0 )
game_state := GAME_STATE_OVER
if( score > high_score )
high_score := score
' else replace the player and reset the timer
GameStart
else
num_ships--
'subtract a ship
else
restart_timer --
'/////TERRAIN AND STAR CODE
PUB PrepMap | i , s
s := 1234
i := 0
repeat 64
map_height[i] := ?s
map_height[i] //= 20
i++
i := 0
repeat 66
map_height[i//64] := ( map_height[ i//64 ] + map_height[ (i+1)//64 ] + map_height[ (i+2)//64 ] ) / 3
i++
i := 0
repeat 32
star_list[i] := ?s
star_list[i] //= 360
star_list[i+1] := ?s
star_list[i+1] //= 180
i += 2
PUB RenderMap(x,y) | i, j, first
gr.colorwidth(2,1)
i := 0
j := ( x / 10 ) // 64
first := x // 10
first += 130
gr.plot( -first, -y + map_height[j] )
repeat 28
gr.line( -first + i*10, -y + map_height[j] )
i++
j := (j+1) // 64
i := 0
gr.colorwidth(2, 0)
repeat 32
gr.plot( star_list[i] - 180, star_list[i+1] - 90 )
i += 2
'/////////BULLET CODE
PUB PrepBullets | i
i := 0
REPEAT MAX_BULLETS * BULLET_SIZE
bullet_list[i] := $0000
i++
num_bullets := 0
bullet_timer := 1
PUB AddBullet( x, y ) | i
i := 0
if( num_bullets < MAX_BULLETS )
if( bullet_timer == 0 )
REPEAT UNTIL bullet_list[i]==0
i+=BULLET_SIZE
bullet_list.WORD[i+_X] := x
bullet_list.WORD[i+_Y] := y
bullet_list.WORD[i+_LIFETIME] := BULLET_LIFETIME
bullet_timer := RELOAD_TIME
PUB RenderBullets( x, y ) | i
gr.colorwidth(2, 1)
i := 0
repeat MAX_BULLETS
if( bullet_list[i] <> 0 )
gr.plot( bullet_list.WORD[i+_X] - x, bullet_list.WORD[i+_Y] - y)
i += BULLET_SIZE
PUB UpdateBullets | i
i := 0
num_bullets := 0
repeat MAX_BULLETS
if( bullet_list[i] <> 0 )
bullet_list.WORD[i+_X] += BULLET_SPEED
bullet_list.WORD[i+_LIFETIME]--
if( bullet_list.WORD[i+_LIFETIME] == 0 )
bullet_list[i] := 0
else
num_bullets++
i += BULLET_SIZE
if( bullet_timer > 0 )
bullet_timer--
'/////////MOB CODE
PUB PrepMobs | i
i := 0
REPEAT MOB_SIZE * MAX_MOBS
mob_list[i] := $00_00
i++
mob_timer := 10
num_mobs := 0
PUB UpdateMobs | i
i := 0
num_mobs := 0
repeat MAX_MOBS
if( mob_list[i] <> 0 )
UpdateAI( @mob_list[i] )
UpdatePos( @mob_list[i] )
mob_list.WORD[i+_LIFETIME]--
if( mob_list.WORD[i+_LIFETIME] == 0 )
mob_list[i] := 0
else
num_mobs++
i += MOB_SIZE
mob_timer--
if( mob_timer == 0 )
mob_timer := 30
if( num_mobs < MAX_MOBS )
AddMob
PUB AddMob | i
i:=0
REPEAT UNTIL mob_list[i] == 0
i += MOB_SIZE
mob_list.WORD[i+_X] := camera_x + 200
mob_list.WORD[i+_Y] := ?seed
mob_list.WORD[i+_Y] //= 120
mob_list.WORD[i+_Y] += 40
mob_list.WORD[i+_VEL] := WORD[ @mob_movement[0] ] 'vel
mob_list.WORD[i+_LIFETIME] := 500 'lifetime
mob_list.WORD[i+_AI] := $00_00 'ai state
PUB UpdateAI( mob_addr ) | count, curr_step
count := BYTE[mob_addr][_AI_COUNT]
curr_step := BYTE[mob_addr][_AI_STEP]
count ++
if( count > 10 )
count := 0
curr_step := (curr_step+1) // 6
WORD[ mob_addr ][ _VEL ] := WORD[ @mob_movement[ curr_step ] ]
BYTE[ mob_addr ][ _AI_STEP ] := curr_step
BYTE[ mob_addr ][ _AI_COUNT ] := count
PUB RenderMobs( x, y ) | i
gr.colorwidth(3, 0)
i := 0