I am working on Frenzy again, but I'm stuck at the moment. Here's my situation:
My DL:
DLISTS
.byte <(SCREEN),$60,>(SCREEN),$00+$00,#LEFTSIDE;SCREEN - PLAY FIELD
.byte $00,$40,>(STAMPS),$20+$1F,OFFSCRN ;PLAYER 1
.byte $00,$40,>(STAMPS),$40+$1F,OFFSCRN ;PLAYER 2
.byte $00,$40,>(STAMPS),$20+$1F,OFFSCRN ;PLAYER SHOT 1
.byte $00,$40,>(STAMPS),$40+$1F,OFFSCRN ;PLAYER SHOT 2
.byte $00,$40,>(STAMPS),$60+$1F,OFFSCRN ;ROBOT SHOT 1 / BIG OTTO 1
.byte $00,$40,>(STAMPS),$60+$1F,OFFSCRN ;ROBOT SHOT 2 / BIG OTTO 2
.byte $00,$40,>(STAMPS),$60+$1F,OFFSCRN ;ROBOT SHOT 3 / BIG OTTO 3
.byte $00,$40,>(STAMPS),$60+$1F,OFFSCRN ;ROBOT SHOT 4 / BIG OTTO 4
.byte $00,$40,>(STAMPS),$60+$1F,OFFSCRN ;ROBOT SHOT 5
.byte $00,$40,>(STAMPS),$60+$1F,OFFSCRN ;EVIL OTTO
.byte $00,$40,>(STAMPS),$60+$1F,OFFSCRN ;ROBOT 1
.byte $00,$40,>(STAMPS),$60+$1F,OFFSCRN ;ROBOT 2
.byte $00,$40,>(STAMPS),$60+$1F,OFFSCRN ;ROBOT 3
.byte $00,$40,>(STAMPS),$60+$1F,OFFSCRN ;ROBOT 4
.byte $00,$40,>(STAMPS),$60+$1F,OFFSCRN ;ROBOT 5
.byte $00,$40,>(STAMPS),$60+$1F,OFFSCRN ;ROBOT 6
.byte $00,$00,$00,$00,$00
The above DL in 320A mode uses 410 Maria cycles, I know that thanks to GroovyBee's utility.
The 6 robots at the end are shared for each zone with up to 22 robots (that's how many you can have with Frenzy). My logic only allows 6 robots to be in a zone at one time. They won't move into the zone otherwise.
My 'list of objects in memory' is set for 38 objects (the 16 in the DL above, + the 22 actual robots on the screen). I only move one robot per frame, as the arcade games does. As you may guess, the robot I'm working on gets checked for his DL 'slot' (0-5) and moved to the Display List above to get put on the screen.
Here's my object list, and what each variable is for:
; OBJECT VARIABLES HPLIST DS 40 ;40 BYTES - HORIZONTAL POSITION HCLIST DS 40 ;40 BYTES - HORIZONTAL COLUMN VPLIST DS 40 ;40 BYTES - VERTICAL POSITION VZLIST DS 40 ;40 BYTES - VERTICAL ZONE MXLIST DS 40 ;40 BYTES - MOVEMENT IN X DIRECTION MYLIST DS 40 ;40 BYTES - MOVEMENT IN Y DIRECTION ANLIST DS 40 ;40 BYTES - OBJECT ANIMATION OFFSET SLLIST DS 40 ;40 BYTES - LOW BYTE STAMP ADDRESS DOLIST DS 40 ;40 BYTES - SOMETHING CHANGED - RELOAD OTLIST DS 40 ;40 BYTES - OBJECT TYPE LIST ($00=PLAYER, $01=SKELETON, $02=EYEBALL...) OZLIST DS 40 ;40 BYTES - OLD ZONE FROM LAST FRAME ODLIST DS 40 ;40 BYTES - OBJECT DIRECTION OWLIST DS 40 ;40 BYTES - OBJECT WAIT FRAMES BEFORE NEXT MOVE OFLIST DS 40 ;40 BYTES - OBJECT NEXT FRAME TO MOVE OMLIST DS 40 ;40 BYTES - OBJECT IS MOVING (1=YES, 0=NO) OSLIST DS 40 ;40 BYTES - OBJECT SLOT IN DL (ONLY 6 ROBOTS PER ZONE) OTOPLS DS 40 ;40 BYTES - OBJECT TOP BITMAP EDGE OBOTLS DS 40 ;40 BYTES - OBJECT BOTTOM BITMAP EDGE OLFTLS DS 40 ;40 BYTES - OBJECT LEFT BITMAP EDGE ORHTLS DS 40 ;40 BYTES - OBJECT RIGHT BITMAP EDGE PDLIST DS 40 ;40 BYTES - PRIOR DIRECTION OF OBJECT
'Direction' mentioned in the above list, is as folows:
; 6 ; 5 | 7 ; \ | / ; 4---+---0 ; / | \ ; 3 | 1 ; 2 ;
'Object Type' is this:
; OBJECT DEFINITIONS HUMANOID = $00 ;PLAYER SKELETON = $01 ;ROBOT TYPE 1 (SKELETON) EYEBALL = $02 ;ROBOT TYPE 2 (EYEBALL) ROBOT = $03 ;ROBOT TYPE 3 (BERZERK ROBOT) PVSHOT = $04 ;PLAYER VERTICAL SHOT PDSHOT = $05 ;PLAYER DIAGONAL SHOT PHSHOT = $06 ;PLAYER HORIZONTAL SHOT RVSHOT = $07 ;ROBOT VERTICAL SHOT RDSHOT = $08 ;ROBOT DIAGONAL SHOT RHSHOT = $09 ;ROBOT HORIZONTAL SHOT OTTOKILL = $0A ;'KILLABLE' OTTO (FRENZY) OTTOINVN = $0B ;'INVINCABLE' OTTO (BERZERK) OTTOBORN = $0C ;OTTO BEING BORN OTTODETH = $0D ;OTTO DYING ROBOTDTH = $0E ;ROBOT DEATH SEQUENCE PLAYRDTH = $0F ;PLAYER DEATH SEQUENCE DISABLED = $FF
This part works well.
The issue arises when I implement collision detection. being that whenever an object moves (which is every frame except in the robot's case) I run out of CPU time. This is because I have to check each object that moves, with the other 30 (22 robots, 1 player, 7 shots, and evil otto)
So that means traversing the list at least 10 times *per frame*. I'm trying to make my collision detection routine as tight as possible, but it doesn't seem to help. I get robots that don't move every frame, and some erratic behavior, like the player running into walls where he didn't before the Collision Detection was implemented (I've attached a bin below).
Here's my collision detection routine: (be nice!)
DOOBJECTCOL
STX TEMP3
LDY #$00
DOCLOOP
CPY TEMP3
BEQ DOCNEXT
LDA OTLIST,Y ;SEE IF OBJECT IS ACTIVE
BMI DOCNEXT
JSR OBJECTCOLL
BEQ DOCNEXT
; BERZERK WOULD KILL BOTH OBJECTS
BMI DOCYDIR
DOCXDIR
LDA #$00
STA MXLIST,X
BEQ DOCNEXT
DOCYDIR
LDA #$00
STA MYLIST,X
DOCNEXT
INY
CPY #ALLOBJECT
BMI DOCLOOP
DOCEXIT
RTS
; OBJECTCOLL - THIS ROUTINE CHECKS FOR A COLLISION BETWEEN A MOVING OBJECT AND ANOTHER OBJECT,
; IDENTIFIED BY X AND Y
; OBJECTIVE: ADD TOGETHER POSITION OF MOVING OBJECT AND VELOCITY, CHECK FOR COLLISION WITH OTHER OBJECT
; IF THERE IS ONE, CHECK THE HORIZONTAL DIRECTION WITHOUT THE VELOCITY ADDED IN.
; IF THERE IS STILL A COLLISION, WE KNOW THAT THE VERTICAL DIRECTION IS WHAT CAUSED THE COLLISION THIS FRAME
; IF NOT, WE KNOW THAT IT WAS THE HORIZONTAL ONE. RETURN THE DIRECTION THAT CAUSED THE COLLISION
; AS FOLLOWS: POSITIVE ($01) FOR X DIRECTION, NEGATIVE ($FF) FOR Y DIRECTION, ZERO ($00) FOR NO COLLISION.
; INPUT: X - MOVING OBJECT, Y - OTHER OBJECT !!!ASSUMES BOTH OBJECTS ARE VALID TYPES AND NOT EQUAL!!!
; OUTPUT: A = THE COLLISION INFORMATION: $01 = X DIRECTION, $FF = Y DIRECTION, $00 = NO COLLISION
; USES: A, TEMP0-2
OBJECTCOLL
LDA MXLIST,X ;TAKE HORIZONTAL VELOCITY
CLC
ADC HPLIST,X ;ADD IT TO OUR CURRENT HORIZONTAL POSITION
STA TEMP0 ;STORE IT
LDA MYLIST,X ;TAKE VERTICAL VELOCITY
CLC
ADC VPLIST,X ;ADD IT TO OUT CURRENT VERTICAL POSITION
STA TEMP1 ;STORE IT
LDA VPLIST,X ;FIND OUT WHICH SPRITE IS BELOW THE OTHER TO GET CORRECT HEIGHT
CMP VPLIST,Y ;IS THE VERTICAL POSITION OF THE OBJECT LESS THAN THE OTHER OBJECT?
BMI OOXISLESS ;YES, USE THE HEIGHT OF THE OBJECT FOR THE COMPARISON
OOYISLESS
LDA OBOTLS,Y ;GET THE HEIGHT OF THE LOWER (IN VALUE) SPRITE
SEC
SBC OTOPLS,Y
JMP OOSTART ;START THE COLLISION DETECTION
OOXISLESS
LDA OBOTLS,X ;GET THE HEIGHT OF THE LOWER (IN VALUE) SPRITE
SEC
SBC OTOPLS,X
OOSTART
STA TEMP2
INC TEMP2 ;ADD 2 TO GET THE HEIGHT RIGHT
INC TEMP2
OOXCOMP
LDA TEMP0 ;TAKE OUR 'NEW' OBJECT POSITION
SEC
SBC HPLIST,Y ;SUBTRACT OTHER OBJECT POSITION TO GET HORIZONTAL DIFFERENCE
BPL OOXCHECK
EOR #$FF ;USE ABSOLUTE VALUE
CLC
ADC #$01
OOXCHECK
CMP #$04 ;LESS THAN 4 HORIZONTAL PIXELS DIFFERENCE?
BCS OOEXIT ;NOPE, NO COLLISION
OOYCOMP
LDA TEMP1 ;POSSIBLY, CHECK FOR Y DIRECTION NOW
SEC
SBC VPLIST,Y ;SUBTRACT OTHER OBJECT POSITION TO GET VERTICAL DIFFERENCE
BPL OOYCHECK ;USE ABSOLUTE VALUE
EOR #$FF
CLC
ADC #$01
OOYCHECK
CMP TEMP2 ;LESS THAN (SPRITE HEIGHT) VERTICAL PIXELS DIFFERENCE?
;BCS OOEXIT ;NOPE, NO COLLISION
BCC OOCOLL ;YES, THERE WAS A COLLISION!
OOEXIT
LDA #$00
RTS
OOCOLL
LDA HPLIST,X ;GET HORIZONTAL POSITION -WITHOUT- MOVEMENT ADDED IN
SEC
SBC HPLIST,Y ;SUBTRACT OTHER OBJECT POSITION
BPL OOXCHECK2
EOR #$FF ;USE ABSOLUTE VALUE
CLC
ADC #$01
OOXCHECK2
CMP #$04 ;LESS THAN 4 HORIZONTAL PIXELS DIFFERENCE?
BCC OOYCOLL ;STILL HAVE A HORIZONTAL COLLISION, WHICH MEANS VERTICAL HAPPENED THIS FRAME
OONOXCOLL
LDA #$01 ;YES, THERE WAS A HORIZONTAL COLLISION THIS FRAME
RTS
OOYCOLL
LDA VPLIST,X ;GET VERTICAL POSITION -WITHOUT- MOVEMENT ADDED IN
SEC
SBC VPLIST,Y ;SUBTRACT OTHER OBJECT POSITION
BPL OOYCHECK2
EOR #$FF ;USE ABSOLUTE VALUE
CLC
ADC #$01
OOYCHECK2
CMP TEMP2 ;LESS THAN (SPRITE HEIGHT) VERTICAL PIXELS DIFFERENCE?
BCC OOBOTHCOLL ;STILL HAVE A VERTICAL COLLISION, WHICH MEANS STOP MOVING ALLTOGETHER
OONOYCOLL
LDA #$FF ;YES, THERE WAS A VERTICAL COLLISION THIS FRAME
RTS
OOBOTHCOLL
LDA #$02 ;WE MAY USE THIS OR NOT...
RTS
Any ideas anyone? Maybe a quick and dirty software collision detection routine that I can use here?
Thanks for your help, guys.
Bob














