Advice on the Art of Genesis level Building
Moderator: BigEvilCorporation
-
- Very interested
- Posts: 2440
- Joined: Tue Dec 05, 2006 1:37 pm
- Location: Estonia, Rapla City
- Contact:
In my stuff I have a "zone" based setup. All of the stages are built of 16x16 tile zones, each zone is compressed with non bloatly RLE (1 data element for up to 4 same tiles, 2 data elements for 5 to 65536 consecutive tiles). Each tile is 16x16 pixel block, and there's always 4 active zones, where objects are checked etc. For faster seeking in level data there's a seek table too when needed, and there's some "instructions" between zones to trigger events or tile data updates etc.
Mida sa loed ? Nagunii aru ei saa
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen
-
- Very interested
- Posts: 2440
- Joined: Tue Dec 05, 2006 1:37 pm
- Location: Estonia, Rapla City
- Contact:
Its a platforming run 'n' gun mostly, inspired by Contra, Metal Slug and Turrican.eteream wrote:TmEE, what type of game is? (platformer, beat'm up,...)
How many scrolls have? (1,2,... 1 direction, both directions,...)
1 Foreground scroll layer(grounds etc.) and a backgorund layer, which I've not yet decided how to handle, scrolling happens in all directions.
Each sector requires 512 bytes of space when decompressed, there's always 4 decompressed sectors so 2Kbytes is needed at all times.
Mida sa loed ? Nagunii aru ei saa
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen
Yes, I was wrong: definitely you can work with compresed map-data in active game. For one direction scroll game simply keep decompressing when you need it. For multiple direction scroll make 'zones' as TmEE said.
Only one account, when screen scrolls it takes more CPU than when not.
But I think MD can't handle a deep tree to draw various objects in one frame.
There is any chance to see that NES game?
Megadrive can handle some binary command based scripting, but the whole world...?
Only one account, when screen scrolls it takes more CPU than when not.
You can create a map for the map (and go on... if you like), something like TmEE said. He has a blocks composed by tiles, and a map composed by blocks. But you can create more levels in this structure, and you get that tree. With the tree, finding something (for colision detection, drawing only near things,...) is easy and factible in a 3D world, while in memory you only have unique 3D objects.MottZilla wrote: In commercial games I've heard of compression techniques like a Tree system where you have your level made up of big blocks which are defined somewhere. Sometimes these big blocks are made up of smaller blocks that are defined elsewhere. Then with all of that you might use RLE or some other compression to get size down even more. I suppose if you only had a few of these "big" blocks or little blocks you could save data room by only using as many bits as you needed. I'm sure there are alot of ways to compress level data.
But I think MD can't handle a deep tree to draw various objects in one frame.
Completly true. But... you are speaking about: idle, background task... are you working in a PC game, a modern game? well, well, well... reply if you can do it.Gigasoft wrote: For tile updates, you could transfer a manageable number of tiles every frame until you're done. Uncompressing can be done in the background when the game is idle. In an upcoming game I'm making, I switch to a background task that performs loading of world data whenever I'm waiting for the next frame, enabling seamless scrolling in a very large world. I used the same technique in a NES game (which was never finished) with splendid results. In both games, I have 4x4 screenfuls loaded at once.
There is any chance to see that NES game?
I don't fully understant it. Are you talking about scripting (or some kind of it)? You do not have a tile map?Gigasoft wrote: The world data itself is command based, where there are commands to draw floors, walls and other objects, and the objects can be placed freely without regard for screeen boundaries.
Megadrive can handle some binary command based scripting, but the whole world...?
Nope, not PC, Mega Drive. I used the same technique on the NES. I switch to loading task at the end of frame processing, and the VBL handler returns me back to where I was before. Many Capcom NES and SNES games have support for (non-preemptive) multitasking too in the code, although they don't usually use it much. For example, in Mega Man 5, the debug key handler is a separate task.
I don't have a tile map in the ROM, it's dynamically created when moving around. Command based worlds were used in many popular Nintendo titles such as the Super Mario Bros series, Super Metroid, Zelda 2, Zelda 3 (in dungeons, caves and houses), but in those, loading only happened at screen transitions.
In my NES game, each screen was a separate data block, so objects had to fit within their screen. I found this to be too limiting, so in my upcoming Mega Drive game I have a technique where the world is divided into a tree of arbitrarily sized regions, and when loading a screeen, I find the objects that overlap the screen (using region commands to skip over large numbers of irrelevant objects) and draw the portion that is within the screen. It's okay for this process to take a couple of frames since it only happens for every screenful scrolled, and is running in the background loading screens that haven't scrolled into view yet. An early version of the system has been implemented and works, but I'm redesigning it to have better support for heights. There will be a terrain map containing byte indexes into a table with heights and ground types, a display map for planes A and B, and a map with heights for the blocks on A and B. They are all generated from the same data, except when plane A is separate from B. In total, these screens use 5000h bytes of RAM, still leaving plenty more for other things. Something that worked in the NES game but won't work here is breakable blocks, due to the detachment of terrain and display maps (the same block may not be loaded simultaneously in both maps).
I'll see if I can dig up that NES game, it's on my other computer.
I don't have a tile map in the ROM, it's dynamically created when moving around. Command based worlds were used in many popular Nintendo titles such as the Super Mario Bros series, Super Metroid, Zelda 2, Zelda 3 (in dungeons, caves and houses), but in those, loading only happened at screen transitions.
In my NES game, each screen was a separate data block, so objects had to fit within their screen. I found this to be too limiting, so in my upcoming Mega Drive game I have a technique where the world is divided into a tree of arbitrarily sized regions, and when loading a screeen, I find the objects that overlap the screen (using region commands to skip over large numbers of irrelevant objects) and draw the portion that is within the screen. It's okay for this process to take a couple of frames since it only happens for every screenful scrolled, and is running in the background loading screens that haven't scrolled into view yet. An early version of the system has been implemented and works, but I'm redesigning it to have better support for heights. There will be a terrain map containing byte indexes into a table with heights and ground types, a display map for planes A and B, and a map with heights for the blocks on A and B. They are all generated from the same data, except when plane A is separate from B. In total, these screens use 5000h bytes of RAM, still leaving plenty more for other things. Something that worked in the NES game but won't work here is breakable blocks, due to the detachment of terrain and display maps (the same block may not be loaded simultaneously in both maps).
I'll see if I can dig up that NES game, it's on my other computer.
Eteream:
What I'd say there is that there ARE a lot of games that do constantly or casually update tile data in VRAM. Contra simply could not be the only game (even if I haven't ever checked any other) because it shares engine with other games - for example Rocket Knight Adventures... Generaly same engine with changes and additions regarding specific effects and object behaviours.
All sonics except for first one, do update tiles frequently, in speific places in levels, that can only be passed one-way or through only one path, and have minimal tile usage on screen.
The best example of very smooth and fast, almost-constant "live" tile raster data updating is one in Sonic 3d blast. Almost-constant it is because it gets updated in small steps while also updating offscreen map whenever character moves. also all ground animation (water, snow, fans, bubbles, whatever) is done via DMA updating.
Such dma stuff is done also on many other games, while in different fashion, still share some common logic. As far as I remember, quite complex tile updating is used in "Mickey Mania" and other games sharing same engine ("Puggsy" for example).
Decompression is also very common thing for any game that has large levels, otherwise stuff gets needlessly bloated. For example, a large level (maybe mainly filled with air..?) of, lets say, 30 by 30 screens wil take up about 2Mbytes of cart space.
Macroblocks and RLE do make sense.
All macroblocks used in level may also be decompressed to 68k ram, for fast dma transfer to VRAM whenever needed.
ROMs are not realy that cheap today, if we talk about ones that are relatively glue-less compatible with genesis. Parallel NOR roms still cost considerable amounts of money, and cheap and 3.3V or 5V compatible ones are about 1..4Mbyte in reasonable prices. 16Mbyte is the upper limit and usualy require more specific power needs (say 3.0V) along with more specific bus voltage adapting. Large NAND arrays (the ones used in USB Sticks, CFs, SDs or any other nonvolatile memory) does not count here. It's completely different technology that requires faulty sector remapping and cannot be used without appropriate SRAM/DRAM on cart and 'magic' chip that will refresh the DRAM (no, segas built-in optional refresh on cart will not work with enything newer than 1990 DIP 4-bit wide DRAMs) and load the required blocks from the NAND array, while performing faulty sector mapping.
Everything can be built, especially in small quantities, yet if we'd want to produce large runs of carts, every cent matters. That meaning - less logic / voltage adaptation / psu stuff in cart, smaller rom chip(s) --> cheaper, faster production with more reliable products as the result
I think the optimum is still 4Mbytes of maximum cheap NOR rom, that is 16bit wide and in simple non-bga smd chip package. Advanced carts could have a small additional chip (that I can produce) with custom internals that helps to interface to larger NOR roms and perform address decoding and programmable page mapping, adapt simple peripheral (like i²c EEPROM that costs nothing - for savegames) to parallel access bus, and maybe add some reliable stereo dac with large intelligent FIFO.
Adding, for example, a super cheap nowdays gigabyte SD card inside cart can be done, but requires aforementioned 2..4Mbyte DRAM for page/segment loading, much smarter custom chip (that will cost more due to significantly larger internal resources required) that will have much more pins (because entire genesis address and data buss will have to be put THROUGH it), that might cause the need to choose BGA packages, that will require much finer at least 4-layer PCB production...
...and the price skyrockets.
I think genesis even phylosophicaly 'requires' skillful/artful/compact/tailored coding techniques to be used. Just like pixel-level tailoring of image data... Otherwise it's not realy that oldschool beauty anymore
What I'd say there is that there ARE a lot of games that do constantly or casually update tile data in VRAM. Contra simply could not be the only game (even if I haven't ever checked any other) because it shares engine with other games - for example Rocket Knight Adventures... Generaly same engine with changes and additions regarding specific effects and object behaviours.
All sonics except for first one, do update tiles frequently, in speific places in levels, that can only be passed one-way or through only one path, and have minimal tile usage on screen.
The best example of very smooth and fast, almost-constant "live" tile raster data updating is one in Sonic 3d blast. Almost-constant it is because it gets updated in small steps while also updating offscreen map whenever character moves. also all ground animation (water, snow, fans, bubbles, whatever) is done via DMA updating.
Such dma stuff is done also on many other games, while in different fashion, still share some common logic. As far as I remember, quite complex tile updating is used in "Mickey Mania" and other games sharing same engine ("Puggsy" for example).
Decompression is also very common thing for any game that has large levels, otherwise stuff gets needlessly bloated. For example, a large level (maybe mainly filled with air..?) of, lets say, 30 by 30 screens wil take up about 2Mbytes of cart space.
Macroblocks and RLE do make sense.
All macroblocks used in level may also be decompressed to 68k ram, for fast dma transfer to VRAM whenever needed.
ROMs are not realy that cheap today, if we talk about ones that are relatively glue-less compatible with genesis. Parallel NOR roms still cost considerable amounts of money, and cheap and 3.3V or 5V compatible ones are about 1..4Mbyte in reasonable prices. 16Mbyte is the upper limit and usualy require more specific power needs (say 3.0V) along with more specific bus voltage adapting. Large NAND arrays (the ones used in USB Sticks, CFs, SDs or any other nonvolatile memory) does not count here. It's completely different technology that requires faulty sector remapping and cannot be used without appropriate SRAM/DRAM on cart and 'magic' chip that will refresh the DRAM (no, segas built-in optional refresh on cart will not work with enything newer than 1990 DIP 4-bit wide DRAMs) and load the required blocks from the NAND array, while performing faulty sector mapping.
Everything can be built, especially in small quantities, yet if we'd want to produce large runs of carts, every cent matters. That meaning - less logic / voltage adaptation / psu stuff in cart, smaller rom chip(s) --> cheaper, faster production with more reliable products as the result
I think the optimum is still 4Mbytes of maximum cheap NOR rom, that is 16bit wide and in simple non-bga smd chip package. Advanced carts could have a small additional chip (that I can produce) with custom internals that helps to interface to larger NOR roms and perform address decoding and programmable page mapping, adapt simple peripheral (like i²c EEPROM that costs nothing - for savegames) to parallel access bus, and maybe add some reliable stereo dac with large intelligent FIFO.
Adding, for example, a super cheap nowdays gigabyte SD card inside cart can be done, but requires aforementioned 2..4Mbyte DRAM for page/segment loading, much smarter custom chip (that will cost more due to significantly larger internal resources required) that will have much more pins (because entire genesis address and data buss will have to be put THROUGH it), that might cause the need to choose BGA packages, that will require much finer at least 4-layer PCB production...
...and the price skyrockets.
I think genesis even phylosophicaly 'requires' skillful/artful/compact/tailored coding techniques to be used. Just like pixel-level tailoring of image data... Otherwise it's not realy that oldschool beauty anymore
In Mega Man 5, the GG code ATLKGL (C33C:60) enables debug keys on controller 2. Some of these are processed in the main game task (Task 0). These are Left (pauses the game) and Right (palette editor). Task 1 handles palette and background animations. Task 2 just starts up the other tasks. Task 3 is supposed to handle some more debug keys, but it's never actually started. To enable it, write A9 E4 85 94 A9 3B 85 93 A9 03 20 F3 FE 4C 0B FF to offset 3FFCD in the ROM, and write BD to offset 3DE7E. This enables A for restart and Down for upside down play. With EA EA EA at 3DE30, there's no introduction and the A button instead skips to the next level.
For "task" I understand some kind of procedure with his own stack, 'memory map' and register set, and with some kind of task schedule.
May be "interrupt procedure" is enough. One for debug proposes (zero division,...), one for VINT, one for RESET, and one for IDLE or non-VINT code.
It really is the ram faster than the rom? how much? why?
dtech, I don't want to be rude, but we are speaking about working with more tiles that the ones are stored on VRAM, and dynamically change them between RAM and VRAM (or something like that).
Character animation with DMA is so easy (this afternoon I did it to simulate water movement) is just one C line. But working with a background with more tiles that the ones you have in VRAM is a challenge.
May be "interrupt procedure" is enough. One for debug proposes (zero division,...), one for VINT, one for RESET, and one for IDLE or non-VINT code.
Yes, they have commands associated to a block, for example when you enter into a pipe a number command determines which is the new map. But essentially they are map tile based (yes, with commands!). (Zelda-> Cellda! )Gigasoft wrote: I don't have a tile map in the ROM, it's dynamically created when moving around. Command based worlds were used in many popular Nintendo titles such as the Super Mario Bros series, Super Metroid, Zelda 2, Zelda 3 (in dungeons, caves and houses), but in those, loading only happened at screen transitions.
It's not clear if you're saying that RAM is more faster than the ROM, but in any case, I listened similar things many times, but without providing any data.dtech wrote: All macroblocks used in level may also be decompressed to 68k ram, for fast dma transfer to VRAM whenever needed.
It really is the ram faster than the rom? how much? why?
dtech, I don't want to be rude, but we are speaking about working with more tiles that the ones are stored on VRAM, and dynamically change them between RAM and VRAM (or something like that).
Character animation with DMA is so easy (this afternoon I did it to simulate water movement) is just one C line. But working with a background with more tiles that the ones you have in VRAM is a challenge.
Code: Select all
DMA(source+(step++%4), destiation, size);
Yes, by a command I just mean something which specifies a large object to be made out of 16x16 blocks, just like in those Nintendo titles.
If you load the level data into RAM as tiles first, transferring them will take just a short time because you don't have to interpret the level data as you draw. In my game, the data is stored as 16x16 tiles in RAM, and is only converted to 8x8 tiles one row at a time when updating borders, but the conversion to 8x8 tiles happens in advance so that the row can be transferred fast in the VBL handler. Drawing has to happen during VBL so it won't be disturbed by the HBL routine.
If you load the level data into RAM as tiles first, transferring them will take just a short time because you don't have to interpret the level data as you draw. In my game, the data is stored as 16x16 tiles in RAM, and is only converted to 8x8 tiles one row at a time when updating borders, but the conversion to 8x8 tiles happens in advance so that the row can be transferred fast in the VBL handler. Drawing has to happen during VBL so it won't be disturbed by the HBL routine.
-
- Very interested
- Posts: 2440
- Joined: Tue Dec 05, 2006 1:37 pm
- Location: Estonia, Rapla City
- Contact:
You can decompress GFX straight to VRAM, but VRAM is slow to transfer to, so that's why you decompress to RAM so you can neatly DMA the stuff to VRAM. RAM itself is sliiiightly slower than ROM thanks to some refresh cycles that happen every happen every once in a while (RAM is PSRAM not plain SRAM), you can enable ROM area refreshes too in one register (forgot it) which makes ROM as "slow" as RAM is.eteream wrote:It's not clear if you're saying that RAM is more faster than the ROM, but in any case, I listened similar things many times, but without providing any data.
It really is the ram faster than the rom? how much? why?
Mida sa loed ? Nagunii aru ei saa
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen
Dtech thank you your post was very educational. I had no idea that Sonic and the Contra engines were so technical and had so much depth to each game's 'Engine' architecture.dtech wrote:(A short reply due to lack of time at the moment)
HINT and VINT - horisontal and vertical interrupt, realy work well on genny, in contrast to pc cga/ega/vga hell
Sonic3 and many other games use hint for water.
Regarding reprogramming - challenge is everything!
To have large, interesting levels, you also need to reprogram the maps quite frequently and fast, usually involving decompression of some sort. This is a challenge, especially if a game is a fast scroller. I remember playfield was programmable to 64x64 tiles and thus, when running around, that flayfield need to be updated off-screen for all the new stuff there is. Also handle the disapperaing and appearing enemies and their actions. This all is a hard part.
Reprogramming, however, is a relatively easy one - when some token is reached with the hero alone in the center on mostly only background visible and ground of some sort, engine updates specific blocks of tile data (that is used on the next part of the level), the ones, which are on the screen, stay intact. Games usualy have a slight hickup at that point (a freeze for a frame or two) and then does not allow you to go back (because graphics will be trashed up by new tiles). sonic2/3/knuckles do this stuff a lot and quite smoothly.
I think i could dig up my old tool sources that had quite a powerful optimiser amongst them, and maybe rework them for windows and any user interface (they were for DOS and x-mode graphics hahaha *scary*).
Another extreme programming challenge is to make effective enemy/object engine - again, sonic2/3/K does this amazingly well. Challenge is to make it all flexible and fluent - that every object that enters the proximity space, becomes active and has it's own processing/interaction routine (form rom, shared for all enemies of the same type), yet have dynamically assigned context scratchpads (separate for every 'live' object), that hold objects behaviour/position/action/phase, and that all such objects are processed using a dynamically maintained list where such routine can terminate itself and remove from list (when, for example, enemy is killed and explosion animation is done and over) or suspend (or keep alve) if that object is important (boss doesn't disapper or stop operating when leaving frame).
Such engine allows almost interaction things to be handled in the same way (like it's done in sonic) - be it a wall opening from a button press or operating a pulleys or some mechanisms, bosses that can release more enemies, animated checkpoints, etc...
I find this thing, along with map update engine, to be the hardest points, but also most beneficial ones, when those are up and running Because creating detailed and ellaborate levels becomes a joy! As well as creating enemies, that can generate more enemies (even by just shooting) and interactive objects.
Contra hard corps is an another example of extremely well programmed engine that does hell lot of tricks and everything combined in a solid piece of consistent code. Same about vectorman and well... many many other games
However I am also starting to feel a little worried now. Because everytime I think I have understood some aspect of Sega Console programming some new information is thrown my way and then I start to doubt my grasp of Sega programming.
However Dtech have you considered writing a book on Sega Game programming? With your knowledge and the lack of books on Sega Game programming it would do very well in sales. I am very serious it would!
Where can I read more about implementing Vint and Hint it seems a very useful for any programmer's toolkit. Is there a tutorial or documentation you can refer me too?
Why won't you share some of your routines with the community? Please show me some of your code.Gigasoft wrote:For tile updates, you could transfer a manageable number of tiles every frame until you're done. Uncompressing can be done in the background when the game is idle. In an upcoming game I'm making, I switch to a background task that performs loading of world data whenever I'm waiting for the next frame, enabling seamless scrolling in a very large world. I used the same technique in a NES game (which was never finished) with splendid results. In both games, I have 4x4 screenfuls loaded at once.
Usually, level data is not based on individual tiles, but larger blocks composed of tiles (usually 2 by 2 or 4 by 4 tiles). This is also so in my game, where the result after loading is an arrangement of blocks made of 2 by 2 tiles. The world data itself is command based, where there are commands to draw floors, walls and other objects, and the objects can be placed freely without regard for screeen boundaries.
Tiido please make some tutorials please! Something for beginners like me.TmEE co.(TM) wrote:Its a platforming run 'n' gun mostly, inspired by Contra, Metal Slug and Turrican.
1 Foreground scroll layer(grounds etc.) and a backgorund layer, which I've not yet decided how to handle, scrolling happens in all directions.
Each sector requires 512 bytes of space when decompressed, there's always 4 decompressed sectors so 2Kbytes is needed at all times.
Please share water movement effect routine. You guys talk about such Amazing stuff but when are you going to share some code. Eteream please take time to make some tutorials. It is so frustrating seeing people talk about these great routines but no one is showing me how it's done.eteream wrote: Character animation with DMA is so easy (this afternoon I did it to simulate water movement) is just one C line. But working with a background with more tiles that the ones you have in VRAM is a challenge.
For God's Sake Gentlemen ... please less talk and more code!
Especially if Code is in the Basic Language ... hehehhehe
I need a Black Belt in Game Programming!
-
- Very interested
- Posts: 2440
- Joined: Tue Dec 05, 2006 1:37 pm
- Location: Estonia, Rapla City
- Contact:
The code is mostly in ASM or C here, and I was once writing a guide but it never got anywhere, and I'm a bit too buzy now...
Mida sa loed ? Nagunii aru ei saa
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen
Well, here are some short excerpts. I can't share too many secretsAlex Khan wrote: Why won't you share some of your routines with the community? Please show me some of your code.
The VSync function.
Code: Select all
vsync:
move.l d0-d7/a0-a6,-(a7)
move.w #$2700,sr
move.w a7,stack1
move.w stack2,a7
move.l (a7)+,d5-d7/a4-a6
tst.w LoadRetryPC
beq load_noretry
move.l (a7)+,d0-d4/a0-a3
move.w LoadRetrySP,a7
move.w LoadRetryPC,-(a7)
clr.w -(a7)
rts
load_noretry:
move.l (a7)+,d0-d4/a0-a3
rte
The end of my VBL handler:
Code: Select all
move.w #$2300,sr
move.w stack1,d0
beq noresumevs
clr.w stack1
move.l d5-d7/a4-a6,-(a7)
move.w a7,stack2
move.w d0,a7
bra vsynccont
noresumevs:
move.l (a7)+,d0-d4/a0-a3
rte
Code: Select all
rr0:
moveq #-1,d0
rts
ReadRect:
moveq #0,d0
moveq #0,d1
moveq #0,d4
moveq #0,d5
move.b (a0)+,d0
move.b (a0)+,d1
move.b (a0)+,d4
move.b (a0)+,d5
BeginDrawRect:
sub.w CurLoadHt,d4
moveq #16,d6
sub.w d2,d0
cmp.w d6,d0
bge rr0
add.w d0,d1
ble rr0
sub.w d3,d4
cmp.w d6,d4
bge rr0
add.w d4,d5
ble rr0
cmp.w d6,d1
blt rr1
moveq #16,d1
rr1:
cmp.w d6,d5
bcs rr2
moveq #16,d5
rr2:
tst.w d0
bmi rr3
sub.w d0,d1
add.w d0,a1
clr.w d0
rr3:
neg.w d0
tst.w d4
bmi rr4
sub.w d4,d5
lsl.w #6,d4
add.w d4,a1
clr.w d4
rr4:
neg.w d4
moveq #64,d6
sub.w d1,d6
rts
Code: Select all
HoleTable dc.b 14,14,2,0
DispC_hole:
moveq #0,d7
move.b (a0)+,d7
bsr ReadRect
move.b (a0)+,d3
tst.w d0
bmi rch2
lsl.w #2,d7
move.w #HoleTable,a2
add.l d7,a2
move.b (a2)+,d7
subq.w #1,d1
move.l a1,a3
add.w #$2000,a3
move.b CurLoadHt+1,d2
tst.w d4
bne rch1
subq.w #1,d5
rchlp2:
move.w d1,d0
cmp.b d3,d4
beq rch0
subq.w #1,d2
rchlp:
move.b d7,(a1)+
move.b d2,(a3)+
dbra d0,rchlp
add.w d6,a1
add.w d6,a3
addq.b #1,d4
rch1:
move.b (a2),d7
dbra d5,rchlp2
rts
rch0:
move.b 1(a2),d7
addq.w #1,d1
addq.w #1,d5
move.l d0/d1/d5/a1,-(a7)
bsr FillMapRect
move.l (a7)+,d0/d1/d5/a1
move.b CurLoadHt+1,d7
sub.b -1(a0),d7
add.w #$2000,a1
bra FillMapRect
TerrC_hole:
addq.l #1,a0
bsr ReadRect
move.b CurLoadTerrHt,d7
sub.b (a0)+,d7
bra FillMapRect
Well, as I said, it's nothing special. Just a TEST did that day.Alex Khan wrote:Please share water movement effect routine. You guys talk about such Amazing stuff but when are you going to share some code. Eteream please take time to make some tutorials. It is so frustrating seeing people talk about these great routines but no one is showing me how it's done.eteream wrote:...
On my stage (module) init VINT callback:
Code: Select all
GFX_Enable( 0 );
...
// Load level
DO_DMA( DMA_RAM_TO_VRAM, (void*)g_tilesLvl1, TILE_LVL1*TITLE_SIZE, sizeof(g_tilesLvl1) );
DO_DMA( DMA_RAM_TO_CRAM, (void*)g_paletteLvl1, 0, sizeof(g_paletteLvl1) );
...
GFX_Enable( 1 );
Code: Select all
u16 y, x;
for( y = 0; y < SCREEN_TITLES_HEIGHT; y++ )
{
CopyToVRAM_1Addr( ADDR_PLANE_B + (PLANE_TITLES_WIDTH * 2 * y) );
for( x = 0; x < SCREEN_TITLES_WIDTH; x++ )
{
// 2????
CopyToVRAM_2Data( g_mapLvl1[LVL1_TITLESHEIGHT+2-SCREEN_TITLES_HEIGHT+y][x] );
}
}
Modify four tiles on tile table, witch are mapped all around plane B (the scene is about a bridge):
Code: Select all
static u16 i=0;
i++;
DO_DMA( DMA_RAM_TO_VRAM, (void*)g_tilesWater+((i>>(4+0))%3), TILE_LVL1*TITLE_SIZE, sizeof(g_tilesWater[0]) );
DO_DMA( DMA_RAM_TO_VRAM, (void*)g_tilesWater+((i>>(4+3))%3), TILE_LVL1*TITLE_SIZE+TITLE_SIZE, sizeof(g_tilesWater[0]) );
DO_DMA( DMA_RAM_TO_VRAM, (void*)g_tilesWater+((i>>(4+2))%3), TILE_LVL1*TITLE_SIZE+TITLE_SIZE*2, sizeof(g_tilesWater[0]) );
DO_DMA( DMA_RAM_TO_VRAM, (void*)g_tilesWater+((i>>(4+1))%3), TILE_LVL1*TITLE_SIZE+TITLE_SIZE*3, sizeof(g_tilesWater[0]) );
http://www.consolasparasiempre.net/kid/angellandE.htm
http://www.consolasparasiempre.net/kid/ ... veiled.pdf
which explains how a commercial game works.