Jump to content
IGNORED

Portal problem in Adventure


accousticguitar

Recommended Posts

I've been working on a new Adventure hack, and I've run into a problem. The portals for the white and black castles won't allow the square to enter. Strangely enough, they will allow a dragon to enter. It will disappear into the castle if it hits the portal. What could I be doing wrong? I changed the EntryRoomOffsets to the new room number for the entry room inside the castle, but it just doesn't work. It doesn't seem to matter what number I put there, it won't let me in.

Link to comment
Share on other sites

What happens when you try to enter? Does it attempt to switch to the new screen? Does the new screen have an opening on the bottom to allow the player to pass through? Dragons are exempt from playfield collision, so that would explain why they could pass through if the playfield is what's obstructing the path.

Link to comment
Share on other sites

Hmm. It sounds like a problem with the portcullis collision routines. Can you drop items into the portcullis? Check various ones. If you added objects, like more portcullis' or keys, that could have thrown off your numbers or something.

 

Try looking at the Portals_2 through Portals_4 routines and see what they pull references from. From what can see, it might think the player is on another screen, or maybe your portcullis states are messed up. Also, are there any other problems that have surfaced at the same time as this bug?

 

Heh, watch Nukey Shay pop out of nowhere and know exactly what's wrong. :P

Edited by EarthQuake
Link to comment
Share on other sites

I am now getting an "origins reverse indexed" error when I try to assemble it, but I don't think it's related. I've been adding rooms and I always have trouble when I try to do that. I have not added any portals or objects to the game. Items do drop into the portcullis when I drop them and they are touching it.

Link to comment
Share on other sites

Question:

Are you using the missile as the player? If so, you need to update the collision registers used in the PBCollision routine. A hit MUST register before the player can enter. Other objects use a different routine.

 

CXM0P ($30) = collisions between missile0 and the players (bit7=player1, bit6=player0). Bit on = hit.

CXM1P ($31) = collisions between missile1 and the players (bit7=player0, bit6=player1). Bit on = hit.

 

Note the reversed order between them.

 

 

;if you are using missile0...

PBCollision_2:
  LDA CXM0P;3 Get player00-m0 collision
  AND #$40;2
  RTS;6

PBCollision_3:
  LDA CXM0P;3 Get player01-m0 collision
  AND #$80;2
  RTS;6

 

 

;if you are using missile1...

PBCollision_2:
  LDA CXM1P;3 Get player00-m1 collision
  AND #$80;2
  RTS;6

PBCollision_3:
  LDA CXM1P;3 Get player01-m1 collision
  AND #$40;2
  RTS;6

Edited by Nukey Shay
Link to comment
Share on other sites

Nope, nothing that fancy. The weird thing is I can go into the yellow castle just fine, but not the black or white ones. I started out this hack by taking the Adventure Country hack that I posted here but I switched over to a fresh 8k Adventure format so I could get rid of the room data crossing over page boundaries (I'm still having trouble getting it to assemble when I put in ORGs and RORGs). Since it won't assemble now anyway I might as well go back to the original hack I was doing. At least I could get into the castles. I thought I had that ORG RORG stuff figured out, but I guess not. Oh well, pages crossing boundaries isn't that big of a deal.

Link to comment
Share on other sites

The only other thing that I can think of (without seeing actual code) is that the values provided in CastleRoomOffsets

doesn't match the first byte in PortInfo1, 2, and 3. These must be the same (watch out for missing "$" on hex values). Not EntryRoomOffsets...these are the rooms you get sent to). Also, keys and gates must run consecutively in memory.

 

And managing ORG $xx00's is not so difficult...just only put a maximum of 256 bytes between them. If you go over that, Dasm will report it (so grab a full bitmap and move it someplace else).

Link to comment
Share on other sites

A good habit to start doing is to change very little at a time between revisions of your code. Playtest after each couple of lines you add/change so you know exactly what causes a problem if one should arise.

 

In fact, keep a copy of each major revision so if a problem crops up, you can revert back to your last known working state. It has saved me A LOT of time. Right now I have a folder with my last 14 major revisions, and fortunately they saved me around revision #13 when I couldn't figure out why I was starting to get a black screen.)

 

Oh, and ORG and RORG tags make data tables so much easier to organize without crossing page boundaries. You can place 12 screen bitmaps on a page with 4 bytes left over. Making sure you don't cross these boundaries is what prevents the playfield from having skewed pixels in-game (something I saw a few times in your Adventure Country hack).

Edited by EarthQuake
Link to comment
Share on other sites

A good habit to start doing is to change very little at a time between revisions of your code. Playtest after each couple of lines you add/change so you know exactly what causes a problem if one should arise.

I am definitely going to start doing that.

Oh, and ORG and RORG tags make data tables so much easier to organize without crossing page boundaries. You can place 12 screen bitmaps on a page with 4 bytes left over. Making sure you don't cross these boundaries is what prevents the playfield from having skewed pixels in-game (something I saw a few times in your Adventure Country hack).

I was able to make them work in the Dragon's Lair hack of Missadventure Revised, but I can't seem to get them to work in the Adventure Country hack. When I put the ORGs and RORGs in it comes up with the "origins reverse indexed" error. I'm going to have to ignore it for now I guess.

Link to comment
Share on other sites

That error is usually attributed to a specified address that is lower than the address that the previous ORG had (i.e. trying to go in reverse). Search for ORG from top-to-bottom and make sure that they are sequential. Dasm will tell you what ORG did it right above the error ;)

 

Example:

I stuck an ORG of $1B00 below a byte that had an ORG of $1BFF in Raiders. Here's what Dasm told me:

 

DASM V2.20.10, Macro Assembler ©1988-2004

segment: INITIAL CODE SEGMENT 1b00 eqm vs current org: 1c00

Raiders.asm (1895): error: Origin Reverse-indexed.

Aborting assembly

 

You can also avoid that problem by using ALIGN 256 instead. I use ORG's, but you don't have to follow my methods. The goal is just to keep bitmap info off page breaks so that no glitching occurs. Either method gets you there.

Edited by Nukey Shay
Link to comment
Share on other sites

What Nukey was trying to say was that the error you got is because one or more of your ORG/RORG tags has a value that is higher than the ORG/RORG tags that follow it. ORG tags are much better because you can see exactly how it's organized and how many bytes each page has. Here are how the tags are in my code:

 

2600 constants here...
Game variables here...

ORG  $1000
RORG $D000

Code for first bank here...

ORG  $10E4 <- These might change depending on
RORG $D0E4 <- how much space your code takes up.

28 bytes of data tables can go here...
Again, this amount of free space might change.

ORG  $1100
RORG $D100

256 bytes of data tables can go here...

ORG  $1200
RORG $D200

You can put more data tables...

ORG  $1300
RORG $D300

...between each of these tags.

ORG  $1400
RORG $D400

You can put 256 bytes of data on each page.

ORG  $1500
RORG $D500

ORG  $1600
RORG $D600

ORG  $1700
RORG $D700

ORG  $1800
RORG $D800

ORG  $1900
RORG $D900

ORG  $1A00
RORG $DA00

ORG  $1B00
RORG $DB00

ORG  $1C00
RORG $DC00

ORG  $1D00
RORG $DD00

ORG  $1E00
RORG $DE00

ORG  $1F00
RORG $DF00

248 bytes of data tables can go here...

ORG  $1FF8
RORG $DFF8

6502 vectors are here...

ORG  $2000
RORG $F000

Code for second bank here...

ORG  $27FB <- Again, the values used here depend
RORG $F7FB <- on how much space the code takes up.

And because my code almost ends up taking an additional page,
I'm left with 5 bytes here. ($2800 minus $27FB equals 5) 

ORG  $2800
RORG $F800

And use tags here just like I did in the first bank.

ORG  $2FF8 <- Leave unchanged.
RORG $FFF8

 

 

Remember, if you try to squeeze too much data between org tags, it will complain about it. That is it's purpose, to tell you if your data crosses pages. Always count up the bytes in your data and separate your tables so they fit between the tags. Sometimes it's like a puzzle, but if you're using the 8K source, it will be easy to find places for your table. One note about the tags, the Room Data Table is larger than 256 bytes. This means you have to leave out an ORG/RORG tag so you have a "page" of 512 bytes. I would suggest putting the Room Data Table at the very end of your source file.

 

Remember that you don't need ORG/RORG tags in every section. They just help you keep track of how much ROM space you're using.

 

I didn't miss anything, did I Nukey?

Edited by EarthQuake
Link to comment
Share on other sites

You got it right, but that's not what he asked ;)

 

 

Replace -almost- all occurances of ORG/RORG with ALIGN 256 (keep at least 1 space in front of the word so Dasm won't mistake it for a label)...you could just comment them out or delete them...

 

ex:

;	  ORG $1F00
;	  RORG $DF00
  ALIGN 256

 

Keep the ORG/RORG at the start of each bank (so Dasm is given an intro address to assemble to), and the end of each bank (so that the reset/interrupt vectors stay at $xFFC-$xFFF). $xFF8-$xFFB remain unusable in an F8 binary.

 

You still need to be careful about adding more than 256 bytes between them. If a section contains more than that, Dasm won't report an error. If/when the next ALIGN 256 command is reached, Dasm will just skip over uneven addresses until it reaches the next page break at $xx00 (potentially wasting up to 255 bytes of ROM). That is why I prefer using ORG's ;) You don't need to worry so much about Adventure, because you can just count the number of screen bitmaps you place between them. 256 divided by 21 bytes per screen = 12 screens with 4 bytes left over.

Edited by Nukey Shay
Link to comment
Share on other sites

Thanks for the help guys. I think I've narrowed the problem down. I commented out some of the ORGs and RORGs then tried assembling it and found that the problem lies with 3 different ones. 1C00, 1D00, and 2CDE. I changed some of the sprite graphics that lie between 1C00 and 1D00 so that may be part of the problem. The 2CDE tag is the one before the room data tables which are larger than they used to be (which may be another part of the problem).

 

I always assumed the tags went something like this with an ORG RORG before the data:

 

ORG

RORG

256 bytes of data

 

 

But it seems like you are saying you need an ORG RORG before and after the 256 bytes of data which would look more like this:

 

ORG RORG

256 bytes of data

ORG RORG

 

I haven't tried the ALIGN 256 yet. I'd hate to waste all that extra space if there's a chance I can figure out this ORG RORG stuff.

 

Edit: Oh yeah, one more dumb question. How do you count bytes so that you know whether or not you are over the 256 bytes (like with the sprite graphics)?

Edited by accousticguitar
Link to comment
Share on other sites

You don't have to if you are using ORG to seperate pages. That's why I like it. If you try placing 257 bytes between (for example) an ORG $1D00 and ORG $1E00, Dasm will complain...printing this right on the screen:

 

DASM V2.20.10, Macro Assembler ©1988-2004

segment: INITIAL CODE SEGMENT 1E00 vs current org: 1E01

filename.asm (xxxx): error: Origin Reverse-indexed.

Aborting assembly

 

"Initial code segment" is where it tried to ORG. "Vs. current org" is the current address that it's at (it spilled over 1 byte because I tried putting 257 bytes between them).

"filename.asm" is the name of the assembly, and "(xxxx)" would print a number...the line number in the assembly file that the error occurs on (useful if you are using a text editor that shows your current line #).

 

 

 

I dunno an efficient way of counting bytes between ALIGN's (other than manually looking at them).

Link to comment
Share on other sites

BTW an ending ORG/RORG (by itself) means nothing unless it's followed by at least one byte, value, opcode, or whatever. It's just a setting for Dasm to use when placing data in a file. So if you had more than 256 bytes between pages in one area, Dasm might not complain at all. Like this:

 

Ex...

	  ORG $1E00
;257 or more bytes follow...
  ORG $1F00
;nothing here

;vector stuff at the end
  ORG $1FF8
  .word 0,0,START,0

 

The ORG at $1F00 didn't catch the problem because Dasm didn't try placing anything there. It wouldn't notice there's a problem until it spills over $1FF8 (because that's where the next set of data actually exists in this example).

 

 

Also, you can use ORG to fill a block of memory if you want. Unreferenced areas will automatically get filled with the byte $FF, but you can change it to whatever you want. This fills leftover memory before $1F00 to zero...

 

Ex...

	  ORG $1F00,0

 

 

About RORG...

You might be wondering why these are required. The is due to the 6507's limitations. All ROM must be assembled to odd-numbered 4k blocks of memory. If you tried just using ORG $1000 for the first block and ORG $3000 for the second, Dasm would assume that another 4k block exists at $2000 (and it will happily fill 4k of $FF's between them)...generating a 12k binary. That's where RORG comes in and corrects things. You can ORG to $1000 and $2000 (avoiding the "assumed" block problem), and RORG to odd-numbered blocks to keep the 2600 happy.

Link to comment
Share on other sites

Counting bytes...

 

Although Nukey is correct in that you don't have to count bytes, because DASM tells you which ORG tag is being "overflowed" and by how many bytes, it's always helpful to know anyways.

 

Tables are series of bytes that routines in your code can easily sift through. Here are some examples:

 

Simple 3-byte table...

 .byte $00, $00, $00

 

Dragon difficulty table at 6 bytes...

DragonDiff:		.byte $D0,$E8	; Level 1 (Position B, Position A)
			   .byte $F0,$F6	; Level 2 (Position B, Position A)
			   .byte $F0,$F6	; Level 3 (Position B, Position A)

 

Part of the object data table at 24 bytes...

YellowPortcullisData: .word PortcullisInfo1, YellowPortcullisR, PortcullisStates
				  .byte $00,$00
WhitePortcullisData:  .word PortcullisInfo2, WhitePortcullisR,  PortcullisStates		  
				  .byte $00,$00
BlackPortcullisData:  .word PortcullisInfo3, BlackPortcullisR,  PortcullisStates		  
				  .byte $00,$00

 

Each value after a .byte is one byte, and each value after a .word is two bytes. It helps to add a little comment at the end of each table telling how many bytes it uses (although you gotta remember to change this if you modify the table).

 

And also, this is totally unrelated, but it's a cool addition when your hack is finished and you have some extra bytes left. You can create a table where each value corresponds to an ascii character, so when your hack is viewed in a hex editor with text viewing, you can have a secret message or author information!

 

	   .byte $45,$41,$52,$54,$48,$51,$55,$41,$4B,$45

:D

post-5734-1223810563_thumb.png

Edited by EarthQuake
Link to comment
Share on other sites

Yay, I got it to work by counting bytes! (Where is the emoticon for clapping hands in childish glee?) I was way over in a couple places. Thanks for all the help! I do have one more question. How many bytes are the room data tables? I'm guessing 8 bytes per room.

Link to comment
Share on other sites

In RoomDataTable?

 

8 per room in the 8k assembly, 9 per room in the original game (because it included an alternate color value for the B&W switch). This table most likely spill over (and it's nothing serious to the console when it does). The only way to avoid it would be to never have more than 32 total screens. Most of Adventure's tables are not time-critical...just the bitmaps of screens and objects. Of course, it's always good practice to save cycles wherever possible (so that future additions have extra time).

Link to comment
Share on other sites

Something that would save a lot of space in the game is to edit that huge RoomDataTable into seperate tables. One for the LSB of the first variable, one for the MSB, one for the color, etc. Then it's no longer necessary to do a subroutine to fetch a base address and dink around with Y offsets/indirect loads (the room number itself becomes the offset for each specific table). The same could be done with the Objects table (the object number itself becomes the offset for reading).

 

I might make an updated version of the 4k and 8k optimized code, as this simple change could lead to a lot of spare time before a screen call is needed (maybe even get it down to 2 frames - improving performance).

Link to comment
Share on other sites

By the way I figured out one cause for the portcullis' not to work. If you rearranged things in the main game loop to optimize it, calling the portcullis routine too late in the loop will recreate the exact problem you had. In my case, I placed it right before the main game loop returns to the beginning, right after the last PrintDisplay.

 

Atwwong! I see you buddy! ;)

Edited by EarthQuake
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...