Jump to content
IGNORED

Scrolling Playfield


Mikes360

Recommended Posts

Hi Guys,

 

Many games on the Atari 2600 now have very nice horizontal and vertical scrolling engines. I am looking to implement one myself and am looking for ideas for how this should be done. I have attached a image of a mock up playfield that I want to create with a black windows showing the players visible area.

 

So I would like advise in these areas:

  • How this data is stored in ROM
  • How the data is fetched and drawn in a kernel
  • How the current position within the level is stored
  • How player sprites may also be drawn within this framework

I have herd people talk about tiling engines I guess that may be a god way to approach the problem, again I am not familiar to this.

 

Thanks and I hope to hear from you soon.

 

Thanks,

Mike

post-34963-0-40587500-1391440948_thumb.png

Link to comment
Share on other sites

Mikes360,
great questions! :) Awesome you are building a Framework, here are some ideas that may be helpful:

 

How the data is stored in ROM; you won't get much advantage from storing it flipped around since you need to be able to scroll the bits back and forth through reversing playfield registers. Do you need to be able to modify your large virtual world? If so you will need extra RAM like the SuperChip.

 

How is the data fetched and drawn in a kernel - the bits in the target playfield window you've shown with the black box need to be flipped to and fro to fit the playfield when reassembled.

 

How is the current position within the level stored - you may want to have an x,y addressable camera object so you can easily pan the playfield around.

 

Player sprites could have two methods - being able to map them to the local playfield and being able to map them to a virtual world pixel/tile so they move with the camera, only showing up when their target tile is also visible within the camera view.

 

Link to comment
Share on other sites

This topic is of interest to me as well. In my 4 way scrolling engine each element stores 8 horizontal playfield pixels. Since I can only address 256 elements that makes my levels 16 rows deep and 128 columns wide.

 

The next level challenge is to smoothly transition from one 256 element array to the next to make areas seem bigger.

  • Like 1
Link to comment
Share on other sites

I was wondering if a 40 pixel wide scrolling asymmetrical playfield would be possible. I have seen examples of 20 pixels does anyone know of a 40 pixel example? I have read about ASDK and bolderdash both are very impressive.

 

Mikes360,

There are some fantastic demo examples with a 40 pixel scrolling playfield but they use mapping tables, not dynamic techniques. A 40 pixel game engine would be pretty cool!

 

The limits of the table size for your virtual world bitmap might make it necessary to transition between two or more tables like Loon is looking at doing if you want the virtual world many times larger than the screen.

 

We can store a maximum of 2048 BITS (256 bytes) in a virtual world bitmap table so if we limit ourselves to one table this is going to limit the size of our virtual world and how many times bigger than the playfield it can be:

 

The 20 pixel wide scrolling playfield for the ASDK is 10 pixels tall, yielding 200 large tile pixels on screen which makes for a virtual world 10x larger than the screen.

 

I've chosen dimensions of 92x20 so this works out to fitting 5 screens (a playfield being considered a "screen") across by two screens down.

 

If your playfield is 40 pixels across by 20 pixels down you'll be marshalling 800 pixels on the screen/playfield from a virtual world 2.5x the size of the screen.

Link to comment
Share on other sites

Super Cobra scrolls 40 pixels.

 

What examples do you have that scroll 20? That's only half the screen.

Super Cobra is a fun game! I first played a version of this called Whirly Bird Run on the CoCo :)

 

It looks like it is using techniques like in the demos for it's 40 pixel wide scrolling playfield not a dynamic virtual world.

 

BoulderDash and the ASDK have tile engines; the ASDK scrolls 20 large tile pixels accross by constructing them out of 40 pixels; the resulting large virtual pixels/tile size fits an 8x8 fine pixel sprite.

Link to comment
Share on other sites

It looks like it is using techniques like in the demos for it's 40 pixel wide scrolling playfield not a dynamic virtual world.

 

Based on "How this data is stored in ROM", I didn't think he was asking for a dynamic world.

 

BoulderDash and the ASDK have tile engines; the ASDK scrolls 20 large tile pixels accross by constructing them out of 40 pixels; the resulting large virtual pixels/tile size fits an 8x8 fine pixel sprite.

I'd imagine that techniques used in BoulderDash would be more than a bit overwhelming for somebody just starting out on the 2600 (I'm assuming this based on this topic being in the Newbies forum). I'm not familiar with ASDK - I gather that's where he's seen examples of 20 pixel scrolling.

Link to comment
Share on other sites

 

 

Based on "How this data is stored in ROM", I didn't think he was asking for a dynamic world.

 

 

I'd imagine that techniques used in BoulderDash would be more than a bit overwhelming for somebody just starting out on the 2600 (I'm assuming this based on this topic being in the Newbies forum). I'm not familiar with ASDK - I gather that's where he's seen examples of 20 pixel scrolling.

 

Spice,

good point! From discussion the BD techniques are very advanced, involving a lot of precalculations and memory.

 

The OP seems to be an advanced developer judging from Point Zero (and the fact that he wants to build a scrolling tile engine) but I don't think anyone could easily reuse the BoulderDash techniques simply they are proprietary and the commented source is unavailable.

 

The ASDK's source is available and fully commented and the routines could be a helpful reference for advanced developers who are actually building their own tiling engines.

 

The ASDK is easy for beginners to use too without going under the hood (developers can even use bB); the idea was to provide a Framework where scrolling and all graphics functionality was transparent; an Assembly developer who comes straight from c64 or VIC-20 land can use the ASDK to build scrolling Atari games right away :)

Link to comment
Share on other sites

This topic is of interest to me as well. In my 4 way scrolling engine each element stores 8 horizontal playfield pixels. Since I can only address 256 elements that makes my levels 16 rows deep and 128 columns wide.

 

The next level challenge is to smoothly transition from one 256 element array to the next to make areas seem bigger.

 

The question I've been thinking about recently is would it make more

sense to keep track of bits and byte seperately in the x direction

 

ie if you use a single byte for x (and 8 bit math) you're limited to

a 32 byte wide world.

  • Like 1
Link to comment
Share on other sites

Answering a few more questions I think a static world would be fine for the play field itself. I have looked at the DPC+ demos and think that would be a great way to trim cycles in the drawing kernel as I am currently using Indirect Indexed addressing and I barely have 20 cycles left to do other GFX I would need.

 

With regards to my current approach I am thinking of just laying the play filed data out linearly in ROM and having 6 RAM pointers that just get set so if a player moves right by one pixel I just increment all the pointers by one and visa-versa.

 

Seems a fairly simple starting point.

Link to comment
Share on other sites

Super Cobra scrolls 40 pixels.

 

I have taken a look at this is the game using some kind of extended RAM? I can see it's listed in stella as E0* (8K).

 

I am currently thinking the only way to do it nicely would be to have a large RAM buffer that I populate with the current play field data and when the player moves left I shift the current play field bytes out by one bit and load the next byte and shift that in by one bit.

 

This would be possible with DPC+ I guess but there must be a simpler way.... Can anyone shed any light on how Super Cobra does it?

Link to comment
Share on other sites

It uses a RAM buffer, with no additional RAM on the cartridge (only extra ROM).

 

I don't know if Super Cobra does this, but if you're looking to save RAM, you can use the lower nybble of the PF0 buffers to store data, as the lower nybble doesn't get displayed on the TV.

 

I did something very similar to what you're trying to accomplish in this demo:

 

http://atariage.com/forums/blog/207/entry-7336-wonder-boy-2600-wip/

 

Unfortunately I don't remember how I did it off the top of my head. I'll try to dig up the source sometime soon, perhaps I can point you in the right direction.

Link to comment
Share on other sites

It looks to me like if you want to get horizontal scrolling working at single pixel resolution you will need to shift bits in and out from some kind of RAM buffer.

 

This will also need to be done for every new PF line so you would change the PF GFX every two or even three scanlines to accommodate this and remove single line resolution.

 

Unless your using DPC+ then you could set your PF up outside the main kernel.

 

Anyone have any other suggestions?

Edited by Mikes360
Link to comment
Share on other sites

I always wonder by these kind of games (games with big maps, small memory footprint) how the levels are stored. I assume there must be some sort of compression going on? Things would get even more interesting if you throw in a random number generator.

Edited by roland p
Link to comment
Share on other sites

Many (old) games use pseudo random number generators (PRNG) which can be a very simple

small routine which generates (reproducable) series of numbers.

Some are even tuned to i.e. generate ALL 256 byte values in a non linear fashion etc.

Assembloids2600 uses those ;-)

The Atari2600 itself uses something related, the polynomial counters, in hardware even.

Pifall, Elite as well (famous examples).

Recently that approach is hyped even for current gen games again (which is ridiculous really, I mean to hype it ;).

I.e. you can feed it with any value and it will always provide the same following value, which is not linearly based on the seed.

Some of them work both ways, so you seek back and forth.

Some early games (also for C64) use SINGLE bytes for a level map.

I.e. bit 0,1,2 decide the terrain type, bit 3,4 decide in which direction to exit and 5,6,7 decide which monsters to meet or such.

This one below is one out of Assembloids2600

The# $1d is one of the great 'magic bytes' that generate a complete series.

rnd8
.(
           lda seed
           beq doEor
           clc
           asl
           beq noEor 
           bcc noEor
doEor      eor #$1d
noEor      sta seed
  rts
.)
Edited by enthusi
  • Like 1
Link to comment
Share on other sites

You could break level's down into graphical components like trees, buildings ect and then build levels up of sequences of these components referenced as table indexes for example.

 

Then a level may be described in a few bytes.

 

This would only be a good idea if you have levels with lots of repeating GFX I guess.

Link to comment
Share on other sites

 

good point! From discussion the BD techniques are very advanced, involving a lot of precalculations and memory.

The OP seems to be an advanced developer judging from Point Zero (and the fact that he wants to build a scrolling tile engine) but I don't think anyone could easily reuse the BoulderDash techniques simply they are proprietary and the commented source is unavailable

 

We are happy to answer questions. Detailed questions. And provide source code for the tiling engine, even if in dribs and drabs. However anything copyrighted to FSS or Boulder Dash® specific cannot be released..

The tiling engine used in BD is extremely complex, and the result of many years of development.

  • Like 1
Link to comment
Share on other sites

We are happy to answer questions. Detailed questions. And provide source code for the tiling engine, even if in dribs and drabs. However anything copyrighted to FSS or Boulder Dash® specific cannot be released..

 

Lurking programmer too afraid to posts says to himself: "I watch my dreams fly away like a balloon. Why do people always cut my string?"

 

post-13-0-15997300-1391616871.gif

 

:D

Link to comment
Share on other sites

 

Lurking programmer too afraid to posts says to himself: "I watch my dreams fly away like a balloon. Why do people always cut my string?"

 

attachicon.gifballoonbye-bye.gif

 

:D

 

Take a public domain play-alike like Cave Runner and convert the graphics and levels.

http://hol.abime.net/5933

 

Pretty sure the CaveRunner authors would be agreeable as is Andrew Davie and Thomas Jentzsch to provide advice on modifying their game engine.

Link to comment
Share on other sites

I have hit a bit of an issue. Say I want to store my PF2 GFX in PF1 (As a scene moves right). The data needs to be un-reversed. How would you recommend its done?

 

Would you create two versions of the GFX (normal + reversed)?

  • I would imagine you just have a table of the GFX data addresses and depending on if you writing to PF2 or PF1 you just load from the different tables. It would be super useful to define the GFX as normal and have a macro that generated a reversed version for you!

 

Or would you just flip the GFX on the fly? Seems expensive to do mid kernel unless the below can be optimised to hell!

  • MAC REVERSE_BYTE ; byteToSwap, swappedByte
        ASL {1}
        ROR
        ASL {1}
        ROR
        ASL {1}
        ROR
        ASL {1}
        ROR
        ASL {1}
        ROR
        ASL {1}
        ROR
        ASL {1}
        ROR
        ASL {1}
        ROR
        STA {2}
    ENDM
    

 

Link to comment
Share on other sites

Say you want to scroll the PF image to the left. Your code would look something like this:

 

    ;get new bit of PF into carry flag somehow before this. X contains line index

    ror PF2RightBuffer,X
    rol PF1RightBuffer,X
    ror PF0RightBuffer,X

    lda PF0RightBuffer,X
    and #%000010000
    beq CarryNotSet
    
    sec
    .byte $24  ; opcode for BIT zeropage instruction. has no effect on carry flag, effectively skips next byte

CarryNotSet

    clc
    
    ror PF2LeftBuffer,X
    rol PF1LeftBuffer,X
    ror PF0LeftBuffer,X

I have not tested the above code, but something like it should work (and I believe that's how I did the scrolling in my demo). The idea is you don't have to reverse the bytes, you can just reverse the rox instruction.

 

Note that this code will trash any data you had living in the lower nybble of the PF0 buffers. There are ways around it though.

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