530 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			530 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
 | 
						|
{-----------------------------------------------------------------------+
 | 
						|
|                                                                       |
 | 
						|
|       Snake game                                                      |
 | 
						|
|                                                                       |
 | 
						|
+-----------------------------------------------------------------------}
 | 
						|
 | 
						|
gcl0x
 | 
						|
 | 
						|
{
 | 
						|
Maybe:
 | 
						|
XXX Don't allow autoplayer to obtain a hi score
 | 
						|
XXX Use DOKE to plot fat pixels
 | 
						|
XXX More colors, less green
 | 
						|
XXX Smarter border drawing (spiral draw)
 | 
						|
XXX Use same drawing techique for clearing playfield
 | 
						|
XXX Increasing speed
 | 
						|
XXX Increase speed when pressing button
 | 
						|
}
 | 
						|
 | 
						|
{-
 | 
						|
  First setup all subroutine definitions and variables, without making
 | 
						|
  calls. This way allows use of vLR to hop from page to page during setup,
 | 
						|
  with minimal overhead. At the end, run the main loop.
 | 
						|
-}
 | 
						|
 | 
						|
0 HighScore=
 | 
						|
 | 
						|
{ Print a 5x8 character on screen with the built-in font
 | 
						|
  Char must be in the 32-127 range (this is not checked) }
 | 
						|
[def {PrintChar}
 | 
						|
  {Map ASCII code to offset in font table}
 | 
						|
  Char 82- [if<0 50+ i= \font32up
 | 
						|
            else     i= \font82up] fontData= {Select low or high page}
 | 
						|
  i 2<< i+             {Multiply by 5}
 | 
						|
  fontData+ fontData=  {Add to page address to reach bitmap data for Char}
 | 
						|
 | 
						|
  {Draw 5 vertical slices: 5 using font data}
 | 
						|
  BgColor \sysArgs0.
 | 
						|
  Color   \sysArgs1.
 | 
						|
  Pos     \sysArgs4:
 | 
						|
  6+      Pos=
 | 
						|
  \SYS_VDrawBits_134 \sysFn:
 | 
						|
  $fb i= [do
 | 
						|
    fontData 0? fontData<++ \sysArgs2. 134!!
 | 
						|
    \sysArgs4<++
 | 
						|
    i<++ i if<>0loop]
 | 
						|
  ret
 | 
						|
] PrintChar=
 | 
						|
 | 
						|
[def {PrintText}
 | 
						|
  push
 | 
						|
  Text=
 | 
						|
  [do
 | 
						|
    Text, Char= {Next character to be printed}
 | 
						|
    if<>0       {Zero termination}
 | 
						|
      Text<++   {Advance text pointer}
 | 
						|
      Char 10^ [if=0 Pos<. $800 Pos+ Pos=
 | 
						|
                else PrintChar!]
 | 
						|
      loop]
 | 
						|
  pop ret
 | 
						|
] PrintText=
 | 
						|
 | 
						|
[def
 | 
						|
   $47# $69# $67# $61# $74# $72# $6f# $6e# 0# {Gigatron}
 | 
						|
] Title=
 | 
						|
 | 
						|
[def
 | 
						|
{-
 | 
						|
  DrawLine -- Draw line
 | 
						|
-}
 | 
						|
  Count i=
 | 
						|
  [do if>0
 | 
						|
    Color Pos.
 | 
						|
    Pos Step+ Pos=
 | 
						|
    i 1- i=
 | 
						|
    loop]
 | 
						|
  ret
 | 
						|
] DrawLine=
 | 
						|
 | 
						|
[def
 | 
						|
  push
 | 
						|
  \frameCount, TimeOut- 128& [if=0
 | 
						|
    Timer [if>0 1- Timer=]
 | 
						|
    DrawTimer!
 | 
						|
  ]
 | 
						|
  pop ret
 | 
						|
] UpdateTimer=
 | 
						|
 | 
						|
[def
 | 
						|
  push
 | 
						|
  Head Pos= 63 {White} Color= DrawBlock!
 | 
						|
  pop ret
 | 
						|
] DrawHead=
 | 
						|
 | 
						|
{-----------------------------------------------------------------------+
 | 
						|
|}\vLR>++ ret{          RAM page 3                                      |
 | 
						|
+-----------------------------------------------------------------------}
 | 
						|
$0300:
 | 
						|
 | 
						|
[def
 | 
						|
{-
 | 
						|
  Game over
 | 
						|
-}
 | 
						|
  push
 | 
						|
  $4435 Pos=
 | 
						|
  4 BgColor=
 | 
						|
  [def
 | 
						|
    $47# $41# $4d# $45# $20# $4f# $56# $45# $52# 0# {GAME OVER}
 | 
						|
  ] PrintText!
 | 
						|
 | 
						|
  Score HighScore- [if>0
 | 
						|
    Score HighScore=
 | 
						|
    30 Color= DrawHighScore!
 | 
						|
  ]
 | 
						|
 | 
						|
  PlayGameOverSound!
 | 
						|
 | 
						|
  pop ret
 | 
						|
] GameOver=
 | 
						|
 | 
						|
[def {Wait -- Wait Delay number of frames (range 1..255)}
 | 
						|
  tmp= \frameCount, tmp+ 255& tmp=
 | 
						|
  [do \frameCount, tmp- if<>0loop]
 | 
						|
  ret
 | 
						|
] Wait=
 | 
						|
 | 
						|
[def
 | 
						|
{-
 | 
						|
  Intro
 | 
						|
-}
 | 
						|
  push
 | 
						|
 | 
						|
  {Display welcome tekst}
 | 
						|
  8 {Green} Color=
 | 
						|
  0 BgColor=
 | 
						|
  $800 ClearScreen!
 | 
						|
  $838 Pos= Title PrintText!
 | 
						|
 | 
						|
  pop ret
 | 
						|
] Intro=
 | 
						|
 | 
						|
[def {ClearScreen -- Clear screen from current position to bottom right}
 | 
						|
  Pos= p=
 | 
						|
  Pos 255| 255^         {Clear low byte}
 | 
						|
  i= $8001 i+ i=        {Offset to move to next stripe}
 | 
						|
  BgColor \sysArgs0. \sysArgs1.
 | 
						|
  \SYS_VDrawBits_134 \sysFn:
 | 
						|
  [do
 | 
						|
    {Clear one stripe}
 | 
						|
    p [do
 | 
						|
      \sysArgs4: 134!! {Clears 8 pixels vertically}
 | 
						|
      $800 p+ p= if>0loop]
 | 
						|
    {Next stripe}
 | 
						|
    i+ p=
 | 
						|
    255& 160^ if<>0loop]
 | 
						|
  ret
 | 
						|
] ClearScreen=
 | 
						|
 | 
						|
[def
 | 
						|
  0 stepV- tmp=
 | 
						|
  stepU stepV=
 | 
						|
  tmp   stepU=
 | 
						|
  ret
 | 
						|
] TurnL=
 | 
						|
 | 
						|
[def
 | 
						|
  0 stepU- tmp=
 | 
						|
  stepV stepU=
 | 
						|
  tmp   stepV=
 | 
						|
  ret
 | 
						|
] TurnR=
 | 
						|
 | 
						|
[def
 | 
						|
  Pos    p=
 | 
						|
  Color  Pos.
 | 
						|
  Pos<++ Pos.
 | 
						|
  Pos>++ Pos.
 | 
						|
  p>++ p.
 | 
						|
  ret
 | 
						|
] DrawBlock=
 | 
						|
 | 
						|
{-----------------------------------------------------------------------+
 | 
						|
|}\vLR>++ ret{          RAM page 4                                      |
 | 
						|
+-----------------------------------------------------------------------}
 | 
						|
$0400:
 | 
						|
 | 
						|
[def
 | 
						|
{-
 | 
						|
  RunGame --
 | 
						|
-}
 | 
						|
  push
 | 
						|
 | 
						|
  [do
 | 
						|
    {Control is one of LaunchControl, PlayerControl or AutoControl}
 | 
						|
    Control!
 | 
						|
 | 
						|
    {Leave a trace behind in the pixels two high bits}
 | 
						|
    {Bit 15 and bit 0 of stepU identify the direction}
 | 
						|
    stepU>, 128& tmp=
 | 
						|
    stepU     1& [if<>0 64] tmp+
 | 
						|
 | 
						|
    30+ {Cyan} Color= Head Pos= DrawBlock! {Tail color and trace}
 | 
						|
 | 
						|
    {Make step}
 | 
						|
    Head stepU+ stepU+ Head=
 | 
						|
 | 
						|
    Head, $33& [if<>0 {Hit wall or poison} pop ret]
 | 
						|
    Head, 8^ {Food?} [if=0
 | 
						|
      {Eat food}
 | 
						|
      $40 Timer+ SetTone!
 | 
						|
      2 \soundTimer.
 | 
						|
      Score Timer+ Score=
 | 
						|
      DrawScore!
 | 
						|
      5 AddTimer!
 | 
						|
      Grow<++ Drops<++
 | 
						|
    ]
 | 
						|
    DrawHead!
 | 
						|
 | 
						|
    {Update tail}
 | 
						|
    Grow [if>0
 | 
						|
      1- Grow= {Do nothing while growing}
 | 
						|
      AddFood!
 | 
						|
    else
 | 
						|
      {Tail is following the head}
 | 
						|
      Tail, tmp=
 | 
						|
      Drops [if>0 1- Drops= 63 {White} else 4] Color=
 | 
						|
      Tail Pos= DrawBlock!
 | 
						|
 | 
						|
      tmp 64&  [if=0 $0100 else $0001] x=
 | 
						|
      tmp 128& [if=0 x else 0 x-]
 | 
						|
      1<< Tail+ Tail=
 | 
						|
    ]
 | 
						|
 | 
						|
    UpdateTimer!
 | 
						|
 | 
						|
    2 Wait! {Fixed game speed}
 | 
						|
    loop]
 | 
						|
] RunGame=
 | 
						|
 | 
						|
[def
 | 
						|
  push
 | 
						|
  8 {Green} Color=
 | 
						|
  [do
 | 
						|
    \SYS_Random_34 \sysFn: 34!! Pos=
 | 
						|
    Pos<,      128- [if<0 157+] 1+   {1..157}   $fe& Pos<.
 | 
						|
    Pos>, 127& 64-  [if<0 109+] $11+ {$11..$fd} $fe& Pos>.
 | 
						|
    Pos, 4^ if<>0loop]
 | 
						|
  DrawBlock!
 | 
						|
  pop ret
 | 
						|
] AddFood=
 | 
						|
 | 
						|
{-----------------------------------------------------------------------+
 | 
						|
|}\vLR>++ ret{          RAM page 5                                      |
 | 
						|
+-----------------------------------------------------------------------}
 | 
						|
$0500:
 | 
						|
 | 
						|
[def
 | 
						|
  push
 | 
						|
  {If a key is pressed, start restart the game}
 | 
						|
  \serialRaw, $cf& {~buttonStart&~buttonSelect} $cf^ [if<>0 SetupGame! pop ret]
 | 
						|
 | 
						|
  {Auto snake control}
 | 
						|
  TurnL p=
 | 
						|
  TurnR q=
 | 
						|
  {Look ahead} Head stepU+ stepU+ peek 4^ tmp=
 | 
						|
  {Look left}  Head stepV- stepV- peek 4^ [if<>0 {8^4}12^ [if<>0 0 p= else 0 q= 1 tmp=]]
 | 
						|
  {Look right} Head stepV+ stepV+ peek 4^ [if<>0 {8^4}12^ [if<>0 0 q= else 0 p= 1 tmp=]]
 | 
						|
                                  tmp  [if=0 \entropy, $7f& 6- [if<0 1 else 0]]
 | 
						|
  [if<>0 {8^4}12^ if<>0
 | 
						|
    {Wall or random direction change: must go left or right.
 | 
						|
     Pick randomly, without bias, but don't crash into a wall when not needed}
 | 
						|
    p [if=0 q else
 | 
						|
      q [if=0 p else
 | 
						|
       \entropy, 1& [if=0 p else q]
 | 
						|
      ]
 | 
						|
    ]
 | 
						|
    [if<>0 call {TurnL or TurnR}]
 | 
						|
  ]
 | 
						|
  pop ret
 | 
						|
] AutoControl=
 | 
						|
 | 
						|
[def
 | 
						|
  stepU tmp= {Default keep running in same direction}
 | 
						|
  \serialRaw, $fe^ {~buttonRight} [if=0 $0001 tmp=]
 | 
						|
  \serialRaw, $fd^ {~buttonLeft}  [if=0 $ffff tmp=]
 | 
						|
  \serialRaw, $fb^ {~buttonDown}  [if=0 $0100 tmp=]
 | 
						|
  \serialRaw, $f7^ {~buttonUp}    [if=0 $ff00 tmp=]
 | 
						|
  {Only turn if not reversing 180 degrees}
 | 
						|
  tmp stepU+ [if<>0 tmp stepU=]
 | 
						|
  {Or if there is no tail yet in the beginning of the game}
 | 
						|
  Tail Head- [if=0 tmp stepU=]
 | 
						|
  {Note: `stepV' is not used once under player control}
 | 
						|
  ret
 | 
						|
] PlayerControl=
 | 
						|
 | 
						|
{-----------------------------------------------------------------------+
 | 
						|
|}\vLR>++ ret{          RAM page 6                                      |
 | 
						|
+-----------------------------------------------------------------------}
 | 
						|
$0600:
 | 
						|
 | 
						|
[def {AddTimer}
 | 
						|
  push
 | 
						|
  Timer+ Timer=
 | 
						|
  15- [if>0 15 Timer=]
 | 
						|
  \frameCount, TimeOut=
 | 
						|
  DrawTimer!
 | 
						|
  pop ret
 | 
						|
] AddTimer=
 | 
						|
 | 
						|
[def {SetupGame}
 | 
						|
  push
 | 
						|
 | 
						|
  {Reset score}
 | 
						|
  0 Score= Timer= DrawScore!
 | 
						|
  15 Timer= DrawTimer!
 | 
						|
  DrawHighScore!
 | 
						|
 | 
						|
  {ClearScreen}
 | 
						|
  4 BgColor=
 | 
						|
  $1000 ClearScreen!
 | 
						|
 | 
						|
  {Draw bounding box}
 | 
						|
  26 Color=
 | 
						|
     +1 Step= 159 Count= DrawLine!
 | 
						|
   $100 Step= 111 Count= DrawLine!
 | 
						|
     -1 Step= 159 Count= DrawLine!
 | 
						|
  -$100 Step= 110 Count= DrawLine!
 | 
						|
     +1 Step= 158 Count= DrawLine!
 | 
						|
   $100 Step= 109 Count= DrawLine!
 | 
						|
     -1 Step= 157 Count= DrawLine!
 | 
						|
  -$100 Step= 109 Count= DrawLine!
 | 
						|
 | 
						|
  {Get ready message}
 | 
						|
  $4432 Pos= 3 {Red} Color=
 | 
						|
  [def
 | 
						|
    $47# $45# $54# $20# $52# $45# $41# $44# $59# $21# 0# {GET READY!}
 | 
						|
  ] PrintText!
 | 
						|
  60 Wait!
 | 
						|
  $4432 Pos=
 | 
						|
  [def
 | 
						|
    $20# $20# $20# $20# $20# $20# $20# $20# $20# $20# 0#
 | 
						|
  ] PrintText!
 | 
						|
 | 
						|
  {Place snake}
 | 
						|
  $4430 Head= Tail=
 | 
						|
  DrawHead!
 | 
						|
 | 
						|
  0 Grow= Drops=
 | 
						|
  Timer= 15 AddTimer!
 | 
						|
  $0001 stepU= $0100 stepV= {Start right}
 | 
						|
 | 
						|
  {Place 25 foods}
 | 
						|
  25 [do i= AddFood! i 1- if>0loop]
 | 
						|
 | 
						|
  LaunchControl Control=
 | 
						|
 | 
						|
  pop ret
 | 
						|
] SetupGame=
 | 
						|
 | 
						|
{-----------------------------------------------------------------------+
 | 
						|
|}$08a0 \vLR: ret{      RAM page 8                                      |
 | 
						|
+-----------------------------------------------------------------------}
 | 
						|
$08a0:
 | 
						|
 | 
						|
[def {LaunchControl}
 | 
						|
{-
 | 
						|
  XXX better strategy: run both PlayerControl and AutoControl.
 | 
						|
  The first one to take control will take over the game...
 | 
						|
-}
 | 
						|
  push
 | 
						|
  $449c Head- [if=0
 | 
						|
    {Switch to autopilot when reaching this position}
 | 
						|
    30 {XXX} Color=
 | 
						|
    $0802 Pos=
 | 
						|
    [def $41# $55# $54# $4f# 0#{AUTO}] PrintText!
 | 
						|
    AutoControl Control= call
 | 
						|
  else
 | 
						|
    {Disable launch control once a button is pressed}
 | 
						|
    \serialRaw, $cf& {~buttonStart|~buttonSelect} $cf^ [if<>0 PlayerControl Control= call]
 | 
						|
  ]
 | 
						|
  pop ret
 | 
						|
] LaunchControl=
 | 
						|
 | 
						|
[def { DrawNumber2 - Value Radix }
 | 
						|
  push
 | 
						|
  $20 Char=
 | 
						|
    10 Radix= DrawNextDigit!
 | 
						|
  $30 Char=
 | 
						|
     1 Radix= DrawNextDigit!
 | 
						|
  pop ret
 | 
						|
] DrawNumber2=
 | 
						|
 | 
						|
{-----------------------------------------------------------------------+
 | 
						|
|}\vLR>++ ret{          RAM page 9                                      |
 | 
						|
+-----------------------------------------------------------------------}
 | 
						|
$09a0:
 | 
						|
 | 
						|
[def { DrawNextDigit -- Value Radix }
 | 
						|
  push
 | 
						|
  Value Radix- [if>=0
 | 
						|
    Value=
 | 
						|
    $31 Char=
 | 
						|
    Value [do
 | 
						|
      Radix-
 | 
						|
      if>=0
 | 
						|
        Value=
 | 
						|
        Char<++
 | 
						|
        loop
 | 
						|
    ]
 | 
						|
    PrintChar!
 | 
						|
    $30 Char=
 | 
						|
  else
 | 
						|
    PrintChar!
 | 
						|
  ]
 | 
						|
  pop ret
 | 
						|
] DrawNextDigit=
 | 
						|
 | 
						|
[def { DrawNumber4 - Value Radix }
 | 
						|
  push
 | 
						|
  $20 Char=
 | 
						|
  1000 Radix= DrawNextDigit!
 | 
						|
   100 Radix= DrawNextDigit!
 | 
						|
    10 Radix= DrawNextDigit!
 | 
						|
  $30 Char=
 | 
						|
     1 Radix= DrawNextDigit!
 | 
						|
  pop ret
 | 
						|
] DrawNumber4=
 | 
						|
 | 
						|
{-----------------------------------------------------------------------+
 | 
						|
|}\vLR>++ ret{          RAM page 10                                     |
 | 
						|
+-----------------------------------------------------------------------}
 | 
						|
$0aa0:
 | 
						|
 | 
						|
[def
 | 
						|
  push
 | 
						|
  $802 Pos=
 | 
						|
  Score HighScore- [if>0 30 else 8] Color=
 | 
						|
  0 BgColor=
 | 
						|
  Score Value= DrawNumber4!
 | 
						|
  pop ret
 | 
						|
] DrawScore=
 | 
						|
 | 
						|
[def
 | 
						|
  push
 | 
						|
  $820 Pos=
 | 
						|
  8 Color=
 | 
						|
  0 BgColor=
 | 
						|
  Timer Value= DrawNumber2!
 | 
						|
  TimeOut 60+ 255& TimeOut=
 | 
						|
  pop ret
 | 
						|
] DrawTimer=
 | 
						|
 | 
						|
{-----------------------------------------------------------------------+
 | 
						|
|}\vLR>++ ret{          RAM page 11                                     |
 | 
						|
+-----------------------------------------------------------------------}
 | 
						|
$0ba0:
 | 
						|
 | 
						|
[def
 | 
						|
  push
 | 
						|
  $874 Pos= 0 BgColor=
 | 
						|
  [def $48# $49# $20# 0# {HI }] PrintText!
 | 
						|
  HighScore Value= DrawNumber4!
 | 
						|
  pop ret
 | 
						|
] DrawHighScore=
 | 
						|
 | 
						|
[def {SetupChannel}
 | 
						|
  i= 255| 255^ $fa| p=          {Pointer to channel struct}
 | 
						|
  i<, i=                        {Extract note}
 | 
						|
  0 p. p<++                     {.wavA}
 | 
						|
  1 p. p<++                     {.wavX: 0 "Noise", 1 Triangle, 2 Pulse, 3 Sawtooth}
 | 
						|
  \notesTable i+ 0? p. p<++     {.keyL}
 | 
						|
  \notesTable i+ 1? p. p<++     {.keyH}
 | 
						|
  ret
 | 
						|
] SetupChannel=
 | 
						|
 | 
						|
{-----------------------------------------------------------------------+
 | 
						|
|}\vLR>++ ret{          RAM page 12                                     |
 | 
						|
+-----------------------------------------------------------------------}
 | 
						|
$0ca0:
 | 
						|
 | 
						|
{ Setup a G-major chord with 4 channels but don't play it yet }
 | 
						|
[def {SetTone}
 | 
						|
  push
 | 
						|
  1<< tmp=
 | 
						|
  $100 tmp| {Channel 1} SetupChannel!
 | 
						|
  $200 tmp| {Channel 2} SetupChannel!
 | 
						|
  $300 tmp| {Channel 3} SetupChannel!
 | 
						|
  $400 tmp| {Channel 4} SetupChannel!
 | 
						|
  pop ret
 | 
						|
] SetTone=
 | 
						|
 | 
						|
[def
 | 
						|
  push
 | 
						|
  $49 j= [do
 | 
						|
    j SetTone!
 | 
						|
    5 \soundTimer.
 | 
						|
    [do \soundTimer, if<>0loop]
 | 
						|
    j 1- j= $30^ if<>0loop]
 | 
						|
  pop ret
 | 
						|
] PlayGameOverSound=
 | 
						|
 | 
						|
{-----------------------------------------------------------------------+
 | 
						|
|}\vLR>++ ret{          RAM page 13                                     |
 | 
						|
+-----------------------------------------------------------------------}
 | 
						|
$0da0:
 | 
						|
 | 
						|
{--- Run ---}
 | 
						|
 | 
						|
Intro!
 | 
						|
 | 
						|
$49 SetTone!
 | 
						|
 | 
						|
[do
 | 
						|
  SetupGame!
 | 
						|
  RunGame!
 | 
						|
 | 
						|
  120 \soundTimer.
 | 
						|
  3 {Bright Red} Color= Head Pos= DrawBlock!
 | 
						|
  GameOver!
 | 
						|
  60 Wait!
 | 
						|
 | 
						|
  loop
 | 
						|
]
 | 
						|
 | 
						|
{-----------------------------------------------------------------------+
 | 
						|
|       End                                                             |
 | 
						|
+-----------------------------------------------------------------------}
 | 
						|
 |