Mikes360 Posted February 3, 2014 Share Posted February 3, 2014 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 Quote Link to comment Share on other sites More sharing options...
Mr SQL Posted February 3, 2014 Share Posted February 3, 2014 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. Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted February 3, 2014 Share Posted February 3, 2014 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. 1 Quote Link to comment Share on other sites More sharing options...
Mikes360 Posted February 4, 2014 Author Share Posted February 4, 2014 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. 1 Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted February 4, 2014 Share Posted February 4, 2014 Super Cobra scrolls 40 pixels. What examples do you have that scroll 20? That's only half the screen. Quote Link to comment Share on other sites More sharing options...
Mr SQL Posted February 4, 2014 Share Posted February 4, 2014 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. Quote Link to comment Share on other sites More sharing options...
Mr SQL Posted February 4, 2014 Share Posted February 4, 2014 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. Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted February 4, 2014 Share Posted February 4, 2014 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. Quote Link to comment Share on other sites More sharing options...
Mr SQL Posted February 4, 2014 Share Posted February 4, 2014 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 Quote Link to comment Share on other sites More sharing options...
bogax Posted February 4, 2014 Share Posted February 4, 2014 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. 1 Quote Link to comment Share on other sites More sharing options...
Mikes360 Posted February 4, 2014 Author Share Posted February 4, 2014 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. Quote Link to comment Share on other sites More sharing options...
Mikes360 Posted February 4, 2014 Author Share Posted February 4, 2014 Although when I say 'linearly' I don't quite know about that bit yet! Quote Link to comment Share on other sites More sharing options...
Mikes360 Posted February 4, 2014 Author Share Posted February 4, 2014 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? Quote Link to comment Share on other sites More sharing options...
Wickeycolumbus Posted February 4, 2014 Share Posted February 4, 2014 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. Quote Link to comment Share on other sites More sharing options...
Mikes360 Posted February 5, 2014 Author Share Posted February 5, 2014 (edited) 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 February 5, 2014 by Mikes360 Quote Link to comment Share on other sites More sharing options...
roland p Posted February 5, 2014 Share Posted February 5, 2014 (edited) 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 February 5, 2014 by roland p Quote Link to comment Share on other sites More sharing options...
enthusi Posted February 5, 2014 Share Posted February 5, 2014 (edited) 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 February 5, 2014 by enthusi 1 Quote Link to comment Share on other sites More sharing options...
roland p Posted February 5, 2014 Share Posted February 5, 2014 (edited) Cool! There seem to be 16 magic bytes: http://codebase64.org/doku.php?id=base:small_fast_8-bit_prng and a 16 bit version: http://codebase64.org/doku.php?id=base:small_fast_16-bit_prng Is such thing bidirectional? Edited February 5, 2014 by roland p Quote Link to comment Share on other sites More sharing options...
Mikes360 Posted February 5, 2014 Author Share Posted February 5, 2014 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. Quote Link to comment Share on other sites More sharing options...
+Andrew Davie Posted February 5, 2014 Share Posted February 5, 2014 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. 1 Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted February 5, 2014 Share Posted February 5, 2014 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?" Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted February 5, 2014 Share Posted February 5, 2014 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?" balloonbye-bye.gif 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. Quote Link to comment Share on other sites More sharing options...
bogax Posted February 5, 2014 Share Posted February 5, 2014 (edited) Here's a page with lists of feedback terms Cool!There seem to be 16 magic bytes: http://codebase64.org/doku.php?id=base:small_fast_8-bit_prngand a 16 bit version: http://codebase64.org/doku.php?id=base:small_fast_16-bit_prngIs such thing bidirectional? Edited February 5, 2014 by bogax Quote Link to comment Share on other sites More sharing options...
Mikes360 Posted February 5, 2014 Author Share Posted February 5, 2014 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 Quote Link to comment Share on other sites More sharing options...
Wickeycolumbus Posted February 6, 2014 Share Posted February 6, 2014 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. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.