1K Hires : Car race
Re: 1K Hires : Car race
Great game, and plays well too, fantastic for less than 1K job well done!
Re: 1K Hires : Car race
Source with a lot of comment about how the programs works.
Code: Select all
; Car Race
; a hires racing game for the ZX81 in 1K
; based on RACE for the Videopac
? * TORNADO *
ORG #4009
DUMP 49161
; untested, but v marked sysvar might be used in code
JP begin ; used for jump to program
d_file DEFW dfile ; x
dfcc DEFW dfile+1 ; x
var DEFW vars ; x
dest DEFW 0 ; x
eline DEFW last
chadd DEFW last-1
xptr DEFW 0
stkbot DEFW last ; x
stkend DEFW last ; x
berg DEFB 0 ; x
mem DEFW 0 ; v
DEFB 0 ; v, not used
dfsz DEFB 2 ; x
stop DEFW 1 ; v
lastk DEFB 255,255,255 ; x
margin DEFB 55 ; x
nxtlin DEFW basic ; v
oldppc DEFW 0 ; v
flagx DEFB 0 ; x
strlen DEFW 0 ; v
taddr DEFW 3213 ; v
seed DEFW 0 ; x
frames DEFW 65535 ; x
coords DEFB 0,0 ; v
prcc DEFB 188 ; v
sposn DEFB 33,24
cdflag DEFB 64
DEFB 0 ; the mask of the racecar
onoff DEFB 0,255,255,0,0
DEFB 0
c1 DEFB 096,1 ; computercars x and y pos
c2 DEFB 048,0
carudg DEFB 7,224 ; UDG of computercars
DEFB 111,246
DEFB 127,254
DEFB 111,246
DEFB 9,144
DEFB 107,214
DEFB 120,30
DEFB 103,230 ; 230 used as end marker
begin LD IX,hr
eog LD BC,5 ; end of game
LD HL,score-1 ; check on hiscore
LD DE,high-1
fhigh INC DE
INC HL
LD A,(DE)
CP (HL)
JR C,sethi
JR NZ,nohigh
DEC C
JR NZ,fhigh
nohigh DEFB 33 ; hide LDIR in LD HL,nnnn
sethi LDIR ; copy score to hiscore
wstart XOR A ; wait for startkey
IN A,(254)
CPL
AND 28
JR Z,wstart ; wait for startkey
LD HL,c1
SET 7,(HL) ; cars out of screen
INC HL
INC HL
SET 7,(HL)
LD HL,score ; reset score
LD BC,#51C
clsc LD (HL),C
INC HL
DJNZ clsc
INC HL
LD (HL),C ; reset time
makescr LD HL,hiresdata ; clear positions around
LD BC,#807 ; playercar
clcar LD DE,onoff ; the car mask
INC L ; skip pointer
INC L ; skip border
fend LD A,(DE) ; fetch mask
AND (HL) ; keep car
LD (HL),A ; set car
INC E ; next mask
INC L ; next pos in line
LD A,L
INC A
AND C ; AND C for speed only
JR NZ,fend ; handle full line
INC HL ; skip border right
DJNZ clcar ; handle all lines
LD BC,#1081 ; 16 lines and border
LD (maxval+1),A ; always ZERO from AND C
er1 LD (HL),A ; no line nr
INC L
LD (HL),C ; set border (needed once)
INC L
LD (HL),A ; erase full line
INC L
LD (HL),A
INC L
LD (HL),A
INC L
LD (HL),A
INC L
LD (HL),A
INC L
LD (HL),C ; set border
INC HL
DJNZ er1 ; now only playercar on screen
LD DE,c2 ; now set new computercars
LD HL,c1
LD A,(hiresdata)
INC A
CP (HL) ; car1 below car player
EX DE,HL
JR NC,okcall ; if not do display 1
CP (HL) ; car2 also below car player
EX DE,HL
JR NC,okcall ; if not do display 2
EX DE,HL
PUSH HL
LD HL,hiresdata+64
CALL place+6 ; special display for car1
DEFB 254 ; cp 225 = C, hide PUSH HL
okcall PUSH HL
CALL NC,place ; NC to skip entry above
POP DE
CALL place+6 ; second car after first car
LD A,%11101111 ; read keys 6 to 0
IN A,(254)
CPL
AND 3
JR Z,delay ; no key pressed
DEC A
JR Z,right ; right pressed
left CALL sleft ; move mask
JR C,uleft ; C = undo false move
CALL coltest ; shift ok, now test car
JR C,uleft-1 ; C = undo false move
LD DE,onoff+5
LD B,5
flst DEC DE
DEC B
LD A,(DE)
OR A
JR Z,flst ; find left start
LD HL,hiresdata+2
LD A,L
ADD A,B
LD L,A ; point to UDG
LD B,8 ; 8 lines
slloop PUSH DE ; save start of mask
PUSH HL ; save start of line
sllp2 RL (HL) ; move left
DEC L
DEC E
LD A,(DE)
INC A ; no OR A, carry status needed
DEC A
JR NZ,sllp2 ; all needed fields done?
sldone POP HL ; start of left back
LD DE,8
ADD HL,DE ; calc new line
POP DE ; mask back
DJNZ slloop ; handle all lines
JR delay ; car is moved left
right CALL sright ; move mask
JR C,uright ; C = undo false move
CALL coltest ; test collisin with car
JR C,uright-1 ; C = uno false move
LD B,255
LD DE,onoff-1
frst INC DE
INC B
LD A,(DE)
OR A
JR Z,frst ; find start right
LD HL,hiresdata+2
LD A,L
ADD A,B
LD L,A ; point to UDG
LD B,8 ; AS LEFT, but with move right
srloop PUSH DE
PUSH HL
srlp2 RR (HL)
INC L
INC E
LD A,(DE)
INC A ; no OR A, carry status needed
DEC A
JR NZ,srlp2
POP HL
LD DE,8
ADD HL,DE
POP DE
DJNZ srloop
JR delay
AND A ; reset carry from colltest
uleft CALL sright+1 ; undo maskmove
JR delay
AND A ; reset carry
uright CALL sleft+1 ; undo maskmove
delay LD HL,frames ; 1 frame delay to make
LD A,(HL) ; a stable screen
wait CP (HL)
JR Z,wait
ADD A,50
JR NC,notime ; test if a second has passed
LD (HL),A ; reset sec counter
LD HL,time+2
LD B,1
CALL points ; increase screencounter
LD D,B ; always 0
LD B,8
LD E,B ; DE=8, B=8
LD HL,hiresdata ; after a second increase
LD A,(HL) ; screenposition of player
upcar INC (HL)
ADD HL,DE
DJNZ upcar ; all lines of player done?
LD B,A ; fetch linepositon
SUB E ; not counting size of UDG
LD HL,score+4
CALL NZ,points ; add position as score
notime LD A,(time) ; test end of game (300 sec)
CP 31 ; "3"
JP Z,eog
LD HL,c1 ; when here, no collission so
DEC (HL) ; both cars are allowed to go
INC L ; down by 1 position
INC L
DEC (HL)
JR NZ,make1 ; second car not out of screen
LD HL,c1 ; car1 becomes car2
LD DE,c2
LDI
LD A,(HL)
LD (DE),A
EX DE,HL
rnd LD HL,0 ; calculate new RND as x-pos
INC HL
LD A,H
AND #1F
LD H,A
LD (rnd+1),HL
LD A,(HL)
AND 3
LD (DE),A ; new car1 x-pos
DEC DE
LD A,103
LD (DE),A ; linepos is just out screen
make1 JP makescr ; back to loop
coltest LD HL,c1-1
CALL ctest ; test car 1
RET C ; same place, not ok
ctest LD A,(hiresdata) ; car1 and car2 tested
INC HL
SUB (HL)
INC HL
LD C,A ; differenc to C
SBC A,A ; 255 or 0
XOR C ; A = ABS (C), absolute value
CP 8
RET NC ; >8 lines from player=no col
EX DE,HL ; c1/c2 x-pos to DE
LD HL,onoff
LD A,(DE) ; fetch X
ADD A,L
LD L,A ; point to mask player
LD A,(HL) ; fetch mask
INC HL
OR (HL) ; and test next also
EX DE,HL
RET Z ; not same place, NoCol
SCF ; we have collission
RET
change LD (HL),28 ; the score and timeroutine
DEC HL
DEFB 62 ; save a byte, no JR needed
points PUSH HL ; B at least 1 on entry!
INC (HL) ; start is saved for B>1
LD A,(HL)
CP 38 ; overflow?
JR Z,change ; go to next pos if so
POP HL ; fetch start
DJNZ points ; handle all points
RET
sleft AND A ; reset carry
LD HL,onoff+4
LD B,5
sl RL (HL) ; move mask left
DEC HL
DJNZ sl ; but only 5 positions
RET
sright AND A ; reset carry
LD HL,onoff
LD B,5
sr RR (HL) ; move mask right
INC HL
DJNZ sr ; but only 5 positions
RET
place LD HL,hiresdata-8 ; linedown corrects to start
fpos CALL linedown ; 1 line down (or up!)
LD A,(DE) ; y-pos of c1/c2
DEC A ; 1 pos down
CP (HL) ; find start of car
JR C,fpos
INC E ; point to x
LD B,A ; y pos
LD A,(DE)
LD C,A ; x pos
EXX
LD HL,onoff
ADD A,L
LD L,A ; point to x on line for col
EXX ; some extra reg needed
LD DE,carudg-1
nextset INC E ; carudg pos1 in line
LD (HL),B ; linenr to screen
LD A,B
CP 96
JR NC,nochange ; out of screen
maxval CP 0
JR C,nochange
LD (maxval+1),A ; find start for display
LD (stscreen+1),HL
nochange LD A,L
ADD A,2
ADD A,C
LD L,A ; no carry possible
LD A,(hiresdata)
CP B
JR NZ,nocol ; collision only on y player
EXX ; and back to first set
LD A,(HL) ; fetch old screen
INC L
OR (HL) ; test clear
DEC HL ; back to start for next
EXX
JR NZ,bump ; collision with player
nocol LD A,(DE) ; copy computer UDG to screem
LD (HL),A
INC L
INC E
LD A,(DE)
LD (HL),A
LD A,5
SUB C
CALL l2in ; test for screenwraparound
LD A,(DE)
SUB 230 ; end of carudg and A=0!
JR NZ,nextset
RET ; car is set
bump POP HL ; drop return
LD HL,c1
INC (HL) ; undo down
INC L
INC L
INC (HL) ; undo down
LD HL,hiresdata ; fetch player car
LD DE,8
LD B,E
LD A,(HL)
CP B
JR Z,downcret ; at bottom, no down possible
downcoll DEC (HL) ; car pushed down
ADD HL,DE
DJNZ downcoll
downcret JP makescr
linedown LD A,8 ; the screen has player UDG on
LD B,(HL) ; top in memory, but this is
l2in DEC B ; not always top of screen.
ADD A,L ; this calculates the move
LD L,A ; back to top when needed.
adddone LD A,(hiresdata)
CP B ; B =next line
RET NZ ; if not playerudg then end
LD HL,hiresdata ; otherwise back to top.
; RET ; exit through lbuf saves 1 byte
lbuf LD R,A
emptyline DEFB 129,0,0,0,0,0,129 ; 129 = ADD A,C no effect on code!
RET
hr1del JR $+2 ; some timingdelay
SBC HL,DE
JR hr11
hr LD B,14 ; sync first
hr00 DJNZ hr00
LD BC,#301 ; 3 lines on top in lowres
LD HL,dfile+#8000
LD A,#1E
LD I,A
LD A,#F5
CALL #2B5 ; lowres display
stscreen LD HL,hiresdata ; changes per screen!
LD B,96 ; 96 lines double shown
JR hr1
settop LD HL,hiresdata ; needed on wraparound
DEC B ; 1 to much, but
RET Z ; never ZERO! (timing)
hr1 LD C,2 ; line double displayed
hr11 LD A,(HL)
CP B
JP Z,linedisp ; show line or empytline
empty LD A,emptyline/256
LD I,A
LD A,emptyline*256/256
CALL lbuf+#8000
LD DE,0 ; no change in pointer
JP dline
linedisp INC HL ; skip pointer
LD A,H
LD I,A
LD A,L
CALL lbuf+#8000 ; show line
DEC HL ; timing
NOP ; timing
LD DE,8 ; adjust pointer
dline ADD HL,DE
cxlinenr LD A,(hiresdata) ; fetch player y-pos
DEC C
JR NZ,hr1del ; some delay and show twice
INC A
CP B ; next in line player?
JP Z,settop ; if so change to top
INC BC ; timing
DJNZ hr1 ; normal loop
PUSH HL ; end of screen, 2 bytes
POP HL ; still needed?
CALL #292
CALL #220
LD IX,hr
JP #2A4
DEFB 0,0 ; filler
basic DEFB 0,1 ; filler and basic call
DEFW lenbas-$
DEFB 249,212,28
DEFB 126
DEFB 143,0,18,0,0
lenbas DEFB 118,0
DEFB 118
dfile EQU lenbas ; the screen
score DEFB 28,28,28,29,37,0
time DEFB 28,28,28,0
high DEFB 28,28,28,36,29
DEFB 118
DEFB 0
; at #4308 never to next highbyte with 192 bytes of screen
hiresdata DEFB 8,129,0,7,224,0,0,129
DEFB 7,129,0,110,118,0,0,129
DEFB 6,129,0,120,30,0,0,129
DEFB 5,129,0,111,246,0,0,129
DEFB 4,129,0,9,144,0,0,129
DEFB 3,129,0,107,214,0,0,129
DEFB 2,129,0,120,30,0,0,129
DEFB 1,129,0,103,230,0,0,129
endcarpl DEFB 5,129,7,224,0,0,0,129
DEFB 4,129,110,118,0,0,0,129
DEFB 3,129,124,62,0,0,0,129
DEFB 2,129,104,22,0,0,0,129
DEFB 1,129,14,112,0,0,0,129
; rest of hiresdata is set by the program.
; therefore this part can be used by the ROM-loader as stack.
vars DEFB 128
last EQU $
Re: 1K Hires : Car race
Good score, I just got over it.Baggers wrote:16534
Re: 1K Hires : Car race
Found a restartbug, the playercar isn't set back on the bottom.
Re: 1K Hires : Car race
Dear Dr,
First of all: I really like to drive (and not only virtually) so this program is really close to me - nice work (as always), but ...
Yesterday I tested the latest version of my tape loader solution with your games in my real hardware environment and found some mistake. (see the attachment) For example the Car race: parts of the computer cars are hidden when they are near by player's car (in front) - i created some screenshot about this, too.
Regards,
Zsolt
First of all: I really like to drive (and not only virtually) so this program is really close to me - nice work (as always), but ...
Yesterday I tested the latest version of my tape loader solution with your games in my real hardware environment and found some mistake. (see the attachment) For example the Car race: parts of the computer cars are hidden when they are near by player's car (in front) - i created some screenshot about this, too.
Regards,
Zsolt
- Attachments
-
- 1KHR_drBeep.zip
- (632.18 KiB) Downloaded 339 times
ZX81 (8K), ENTERPRISE 128, [ZX SPECTRUM (48K,+,+128K,+2,+2A), TS1000, TS1500, TS2068, Cambridge Z88, PRIMO A64 (red)]
Re: 1K Hires : Car race
Some of them can be explained.zsolt wrote:Dear Dr,
First of all: I really like to drive (and not only virtually) so this program is really close to me - nice work (as always), but ...
Yesterday I tested the latest version of my tape loader solution with your games in my real hardware environment and found some mistake. (see the attachment) For example the Car race: parts of the computer cars are hidden when they are near by player's car (in front) - i created some screenshot about this, too.
Regards,
Zsolt
The screenintrupt is a fact before the entire car is drawn on my 'dummy' screen which is used for the actual draw. When the next intrupt appears after the drawing the screen will be correct. The player car is constantly on screen, the computercars are erased and redrawn each time. This is needed for the right screenorder of the cars and the limited space of the computer, the screenmemory must be defined in the right order of the cars which may vary.
The ball in PONG is the final ball which goes out of screen, the first line is redrawn and the test says out of screen. Then the code ends. This will NOT happen when their is no vertical move on the last ball. I found this minor to the gameplay and left it in.
The upper lowresdisplay might be from an older version, the latest version of PONG has a smaller hiresscreen to give the lowres some room to get in sync.
Also the 3d RANDOM MAZE has a later version with improved lowres display.
As for Ghost Hunt, I never got italic cross.
Re: 1K Hires : Car race
Zsolt pointed to the incorrect display in some cases.
I managed to speed the drawingroutine so the flicker is (almost) gone.
I managed to speed the drawingroutine so the flicker is (almost) gone.
- Attachments
-
- car.p
- (856 Bytes) Downloaded 755 times
Re: 1K Hires : Car race
zsolt wrote:Dear Dr,
First of all: I really like to drive (and not only virtually) so this program is really close to me - nice work (as always), but ...
Yesterday I tested the latest version of my tape loader solution with your games in my real hardware environment and found some mistake. (see the attachment) For example the Car race: parts of the computer cars are hidden when they are near by player's car (in front) - i created some screenshot about this, too.
Regards,
Zsolt
The screen of ghosthunt is kept as it is, the small reverse italic is kept since the score can be read
The same for 3d rnd maze.
Car Race is altered, other games are in end of game state (car race can have a similar effect)
So now again back to Outlaw!