Jump to content
IGNORED

RallyX Scrolling/Coleco/Z80/Source


Recommended Posts

It has been a challenge.

Ever since I tested my first game on a real ADAM it has been a discovery of blah.

 

Maybe I thought I could do anything but I am not discouraged and want to finish the game.

However, the port has to be updated to a Super type game because I just can't create a direct port so I might as well update to an improved tribute.

That said...

My next phase is that my character stays in the middle of the screen with the environment scrolling around you.

I looked at Rally X for Coleco on Youtube and was blown away so I know it is possible.

I am not asking for proprietary information but obviously there is a formula to all of this taught somewhere.

 

I know I can pound the code and get a blah result when at the end of the day it probably is some type of SRL optimizations with a direct OUT command for speed... I don't know I just want to be professional and I can not find real info anywhere.

 

 

So if someone out there willing to share some efficient Z80 8 directional scroll code I would be most appreciative.
Or point me in the right direction. I am not asking anyone to write my code for me, I just need schooling and it's not like you can go to your local university and take classes on Coleco programing.

 

Link to comment
Share on other sites

Study this code for msx

Same vdp, same z80, no need of ram

https://github.com/artrag/scroll_8_ways

 

A simple solution for rallyx is that all tiles are prerotated in rom and a given subset is loaded in vram when needed according to the car direction

Can I just ask, and this is a serious question...

Why could I not find this with just Google?

 

I am seriously grateful...on all fours groveling in appreciation.

 

My point being I hate to ask for help if I can figure it out on my own but I am learning the ins and outs of the Colecovision where the graphics are not as bad to access as the TI-994A but they are horrible compared to a lot of other machines.

 

When I seen Rally X I was floored and I knew there was no way a thousand line hack was going to create the same result.

If there is a directory somewhere with these types of routines please pass that along because if this has what I need then I will be back on track in no time.

 

Thank you again.

Edited by Mike Harris
Link to comment
Share on other sites

The issue that I have found is boiling down to a format that will work in a Coleco setting.
TNIASM is another one.

 

What I gather is that this is using compressed data, expanded into VRAM then page flipping...

 

I take it that this is also the reason why Rally X is for the SGM because of the expanded memory.

Being as Destructor, Zaxxon and a few others work on stock Colecovision I suspect that they used other formulas. They also are choppy in execution.

 

If someone out there with z80 code for 8 way scrolling in Coleco format is reading could you post it please.

Link to comment
Share on other sites

Even without the SGM you can use page-flipping. Mode 1 only needs about 4K. Mode 2 needs 12K, and that's for full single-page usage. Either way you have a good amount of space to draw offscreen with, so that you can page-flip when done. The TMS does not seem to offer any memory block copy functionality, and the page registers are too coarse to just bump over a pattern at a time.

Link to comment
Share on other sites

Even without the SGM you can use page-flipping. Mode 1 only needs about 4K. Mode 2 needs 12K, and that's for full single-page usage. Either way you have a good amount of space to draw offscreen with, so that you can page-flip when done. The TMS does not seem to offer any memory block copy functionality, and the page registers are too coarse to just bump over a pattern at a time.

 

In my case is that I am a newbie with zero experience which makes me bug you guys on how to do it.

 

When I was in the military it was teach you once, you do then teach others.

 

I need source code to show me the way or I will spend the next year trying to figure it out.

 

I get the concepts of page flipping, buffering and scrolling but at the end of the day there is a formula that is taught as gospel so you don't have to pound your way through it.

 

Most of these guys like Pixelboy or whomever I can find articles of homebrew going back over 10 years so I know that THEY know what's what but getting info these days is pulling teeth.

 

Example of opcode starting a course in z80 on this very website and never got past the first class that I could find.

http://atariage.com/forums/topic/193683-z80-assembly-module-1-basic-z80-programming/

 

http://www.colecovision.dk/cv-z80-assembly.htm

 

I am on fire to make games for the Coleco mainly for my benefit, not to take business away from anyone.

Edited by Mike Harris
Link to comment
Share on other sites

A MSX game using 8-way scrolling.

 

https://www.youtube.com/watch?v=k73p_KP0em4

 

A Colecovision one. (works in unexpanded Colecovision)

 

https://www.youtube.com/watch?v=HH-OnfUuD60

 

The graphics that can be shown are very limited because the trick of precomputed tiles, this means you only update the pattern table (768 bytes in two frames).

 

I'm not aware of examples of Z80 code about scrolling in 8-way.

 

Basically it's composed of this:

 

1. You create your map using the most limited possible set of graphics.

2. You create a program that takes each tile and generates the intermediate versions for scrolling: tile and adjacent tiles (1 for horizontal/vertical scrolling, 3 for diagonal scrolling). One tile can expand to many tiles!!! so typically scroll is in 2-pixels step.

2.1. At same time you generate a map of tiles for each scrolling offset. (for 2 pixels scroll, it would be 4 tables, for 2 pixel diagonal scroll, it would be 16 tables)

3. If the total tiles didn't exceeded the maximum 256 tiles then you can continue.

4. Load the bitmaps into the VDP (repeat 3 times in mode 2, or only 1 in mode 1)

5. For each display frame, you extract the X,Y offset to select a table, and then take each tile from your map, translate with table, and put into VRAM screen.

  • Like 2
Link to comment
Share on other sites

Look, artrag already answered your question: There is no magic. You really need to get this one-algorithm-fits-all idea out of your head.

 

Each scrolling game you will ever make on the ColecoVision will have a completely different scrolling engine (unless it's a sequel that reuses the same engine, of course). This is because the CV makes it hard to do smooth scrolling to begin with, and code optimizations to get smooth scrolling will impact your game's design, and vice-versa.

 

So there are two ways to approach a scrolling game on the ColecoVision: You first design the scrolling engine only, and once you have it working as a satisfactory demo, you build your game around it. The other method is simply to design the full game on paper, and then try to develop the scrolling engine in parallel with the entire game itself. That second option is only recommendable for expert coders who know the console inside and out.

 

No one can really help you with this, because if someone shows you a particular smooth scrolling algorithm, this engine will probably come with technical limitations that will get in the way of your creative process for your game.

 

To get started, you need to understand how the screen refresh interrupt works, as it's the key point of any VRAM-intensive process. Then you need to understand that you can only send a certain maximum number of bytes to VRAM during each screen refresh cycle, and this limit will strongly influence whatever scrolling engine you will ever create.

 

Good luck, space cadet.

Link to comment
Share on other sites

But for the closest thing to "1 size fits all", and for mode 1, you'd note that CV BIOS sets up the following:

 

Sprite generator table is at 3800

Pattern color table is at 2000

Sprite attribute table at 1B00

Pattern name table at 1800

Pattern generator table at 0

 

Mark off two buffers in VRAM. Note that the pattern generator table has 1800 bytes available. This lets you flip through 3 different full tile sets if you wanted. But maybe you're only using 2 tile types: wall or not. Well, if you want block by block scrolling, this makes it easy: Choose your second pattern name table page at, say, 1000. Now, while 1800 is being displayed, make your updates to the area at 1000. Then on vblank, set register 2 to (1000/400), or 4. Now your updates will be to the 1800 region. When finished updating and on next vblank, set register 2 to (1800/400) or 6. And so on.

 

Note that you will likely be redrawing the entire offscreen buffer since going by what has changed would likely be slower.

 

 

Now, if you want to do SMOOTH scrolling, that's where you need to start using multiple tiles with multiple permutations. You now need to have blank space with tile to right, blank space with tile above, blank space with tile upper right, blank space with tile above and upper right, blank space with tile upper right and right, blank space with walls above, right, and upper right, and inverse versions of the above. You'll need a repeat of each of these tiles with every scroll amount for right, up, and up right. You can use mirroring tricks to support the other directions and wall combinations. But now you can begin to see why this is so hard and needs to be well integrated with your game.

Link to comment
Share on other sites

post-24767-0-66555600-1551939521.gif

I produce a source code that I used to scroll in all direction. This is the quickest way to print a ton of tiles on screen at a cost of ROM space. VDP is slow so you'll need to swap screen technique to double buffer to hide the tearing. Unfortunately it's in C, but you'll get the idea. It only takes 2 bytes to scroll the entire screen.

This is the code, click spoiler to expand.

 


#include <coleco.h>
#include <getput1.h>
#define chrgen  0x0000
#define coltab  0x2000
#define chrtab  0x1800
#define sprtab  0x3800
#define sprgen  0x1b00

byte a,b,c,d,e,f,x,y,
game,
scrolly,Wide,scrollx;

const byte Leveldata[] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,1,1,1,1,1,1,1,1,1,3,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,1,1,1,1,1,1,1,1,3,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
};

const byte PATTERNRLE[] = {
  0x1F, 0x00, 0x20, 0x50, 0x04, 0x4A, 0xA0, 0x08, 0x14, 0x00, 0x20, 0x00, 0x04, 0x40, 0x00,
  0x08, 0x00, 0x00, 0x20, 0x00, 0x04, 0x40, 0x00, 0x08, 0x00, 0xC3, 0x81, 0x00, 0x00, 0x81, 0xC3,
  0xE7, 0xE7, 0xFE, 0x00, 0xEA, 0x00, 0x04, 0x0C, 0x18, 0x30, 0x00, 0x60, 0x82, 0x00, 0x81, 0x66,
  0x85, 0x00, 0x21, 0x66, 0xFF, 0x66, 0xFF, 0x66, 0x00, 0x18, 0x3E, 0x60, 0x3C, 0x06, 0x7C, 0x18,
  0x00, 0xFF, 0x81, 0xB9, 0xA5, 0xB9, 0xA5, 0x81, 0xFF, 0x3C, 0x66, 0x3C, 0x38, 0x67, 0x66, 0x3F,
  0x80, 0x00, 0x00, 0x18, 0x30, 0x85, 0x00, 0x00, 0x18, 0x82, 0x30, 0x00, 0x18, 0x82, 0x00, 0x00,
  0x18, 0x82, 0x0C, 0x00, 0x18, 0x82, 0x00, 0x04, 0x5A, 0x3C, 0x7E, 0x3C, 0x5A, 0x82, 0x00, 0x81,
  0x18, 0x02, 0x7E, 0x18, 0x18, 0x85, 0x00, 0x01, 0x18, 0x30, 0x84, 0x00, 0x00, 0x7E, 0x88, 0x00,
  0x00, 0x18, 0x82, 0x00, 0x04, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x82, 0x00, 0x04, 0x7C, 0xCE, 0xD6,
  0xE6, 0x7C, 0x82, 0x00, 0x04, 0x18, 0x38, 0x18, 0x18, 0x7E, 0x82, 0x00, 0x04, 0x7C, 0x06, 0x7E,
  0x60, 0x7E, 0x82, 0x00, 0x04, 0x7C, 0x06, 0x7C, 0x06, 0x7C, 0x82, 0x00, 0x81, 0xCC, 0x02, 0xFE,
  0x0C, 0x0C, 0x82, 0x00, 0x04, 0x7E, 0x60, 0x7C, 0x06, 0x7C, 0x82, 0x00, 0x04, 0x3E, 0x60, 0x7C,
  0x66, 0x3C, 0x82, 0x00, 0x04, 0xFE, 0x06, 0x0C, 0x18, 0x30, 0x82, 0x00, 0x04, 0x3C, 0x66, 0x3C,
  0x66, 0x3C, 0x82, 0x00, 0x04, 0x3C, 0x66, 0x3C, 0x06, 0x7C, 0x83, 0x00, 0x02, 0x18, 0x00, 0x18,
  0x84, 0x00, 0x0A, 0x18, 0x00, 0x18, 0x30, 0x0E, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0E, 0x84, 0x00,
  0x0A, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x70, 0x83, 0x00, 0x04, 0x38,
  0x6C, 0x08, 0x00, 0x18, 0x8A, 0x00, 0x04, 0x7C, 0xC6, 0xFE, 0xC6, 0xC6, 0x82, 0x00, 0x04, 0xFC,
  0xC6, 0xFC, 0xC6, 0xFC, 0x82, 0x00, 0x04, 0x7C, 0xC6, 0xC0, 0xC6, 0x7C, 0x82, 0x00, 0x00, 0xFC,
  0x82, 0xC6, 0x00, 0xFC, 0x82, 0x00, 0x04, 0xFE, 0xC0, 0xFE, 0xC0, 0xFE, 0x82, 0x00, 0x04, 0xFE,
  0xC0, 0xFE, 0xC0, 0xC0, 0x82, 0x00, 0x04, 0x7E, 0xC0, 0xDC, 0xC6, 0x7C, 0x82, 0x00, 0x81, 0xC6,
  0x02, 0xFE, 0xC6, 0xC6, 0x82, 0x00, 0x00, 0xFC, 0x82, 0x30, 0x00, 0xFC, 0x82, 0x00, 0x04, 0xFE,
  0x06, 0x06, 0xC6, 0x7C, 0x82, 0x00, 0x04, 0xC6, 0xCC, 0xF8, 0xCC, 0xC6, 0x82, 0x00, 0x83, 0xC0,
  0x00, 0xFE, 0x82, 0x00, 0x04, 0xC6, 0xEE, 0xFE, 0xD6, 0xC6, 0x82, 0x00, 0x04, 0xC6, 0xE6, 0xFE,
  0xCE, 0xC6, 0x82, 0x00, 0x00, 0x7C, 0x82, 0xC6, 0x00, 0x7C, 0x82, 0x00, 0x04, 0xFC, 0xC6, 0xFC,
  0xC0, 0xC0, 0x82, 0x00, 0x04, 0x7C, 0xC6, 0xC6, 0xCC, 0x76, 0x82, 0x00, 0x04, 0xFC, 0xC6, 0xFC,
  0xCC, 0xC6, 0x82, 0x00, 0x04, 0x7E, 0xC0, 0x7C, 0x06, 0xFC, 0x82, 0x00, 0x00, 0xFC, 0x83, 0x30,
  0x82, 0x00, 0x83, 0xC6, 0x00, 0x7C, 0x82, 0x00, 0x82, 0xC6, 0x01, 0x6C, 0x38, 0x82, 0x00, 0x04,
  0xC6, 0xD6, 0xFE, 0xEE, 0xC6, 0x82, 0x00, 0x04, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x82, 0x00, 0x81,
  0xC6, 0x02, 0x7E, 0x06, 0xFC, 0x82, 0x00, 0x04, 0xFC, 0x18, 0x30, 0x60, 0xFC, 0xFE, 0x00, 0xFE,
  0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE,
  0x00, 0xB2, 0x00, 0xFF};

const byte COLORRLE[] = {
  0x87, 0xF4, 0x87, 0x3C, 0x87, 0xFB, 0x07, 0x12, 0x13, 0xC3, 0xC2, 0x12, 0x12, 0xC6, 0xC6,
  0xFE, 0xF0, 0xFE, 0xF0, 0xFE, 0xF0, 0xFE, 0xF0, 0xFE, 0xF0, 0xFE, 0xF0, 0xFE, 0xF0, 0xFE, 0xF0,
  0xFE, 0xF0, 0xFE, 0xF0, 0xFE, 0xF0, 0xFE, 0xF0, 0xFE, 0xF0, 0xFE, 0xF0, 0xFE, 0xF0, 0xEE, 0xF0,
  0xFF};


  
void Scroll(){

put_at(0,0,Leveldata+(scrolly*Wide)+scrollx,32);
put_at(0,1,Leveldata+(scrolly*Wide)+scrollx+Wide*1,32);
put_at(0,2,Leveldata+(scrolly*Wide)+scrollx+Wide*2,32);
put_at(0,3,Leveldata+(scrolly*Wide)+scrollx+Wide*3,32);
put_at(0,4,Leveldata+(scrolly*Wide)+scrollx+Wide*4,32);
put_at(0,5,Leveldata+(scrolly*Wide)+scrollx+Wide*5,32);
put_at(0,6,Leveldata+(scrolly*Wide)+scrollx+Wide*6,32);
put_at(0,7,Leveldata+(scrolly*Wide)+scrollx+Wide*7,32);
put_at(0,8,Leveldata+(scrolly*Wide)+scrollx+Wide*8,32);
put_at(0,9,Leveldata+(scrolly*Wide)+scrollx+Wide*9,32);
put_at(0,10,Leveldata+(scrolly*Wide)+scrollx+Wide*10,32);
put_at(0,11,Leveldata+(scrolly*Wide)+scrollx+Wide*11,32);
put_at(0,12,Leveldata+(scrolly*Wide)+scrollx+Wide*12,32);
put_at(0,13,Leveldata+(scrolly*Wide)+scrollx+Wide*13,32);
put_at(0,14,Leveldata+(scrolly*Wide)+scrollx+Wide*14,32);
put_at(0,15,Leveldata+(scrolly*Wide)+scrollx+Wide*15,32);
put_at(0,16,Leveldata+(scrolly*Wide)+scrollx+Wide*16,32);
put_at(0,17,Leveldata+(scrolly*Wide)+scrollx+Wide*17,32);
put_at(0,18,Leveldata+(scrolly*Wide)+scrollx+Wide*18,32);
put_at(0,19,Leveldata+(scrolly*Wide)+scrollx+Wide*19,32);
put_at(0,20,Leveldata+(scrolly*Wide)+scrollx+Wide*20,32);
put_at(0,21,Leveldata+(scrolly*Wide)+scrollx+Wide*21,32);
put_at(0,22,Leveldata+(scrolly*Wide)+scrollx+Wide*22,32);
put_at(0,23,Leveldata+(scrolly*Wide)+scrollx+Wide*23,32);

}

 void Scrolltest(void){
scrollx=0;
scrolly=0;
Wide=64;
game=1;
Scroll();
enable_nmi();
while(game==1){
delay(1);
if((joypad_1&UP) && scrolly!=0){scrolly--;disable_nmi();Scroll();enable_nmi();}
if(joypad_1&DOWN && scrolly!=24){scrolly++;disable_nmi();Scroll();;enable_nmi();}
if((joypad_1&LEFT) && scrollx!=0){scrollx--;disable_nmi();Scroll();enable_nmi();}
if((joypad_1&RIGHT) && scrollx!=32){scrollx++;disable_nmi();Scroll();enable_nmi();}
//if(keypad_1==1){game=0;cls();}

}



} 

void main(){
	disable_nmi();
	screen_mode_2_text();
	screen_on();
rle2vram(PATTERNRLE,0x0000);
duplicate_pattern();
rle2vram(COLORRLE,0x2000);
Scrolltest();
}

void nmi(){

}


 



Wide is how many tiles are in the table horizontally. The limitation is, the maximum map size is 256 by 256 due to the use of 8-bit variables.

Smooth scrolling in 8 direction takes a TON of work. 1 direction smooth scrolling is difficult. I don't have the tools or skill to do it but I got the idea how it is done. I have applied smooth scrolling horizontally to A Sparrow goes Flapping.

Alldirection.rom

  • Like 2
Link to comment
Share on other sites

To simplify the explanation (at least of the first post), note that what he does is both double-buffering and multiple pattern generation tables. The memory breakdown looks like this:

+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
|   0| 300| 400| 700| 800| B00| C00| F00|1000|1300|1800|1B00|2000|2300|2800|2B00|3000|3300|3800|3B00|3C40|
| PT1|    |BUF1|    | PT2|    |BUF2|    | PT3|    | PT4|    | PT5|    | PT6|    | PT7|    | PT8|    |CTBL|
+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+

PT# are the pattern tables which have the same blocks but shifted by 1 pixel each

BUF# are the name tables that you swap between on different frames

CTBL is the color table. I don't know why they chose to shift it over by 1 from a more rounded address.

All the blank space is available for other purposes (sprites, most likely). The reason it's so fragmented is that each table type has a granularity enforced. Pattern tables are on 0x800 boundaries, pattern name tables on 0x400 boundaries, color table on 0x40 boundaries, and so on.

 

Note that sprite generator tables must ALSO be on 0x800 boundaries, so you have two options here: Either split the pattern space between sprites and static patterns, or do 2-pixel scrolling so that you only need 4 pattern tables, and call it good enough. The sprite attribute tables are on 0x80 boundaries, so much more flexible.

 

It's also worth noting that there is some optimization that can be done when blasting new map rows in: The VDP auto-increments its destination register so that you can keep feeding it bytes. So why send it a new address on every new line, when the new address matches where the auto-incremented address already is anyway? Also, since these strategies depend on having the decompressed map in RAM, you can skip the calculation of each new map row. If the map is 128 bytes wide, find your initial location. Then write 32 bytes and advance by (128-32) bytes, and start writing the next 32 bytes. Why go through more bit shifting and addition?

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