Jump to content

Mord's Blog

  • entries
    170
  • comments
    93
  • views
    100,660

Action RPG


Mord

437 views

Adding the playfield was a nightmare.

 

I had thought up ways of trying to impliment it but not only could I not get

them to work at first - I also saw the glaring problem of excessive ram usage that

really wasn't necessary. As a result, versions 0.002 and 0.003 are dead. I could

have just named this as version 0.002 but given this version does reuse some of the

code I wrote in both versions 0.002 and 0.003...

 

The playfield has a similar, but greater, resolution as Atari's Adventure. Adventure

divides the screen up into 7 zones. the middle 5 being twice as big as the top and bottom

zones. Using some simple math on 192 scanlines for a visible picture, you see that

it uses a 16/32/32/32/32/32/16 zone approach. This is ok, but since I'm planning on

bankswitching this rom later on, I can afford to use up the extra rom to have equal

sized zones. In this version, I drew the yellow castle as the playfield. It has nothing

to do with the game idea I'm heading towards, but does show some of the possibilities.

 

Additionally, I'm surprised I've still managed to keep in the background changing

code so far. There was almost not enough time to do everything I wanted however so

when I go ahead to adding a few more things it'll probably have to go, or get limited

somehow.

 

Two problems I had with this code - not updating things fast enough in instances

where I had to update the player AND the playfield at the same time. I was just barely

late in updating the Playfield registers. As a result it gave me an odd looking error

in the form of "playfield bleeding" onto the next line. Because I forgot that P1 is

arranged differently than P0 and P2, it took me a while to figure out exactly what

was going on. It was only affecting the left side however so I knew it had to be

a timing issue. ^^;; To fix it, I moved some things with the background color around,

pushing the update of the variable to after the playfield was updated (5 cycles freed)

then moved the loading of the bgcolor variable just before the line's WSYNC instead

of right after it. (3 cycles)

 

There was also a case where the screen would roll whenever the player crossed over

a zone boundary. (the top line of the player only) The problem was with how I had

added the code to set PlayerSize into Y to determine how long to keep displaying the

player before we turned it (the missiles) off again.

 

dec LineCounter
ldy PlayerSize
bne .SomeLabelI'mForgettingTheNameOf ^^;;

 

Basically that's what I did. I shoved the ldy right between a DEC that was trying

to count down the lines remaining in the current zone, and the bne that was waiting to

test for the Zero Flag that the dec would at one point set and signal a new zone.

 

Because PlayerSize is always non-zero....

 

Anyway, moving it fixed the problem.

 

My next goal is to play with the collision latches and to start in on the

collision detection between the player (missiles) and the playfield. This should

be a simple update compared to adding the playfield. X_X

 

Oh, and while I'm now calling it "Action RPG", don't anyone get their hopes up for a finished

rom any time soon. ;) For attachments, I've included a screenshot of what version 0.004 looks

like, as well as a zip containing screenshot, notes, rom, and source for version 0.001.

4 Comments


Recommended Comments

You might want to look at Nukey Shay's adventure hacks. They include a very nice way by which playfield "zones" may vary in size, even within a room. From top to bottom, label each scan lines pair as follows:

DABACABAEABACABA (repeating every 16 line-pairs). If the leat-significant nybble of a zone's PF0 data is $0F, the zone will extend until the next "E" line pair. If $07, until the next "D" or "E" pair. If $03, "C", "D", or "E". If $01, the next line pair that isn't "A". If $00, to the next line pair.

 

This makes it possible to include rather fine details in the rooms without expanding memory requirements in places such ability is not exploited.

Link to comment

BTW, if you're trying to save a few cycles in the kernel, you might want to have separate kernel loops for the following cases:

  • Above both sprites, both of which start on the same scan line
  • Above both sprites, with P0 starting first
  • Between the tops of P0 and P1
  • Below the tops of both sprites

Requiring P0 to start above P1 should not pose any particular problem, though if you didn't want to impose that requirement you could add two more cases. Some further time savings could be achieved if you separated out the cases that were completely below sprites (WR's game design just keeps showing the last blank row of a sprite over and over again) but that might add some extra complexity.

Link to comment

BTW, if you're trying to save a few cycles in the kernel, you might want to have separate kernel loops for the following cases:

  • Above both sprites, both of which start on the same scan line
  • Above both sprites, with P0 starting first
  • Between the tops of P0 and P1
  • Below the tops of both sprites

Requiring P0 to start above P1 should not pose any particular problem, though if you didn't want to impose that requirement you could add two more cases. Some further time savings could be achieved if you separated out the cases that were completely below sprites (WR's game design just keeps showing the last blank row of a sprite over and over again) but that might add some extra complexity.

 

 

Thanks for the tips. I haven't added sprites into the kernal yet as I build this thing up little by little, but things like that have been on the corner of my mind for a while already.

 

Looking at the other note about the playfield zones, I have a vague idea what you're talking about, but something's not clicking somewhere. Probably a good thing that I'm going to look at collision detection next for a bit so I can hopefully figure out exactly how nukey's technique works. :lust: :D

Link to comment
Looking at the other note about the playfield zones, I have a vague idea what you're talking about, but something's not clicking somewhere. Probably a good thing that I'm going to look at collision detection next for a bit so I can hopefully figure out exactly how nukey's technique works. :lust: :D

 

Nukey's technique is a bit tricky, but worth considering. Because the kernel uses three bytes of ROM for each playfield zone, but the TIA ignores four bits of one of them, those bits are free for other purposes.

 

Warren Robinett's original kernel did something like:

 lda ScanLineCnt
 and #$0F
 bne no_new_row
; Now handle new playfield row
 ldy RoomDefIndex
 lda (RoomLo),y
 sta pf0
 iny
 lda (RoomLo),y
 sta pf1
 iny
 lda (RoomLo),y
 sta pf2
 iny
 sty RoomDefIndex

Nukey managed to squeeze in enough cycles to change it to something like:

 lda ScanLineCnt
 and $FA
 bne no_new_row
; Now handle new playfield row
 ldy RoomDefIndex
 lda (RoomLo),y
 sta pf0
 iny
 lda (RoomLo),y
 sta pf1
 iny
 lda (RoomLo),y
 sta pf2
 iny
 sty RoomDefIndex
...
no_new_row:
 ldy RoomDefIndex; Note we can afford to spend a little extra time here since we're not updating playfield
 lda (RoomLo),y
 and #$0F
 sta $FA

A bit tricky, but nonetheless elegant in its own way.

Link to comment
Guest
Add a comment...

×   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...