Article View: net.micro.atari
Article #1587Re: Action! Programming (long, with game included)
From: Michael Jenkin
Date: Wed, 27 Nov 1985 16:42
Date: Wed, 27 Nov 1985 16:42
576 lines
13866 bytes
13866 bytes
>
>(Flame on)
>What is the advantage of Action! over BASIC, Pascal or C? Does it fit in one
>of these "families" of languages or is it a new one? Why we have such a
>proliferation of languages anyway? I'm still trying to learn AB,MBII and
>BXE/BXL, familiarizing myself with C, let along trying to learn Pascal and
>Action!
>(Flame off)
Action! is a compact, powerful, structured language. It can easily be
used to write sophisticated code taking advantage of specialized system
hardware. It compiles quickly, and can be used to generate stand-alone
applications.
Action! is available as a cartridge from O.S.S. The cartridge takes up
8K of user memory, but contains (I think) 24K worth of code inside.
It consists of three different programs
(1) a full screen editor.
(2) a compiler
(3) a run-time support package
In addition, O.S.S. offers a stand-alone run-time package (both for commercial
and private release), and a toolkit of useful packages. It is possible to
write very complicated programs in ACTION!. I have written both an 80
column software card in ACTION! as well as a number of graphics games.
In action it is possible to write dli, vbi, and interrupts attached to
other system timers. There are a number of bugs in the cartridge, but
they have been quite well documented in Analog magazine.
To give you an idea of the flavour and power of the machine, I have enclosed
a very simple game (the idea of which was stolen from an Analog game
which was published in 6502 code). You are a rabbit, and your job is to
pick up numbers that appear on the screen. In addition, you have a gun
which can be used to shoot the numbers (you don't get any points for them),
and to shoot at the walls which will close in on you. You will need a
joystick in port #1 to play the game.
About ACTION!. Spacing is up to you, the compiler doesn't care.
There are a number of tricks in the following code. The first CARD array is
allocated memory last, so the address of "last" will contain the
first usable memory location. This game builds its own screen and
allocates space for the display list, players, etc. Declarations
of the form
CARD x=$FFFF
declare x as a CARD (16 bit unsigned) allocated at memory location $FFFF,
while
CARD x=[$FFFF]
declares x as a CARD with initial value $FFFF. Note that routines can
be coded the same way (see SETVBV for example).
All declarations are static, and subroutines are not recursive. Code
blocks can be included (SAVETEMPS and GETTEMPS are code blocks) to allow
machine code to be included in-line. SAVETEMPS and GETTEMPS save the
ACTION! registers for interrupt routines.
;---------- cut here ------------
;*
;*
;* harvey.act - based on an Analog game
;* of the same name.
;* (c) 1985 Michael Jenkin
;*
;* compile with lower case on
;*
CARD ARRAY last(2)
BYTE ARRAY pm,misl,plr0,
plr1, plr2, plr3,dl,sline,rnum,
snum,disp,ctbl(3)=[$10 $50 $90],
vtbl(3),atbl(3),byloc(2),bxloc(2),
metro(2)=[38 41],winc(4),shotx(4),
shoty(4),sincx(4),sincy(4),
gomsg=['g 'a 'm 'e 0 0 'o 'v 'e
'r],psmsg=['p 'r 'e 's 's 0 0 's 't
'a 'r 't],RTCLOK(3)=$0012,
stblx(4)=[$01 $FF 0 0],
stbly(4)=[0 0 $01 $FF],
harlf1(12)=[0 0 $12 $0A $3C $74
$3C $1C $1E $3E $3F $7E],
harlf2(12)=[0 0 $0B $0A $3C $74
$3C $1C $1E $3E $3F $7E],
harrt1(12)=[0 0 $48 $50 $3C $2E
$3C $38 $78 $7C $FC $7E],
harrt2(12)=[0 0 $D0 $50 $3C $2E
$3C $38 $78 $7C $7C $EF],
harfr1(12)=[0 0 $42 $24 $3C $14
$3C $18 $3C $7E $7E $E7],
harfr2(12)=[0 0 $42 $24 $3C $28
$3C $18 $3C $7E $7E $E7],
hardn1(12)=[0 0 $44 $24 $3C $14
$3C $18 $3C $7E $FE $07],
hardn2(12)=[0 0 $22 $24 $3C $28
$3C $18 $3C $7E $7F $E0],
harup1(12)=[0 0 $44 $24 $3C $3C
$3C $18 $3C $66 $FE $07],
harup2(14)=[0 0 $22 $24 $3C $3C
$3C $18 $3C $66 $7F $E0 0 0],
mismsk(4)=[$03 $0C $30 $C0],
M0PF(4),HPOSM0(4)=$D004
BYTE lives,HPOSP2=$D002,HPOSP3=$D003,
harx, hary,SDMCTL=$022F,
GRACTL=$D01D,PMBASE=$D407,
COLOR2=$02C6,COLOR3=$02C7,
COLOR4=$02C8,PCOLR0=$02C0,
PCOLR1=$02C1,PCOLR2=$02C2,
PCOLR3=$02C3,strigf,tim2st,
tictoc,AUDF1=$D200,vol1,
HITCLR=$D01E,diesw,vol2,
IRQEN=$D20E,GPRIOR=$026F,
CONSOL=$D01F,VCOUNT=$D40B,
WSYNC=$D40A,COLBK=$D01A,
RANDOM=$D20A,AUDC1=$D201,
AUDC2=$D203,AUDC4=$D207,
AUDC3=$D205,poplt,popft,
P0PF=$D004,POPL=$D00C,
nsound,freq3,AUDF3=$D204,
AUDF2=$D202,ATRACT=$004D,
xtemp,ytemp,STICK0=$0278,
STRIG0=$0284,HPOSP0=$D000
CARD CDTMV1=$0218,CDTMV2=$021A,
CDTMA1=$0226,CDTMA2=$0228
CARD ARRAY pk1(11),pk2(11)
DEFINE
SAVETEMPS="[$A2 7 $B5 $A8 $48 $CA $10 $FA]",
GETTEMPS="[$A2 0 $68 $95 $A8 $E8
$E0 8 $D0 $F8]",
XITVBV="[$4C $E462]"
PROC SETVBV=$E45C(BYTE areg,xreg,yreg)
PROC DLinit()
CARD sdlist=$0230
BYTE i
BYTE POINTER k
pm = (last + $0FFF) & $F000
misl = pm + $180
plr0 = misl + $80
plr1 = plr0 + $80
plr2 = plr1 + $80
plr3 = plr2 + $80
dl = plr3 + $80
sline = dl + 24
rnum = sline + 8
snum = rnum + 8
disp = snum + 4
FOR i = 0 TO 3 DO
dl(i) = $70
OD
dl(4) = $47
dl(5) = disp & $FF
dl(6) = disp RSH 8
FOR i = 7 TO 15 DO
dl(i) = $07
OD
dl(16) = $70
dl(17) = $70
dl(18) = $46
dl(19) = sline & $FF
dl(20) = sline RSH 8
dl(21) = $41
dl(22) = dl & $FF
dl(23) = dl RSH 8
SDLIST = dl
k = "RABBITS:3 SCORE:0000"
FOR i = 0 TO 19 DO
k ==+ 1
sline(i) = k^ + $A0
OD
Zero(disp,200)
RETURN
PROC pkinit()
pk1(0) = harrt1
pk1(1) = harrt1
pk1(2) = harrt1
pk1(3) = 0
pk1(4) = harlf1
pk1(5) = harlf1
pk1(6) = harlf1
pk1(7) = 0
pk1(8) = hardn1
pk1(9) = harup1
pk1(10)= harfr1
pk2(3) = 0
pk2(0) = harrt2
pk2(1) = harrt2
pk2(2) = harrt2
pk2(3) = 0
pk2(4) = harlf2
pk2(5) = harlf2
pk2(6) = harlf2
pk2(7) = 0
pk2(8) = hardn2
pk2(9) = harup2
pk2(10)= harfr2
RETURN
PROC Putnum(BYTE n)
BYTE x, y, RANDOM=$D20A
DO
x = RANDOM
IF x < 200 AND disp(x) = 0 THEN
EXIT
FI
OD
DO
y = RANDOM & $0F
IF y < 10 THEN
EXIT
FI
OD
disp(x) = y % ctbl(n)
atbl(n) = x
vtbl(n) = y
RETURN
PROC Eranum(BYTE n)
BYTE x
x = atbl(n)
disp(x) = 0
RETURN
PROC vbgmovr()
BYTE n
BYTE POINTER j
AUDC1 = 0
AUDC2 = 0
AUDC3 = 0
AUDC4 = 0
CDTMV1 = 0
CDTMV2 = 0
j = gomsg
FOR n = 0 TO 9 DO
disp(85+n) = j^
j ==+ 1
OD
j = psmsg
FOR n = 0 TO 11 DO
disp(144+n) = j^
j ==+ 1
OD
RETURN
PROC vbwalls()
IF winc(0) <> 0 THEN
winc(0) ==- 1
IF byloc(0) > 30 THEN
byloc(0) ==- 1
FI
FI
IF winc(1) <> 0 THEN
winc(1) ==- 1
IF byloc(1) <= 204 THEN
byloc(1) ==+ 1
FI
FI
IF winc(2) <> 0 THEN
winc(2) ==- 1
HPOSP2 = bxloc(0)
IF bxloc(0) > 39 THEN
bxloc(0) ==- 1
FI
FI
IF winc(3) <> 0 THEN
winc(3) ==- 1
HPOSP3 = bxloc(1)
IF bxloc(1) < 208 THEN
bxloc(1) ==+ 1
FI
FI
RETURN
PROC vbplayer()
BYTE d,x
CARD pic
xtemp = 0
ytemp = 0
IF STICK0 <> $0F AND
(RTCLOK(2) & $07) <> 0 THEN
AUDF2 = $10
VOL2 = $04
FI
d = STICK0 - 5
IF (RTCLOK(2) RSH 3 & 1) = 1 THEN
pic = pk1(d)
ELSE
pic = pk2(d)
FI
d = STICK0
FOR x = 0 TO 3 DO
IF (d & 1) = 0 THEN
xtemp = stblx(3-x)
ytemp = stbly(3-x)
FI
d = d RSH 1
OD
IF POPLT = $0C THEN
rnum(0) ==- 1
lives ==- 1
diesw ==+ 1
FI
IF (POPLT & $04) <> 0 THEN
harx ==+ 1
xtemp = 0
FI
IF (POPLT & $08) <> 0 THEN
harx ==- 1
xtemp = 0
FI
IF (byloc(0) + 2) RSH 1 = hary THEN
rnum(0) ==- 1
lives ==- 1
diesw ==+ 1
FI
IF (hary + 10) * 2 = byloc(1) THEN
rnum(0) ==- 1
lives ==- 1
diesw ==+ 1
FI
harx ==+ xtemp
HPOSP0 = harx
hary ==+ ytemp
MoveBlock(plr0+hary,pic,14)
RETURN
PROC vbgun()
BYTE t,x,n,shots=[0]
t = strigf
strigf = STRIG0
IF strigf = 0 AND
(xtemp % ytemp) <> 0 THEN
FREQ3 = $40
AUDC3 = $04
shots ==+ 1
x = shots & 3
sincx(x) = xtemp * 2
sincy(x) = ytemp * 2
shotx(x) = harx + 3
shoty(x) = hary + 8
FI
Zero(misl,$80)
FOR x = 0 TO 3 DO
IF (sincx(x) % sincy(x)) <> 0 THEN
shoty(x) ==+ sincy(x)
IF shoty(x)*2+2 >= byloc(1) THEN
sincx(x) = 0
sincy(x) = 0
winc(1) ==+ 8
FI
IF shoty(x)*2-10 <= byloc(0) THEN
sincx(x) = 0
sincy(x) = 0
winc(0) ==+ 8
FI
t = shoty(x)
misl(t) ==% mismsk(x)
misl(t+1) ==% mismsk(x)
t = M0PF(x)
n = 0
DO
IF (t&1) = 1 THEN
eranum(n)
putnum(n)
EXIT
FI
t = t RSH 1
N ==+ 1
IF N = 4 THEN
EXIT
FI
OD
shotx(x) ==+ sincx(x)
HPOSM0(x) = shotx(x)
IF shotx(x) >= bxloc(1) THEN
sincx(x) = 0
sincy(x) = 0
winc(3) ==+ 8
FI
IF shotx(x)-6 <= bxloc(0) THEN
sincx(x) = 0
sincy(x) = 0
winc(2) ==+ 8
FI
FI
OD
t = 0
FOR x = 0 TO 3 DO
t ==% sincx(x) % sincy(x)
OD
IF t = 0 THEN
AUDC3 = 0
FI
FOR t = 0 TO 2 DO
IF P0PF RSH 1 = 1 THEN
eranum(t)
x = vtbl(t)
putnum(t)
n = 3
snum(n) ==+ x
DO
IF snum(n) > '9 +$A0 THEN
snum(n) = '0 +$A0
IF n = 0 THEN
EXIT
ELSE
n ==- 1
FI
ELSE
EXIT
FI
OD
FI
OD
RETURN
PROC vb()
BYTE n
SAVETEMPS
IF diesw <> 0 AND lives = 0 THEN
vbgmovr()
GETTEMPS
XITVBV
FI
poplt = POPL
popft = P0PF
IF nsound > 0 THEN
nsound ==- 1
AUDC4 = (nsound RSH 1) % $A0
FI
IF vol1 > 0 THEN
vol1 ==- 1
AUDC1 = vol1 % $C0
FI
IF vol2 > 0 THEN
vol2 ==- 1
AUDC2 = vol2 % $80
FI
freq3 = freq3 * 4
AUDF3 = freq3
IF diesw <> 0 THEN
diesw ==+ 1
PCOLR0 ==+ 2
AUDF2 = PCOLR0 * 8
AUDC2 = $88
GETTEMPS
XITVBV
FI
vbwalls()
ATRACT = 0
vbplayer()
vbgun()
HITCLR = 0
GETTEMPS
XITVBV
PROC t1()
SAVETEMPS
IF tim2st <> 2 THEN
tim2st ==- 1
FI
CDTMV1 = 256
rnum(0) = vtbl(0) + $A0
GETTEMPS
RETURN
PROC t2()
SAVETEMPS
CDTMV2 = tim2st
byloc(0) ==+ 1
byloc(1) ==- 1
bxloc(0) ==+ 1
HPOSP2 = bxloc(0)
bxloc(1) ==- 1
HPOSP3 = bxloc(1)
tictoc ==! 1
AUDF1 = metro(tictoc)
vol1 = $08
GETTEMPS
RETURN
PROC init()
BYTE i, GPRIOR = $026F
rnum(0) = '3+$A0
lives = 3
FOR i = 0 TO 3 DO
snum(i) = '0+$A0
OD
FOR i = 0 TO 2 DO
putnum(i)
OD
Zero(disp,200)
RETURN
PROC play()
BYTE i
GPRIOR = $04
byloc(0) = 40
byloc(1) = 196
bxloc(0) = 60
bxloc(1) = 184
HPOSP2 = 60
HPOSP3 = 184
harx = 122
hary = 55
SDMCTL = $2E
GRACTL = 3
PMBASE = pm RSH 8
COLOR2 = $96
COLOR3 = $48
PCOLR0 = $18
PCOLR1 = $98
PCOLR2 = $34
PCOLR3 = $C4
strigf = 1
SETVBV(7,VB RSH 8, VB & $FF)
CDTMA1 = t1
CDTMA2 = t2
CDTMV1 = 256
HITCLR = 0
diesw = 0
tictoc = 0
vol1 = 0
vol2 = 0
IRQEN = 0
FOR i = 0 TO 2 DO
winc(i) = 0
shotx(i) = 0
shoty(i) = 0
sincx(i) = 0
sincy(i) = 0
OD
Zero(plr0,$80)
Zero(plr1,$80)
SetBlock(plr2,$0080,$FF)
SetBlock(plr3,$0080,$FF)
RETURN
PROC MAIN()
BYTE i=[0],a,b,n
BYTE ARRAY grp2(4)=$D00F
pkinit()
DLINIT()
init()
play()
DO
i = (i + 1) & 1
a = byloc(i) RSH 1
b = byloc(i) & 1
WHILE VCOUNT <> a DO OD
IF b = 1 THEN
WSYNC = 1
FI
COLBK = RANDOM & $F6
FOR n = 0 TO 9 DO
grp2(i) = 0
WSYNC = 1
COLBK = RANDOM & $F6
OD
COLBK = COLOR4
IF (consol & 1) = 0 THEN
DLINIT()
init()
play()
ELSEIF lives <> 0 AND diesw <> 0 THEN
play()
FI
OD
RETURN
--
--
Michael Jenkin University of Toronto
USENET: {decvax,ihnp4,allegra}!utcsri!utai!jenkin
CSNET: jenkin@Toronto
BELL: 416-978-7321
Technical Details
Message-ID:
<982@utai.UUCP>Path:
arc1-ca.pugleaf.net!utzoo!utcsri!utai!jenkinReferences:
<633@tekigm.UUCP>Show Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/18/84; site utai.UUCP Path: arc1-ca.pugleaf.net!utzoo!utcsri!utai!jenkin From: jenkin@utai.UUCP (Michael Jenkin) Newsgroups: net.micro.atari Subject: Re: Action! Programming (long, with game included) Message-ID: <982@utai.UUCP> Date: Wed, 27-Nov-85 11:42:10 EST Article-I.D.: utai.982 Posted: Wed Nov 27 11:42:10 1985 Date-Received: Wed, 27-Nov-85 17:05:53 EST References: <633@tekigm.UUCP> Reply-To: jenkin@utai.UUCP (Michael Jenkin) Distribution: net Organization: CSRI, University of Toronto Lines: 576