Jump to content
IGNORED

Adventure... with a hot-air balloon


e1will

Recommended Posts

BTW that file already has the data tables split up into seperate ones. Be sure to read the thread anyway because it details the changes I did to the room data. Also, there's hardly any cycle time used every other scanline, so creating multicolor objects should also be easy if you devote 4 bytes of ram for the additional pointers and make some additional data tables and color maps :) Interested?

Link to comment
Share on other sites

BTW that file already has the data tables split up into seperate ones. Be sure to read the thread anyway because it details the changes I did to the room data. Also, there's hardly any cycle time used every other scanline, so creating multicolor objects should also be easy if you devote 4 bytes of ram for the additional pointers and make some additional data tables and color maps :) Interested?

 

Indeed ;)

Link to comment
Share on other sites

Nukey,

 

You have the following quote in the code:

 

;----------------------end of subroutine...rest of bank can be devoted to GFX :)------------

 

;memory addresses $D100 to $D8FF are completely free

;if desired, graphics tables can be transferred here to make custom objects,

;larger objects, many more rooms, etc.

;Don't forget to use ORG with RORG (ORG begins with $1, and RORG begins with $D)

 

Does this mean that to add extra room graphics, I can copy and paste an entire bank of room graphics (changing the name of the rooms, of course) after an ORG $1100 and RORG $D100? I tried doing this, basically and got the following error: Origin Reverse-indexed. Somewhere I'm missing something...

Link to comment
Share on other sites

Maybe this quote from Nukey Shay will help:

Think of a block of ROM memory...the 4k contents of a single "bank" in an 8k game. This 4k is divided into 16 pages, each 256 bytes long. Page crossing occurs when something is defined in 2 pages rather than 1. This can lead to errors in the display kernel, because loading data beyond a page break adds a machine cycle difference between data that does not cross the boundary...it takes the loading instruction just a little longer than it's supposed to whenever it occurs.

 

To fix it in an assembly file, just keep a maximum of 256 bytes in each page. Some people use the ALIGN 256 instruction for Dasm. I just use ORG's...as in:

 

ORG $1500

RORG $D500

 

;256 bytes of data

 

ORG $1600

RORG $D600

 

;256 bytes of data

 

;etc

 

You need to rearrange room gfx tables so that they always fit between the ORG's. Adventure uses 21 bytes to define each of its screens...so you can fit 12 screens in each page with 4 bytes left over (these 4 bytes can be used for small data tables, or data that does not matter if it crosses a page - i.e. stuff not used in the display.

Link to comment
Share on other sites

Maybe this quote from Nukey Shay will help:

Think of a block of ROM memory...the 4k contents of a single "bank" in an 8k game. This 4k is divided into 16 pages, each 256 bytes long. Page crossing occurs when something is defined in 2 pages rather than 1. This can lead to errors in the display kernel, because loading data beyond a page break adds a machine cycle difference between data that does not cross the boundary...it takes the loading instruction just a little longer than it's supposed to whenever it occurs.

 

To fix it in an assembly file, just keep a maximum of 256 bytes in each page. Some people use the ALIGN 256 instruction for Dasm. I just use ORG's...as in:

 

ORG $1500

RORG $D500

 

;256 bytes of data

 

ORG $1600

RORG $D600

 

;256 bytes of data

 

;etc

 

You need to rearrange room gfx tables so that they always fit between the ORG's. Adventure uses 21 bytes to define each of its screens...so you can fit 12 screens in each page with 4 bytes left over (these 4 bytes can be used for small data tables, or data that does not matter if it crosses a page - i.e. stuff not used in the display.

 

And I tried to get away with that doing a copy and paste of another 256 bytes of data, then changing the room names, and assigning it to what I thought was available:

 

ORG $1100

RORG $D100

 

But it didn't work...so I'm doing something wrong.

Link to comment
Share on other sites

I would suggest not bothering with filling in ORG's at all. You can worry about shuffling data tables around later on if you want (to avoid screen pixel glitches). I wouldn't be able to guess which page of yours is messing up unless I know exactly precisely which assembly you started with.

 

 

Note that in the LATEST assembly (which you obviously aren't using yet, because RORG's don't exist in the first bank for that one), it's not using WSYNC's to kill scanlines...and drawing sprites is done by bumping the LSB pointer. So if you move to that assembly, it's absolutely necessary that your data does NOT cross page breaks.

 

Anyway, I suggest running a list file whenever you use Dasm. It will point right at the spot that had too many bytes put in it if you are getting the reverse indexed error (the problem ORG will be shown right at the bottom of your text file).

Link to comment
Share on other sites

I would suggest not bothering with filling in ORG's at all. You can worry about shuffling data tables around later on if you want (to avoid screen pixel glitches). I wouldn't be able to guess which page of yours is messing up unless I know exactly precisely which assembly you started with.

 

Here's the file I'm working with, complete with the errors.

AdventureRevision.txt

Link to comment
Share on other sites

There's only 1 problem that stops assembly...and that is the added lines to RoomDataTable (you added a bunch of lines there, but the page was already full before you started).

 

You could just grab the whole thing (everything from ;Room Data on down to your last added line), cut it, and paste it to just above ORG $2CDE in the file.

 

 

As I mentioned earlier, the assemblies I did usually had everything crammed up in the last pages of each bank. If you want to add or expand tables, move them someplace else (or tables of an equal number of bytes or more).

 

 

Alternately, you could comment out all of the ORG/RORG lines in the code except the ones at x000 and xFF8...for the time being until you get used to avoiding page breaks.

Link to comment
Share on other sites

Okay...so now I try to add a new object, a portcullis to a red castle in a new area. Everything was working until I got to this part. I have not added a red key yet, but I did go through all the code trying to add the details while trimming bytes here and there to keep from over-runs. But whatever I seem to do, the over-run occurs in the same area.

 

I hate to be so dense on this thing, but it's enough to drive a person batty. Soon I'll be carried away like a dead dragon off to who knows where...

 

UPDATE...

 

I GOT IT!!! Wow, took me forever! Sheesh, I don't know how I finally got it fixed. It ended up I was probably missing an important piece of data.

Edited by keithbk
Link to comment
Share on other sites

Okay, have a question...

 

I have created a Red Castle with a portcullis and a Red Key. For some reason, the Red Key will not open the portcullis. Is the association of the Red Key with the portcullis in the offset data?

 

Here is what I have, and I believe I have all the associations correct:

 

;Portcullis #1, #2, #3, #4

PortOffsets:

.byte $08,$10,$18,$20

 

;Keys #1, #2, #3, #4 (Yellow, White, Black, Red)

KeyOffsets:

.byte $60,$68,$70,$78

 

;Castle Entry Rooms (Yellow, White, Black, Red)

EntryRoomOffsets:

.byte $12,$1A,$1B,$26

 

;Castle Rooms (Yellow, White, Black, Red)

CastleRoomOffsets:

.byte $11,$0F,$10,$24

Link to comment
Share on other sites

Near the top, did you bump Gates up by 1 (from 2 to 3)? Just adding the object isn't enough...the program loop that actually checks the gates (Portals_2) needs to run an additional time. The "Gates" variable is the number of times this loop runs (checking from #Gates to zero, which is why the keys and gates need to be sequential in ram).

Link to comment
Share on other sites

BTW I should mention that increasing the number of gates can possibly cause screen jitters when gates open or close, because the bat is being dealt with on the same display frame (and the bat's subroutine is very long/time consuming). Keep watch at the scanline counter.

 

The solution I used for such screen jitters was to break up the loop between 2 frames...checking odd-numbered and even-numbered gates on seperate frames. All of this is addressed in the Turning Adventure Into An 8k Game thread. Look at post 17 and 20 to see all the necessary steps of adding gates, and post 21 to edit how NPC's react to added objects.

 

All of this editing is increasing the size of data tables, so you can just comment out the ORG lines if you don't want to address page break glitches just yet.

; put ";" characters to the left of the lines...
;       ORG $2CDE
;       RORG $FCDE

 

Watch out for the dragon maxtrices, tho. These are required to be on a single page for all dragons.

 

 

IF screen jitters become an issue, edit the portion of the main loop right where the Portals_2 subroutine is executed...

 

       JSR    MoveBat             ;Move and deal with bat
      LDY    #Gates              ;For Each Portcullis
      JSR    Portals_2           ;Move and deal with portcullises
      JSR    PrintDisplay        ;Display the room and objects
      JSR    MoveGreenDragon     ;Move and deal with the green dragon
      JSR    MoveYellowDragon    ;Move and deal with the yellow dragon

;added lines:
      LDY    #Gates-1            ;For every other Portcullis
      JSR    Portals_2           ;Move and deal with portcullises

 

...and then edit the loop counter in the Portals subroutine to move by 2's instead of doing all of them.

 

Portals_8:
      DEY                        ;Goto the next portcullis

;added line:
      DEY                        ; (count by 2's)

Edited by Nukey Shay
Link to comment
Share on other sites

I should also mention that the addition of objects is easier if you have Dasm figure out the ram addresses on it's own instead of having to edit them by hand. To do this, edit the variable definitions to use "DS #" instead of "=", and add new ORG's to define the 2 segments (RAM vs. ROM). This is a replacement for the upper portion of your assembly:

 

      processor 6502
;Default 2600 Constants set up by dissasembler..
VSYNC   =  $00
VBLANK  =  $01
WSYNC   =  $02
RSYNC   =  $03
NUSIZ0  =  $04
NUSIZ1  =  $05
COLUP0  =  $06
COLUP1  =  $07
COLUPF  =  $08
COLUBK  =  $09
CTRLPF  =  $0A
PF0     =  $0D
PF1     =  $0E
PF2     =  $0F
RESP0   =  $10
AUDC0   =  $15
AUDC1   =  $16
AUDF0   =  $17
AUDF1   =  $18
AUDV0   =  $19
AUDV1   =  $1A
GRP0    =  $1B
GRP1    =  $1C
ENAM0   =  $1D
ENAM1   =  $1E
ENABL   =  $1F
HMP0    =  $20
VDELP1  =  $26
HMOVE   =  $2A
HMCLR   =  $2B
CXCLR   =  $2C
CXP0FB  =  $32
CXP1FB  =  $33
CXM0FB  =  $34
CXM1FB  =  $35
CXBLPF  =  $36
CXPPMM  =  $37
INPT4   =  $3C
SWCHA   =  $0280
SWCHB   =  $0282
INTIM   =  $0284
TIM64T  =  $0296

;variables...
      SEG.u Variables
      ORG $80

RoomLo        DS 2
RoomHi        = RoomLo + 1
Obj1Lo        DS 8
Obj1Hi        = Obj1Lo + 1
Obj2Lo        = Obj1Lo + 2
Obj2Hi        = Obj1Lo + 3
Obj1X         = Obj1Lo + 4
Obj1Y         = Obj1Lo + 5
Obj2X         = Obj1Lo + 6
Obj2Y         = Obj1Lo + 7
PlayerRoom    DS 3
PlayerX       = PlayerRoom + 1
PlayerY       = PlayerRoom + 2
PlayerYadj    DS 1
ScanLineCnt   DS 1
RoomDefIndex  DS 3
Player0Def    = RoomDefIndex + 1
Player1Def    = RoomDefIndex + 2
Debounce      DS 1
CurrentObject DS 5
Jstick        DS 1
CurrentStick  DS 1
ObjAddress    DS 2
ObjDir        = ObjAddress + 1
LastObj       DS 1
CarriedObj    DS 3
CarriedX      = CarriedObj + 1
CarriedY      = CarriedObj + 2
HiCnt         DS 1
ObjLst        DS 4
Delta2        = ObjLst + 2
Delta1        = ObjLst + 3
ObjCr         DS 1
State         DS 1
Level         DS 1
Control       DS 1
NoteCnt       DS 1
Sound         DS 1
Index         DS 1
PrevRoom      DS 3
PrevX         = PrevRoom + 1
PrevY         = PrevRoom + 2
LoCnt         DS 1
ObjectNumber  DS 1


;object variables...
SurroundR     DS 3
DotR          DS 3

;all dragons must be consecutive
RDragonR      DS 5
YDragonR      DS 5
GDragonR      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        DS 1
WGateR        DS 1
BGateR        DS 1

BatR          DS 7

;------------------------------------------------------------------------------------
;Ram locations E5-FA free (F9/FA -might- be used by the stack if JSR's nested further)
;------------------------------------------------------------------------------------


 ECHO $FC - *, " bytes of RAM free"

Temp          =  Player0Def ;(shared)
NullR         =  BridgeR    ;(all shared)

;constants...

;Object numbers:
;these are used to calculate the offsets of the object table
SurroundNumber =  SurroundData - Objects ;($00)
YGateNumber    =  YGateData - Objects    ;($08)
WGateNumber    =  WGateData - Objects    ;($10)
BGateNumber    =  BGateData - Objects    ;($18)
AuthorNumber   =  AuthorData - Objects   ;($20)
NumberNumber   =  NumberData - Objects   ;($28)
RDragonNumber  =  RDragonData - Objects  ;($30)
YDragonNumber  =  YDragonData - Objects  ;($38)
GDragonNumber  =  GDragonData - Objects  ;($40)
SwordNumber    =  SwordData - Objects    ;($48)
BridgeNumber   =  BridgeData - Objects   ;($50)
YKeyNumber     =  YKeyData - Objects     ;($58)
WKeyNumber     =  WKeyData - Objects     ;($60)
BKeyNumber     =  BKeyData - Objects     ;($68)
BatNumber      =  BatData - Objects      ;($70)
DotNumber      =  DotData - Objects      ;($78)
ChaliseNumber  =  ChaliseData - Objects  ;($80)
MagnetNumber   =  MagnetData - Objects   ;($88)
NullNumber     =  NullData - Objects     ;($90)

;RD0 used to calculate map direction value when including differences
RD0            =  RoomDiffs - $80

WinRoom        =  $12 ;(Yellow Castle's room number)
ByteNum        =  Game2Objects - (Game1Objects+1) ;number of bytes in each "fill" table
RndNum         =  Loc_4 - (Loc_1 + 3) ; offset value for the room bounds table
RndMax         =  $1F ;Mask for the upper bounds of the random seed
Gates          =  $02 ;# of castle gates - 1


      SEG Romcode

;----------------------------------START OF BANK 1----------------------------------

 

 

Adding stuff then just involves putting the added variable in the list. Ram definitions below it are automatically recalculated. ECHO can be used to display (in hex) the amount of RAM you have free too ;)

Link to comment
Share on other sites

Here is a 16k version of the *newest* version (the one that includes variable resolution and playfield control). It functions by placing the data that is the same for all rooms into each of the 3 display banks (via macros), and room graphics directly into the rom code areas. After picking a bank to place a room gfx in, just include that info in RoomDataTable1 (add $40 or $80 if the room graphics is in the second or third bank).

 

If a sprite object is immobile and only appears in a specific room, it must be present in the bank that includes that room's gfx. It's not necessary to be part of the macro that gets placed in all banks.

 

It would take a while to fill up all this extra space...even if you are sticking a custom immobile object like the signature into each of the 128 rooms (maximum) and using massive room gfx definitions ;)

 

 

Also, the rebound problem present in the earlier version has been corrected. This glitch caused the player to "stick to" the walls when moving against it instead of bouncing off.

 

 

EDIT: added option to build 8k instead of 16k. ROM16K variable at the top of the assembly.

 

EDIT II: Collisions were broken (using BIT in PBcollision and branching via BVC didn't work, changed to LDA/ASL/BPL instead)

Adventure16k.zip

Edited by Nukey Shay
  • Like 1
Link to comment
Share on other sites

To illustrate this part of the above post...

"If a sprite object is immobile and only appears in a specific room, it must be present in the bank that includes that room's gfx. It's not necessary to be part of the macro that gets placed in all banks."

 

...Grab the castle definition and move it to the second bank. You'd need to edit these lines in RoomDataTable1 to indicate that it's in the second bank now...

 

       .byte >Room0F+$40     ;$0F Outside white Castle
      .byte >Room10+$40     ;$10 Outside black Castle
      .byte >Room11+$40     ;$11 Outside yellow Castle

 

(+40 = second bank)

 

Because the castle screen is in the second bank, and the portcullis object is only present in the castle screens, you could remove the portcullis sprite definition from the macro and place it directly in the second bank as well. This saves space in the other 2 banks where it's never drawn.

The same could be done with the author signature, surround object, or number objects.

 

Anything that is specific to a screen or group of screens.

Link to comment
Share on other sites

In addition, if you wanted objects to look different in dark rooms than they do in light rooms...just move all dark room definitions to a seperate bank and use a different set of sprite definitions for it instead of the macro. Keep in mind that you will need to keep your new object gfx exactly where they occur in the macro's addresses...so it might be easier to do via using an editor like HOM rather than juggling things in your assembly.

 

This would work great if you want the bat to be impossible to see or pick up in the dark rooms...just erase the bitmap with zeros in the alternate set of sprites that's in the other bank.

 

Of course, the same effect could be done by hacking the program code...but this is just a rough example.

Edited by Nukey Shay
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...