ZACK

From CPCWiki - THE Amstrad CPC encyclopedia!
Jump to: navigation, search

ZACK is the ZAp-em-up Construction Kit, an unfinished game creator software for the CPC. A unique and very promising package for people who wanted to create professional quality games easily. Written by Richard Wilson (Executioner) in 1993. According to the author himself: Everything got finished except the sound/FX and completed game loader/multi-load code.


Download

You can download the unfinished version and sources of ZACK from author's WINAPE site:

  • ZACK preview (Note: use |CPM to run. ParaDOS is required for second disk image.)

Previews

ZACK previewed in Amstrad Action issue 98

ZACK Programming Language


Commands

BACKGROUND (x,y) = value		Set a background tile
BACKGROUND COLLISION from[ .. to]	Test for background collision
BORDER ink				Set Border
BYTE var{ ,var}				Define Byte variable(s)
CLEAR SCREEN byte			Clear the screen
CONSOLE					Output on Console
CONST var = value{ ,var = value}	Define constant(s)
COPY LAYOUT x,y,width,height TO x,y	Copy a section of the Layout
COPY SPRITE n TO n			Copy a Sprite
DEC var					Decrement a variable
DEFINE var = value{ ,var = value}	Define constant(s) (Same as CONST)
DEFINE KEY key				Define a key
DEFINE MAIN TASK number			Define a Main Task
DEFINE MARKER TASK number		Define a Marker Task
DEFINE MOVE TASK number			Define a Move Task
DEFINE DRAW TASK number			Define a Draw Task
DRAW x,y[,pen]				Not implemented (Draw a line)
DRAW TASK number			Execute DRAW Task
ELSE					ELSE statement
ELSE IF expr				ELSE IF statement
ENDIF					End of IF statement
FLASH OBJECT				Flash the current Object
FOR var = start TO end[ STEP step]	For loop statement
GOTO line				GOTO statement
GOTO MARKER marker			Go to Layout Marker
HIDDEN SCREEN				Output on Hidden Screen
IF expr[ GOTO line]			IF or IF .. GOTO statement
INC var					Increment a variable
INK pen, ink				Set the given pen to palette colour
INPUT var[:width]			Assign user input to variable
INSERT HIGH position			Insert a High Score in the table
KILL number				Kill given Object
KILL ALL				Kill all Objects
LOCATE x,y				Position text cursor
MAIN TASK number			Execute MAIN Task
MOVE x,y				Move graphics position
MOVE OBJECT dx,dy[ SCROLL]		Move current Object (include scroll)
MOVE OBJECTS				Execute MOVE Tasks for all Objects
MOVE TASK number			Execute given MOVE Task
NEW OBJECT obj,part,x,y,mt[,dt[,v1..]]	Create a new Object (mt = Move Task, dt=Draw Task)
NEXT					Continue FOR loop
OBJECT COLLISION from[ .. to]		Check for collision with another Object
ORIGIN x,y				Change the output Origin
PAUSE delay[ KEY key]			Pause for given time (or until key pressed)
PLAY FX number				Not implemented (Play given Sound Effect)
PLAY TUNE number			Not implemented (Play given Tune)
PLOT x,y[,pen]				Not implemented (Plot a point)
PRINT [@x,y,]expr[:width]		Print value (at position, with given width)
REPEAT					Repeat loop statement
RESET var{ ,var}			Reset variable(s) to zero
RESET INKS				Reset palette to default???
RETURN					Return from a Task
SCORE var{, var}			Define a Score variable
SCREEN TYPE number			Set the screen format
SCROLL					Scroll the layout (if scrolling on)
SCROLL OFF				Turn automatic scrolling off
SCROLL ON				Turn automatic scrolling on
SHOW BACKGROUND				Show the background
SHOW KEY key				Show the label for the given key
SHOW MINI number			Show given Mini-Sprite at current position
SHOW OBJECT obj,part			Show an Object at current position
SHOW OBJECTS				Show all Objects
SHOW SCREEN				Show the hidden screen
SHOW SHOT number			Show Shot-Sprite at current position
SHOW SPRITE number			Draw a Sprite at the current position
STOP FX					Not implemented (Stop Sound Effect)
STOP TUNE				Not implemented (Stop Tune playing)
STRING var{ ,var}			Define a String variable
SWAP SPRITE number,number		Swap two sprites
UNTIL expr				End of REPEAT..UNTIL loop
VISIBLE SCREEN				Output on the Visible Screen
WEND					End of WHILE loop
WHILE expr				WHILE loop statement
WINDOW x,y,width,height			Define a window for output
WORD var{ ,var}				Define a Word variable

Some of these commands may not be fully implemented.

Functions

ABS expr				Absolute value
BACKGROUND (x, y)			Background tile (x and y in bytes)
DIR obj					Direction of another object (0..7)
INKEY key				Test a key
MAX (value1{, valuen})			Maximum of values
MIN (value1{, valuen})			Minimum of values
NOT expr				Logical NOT
RND					Random Word


System variables

marker				Byte	Current layout marker number
scroll_type			Byte	Current scroll type (automatic?)
x_scrl				Byte	Current horizontal scroll direction
y_scrl				Byte	Current vertical scroll direction
mk_task				Byte	Task for current marker
m1 .. m8			Byte	Marker variables

lay_x				Word	Layout X position
lay_y				Word	Layout Y position
par_x				Word	Parallax X position
par_y				Word	Parallax Y position

object				Byte	Object number of current object
part				Byte	Part of current object (0 .. 11)
mv_task				Byte	Task to move object
dr_task				Byte	Task to draw object
x				Word	X position of object
y				Word	Y position of object
v1 .. v8			Byte	Object variables
priority			Byte	Priority of object

y_pos				Byte	Y co-ordinate from LOCATE
x_pos				Byte	X co-ordinate from LOCATE

case				Byte	CAPS LOCK state
ctrl_shift			Byte	Shift and CONTROL state
text_mode			Byte	Text output mode
intno				Byte	Current interrupt in frame (0 .. 5)
screen_type			Byte	Current screen type
flash_mask			Byte	Mask for flashing objects

win_y				Byte	Window Y of top left
win_x				Byte	Window X of top left
win_h				Byte	Height of window
win_w				Byte	Width of window
org_y				Byte	Window Y origin
org_x				Byte	Window X origin

current				Byte	Current object reference
parent				Byte	Current parent object reference
main_pty			Byte	Priority of objects from tasks
back_pty			Byte	Priority of objects from layout
new_pty				Byte	Priority of next object
num_obj				Byte	Number of objects
hit				Byte	Collision object reference
escape				Byte	Disable/Enable the Escape key

high		10		Score	Array of high scores
name		10		String	Array of names for high scores
high_pos			Byte	Position from INSERT HIGH command
mask		16		Byte	Array of byte masks for each ink
sequence	?		Byte	Background sequence array

.object				Byte	Parent object number
.part				Byte	Parent part
.mv_task			Byte	Parent Move Task
.dr_task			Byte	Parent Draw Task
.x				Word	Parent X location
.y				Word	Parent Y location
.v1 .. .v8			Byte	Parent object variables

Below is an example ZACK program:

      WORD mky,dots,w1,w2
      BYTE pills,stage,m,power

      PAUSE 10

      SCREEN TYPE 1
      MAIN TASK 1

      DEFINE MAIN TASK 1

0     stage = 1
      m = 0
1     KILL ALL
      NEW OBJECT 1,28,48,0,0,-2
      INC m
      GOTO MARKER m
      mky = lay_y-184
      COPY LAYOUT 256,mky,32,14 TO 0,mky

      x = 24
      y = 0
      FOR v1 = 0 TO m2
      NEW OBJECT 4,x+24,-16,y,1,2,0,0,1,0,0,0,lay_x+x,lay_y-16
      x = x+2
      y = y+4
      IF y=12
      y = 0
      ENDIF
      NEXT

      MAIN TASK 2
      MAIN TASK 3

      WHILE dots
      HIDDEN SCREEN
      SHOW BACKGROUND
      SHOW OBJECTS
      SHOW SCREEN
      CONSOLE
      MOVE OBJECTS
      COPY SPRITE 15 TO 35
      COPY SPRITE 34 TO 15
      COPY SPRITE 33 TO 34
      COPY SPRITE 32 TO 33
      COPY SPRITE 35 TO 32
      IF INKEY 38
      MAIN TASK 2
      ENDIF
      WEND
      INC stage
      IF m1 GOTO 1
      GOTO 0

      DEFINE MAIN TASK 2

      HIDDEN SCREEN
      CLEAR SCREEN 0
      PRINT @11,0,"PAC ATTACK"
      PRINT @12,2,"Stage"
      PRINT @18,2,stage:2
      v2 = 32
      RESET dots,pills
      FOR w2 = mky TO mky+448 STEP 32
      FOR w1 = 32 TO 280 STEP 8
      v1 = BACKGROUND (w1,w2)
      MOVE w1/8+12,v2
      IF v1=0
      v3 = 1
      ELSE IF v1<15
      v3 = 2
      ELSE IF v1<18
      v3 = v1-12
      ELSE
      v3 = 0
      ENDIF
      SHOW SHOT v3
      IF v1=16
      INC dots
      ELSE IF v1=17
      INC pills
      ENDIF
      NEXT
      v2 = v2+4
      NEXT
      PRINT @10,13,"Dots  :"
      PRINT @17,13,dots:4
      PRINT @10,15,"Pills :"
      PRINT @17,15,pills:4
      SHOW SCREEN
      REPEAT
      UNTIL INKEY 47


      DEFINE MAIN TASK 3

      BYTE c1,c2,i1[5],i2[5]
      DEFINE i1[1]=3,i1[2]=2,i1[4]=6,i1[5]=13
      DEFINE i2[1]=3,i2[2]=2,i2[3]=4,i2[4]=0,i2[5]=13
      CONSOLE

      v2 = 1
      FOR w2 = mky TO mky+448 STEP 32
      v4 = 1
      FOR w1 = 32 TO 280 STEP 8
      v1 = BACKGROUND (w1,w2)
      IF v1=0
      v3 = 1
      ELSE IF v1<15
      v3 = 2
      ELSE IF v1<18
      v3 = v1-12
      ELSE
      v3 = 0
      ENDIF
      c1 = i1[v3]
      c2 = i2[v3]
      PLOT v4,v2,mask[c1]
      PLOT v4,v2+1,mask[c2]
      i1[4] = i1[4] XOR 3
      INC v4
      NEXT
      v2 = v2+2
      NEXT


      DEFINE MOVE TASK 0

      power = 0
      w1 = lay_x+28
      w2 = lay_y+48
      IF NOT ((w1 AND 7) OR (w2 AND 31))
      v6 = BACKGROUND (w1+v1*4,w2+v2*4)
      IF v6<16
      v1 = 0
      v2 = 0
      ENDIF
      ENDIF
      IF (lay_y AND 31)=16
      IF v1<2 AND INKEY 63
      v6 = BACKGROUND (w1+8,w2)
      IF v6>15
      v1 = 2
      v2 = 0
      object = 0
      GOTO 1
      ENDIF
      ELSE IF v1>-2 AND INKEY 71
      v6 = BACKGROUND (w1-1,w2)
      IF v6>15
      v1 = -2
      v2 = 0
      object = 1
      GOTO 1
      ENDIF
      ENDIF
      ENDIF
      IF (lay_x AND 7)=4
      IF v2<8 AND INKEY 22
      v6 = BACKGROUND (w1,w2+32)
      IF v6>15
      v1 = 0
      v2 = 8
      object = 3
      ENDIF
      ELSE IF v2>-8 AND INKEY 19
      v6 = BACKGROUND (w1,w2-32)
      IF v6>15
      v1 = 0
      v2 = -8
      object = 2
      ENDIF
      ENDIF
      ENDIF
1     lay_x = (lay_x+v1) AND 255
      lay_y = lay_y+v2
      IF NOT ((w1 AND 7) OR (w2 AND 31))
      v6 = BACKGROUND (w1,w2)
      IF v6=16 OR v6=17
      IF v6=16
      DEC dots
      ELSE
      power = 1
      ENDIF
      BACKGROUND (w1,w2) = 63
      v4 = w1/8-3
      v5 = ((w2-mky+32) AND &FFE0)/16+1
      PLOT v4,v5,0
      PLOT v4,v5+1,0
      ENDIF
      ENDIF
      IF v1 OR v2
      part = (part+1) MOD 6
      ENDIF
      OBJECT COLLISION 4
      IF hit
      BORDER 26
      ENDIF

      DEFINE MOVE TASK 1

      BYTE a,b,d[4],adx[3],ady[3]
      DEFINE adx[1]=8,adx[3]=-8
      DEFINE ady[0]=-32,ady[2]=32

      IF power
      v3 = 255
      IF object=4
      object = 5
      v1 = -v1
      v2 = -v2
      ENDIF
      ENDIF

      IF v3
      DEC v3
      ELSE
      object = 4
      ENDIF

      IF NOT ((w1 AND 7) OR (w2 AND 31))
      v6 = BACKGROUND (w1+v1*4,w2+v2*4)
      IF v1<>0
      a = BACKGROUND (w1,w2-32)
      b = BACKGROUND (w1,w2+32)
      ELSE
      a = BACKGROUND (w1-8,w2)
      b = BACKGROUND (w1+8,w2)
      ENDIF
      IF v6<16 OR (a>15) OR (b>15)
      a = DIR (1)/2
      IF v3
      a = a XOR 2
      ENDIF
      IF a=(v4 XOR 2)
      d[3] = a
      b = 0
      ELSE
      d[0] = a
      b = 1
      ENDIF
      a = RND AND 3
      IF a=(v4 XOR 2)
      a = (a+1) AND 3
      ENDIF
      FOR v4 = b TO b+2
      d[v4] = a
      a = (a+1) AND 3
      NEXT
      d[4] = a
      a = 0
      GOTO 2
1     INC a
      IF a>4
      PAUSE 100
      ENDIF
2     v4 = d[a]
      v6 = BACKGROUND (w1+adx[v4],w2+ady[v4])
      IF v6<15 OR (v6=15 AND ((v4<>0) OR (RND AND 7))) GOTO 1
      v1 = adx[v4]/4
      v2 = ady[v4]/4
      ENDIF
      ENDIF
      w1 = w1+v1
      w2 = w2+v2

      x = MAX (MIN (w1-lay_x,72),-16)
      y = MAX (MIN (w2-lay_y,160),-64)
      part = (part AND 12)+((part+1) AND 3)


Executioner 09:48, 5 September 2006 (CEST)