Jump to content
IGNORED

Turning Adventure into an 8k game...


Nukey Shay

Recommended Posts

My apologies, again.

Small mistakes can really add up, plus I should have understood why every object was acting up.

 

I had accidentally miscounted two bytes when adjusting the RAM locations for the objects. That would explain only one of the portcullises working right, it would explain why the magnet would attract itself (because it's "new" address was in the matrix already). It still doesn't explain why the objects' coordinate locations were screwed up...

 

But all that's fixed now, and I'm happy.

I will soon have a release candidate available for download after I arrange the items for game 1 and 2. Thanks for puttin up with me, Nukey. I've always been one to jump before I look. People used to tell me that was good, but when it comes to this coding and hacking stuff (and not having an edit button :roll: ), you have to watch where you step.

 

Thanks.

Link to comment
Share on other sites

Heh...I was offline for a while and didn't even read it. But you are correct that BDragonR is only set to use 3 bytes of ram (when it should have been 5). A way to avoid having to do these variables "by hand" would be to use an ORG tag...where the bytes and tables will be filled in with the proper addresses as the assembler works it's way down the list...

 

    ORG     $80



RoomLo        =  .byte

RoomHi        =  .byte

Obj1Lo        =  .byte

Obj1Hi        =  .byte

Obj2Lo        =  .byte

Obj2Hi        =  .byte

Obj1X         =  .byte

Obj1Y         =  .byte

Obj2X         =  .byte

Obj2Y         =  .byte

PlayerRoom    =  .byte

PlayerX       =  .byte

PlayerY       =  .byte

PlayerYadj    =  .byte

ScanLineCnt   =  .byte

RoomDefIndex  =  .byte

Player0Def    =  .byte

Player1Def    =  .byte

Debounce      =  .byte

CurrentObject =  ds 5

Jstick        =  .byte

CurrentStick  =  .byte

ObjAddress    =  .byte

ObjDir        =  .byte

LastObj       =  .byte

CarriedObj    =  .byte

CarriedX      =  .byte

CarriedY      =  .byte

HiCnt         =  .byte

ObjLst        =  ds 2

Delta2        =  .byte

Delta1        =  .byte

ObjCr         =  .byte

State         =  .byte

Level         =  .byte

Control       =  .byte

NoteCnt       =  .byte

Sound         =  .byte

Index         =  .byte

PrevRoom      =  .byte

PrevX         =  .byte

PrevY         =  .byte

LoCnt         =  .byte

ObjectNumber  =  .byte




;object variables...

SurroundR     =  ds 3

DotR          =  ds 3


;all dragons must be consecutive

RDragonR      =  ds 5

YDragonR      =  ds 5

GDragonR      =  ds 5

BDragonR      =  ds 5



MagnetR       =  ds 3

SwordR        =  ds 3

ChaliseR      =  ds 3

BridgeR       =  ds 3


;all keys must be consecutive

YKeyR         =  ds 3

WKeyR         =  ds 3

BKeyR         =  ds 3


;all gates must be consecutive

YGateR        =  .byte

WGateR        =  .byte

BGateR        =  .byte



BatR          =  ds 7

 

Personally, I don't use that method because I like to see exactly how many bytes I have available...but using it will allow the assembly to correct the ram assignments automatically as long as everything is still placed in the proper order...and the correct number of bytes to use is indicated (.byte for one, ds # for more).

Link to comment
Share on other sites

BTW be sure to play game 3 a bunch of times after moving the objects (to check if the game is still winnable). You might have to adjust the object boundry table...and you'll definately have to change the boundries if you want objects to be able to appear randomly in added rooms.

Link to comment
Share on other sites

BTW be sure to play game 3 a bunch of times after moving the objects (to check if the game is still winnable).  You might have to adjust the object boundry table...and you'll definately have to change the boundries if you want objects to be able to appear randomly in added rooms.

 

I redid the entire room bounds table, both games object location tables, and also redid the room data table from scratch. I kept everything in mind when assigning objects to rooms. The first two rooms after the number room are the only rooms where the chalice can appear, and the second to the last room which is not even on game 3, will never be assigned an object.

 

:)

 

I do have some other interesting ideas for tutorials, if you are interested yourself that is. I know these couple following features would not be very difficult to implement, but they would influence the way the game works tremendously.

 

-The ability to have seperate starting screens for each difficulty.

-The abillity to have different winning screens for each difficulty.

-The ability to have seperate speeds and attack rates for each dragon per difficulty.

-The ability to add or remove difficulty levels (perhaps the hardest of these).

 

Notice how they all relate to difficulty levels. I probably wouldn't even use any of these, however, they could be useful to anyone else wanting to hack Adventure.

Link to comment
Share on other sites

Easy...most of them can be done simply by grabbing the level number, dividing it by 2 (because levels 1,2,3 are stored as values 0,2,and 4)...then using that value in a new table that holds the differing variables for that particular level. For example, here's how you'd deal with different winning screens...

 

Original...

       LDA    ChaliseR           ;Get the room the Chalise is in.              ;3

      CMP    #WinRoom           ;Is it in the yellow castle?                  ;2

      BNE    MainGameLoop_2     ;If Not Branch..                              ;2

 

 

 

 

Instead of loading the room number for the chalise and then comparing it to the static value of what it needs to be (to win the game)...you'd do the second part first. Figure out which room is the winning screen...and then compare it to the chalise's room...

 

Edited...

       LDA    Level              ;Load the current level number                ;3

      LSR                       ;Divide it by two                             ;2

      TAY                       ;Give it to an unused register (Y in this case);2

      LDA    WinRooms,Y         ;Load the "win" screen number for this level  ;4

      CMP    ChaliseR           ;Compare to the chalise's room                ;2

      BNE    MainGameLoop_2     ;Branch if not the same                       ;2

 

 

Now you'd need a table that holds the 3 room numbers...

 

 

WinRooms:

      .byte $12,$1A,$1B ;the winning screens (inside the yellow, white, and black castles)

 

 

And the game will now let you win as soon as you set into the yellow, white, or black castles (for games 1, 2, and 3 respectively).

Link to comment
Share on other sites

Adding a game timer:

 

 

There have been requests for this one in the past...so I'll do it quick 'n' dirty (i.e. memory-wasting). This mod requires over a page of romspace to use written this way...so you'd probably need to use the 8k assembly to add it in. It also wastes 2 bytes of Ram memory to hold the minutes and seconds.

 

 

First, assign ram memory to the two bytes. I just used $F7 and $F8 ($F9 and $FA are kinda iffy...so I didn't bother with those).

TimerLo       =  $F7

TimerHi       =  $F8

 

 

Now you'll need to add in GFX to hold the digits. In this example, playfield GFX are being used to draw the numbers...so it needs digits that are normal and digits that are reversed. In addition, the digits are stored in the bitmap data twice (so you can just AND off the part not needed for a specific digit). Each digit is 8 bytes in length...and I began each one with $FF (so that the last value grabbed will draw a border underneath the digits).

 

The 2 tables...

TimerDigits:

      .byte $FF

      .byte $00

      .byte $77; | XXX XXX| $F100

      .byte $55; | X X X X| $F101

      .byte $55; | X X X X| $F102

      .byte $55; | X X X X| $F103

      .byte $77; | XXX XXX| $F104

      .byte $00



      .byte $FF

      .byte $00

      .byte $22; |  X   X | $F105

      .byte $22; |  X   X | $F106

      .byte $22; |  X   X | $F107

      .byte $22; |  X   X | $F108

      .byte $22; |  X   X | $F109

      .byte $00



      .byte $FF

      .byte $00

      .byte $77; | XXX XXX| $F10A

      .byte $44; | X   X  | $F10B

      .byte $77; | XXX XXX| $F10C

      .byte $11; |   X   X| $F10D

      .byte $77; | XXX XXX| $F10E

      .byte $00



      .byte $FF

      .byte $00

      .byte $77; | XXX XXX| $F10F

      .byte $11; |   X   X| $F110

      .byte $33; |  XX  XX| $F111

      .byte $11; |   X   X| $F112

      .byte $77; | XXX XXX| $F113

      .byte $00



      .byte $FF

      .byte $00

      .byte $11; |   X   X| $F114

      .byte $11; |   X   X| $F115

      .byte $77; | XXX XXX| $F116

      .byte $55; | X X X X| $F117

      .byte $55; | X X X X| $F118

      .byte $00



      .byte $FF

      .byte $00

      .byte $77; | XXX XXX| $F119

      .byte $11; |   X   X| $F11A

      .byte $77; | XXX XXX| $F11B

      .byte $44; | X   X  | $F11C

      .byte $77; | XXX XXX| $F11D

      .byte $00



      .byte $FF

      .byte $00

      .byte $77; | XXX XXX| $F11E

      .byte $55; | X X X X| $F11F

      .byte $77; | XXX XXX| $F120

      .byte $44; | X   X  | $F121

      .byte $44; | X   X  | $F122

      .byte $00



      .byte $FF

      .byte $00

      .byte $11; |   X   X| $F123

      .byte $11; |   X   X| $F124

      .byte $11; |   X   X| $F125

      .byte $11; |   X   X| $F126

      .byte $77; | XXX XXX| $F127

      .byte $00



      .byte $FF

      .byte $00

      .byte $77; | XXX XXX| $F128

      .byte $55; | X X X X| $F129

      .byte $77; | XXX XXX| $F12A

      .byte $55; | X X X X| $F12B

      .byte $77; | XXX XXX| $F12C

      .byte $00



      .byte $FF

      .byte $00

      .byte $11; |   X   X| $F12D

      .byte $11; |   X   X| $F12E

      .byte $77; | XXX XXX| $F12F

      .byte $55; | X X X X| $F130

      .byte $77; | XXX XXX| $F131

      .byte $00







TimerDigits2:

      .byte $FF

      .byte $00

      .byte $EE; |XXX XXX | $F100

      .byte $AA; |X X X X | $F101

      .byte $AA; |X X X X | $F102

      .byte $AA; |X X X X | $F103

      .byte $EE; |XXX XXX | $F104

      .byte $00



      .byte $FF

      .byte $00

      .byte $44; | X   X  | $F105

      .byte $44; | X   X  | $F106

      .byte $44; | X   X  | $F107

      .byte $44; | X   X  | $F108

      .byte $44; | X   X  | $F109

      .byte $00



      .byte $FF

      .byte $00

      .byte $EE; |XXX XXX | $F10A

      .byte $22; |  X   X | $F10B

      .byte $EE; |XXX XXX | $F10C

      .byte $88; |X   X   | $F10D

      .byte $EE; |XXX XXX | $F10E

      .byte $00



      .byte $FF

      .byte $00

      .byte $EE; |XXX XXX | $F10F

      .byte $88; |X   X   | $F110

      .byte $CC; |XX  XX  | $F111

      .byte $88; |X   X   | $F112

      .byte $EE; |XXX XXX | $F113

      .byte $00



      .byte $FF

      .byte $00

      .byte $88; |X   X   | $F114

      .byte $88; |X   X   | $F115

      .byte $EE; |XXX XXX | $F116

      .byte $AA; |X X X X | $F117

      .byte $AA; |X X X X | $F118

      .byte $00



      .byte $FF

      .byte $00

      .byte $EE; |XXX XXX | $F119

      .byte $88; |X   X   | $F11A

      .byte $EE; |XXX XXX | $F11B

      .byte $22; |  X   X | $F11C

      .byte $EE; |XXX XXX | $F11D

      .byte $00



      .byte $FF

      .byte $00

      .byte $EE; |XXX XXX | $F11E

      .byte $AA; |X X X X | $F11F

      .byte $EE; |XXX XXX | $F120

      .byte $22; |  X   X | $F121

      .byte $22; |  X   X | $F122

      .byte $00



      .byte $FF

      .byte $00

      .byte $88; |X   X   | $F123

      .byte $88; |X   X   | $F124

      .byte $88; |X   X   | $F125

      .byte $88; |X   X   | $F126

      .byte $EE; |XXX XXX | $F127

      .byte $00



      .byte $FF

      .byte $00

      .byte $EE; |XXX XXX | $F128

      .byte $AA; |X X X X | $F129

      .byte $EE; |XXX XXX | $F12A

      .byte $AA; |X X X X | $F12B

      .byte $EE; |XXX XXX | $F12C

      .byte $00



      .byte $FF

      .byte $00

      .byte $88; |X   X   | $F12D

      .byte $88; |X   X   | $F12E

      .byte $EE; |XXX XXX | $F12F

      .byte $AA; |X X X X | $F130

      .byte $EE; |XXX XXX | $F131

      .byte $00

 

 

Then, you'll need some way of showing that value to the player. Since the inside of the yellow castle is the screen that you'd win in...I can just put the timer in there :) Display it at the top of the screen, while the rest of the screen is displayed normally.

 

Because so much time is used up just figuring out WHAT to display, there isn't enough time left to clear out the GFX (so the timer appears on the screen twice...on both the left and right sides). But here's the kernal mod. Scroll up to bank 1 to this point...

 

       STY    RoomDefIndex       ;Save for Next Time.                                  ;3

      STA    WSYNC              ;Wait for Horizontal Blank.                           ;3
; a. X still contains 1, so the important bit 1 for VBLANK is zero.
;    (this trick is also very common)
; b. a very usual trick: we know the state of a flag, so we replace JMP with a branch
;    (here Y always != 0 -> Z-flag = 0)

      STX    VBLANK             ;Clear any Vertical Blank.                            ;3

 

There's a branch that just follows this...but we'll still be using it. So keep the cursor just below that VBLANK line, and paste this in...

 

       LDX    PlayerRoom         ;Check the player's room number                       ;3

      CPX    #$12               ;Is it inside the yellow castle?                      ;2

      BEQ    TimerDisplayInit   ;Branch if so                                         ;2

      JMP    PrintPlayer00      ;Otherwise, skip ahead                                ;3

TimerDisplayInit:

      LDY    #$20               ;Set the value for "Mirrored" GFX                     ;2

      STY    CTRLPF             ;And put in the playfield control register.           ;3

      LDY    #$07               ;Get ready to count down 8 lines                      ;2

      STY    RoomDefIndex       ;Save to a temp                                       ;3

TimerDisplay:

      LDA    TimerHi            ;Grab the high byte of the new timer                  ;3

      AND    #$0F               ;Keep only the lower nybble                           ;2

      ASL                       ;ASL 3 times to multiply it by 8                      ;2

      ASL                       ;                                                     ;2

      ASL                       ;                                                     ;2

      CLC                       ;                                                     ;2

      ADC    RoomDefIndex       ;Then add in the current line                         ;3

      TAY                       ;Set the new index to the Y register                  ;2

      LDA    TimerDigits,Y      ;Load in the GFX for that digit                       ;4

      AND    #$0F               ;Keep only the low nybble                             ;2

      STA    ScanLineCnt        ;...and save temporarily                              ;3

      LDA    TimerHi            ;Now do the same for the high nybble of TimerHi...    ;3

      AND    #$F0               ;Keep only the high nybble                            ;2

      LSR                       ;Divide by 2 (so index is x8)                         ;2

      CLC                       ;                                                     ;2

      ADC    RoomDefIndex       ;Add in the current line                              ;3

      TAY                       ;And set to the Y index                               ;2

      LDA    TimerDigits,Y      ;Load in the GFX for that digit                       ;4

      AND    #$F0               ;Keep only the high nybble                            ;2

      ORA    ScanLineCnt        ;...and throw in the low nybble we saved above        ;3

      TAX                       ;Give to X for the time being                         ;2
;do the same thing for the low timer...this time using mirrored GFX...

      LDA    TimerLo            ;                                                     ;3

      AND    #$0F               ;                                                     ;2

      ASL                       ;                                                     ;2

      ASL                       ;                                                     ;2

      ASL                       ;                                                     ;2

      CLC                       ;                                                     ;2

      ADC    RoomDefIndex       ;                                                     ;3

      TAY                       ;                                                     ;2

      LDA    TimerDigits2,Y     ;                                                     ;4

      AND    #$F0               ;                                                     ;2

      STA    ScanLineCnt        ;                                                     ;3

      LDA    TimerLo            ;                                                     ;3

      AND    #$F0               ;                                                     ;2

      LSR                       ;                                                     ;2

      CLC                       ;                                                     ;2

      ADC    RoomDefIndex       ;                                                     ;3

      TAY                       ;                                                     ;2

      LDA    TimerDigits2,Y     ;                                                     ;4

      AND    #$0F               ;                                                     ;2

      ORA    ScanLineCnt        ;                                                     ;3
;digit GFX ready to print

      STA    WSYNC              ;Wait for Horizontal Blank.                           ;3

      STX    PF1                ;Save the X register to the 2nd playfield register    ;2

      STA    PF2                ;Save the A register to the 3rd playfield register    ;2

      DEC    RoomDefIndex       ;Decrease the line counter                            ;5

      BPL    TimerDisplay       ;Branch if still zero or above (and do the next line) ;2

      LDY    #$21               ;Otherwise, reset everything...done drawing the timer ;2

      STY    CTRLPF             ;Reset the playfield control to reversed GFX          ;3

      LDY    #$06               ;                                                     ;2

      STY    RoomDefIndex       ;Reset the GFX index to begin on the 6th byte         ;3

      LDY    #$5F               ;Reset the scan line counter...                       ;2

      STY    ScanLineCnt        ;...to 9 lines less than normal                       ;3

      STA    WSYNC              ;Send a blank scanline                                ;3

      STA    WSYNC              ;Send a blank scanline                                ;3

 

 

 

That takes care of the display :) Since sprite GFX are not being sent to the display, they will be thrown off a little bit...but it seems to work OK.

 

 

Now, you'll need some way of updating the timer. You wouldn't want it to change during an inactive game (i.e. when you win)...so I just pasted the code to the routine that deals with moving objects attracted by the magnet :D...

 

 

;Deal With Magnet.

Mag_1:
;timer

      LDA    LoCnt              ;                                             ;3

      AND    #$1F               ;                                             ;2

      BNE    NoTime             ;                                             ;2

      SED                       ;                                             ;2

      LDA    TimerLo            ;                                             ;3

      CLC                       ;                                             ;2

      ADC    #$01               ;                                             ;2

      STA    TimerLo            ;                                             ;3

      CMP    #$60               ;                                             ;2

      BNE    SaveSec            ;                                             ;2

      LDA    #$00               ;                                             ;2

      STA    TimerLo            ;                                             ;3

      CLC                       ;                                             ;2

      LDA    TimerHi            ;                                             ;3

      ADC    #$01               ;                                             ;2

      STA    TimerHi            ;                                             ;3

SaveSec:

      CLD                       ;                                             ;2

NoTime:
;end of added section

 

The regular magnet routine just gets pushed down below this new added section (so the next line will be LDA MagnetR+2, etc.)

 

 

And to complete the mod...add in a couple lines to clear out the timer when a new game is begun. I just had this happen when the number screen is being displayed (so the timer still runs if you get killed)...

 

 

SetupRoomObjects:

      LDA    #$00               ;Set the current room to the                  ;2

      STA    PlayerRoom         ;"Number" room.                               ;3

      STA    PrevRoom           ;And the previous room.                       ;3


;added for the timer

      STA    TimerLo            ;Clear the seconds timer                      ;3

      STA    TimerHi            ;Clear the minutes timer                      ;3


;A is still zero...no need to reload...etc...

 

 

Here's the binary that uses a timer...now you can see how long it takes you to get the chalise back (so long as that room is displayed when you win).

adventure_timed_.zip

Link to comment
Share on other sites

Nukey, thanks again for doing all this. :thumbsup: Your 8k tutorials have really helped me to tweak my hack to almost what I originally envisioned it to be, especially with the new maingame routine that eliminated all of my screen flips and rumbles! :D Too bad I have absolutely no room for that timer though... ;) I'll be posting a final release candidate of my hack soon (with some additions :) ), hopefully along with a manual so people can figure it out (and of course, the source code, but not before it's tidied up!).

Link to comment
Share on other sites

No prob. The timer idea just came to me...so I figured I'd throw it out there. It does miscount by 4/60 seconds though...so it's not perfect as written (since it's using bit 6 of the framecounter to decide when to bump up the seconds counter).

 

Here's a Supercharger version

adventure4k_timed_.zip

Link to comment
Share on other sites

Next...adding game levels:

 

This is really kind of easy to do. All you really need to do is seach for the variable "Level" and alter the routines/data tables to work with 4 levels instead of 3. From the top downward...here's the list of changes that need to be done to add in a Level #4:

 

 

CheckReset:
; testing bit 1 is smaller with LSR:

      LSR                       ;And check only the select switch             ;2

      BCC    StoreSwitches      ;Branch if select not being used.             ;2

      LDA    PlayerRoom         ;Get the Current Room.                        ;3

      BNE    SetupRoomObjects   ;Branch if not.                               ;2

      LDY    Level              ;Increment the level.                         ;3

      INY                       ;Number (by two).                             ;2

      INY                       ;Number (by two).                             ;2


;change $06 to $08...

      CPY    #$08               ;Have we reached the maximum?                 ;2

 

 

SetupRoomObjects_2:

      LDA    (CurrentObject),Y  ;(the rooms and positions) into               ;5

      STA.wy DotR,Y             ;the working area.                            ;5

      DEY                       ;                                             ;2

      BPL    SetupRoomObjects_2 ;                                             ;2

      LDA    Level              ;Get the level number.                        ;3

      CMP    #$04               ;Branch if level one.                         ;2

      BCC    SignalGameStart    ;Or two(Where all objects are in defined areas);2

      JSR    RandomizeLevel3    ;Put some objects in random rooms.            ;6

 

This routine will prevent randomized objects if the level number is under a value of $04 ($04 is level 3). You could adjust that to however you wanted (like say...randomize only even-numbered levels by changing CMP #$04/BCC SignalGameStart to LSR/LSR/BCC SignalGameStart...or just by using CMP instructions for each level. I had it randomize even-numbered levels in the binary below by just using 2 LSR instructions (so levels 2 and 3 are swapped).

 

That's all the changes that need to be done to the program. You can decide if you want additional aspects of the new level just by using comparisons in the program to decide if something should be done or not.

 

 

Now that the programming side is finished, you'll need to adjust the number of bytes in the data tables to account for the new level, and also add in a bitmap image for the number "4". Here's a rundown...

 

Change this...

;Object #5 States.

NumberStates:

      .byte $01,<GfxNum1,>GfxNum1         ;State 1 as FCF4

      .byte $03,<GfxNum2,>GfxNum2         ;State 3 as FD04

      .byte $FF,<GfxNum3,>GfxNum3         ;State FF as FD0C

 

 

To this...

;Object #5 States.

NumberStates:

      .byte $01,<GfxNum1,>GfxNum1         ;State 1 as FCF4

      .byte $03,<GfxNum2,>GfxNum2         ;State 3 as FD04

      .byte $05,<GfxNum3,>GfxNum3         ;State 5 as FD0C

      .byte $FF,<GfxNum4,>GfxNum4         ;State FF as FD0C

 

 

 

 

 

Then add this bitmap...

;Object #5 State #3 Graphic :'3'

GfxNum4:

      .byte $02                 ;      X 

      .byte $02                 ;      X 

      .byte $12                 ;   X  X 

      .byte $22                 ;  X   X 

      .byte $7F                 ; XXXXXXX

      .byte $02                 ;      X 

      .byte $02                 ;      X 

      .byte $00                 ;bitmap end

 

 

 

 

Change this...

;Dragon Difficulty

DragonDiff:

      .byte $D0,$E8                 ;Level 1 : Am, Pro

      .byte $F0,$F6                 ;Level 2 : Am, Pro

      .byte $F0,$F6                 ;Level 3 : Am, Pro

 

...to this...

;Dragon Difficulty

DragonDiff:

      .byte $D0,$E8                 ;Level 1 : Am, Pro

      .byte $F0,$F6                 ;Level 2 : Am, Pro

      .byte $F0,$F6                 ;Level 3 : Am, Pro

      .byte $F6,$FE                 ;Level 4 : Am, Pro

 

In level 4, I increased the dragon bite speed to fast in B difficulty...VERY fast in A. You can make them faster or slower just by editing the value to be higher or lower.

 

 

 

The RoomDiffs table will need to contain an extra byte for each line (instead of 3). This table lists the rooms that you end up in when moving to rooms that have the high bit set (+80) in it's directional info. If it does, the next room number is grabbed from this table (which is why you'll need an extra byte for each level added). I just kept it the same as levels 2-3 in this example.

;Room differences for different levels (level 1,2,3)

RoomDiffs:

RD1:  ;<- These "RD" tags used in the room matrix...subtract RD0 to get proper $80 value

      .byte $10,$0F,$0F,$0F       ;Down from Room 01

RD2:

      .byte $05,$11,$11,$11       ;Down from Room 02

RD3:

      .byte $1D,$0A,$0A,$0A       ;Down from Room 03

RD4:

      .byte $1C,$16,$16,$16       ;U/L/R/D from Room 1B (Black Castle Room)

RD5:

      .byte $1B,$0C,$0C,$0C       ;Down from Room 1C

RD6:

      .byte $03,$0C,$0C,$0C       ;Up from Room 1D (Top Entry Room)

 

 

 

Loc_5 will need to have 2 bytes added to the end that points to what table the game object data should be read from. You can reuse game 2's object matrix just by doing this...

Loc_5:

      .byte >Game1Objects                   ;      --continued.

      .byte <Game2Objects,>Game2Objects     ;objects game 02.

      .byte <Game2Objects,>Game2Objects     ;objects game 03.

      .byte <Game2Objects,>Game2Objects     ;objects game 04.

 

 

 

If you want to add in an all-new location chart (which I did for the binary below), you'd just add one...like this:

Loc_5:

      .byte >Game1Objects                   ;      --continued.

      .byte <Game2Objects,>Game2Objects     ;objects game 02.

      .byte <Game2Objects,>Game2Objects     ;objects game 03.

      .byte <Game4Objects,>Game4Objects     ;objects game 04.




;Object locations (room and coordinate) for Game 04

Game4Objects:

      .byte $15,$51,$12           ;Black Dot (Room,X,Y)

      .byte $14,$50,$20,$A0,$00   ;Red Dragon (Room,X,Y,Movement,State)

      .byte $19,$50,$20,$A0,$00   ;Yellow Dragon (Room,X,Y,Movement,State)

      .byte $0E,$50,$20,$A0,$00   ;Green Dragon (Room,X,Y,Movement,State)

      .byte $04,$80,$20           ;Magnet (Room,X,Y)

      .byte $0B,$20,$20           ;Sword (Room,X,Y)

      .byte $14,$30,$20           ;Chalise (Room,X,Y)

      .byte $11,$40,$40           ;Bridge (Room,X,Y)

      .byte $06,$20,$40           ;Yellow Key (Room,X,Y)

      .byte $09,$20,$40           ;White Key (Room,X,Y)

      .byte $19,$20,$40           ;Black Key (Room,X,Y)

      .byte $1C                   ;Portcullis State

      .byte $1C                   ;Portcullis State

      .byte $1C                   ;Portcullis State

      .byte $0D,$20,$20,$90,$00   ;Bat (Room,X,Y,Movement,State)

      .byte $78,$00               ;Bat (Carrying, Fed-Up)

 

 

Then just edit the starting room, X and Y locations, etc. In the example above, I swapped a few.

 

 

 

Here's the binary that adds 2 more levels. Even-numbered levels feature random objects...

adventure5levels.zip

Link to comment
Share on other sites

New...multiple screen resolutions:

 

I just discovered how to mix screen resolutions...where you can choose between 7, 14, 28, or 56 lines of data PER SCREEN :)

 

Normally, Adventure uses 7 lines of playfield data for each screen...like this:

 

;Yellow Castle (outside)

Room11:

      .byte $F0,$FE,$15         ;XXXXXXXXXXX X X X      R R R RRRRRRRRRRR

      .byte $30,$03,$1F         ;XX        XXXXXXX      RRRRRRR        RR

      .byte $30,$03,$FF         ;XX        XXXXXXXXXXRRRRRRRRRR        RR

      .byte $30,$00,$FF         ;XX          XXXXXXXXRRRRRRRR          RR

      .byte $30,$00,$3F         ;XX          XXXXXX    RRRRRR          RR

      .byte $30,$00,$00         ;XX                                    RR

      .byte $F0,$FF,$0F         ;XXXXXXXXXXXXXXXX        RRRRRRRRRRRRRRRR

 

 

7 lines of 3 bytes each. Another thing to take note of is that the first byte in each line ONLY uses the upper nybble (lower nybbles saved to PF0 have no effect on the screen). Keep that in mind...because we'll be experimenting with it :)

 

 

 

Scroll back up to the display kernal. Look at the area that decides WHEN to use a new line of data...

 

PrintPlayer00_2:

      LDA    ScanLineCnt        ;Get Scan Line Count.                                 ;3



      AND    #$0F               ;Have we reached a sixteenth scan line?               ;2


;NOTE! The above line could be changed to 7 (checking every 8th scanline instead).  This will
;effectively DOUBLE the resolution for each screen. (you'll need to update the room GFX tables
;to have 42 bytes instead of 21).  The upper and lower lines of the higher res. bitmaps will
;just *barely* be visible...so by clever placement of the tags, this could be reduced to 36
;bytes per screen :)  Format of the updated line would be this:
;;       AND    #$07               ;Have we reached a eighth scan line?                  ;2
;...that will replace the above line and the program will grab new GFX values on every 8th line



      BNE    PrintPlayer00_4    ;If not, Branch.                                      ;2

 

 

In the message, I'd already found out how to double the screen resolution. But if that change was done, the screens would all need to be doubled up...including all the screens that only NEED 7 lines of data (like those big empty rooms). That's a lot of waste if we changed to using new lines on every 8th scanline.

 

There's a better way :)

 

In this optimized code, ram location $FA is corrupted by the stack when the program is outside of the kernal (due to all those JSR's and such). If we're quick about it...we could use that location to hold the AND value...and then just decide up top when to use $0F, $07 (or even something smaller like $03 or $01). That would allow the game to store bitmaps in multiple modes...even changing modes within a screen (so some lines will be printed 8 times, some 16, etc). You could make a really snazzy game select screen with that!

 

And that's where that unused nybble for PF0 comes in. We can just define what the AND value needs to be in that nybble!

 

 

;Yellow Castle (outside)

Room11:

      .byte $FF,$FE,$15         ;XXXXXXXXXXX X X X      R R R RRRRRRRRRRR

      .byte $3F,$03,$1F         ;XX        XXXXXXX      RRRRRRR        RR

      .byte $3F,$03,$FF         ;XX        XXXXXXXXXXRRRRRRRRRR        RR

      .byte $3F,$00,$FF         ;XX          XXXXXXXXRRRRRRRR          RR

      .byte $3F,$00,$3F         ;XX          XXXXXX    RRRRRR          RR

      .byte $3F,$00,$00         ;XX                                    RR

      .byte $FF,$FF,$0F         ;XXXXXXXXXXXXXXXX        RRRRRRRRRRRRRRRR

 

 

That one just uses the default...printing each line 16 times (by using an AND value of $0F). But you could do this if you wanted those spires to be just a -little-bit longer (by 8 more scanlines)...

 

 

 

;Yellow Castle (outside)

Room11:

      .byte $FF,$FE,$15         ;XXXXXXXXXXX X X X      R R R RRRRRRRRRRR

      .byte $F7,$FE,$15         ;XXXXXXXXXXX X X X      R R R RRRRRRRRRRR

      .byte $37,$03,$1F         ;XX        XXXXXXX      RRRRRRR        RR

      .byte $3F,$03,$FF         ;XX        XXXXXXXXXXRRRRRRRRRR        RR

      .byte $3F,$00,$FF         ;XX          XXXXXXXXRRRRRRRR          RR

      .byte $3F,$00,$3F         ;XX          XXXXXX    RRRRRR          RR

      .byte $3F,$00,$00         ;XX                                    RR

      .byte $FF,$FF,$0F         ;XXXXXXXXXXXXXXXX        RRRRRRRRRRRRRRRR

 

 

I copied the top line and gave 8 scanlines to it...which I robbed from the next following line. You could use multiples of 2, 4, 8, and 16 scanlines just by setting that nybble.

 

 

OK...now that we have a place to hold the value, we need to decide when to use it. And that is accomplished by doing this...

 

 

;Print top line of Room.

      LDY    RoomDefIndex       ;Get room definition index.                           ;3

      LDA    (RoomLo),Y         ;Get first room definition byte.                      ;5

      STA    PF0                ;      and display.                                   ;3


;added lines------

      AND    #$0F               ;Clear off the pixel data...keeping only the AND value;2

      STA    $FA                ;...and save it to ram location $FA                   ;2
;-----------------



      INY                       ;                                                     ;2

      LDA    (RoomLo),Y         ;Get Next room definition byte.                       ;5
;...etc...

 

 

There it's saved to the temp (you can't use the variable Temp...because it's shared with Player0def). $FA seems to work well...it only seems to be corrupted outside of the display kernal. Next, change the display routine to use this ram location instead of an immediate value...

 

 

PrintPlayer00_2:

      LDA    ScanLineCnt        ;Get Scan Line Count.                                 ;3

      AND    $FA                ;Have we reached the custom number of scanlines?      ;3

      BNE    PrintPlayer00_4    ;If not, Branch.                                      ;2

 

 

 

That's it! :D You'll have to change all of the existing bitmaps to use lower nybbles (if any are zero, the game will crash). But all of the bitmaps will now have the option of using higher resolutions.

 

 

Caution: be sure that any gaps that you wish the player to move though are at least 8 scanlines...and it's not a good idea to use smaller horizontal gaps than 2 pixels.

Link to comment
Share on other sites

Oops...bugfix:

 

You'll need to correct the value of $FA whenever the scanline count runs out (otherwise, the entire screen will be using the number of scanlines defined by the very first byte in the bitmap instead of each line). That code goes here:

 

 

PrintPlayer00_4:

      STA    WSYNC              ;Wait for Horzontal blank.                            ;3

      STY    ENABL              ;Enable Ball (If Wanted.)                             ;3

      STX    GRP0               ;Display Player00 definition byte (if Wanted).        ;3




;added lines------

      LDY    RoomDefIndex       ;Get room definition index.                           ;3

      LDA    (RoomLo),Y         ;Get first room definition byte,                      ;5

      AND    #$0F               ;Clear off the pixel data...keeping only the AND value;2

      STA    $FA                ;...and save it to ram location $FA                   ;3
;-----------------





      BNE    PrintPlayer00_3    ;                                                     ;2

 

 

 

Sorry about that :P

post-222-1096049167_thumb.jpg

Link to comment
Share on other sites

This code produces a sharper-looking castle :)

 

;Yellow Castle (outside)

Room11:

      .byte $F7,$FC,$00         ;XXXXXXXXXXX                  RRRRRRRRRRR

      .byte $F3,$FC,$00         ;XXXXXXXXXXX                  RRRRRRRRRRR

      .byte $F3,$FE,$15         ;XXXXXXXXXXX X X X      R R R RRRRRRRRRRR

      .byte $37,$02,$15         ;XX        X X X X      R R R R        RR

      .byte $33,$03,$1F         ;XX        XXXXXXX      RRRRRRR        RR

      .byte $33,$03,$3F         ;XX        XXXXXXXX    RRRRRRRR        RR

      .byte $37,$03,$FF         ;XX        XXXXXXXXXXRRRRRRRRRR        RR

      .byte $37,$01,$FF         ;XX         XXXXXXXXXRRRRRRRRR         RR

      .byte $3F,$00,$FE         ;XX           XXXXXXXRRRRRRR           RR

      .byte $3F,$00,$3E         ;XX           XXXXX    RRRRR           RR

      .byte $3F,$00,$00         ;XX                                    RR

      .byte $FF,$FF,$0F         ;XXXXXXXXXXXXXXXX        RRRRRRRRRRRRRRRR

post-222-1096050681_thumb.jpg

Link to comment
Share on other sites

Damn...the ball object jets kind of jumpy (because using a ram location takes 1 cycle longer than using an immediate value). So here's how to correct it...

 

ScanLineCnt is loaded in a few places...and each time it takes 3 cycles. By using an unused register (X), we can cut this load time down to 2 cycles...saving 1 that we need for the AND $FA :)

 

This change is kind of hard to explain...so I'll just list the updated code sections (including the optional one for the timer if you are using it):

 

 

 

;remove these 2 lines...
;       LDA    #$68               ;                                                     ;2
;       STA    ScanLineCnt        ;Set Scan Line Count.                                 ;3


;Print top line of Room.

      LDY    RoomDefIndex       ;Get room definition index.                           ;3

      LDA    (RoomLo),Y         ;Get first room definition byte.                      ;5

      STA    PF0                ;      and display.                                   ;3

      AND    #$0F               ;Clear off the pixel data...keeping only the AND value;2

      STA    $FA                ;...and save it to ram location $FA                   ;2

      INY                       ;                                                     ;2

      LDA    (RoomLo),Y         ;Get Next room definition byte.                       ;5

      STA    PF1                ;      and display.                                   ;3

      INY                       ;                                                     ;2

      LDA    (RoomLo),Y         ;Get Last room defintion byte.                        ;5

      STA    PF2                ;      and display.                                   ;3

      INY                       ;                                                     ;2

      STY    RoomDefIndex       ;Save for Next Time.                                  ;3
;moved from up top in order to keep in X

      LDX    #$68               ;                                                     ;2

      STX    ScanLineCnt        ;Set Scan Line Count.                                 ;3

      STA    WSYNC              ;Wait for Horizontal Blank.                           ;3
; a. X still contains #$68, so the important bit 1 for VBLANK is zero.
;    (this trick is also very common)
; b. a very usual trick: we know the state of a flag, so we replace JMP with a branch
;    (here Y always != 0 -> Z-flag = 0)

      STX    VBLANK             ;Clear any Vertical Blank.                            ;3


;optional lines for the timer routine

      LDA    PlayerRoom         ;Check the player's room number                       ;3

      CMP    #$12               ;Is it inside the yellow castle?                      ;2

      BEQ    TimerDisplayInit   ;Branch if so                                         ;2





      JMP    PrintPlayer00      ;Otherwise, skip ahead                                ;3

 

 

;optional lines in the timer routine...
;use X instead of A...

      LDX    #$5F               ;Reset the scan line counter...                       ;2

      STX    ScanLineCnt        ;...to 9 lines less than normal                       ;3

      STA    WSYNC              ;Send a blank scanline                                ;3

      STA    WSYNC              ;Send a blank scanline                                ;3

      BNE    PrintPlayer00      ;Branch ahead                                         ;2


;Print Player01 (Object 02)

PrintPlayer01:
;delete this line:
;       LDA    ScanLineCnt        ;Get Current Scan Line.                               ;3
;A still holds the scanline count, so save it to X temporarily

      TAX                       ;                                                     ;2

 

 

 

;Print Player00 (Object01), Ball (Man) and Room.

PrintPlayer00:
;delete this line:
;       LDA    ScanLineCnt        ;Get the Current Scan Line.                           ;3
;now pull that scanline count back...saving 1 cycle

      TXA                       ;Get the Current Scan Line.                           ;2

      LDX    #$00               ;                                                     ;2

 

 

That gives us the 1 cycle we need when WSYNC is reached in PrintPlayer00_2...and it no longer bounces :)

Link to comment
Share on other sites

Apparently, some problems might crop up if the room data contains more than 11 lines of data :? Trying to figure out that one. Or maybe it's just my sloppy coding :lol:

 

 

Next lesson...

Adding hit points to dragons (another often-requested mod):

 

All dragons have a single "state" variable. Once a dragon so much as brushes against the sword, this variable is changed to a value of 1...it's dead. So much for being tough!

 

What you'd need to do is set aside another byte of ram for each dragon...so that rather than just setting the state to 1, it first bumps down this new variable (it's hit counter)...and then saves a state of 1 only when the hit counter reaches zero (so you could have as many as 256 hits to record on any or all dragons).

 

First, you need to reorganize ram to include the new variable...instead of allocating 5 bytes of ram to each dragon, you'd now be using 6...

 

;object variables...

SurroundR     =  $B1;(3 bytes)

DotR          =  $B4;(3 bytes)


;added hit counter
;all dragons must be consecutive

RDragonR      =  $B7;(6 bytes)

YDragonR      =  $BD;(6 bytes)

GDragonR      =  $C3;(6 bytes)


;...etc...

 

...and on down the list. Since the variable table has changed, you'd need to update the object matrix...so scroll down and tack on the new value you want for each dragon (I just used a value of 10 for each one, but this could be any number, and the numbers can be different if you wish). Both tables must be changed (game1objects, and game2objects)...

 

 

;added hit counter
;Game1Objects and Game2Objects must hold the same number of bytes
;Object locations (room and coordinate) for game 01.

Game1Objects:

      .byte $15,$51,$12            ;Black dot     (Room,X,Y)

      .byte $0E,$50,$20,$00,$00,$0A;Red Dragon    (Room,X,Y,Movement,State,Hits)

      .byte $01,$50,$20,$00,$00,$0A;Yellow Dragon (Room,X,Y,Movement,State,Hits)

      .byte $1D,$50,$20,$00,$00,$0A;Green Dragon  (Room,X,Y,Movement,State,Hits)

and

;Object locations (room and coordinate) for Games 02 and 03.

Game2Objects:

      .byte $15,$51,$12            ;Black Dot     (Room,X,Y)

      .byte $14,$50,$20,$A0,$00,$0A;Red Dragon    (Room,X,Y,Movement,State,Hits)

      .byte $19,$50,$20,$A0,$00,$0A;Yellow Dragon (Room,X,Y,Movement,State,Hits)

      .byte $04,$50,$20,$A0,$00,$0A;Green Dragon  (Room,X,Y,Movement,State,Hits)

 

 

Next, you'd need to allow the program to reset this counter when game reset is pressed...

 

 

(frem CheckGameStart)

       LDA    #$00               ;                                             ;2

      STA    RDragonR+4         ;Set the red dragon's state to OK.            ;3

      STA    YDragonR+4         ;Set the yellow dragon's state to OK.         ;3

      STA    GDragonR+4         ;Set the green dragon's state to OK.          ;3

      STA    NoteCnt            ;Set the note count to zero.. (ops!??)        ;3


;added lines...hit counter

      LDA    #$0A               ;                                             ;2

      STA    RDragonR+5         ;Set the red dragon's hit counter to 10       ;3

      STA    YDragonR+5         ;Set the yellow dragon's hit counter to 10    ;3

      STA    GDragonR+5         ;Set the green dragon's hit counter to 10     ;3

 

 

 

OK...now that that is set up...all you need to do is edit in the new routine. Just scroll down to the Move_Dragon routine that deals with detecting the sword, and add in the new check for the hit counter...

 

 

MoveDragon_4:

      STX    ObjAddress         ;Store Object's Dynamic Data Address.         ;3

      LDX    ObjectNumber       ;Get the Object Number.                       ;3

      JSR    FindObjHit         ;See if anoher object has hit the dragon.     ;6

      LDX    ObjAddress         ;Get the Object Address.                      ;3

      CMP    #SwordNumber       ;Has the Sword hit the Dragon?                ;2

      BNE    MoveDragon_5       ;If Not, Branch.                              ;2


;added lines...hit counter

      DEC    NUSIZ1,X           ;                                             ;4

      BNE    MoveDragon_hit     ;If Not, Branch.                              ;2

 

Once it reaches zero, the branch is not taken (and then a 1 is saved to the state...killing the dragon). If the hit counter still holds a value, the Move_Dragon_hit branch is taken to deal with it. If you wanted, you could add in a new sound for dragons that just got scratched. I just used the existing "dying" sound...but used a smaller note counter :)...

 

(paste this below Move_Dragon_5)

MoveDragon_hit:

      LDA    #$03               ;Set Sound Three.                             ;2

      STA    Sound              ;                                             ;3

      LDA    #$05               ;Set a Noise count of 5.                      ;2

      STA    NoteCnt            ;                                             ;3

      RTS                       ;                                             ;6

 

 

 

Complete :)

 

Other ideas for using this new hit counter would be to have it "heal" over time (by checking the HiCnt and bumping UP the hit counter if it's less than "healthy")...or having random values for the number of hits...or moving the dragon slower (it's Y delta number) if the hit counter is halfway dead.

 

But here's the example .bin

adventure_tough_dragons.zip

Link to comment
Share on other sites

BTW I discovered that the game will have MAJOR problems if you move Game1Objects and Game2Objects apart. To fix this...put this label at the end of the Game1Objects table...just under the bat's values...

 

Game1ObjectsEnd:

 

 

and then change the variable up top...

 

ByteNum        =  Game1ObjectsEnd - (Game1Objects+1);number of bytes in each "fill" table

 

 

Now you can move the 2 tables apart if you wish, without any consequences.

Link to comment
Share on other sites

Moving things around in the main game loop, you might be interested to know how much cycle time is used by the various subroutines...and how much free time exists before the next DoVSYNC or PrintDisplay must be run. By using the timer hack, it was possible to have these values be shown on the screen. All that needed to be done is to execute these lines before a given JSR is taken...

 

       LDA    INTIM              ;                                             ;4

      STA    TimerHi            ;                                             ;3

 

And then just after the JSR, add in these lines...

 

       LDA    TimerHi            ;                                             ;3

      SEC                       ;                                             ;2

      SBC    INTIM              ;                                             ;4

      STA    TimerHi            ;                                             ;3

 

 

Since hex values include the digits A through F, you'd also need to add bitmaps for them in the timer's digit data...

 

       .byte $FF

      .byte $00

      .byte $A5; |X X  X X| $F105

      .byte $A5; |X X  X X| $F106

      .byte $E7; |XXX  XXX| $F107

      .byte $A5; |X X  X X| $F108

      .byte $42; | X    X | $F109

      .byte $00



      .byte $FF

      .byte $00

      .byte $66; | XX  XX | $F105

      .byte $A5; |X X  X X| $F106

      .byte $66; | XX  XX | $F107

      .byte $A5; |X X  X X| $F108

      .byte $66; | XX  XX | $F109

      .byte $00



      .byte $FF

      .byte $00

      .byte $C3; |XX    XX| $F105

      .byte $24; |  X  X  | $F106

      .byte $24; |  X  X  | $F107

      .byte $24; |  X  X  | $F108

      .byte $C3; |XX    XX| $F109

      .byte $00



      .byte $FF

      .byte $00

      .byte $66; | XX  XX | $F105

      .byte $A5; |X X  X X| $F106

      .byte $A5; |X X  X X| $F107

      .byte $A5; |X X  X X| $F108

      .byte $66; | XX  XX | $F109

      .byte $00



      .byte $FF

      .byte $00

      .byte $E7; |XXX  XXX| $F105

      .byte $24; |  X  X  | $F106

      .byte $E7; |XXX  XXX| $F107

      .byte $24; |  X  X  | $F108

      .byte $E7; |XXX  XXX| $F109

      .byte $00



      .byte $FF

      .byte $00

      .byte $24; |  X  X  | $F105

      .byte $24; |  X  X  | $F106

      .byte $E7; |XXX  XXX| $F107

      .byte $24; |  X  X  | $F108

      .byte $E7; |XXX  XXX| $F109

      .byte $00

 

 

 

And now the program will show you how much cycle time is used by a give routine (rounded down to the nearest 64 cycles).

 

 

In the original code, $2A was saved to TIM64T. By eliminating 2 WSYNC's, this was increased to $2C. It can be bumped up to $2F by eliminating 2 more. Here's a replacement DoVSYNC...

 

;Preform VSYNC

DoVSYNC:

      LDX    INTIM              ;Get Timer Output                             ;4

      BNE    DoVSYNC            ;Wait for Time-Out                            ;2

      LDA    #$02               ;                                             ;2

      STA    WSYNC              ;Wait for horizonal blank.                    ;3

      STA    VBLANK             ;Start Vertical Blanking.                     ;3

      STA    WSYNC              ;Wait for horizonal blank.                    ;3

      STA    VSYNC              ;Start verticle sync.                         ;3

      STA    WSYNC              ;Wait for horizonal blank.                    ;3

      LDA    #$2F               ;Set clock interval to                        ;2

      STA    TIM64T             ;Countdown next frame.                        ;4

      STX    VSYNC              ;End Vertical sync.                           ;3

      RTS                       ;                                             ;6

 

 

$2F gives us 2944 cycles before PrintDisplay must be run ($2E x 64 cycles). And the value $20 used in TidyUp gives 1984 cycles free after PrintDisplay runs ($1F x 64 cycles).

 

Here's the cycle times taken by the various routines...plus the maximum time taken by each (in the original game).

 

 

JSR BallMovement - 5x64 cycles

4x64 used normally, 5x64 if the player is moving through the bridge

 

 

JSR MoveCarriedObject - 5x64 cycles

0x64 if no object is held, 4x64 when holding an object, 5x64 if the object moves off the screen

 

 

JSR SetupRoomPrint (must happen once in each MainGameLoop)...

22x64 cycles

 

 

JSR PickupPutdown - 3x64 cycles

1x64 normally, 2x64 when joystick button is pressed, 3x64 when bumping into an object (when carrying one).

 

 

JSR Surround

2x64 cycles

 

 

JSR MoveBat - 14x64 cycles

4x64 cycles when normal (flying with an object). When the bat is fed-up with the object, this becomes 13x64 cycles (i.e. looking for a new object). If another object is in the same room that the bat "wants", this becomes 14x64 cycles.

 

 

JSR Portals - 5x64 cycles

1x64 cycles PER GATE normally. Add 1x64 if a gate is opening or closing...but add 2x64 if the key has just hit the gate.

 

 

JSR MoveColorDragon - 10x64 cycles

For each dragon, 8x64 normally (roaming the maze). This is 9x64 if the Dragon has no motion set...and 10x64 if the dragon has just "bit" the player. Only 2x64 cycles are used during it's biting delay time...and 3x64 cycles used if the player has just been swallowed. If the dragon is dead, only 2x64 cycles are used.

 

 

JSR Mag_1 - 9x64 cycles

6x64 cycles normally. 8x64 cycles if other objects are in the same room...but 9x64 if another object is currently being "attracted" to the magnet.

 

 

 

By using the maximum cycle times, you can re-arrange the JSR's between the DOVSYNC and PrintDisplay jumps so that any custom routines you create keep the values below the maximum amount allowed (which is $2Ex64 after DoVSYNC, and $1Fx64 after PrintDisplay). The lines I used to calculate and display the cycle time is also in this assembly (but commented out), so you can paste custom routines in and find out how much time it uses when the game is running. I also listed how much free time exists before the next one is hit (when the JSR's are in their original order).

adventurecycles.zip

Link to comment
Share on other sites

By using the maximum cycle times, you can re-arrange the JSR's between the DOVSYNC and PrintDisplay jumps so that any custom routines you create keep the values below the maximum amount allowed

I wish I had the brains to figure this out! :) This newest DoVSYNC routine has allowed me to add in one more "object" without rumbles and now there are only 2 bytes free in the second bank. I haven't fully tested it out, but so far it looks great!

Link to comment
Share on other sites

A more accurate way would be to use a trace file, and look though that to see what values appear when the program is counting down INTIM before and after a screen is drawn. This just sidesteps that process, and saves the value to where you can see it on-screen. I was really trying to find a way to pack the existing routines together so that only half the number of DoVSYNC/PrintScreen pairs were needed (speeding up everything in the game)...but unfortunately, the player ends up "sticking" in walls rather than bouncing off them :(

Link to comment
Share on other sites

I was playing around with eliminating WSYNC's earlier without changing the TIM64T value which resulted in the player being stuck in the wall or something. I also did not change the BNE to JMP in the last line of MainGameLoop_2, which resulted in the code causing the game select screen to appear everytime the skeleton (last dragon at the end of the loop) appeared. Everything's okay now! :D

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...