Jump to content
IGNORED

MWP Scrolling - The better way IMHO :)


popmilo

Recommended Posts

Trying to fit big game into small amount of memory tends to be hard. Trying to scroll large bitmap screen is even harder.

That is where something like complex scrolling method that wastes no RAM comes in handy.

During my recent experiments with AnalMux's MWP (minimum wrapping principle) scrolling, I think I found a better way to understand it.
Basic principle is still the same, using two LMSs to wrap the screen so that used memory exceeds only slightly more memory than static screen.

Here is the image of memory layout according to 'my way' ;)

 

post-14652-0-54305400-1392835551_thumb.png

 

There are maximum two LMSs used (first row is special case as only one LMS is needed).

Scrolling right is done by increasing X, when X reaches the end -> X=0, Y=Y+1

Scrolling down is done by increasing Y.

 

As you see on the image, there are only SCREEN_WIDTH-1 bytes added at the end of screen memory.

Contents of these bytes need to be copies of 0..SCREEN_WIDTH-1 bytes.

In the case of 3x3 size, bytes 9 and 10 are copies of bytes 0 and 1.

 

LMS addresses and appropriate Mode lines should be easy to calculate from Screen height, Screen width, X and Y.

 

Imho, this "add copy of first row to the right of last row" makes much more sense than the explanation with additional zero row in Ironman Wiki documentation.

 

As I'm in middle of making a game with this, If anyone sees any fault in this reasoning please shout ;)

 

  • Like 2
Link to comment
Share on other sites

Here is one more reason to write about this: how to apply MWP scrolling to large 40x192 bytes bitmap screen ?

4K wrap forces using more LMSs and turning on hardware scroll makes screen 48 bytes wide. 48x192=9216 is just wasting too much ram...

 

My thoughts are to go with 42 bytes wide screen, use LMS in every scanline. Does anyone have any proposition on how to handle large dynamic Display Lists like this ?

Link to comment
Share on other sites

Looks good! Can you give a link to the Ironman wiki documentation for comparison?

Here is the wiki:

https://wiki.strotmann.de/wiki/Wiki.jsp?page=Ironman%20Atari

 

And here is the pdf version:

atari ironman documents.pdf

 

--------------------------------------------

As most of the times, writing something down clears ones head and gives new ideas :)

 

Maybe better way is to split screen into three sections, each 64 lines high.

That would require only 3 or 4 LMSs, each one easily calculated. Yes there would be bytes 'wasted', but I guess something useful can be stored there anyway.

Each section would be 48x64+47 bytes for copied bytes.

 

Forgot to mention, when working with large bitmaps where screen consists from multiple memory regions, that last row is not a copy of first line, but the copy of first row in next screen section.

So if bitmap screen starts at $a000 and each section is 64 lines (64*48=3072), sections would be at $A000, $B000 and $C000:

$AC00-$AC2E would be copy of $B000-$B02E

$BC00-$BC2E would be copy of $C000-$C02E

$CC00-$CC2E would be copy of $A000-$A02E

No problems with 4K wrap, small dlist and plenty of space for full use of HSCROL of 0-15.
Something like that ;)

 

Link to comment
Share on other sites

Here is the image of memory layout according to 'my way' ;)

 

You mean "My Way Principle" Got it? :)

 

I never understood the fuss about this MWP. Maybe because I haven't understood all the explainations I've found.

To be honest. Took me maybe 3 days to figure out the scrolling for MJO. But I guess in the end its similar to MWP.

For horizontal scrolling (HAR'em) I just copy a column of blocks to the right AND to the left. When on screen is "scrolled" I manipulate the LMS entries to wrap the screen

 

Maybe one day I understand MWP and will have hte perfect scrolling :)

 

Note:

BTW, the scrolling in MJO was so tricky, because you can fall down the whole tower (theoretically).

  • Like 1
Link to comment
Share on other sites

How is it different than MWP scrolling? Looks the same to me, or you mean just different explanation of the same technique?

Principle is the same - using the least amount of memory possible, and wrap screen with multiple LMS.

 

Difference is best seen in transitions from column A to column B:

post-14652-0-39066600-1393005494_thumb.png

In old MWP article you can see first two rows shifting left, byte leaving on the left side appears on the right with vertical offset of -1.

But... The row '3' 'suddenly' becomes '001'.

I understand '1'. It is shifted from its top left corner position and comes on bottom. But those '00' made me think about this for hours till I finally got it :)

 

On the other hand MyWayPrinciple TM (Thanks Creature :) ), looks like this when in that 0123 notation representing rows:

post-14652-0-73179800-1393004974_thumb.png

 

Row '3' is copy of row '0' and I marked both with same color so you can see how nicely all those fit together.

In every scroll direction, transitions are simple and just flow...

 

Weekend has finally come, and I'll have some time in next couple of days.

Time to code full 160x192 bitmap 8-directional scroll!

Abbuc won't wait for no one ;)

Link to comment
Share on other sites

But the order gets screwed of the bytes? So how is that corrected????

I guess you are thinking about that vertical offset of -1 in the last column ?

If that is the case, you just have to draw correct bytes into that last column.

 

Let's say you are scrolling screen to the right.

MWP does it's thing and you get 90% of screen moved to the left. Last column on the right is 'screwed up'.

Well, now you draw that last column with those offsets in mind and all is good in the world again :)

 

If you do the MWP scroll right thing again, last column moves left with rest of the screen, and it still looks ok.

One thing is how it is layed out in memory, totaly different how it looks to the observer.

 

Simple formulas based on screen width, height, mwp x and y coordinates should look like this:

 

W = Screen width

H = Screen Height

MX = 0..W-1 ; MWP X offset

MY = 0..H-1 ; MWP Y offset

 

First all info we need for Display List:

LMS1 = MY*W + MX

LMS2 = MX ; No need for LMS2 if MY=0

 

Couple of numbers needed for filling Display List correctly:

"Number of scanlines in top part" = H - MY

"Number of scanlines in bottom part" = MY

 

And now addresses on screen for drawing that last column on the right:

"Address of top part of last column on right" = LMS1+W-1

"Address of bottom part of last column on right" = LMS2+W-1

 

Now you just copy bytes from gamemap into those two vertical parts on the right.

 

One more detail is to maintain equality of first row and that last part sticking out on the side.

 

For example, on first sketch in this topic it is byte 9 that is copied into byte 0 in case of X=1,Y=0.

 

Simple way would be:

LDA (H*W+X-1)
STA (X-1)

Now, this seems strange when X=0, and mangles location -1 but it is simple as it can get and works imho :)

 

ps. All addresses should be offset by screen base address of course.

Link to comment
Share on other sites

What is the gain and it is worth all he hassle in terms if calculation etc?

For me - memory. Scrolling bitmap screen with any other way would take either too much ram or too much cpu speed.

With mwp - for every frame its just couple of lms and ~ 200 bytes copied for horizontal scroll or ~ 40 bytes for vertical scroll.

 

As I'm planning 8-directional game with full bitmap scroll and software sprites, any speedup and save in memory is more than welcome.

 

Enough talking... Tomorrow coding... Now I have to sleep ;)

  • Like 1
Link to comment
Share on other sites

Couple of free days, lots of coffee, good headphones, supportive wife, pen and paper...

post-14652-0-57811500-1393184516_thumb.jpg

Seems like that is what works for me ;)

 

I present you my version of MWP, full 48x192 screen, 8 directional scroll (simple grey texture just for testing):

post-14652-0-56905500-1393184668_thumb.png

 

Joystick controlled, 50 fps (two pixels per frame vertical scroll for same speed in every direction).

Bitmap in three sections at $a000, $b000, $c000. Each is 48x64 bytes long (plus 47 for incoming bytes on the lower right side).

Display list is first assembled as if screen is 256 lines high. Purpose is to have place for 192 scanlines high "window" that moves up and down in memory.
First I clear all previously set movable LMSs and DLISTENDJUMP.
Then LMS1 is set based on Y offset, and its address parameter depends on X offset also.
LMS2 and LMS3 are at fixed position so they are not cleared and only their address parameter needs to change.
If Y offset is not zero, LMS4 is added at fixed position (but with address depending on X offset also).
DLIST END JUMP is added based on Y offset.

It's updated in every vertical blank interrupt and whole 'calculate_dlist' routine takes only around 300 cycles to execute.

 

Simple, right ? ;)

 

Looks like it is working, but I won't be sure until I implement some sort of larger map and drawing incoming graphics on edges.

 

Attached xex and couple of interesting source files:

mwp_test.xex

mwp_test_dlist.asm

mwp_test_scroll.asm

 

ps. To answer Heaven's question once again - "Is it worth it?" - Yes! :D

So fast, and yet so small memory footprint... I'm not dreading making bitmap scrolling game on Atari any more ;)

  • Like 3
Link to comment
Share on other sites

Looks good but the horizontal movement is jerky. Looks like you might be off by one on your HSCROL math. It appears to increment like +1, +1, +1, +1, +0, +1, +1, +1, +1, +0, etc. instead of +1 continuously.

 

Also, it looks like you have another issue where you cross-over a certain horizontal scrolling boundary where an unwanted vertical scroll +1 happens. Another way to say it is that the screen slowly shifts down if you press left for a long time.

  • Like 1
Link to comment
Share on other sites

Looks good but the horizontal movement is jerky. Looks like you might be off by one on your HSCROL math. It appears to increment like +1, +1, +1, +1, +0, +1, +1, +1, +1, +0, etc. instead of +1 continuously.

Guess I was so tired last night my eyes were on frame blending mode, so I didn't notice that ;)

You are right! I didn't change hscroll manipulation code from earlier version so one BPL sneaked in instead of BNE. It's fixed now.

 

Also, it looks like you have another issue where you cross-over a certain horizontal scrolling boundary where an unwanted vertical scroll +1 happens. Another way to say it is that the screen slowly shifts down if you press left for a long time.

I did notice that last night, but didn't think it was a big problem because I knew main routine for dlist manipulation was working ok.

Turnes out I forgot to set those copies of zero row in every section. Fixed that one also.

 

Here is fixed version. Thanks for the tips Xuel!

mwp_test.xex

  • Like 1
Link to comment
Share on other sites

Another thing, don't forget you can use the high range of HSCROL values to reduce DMA. In other words, instead of using HSCROL 0-3, use 12-15. This prevents ANTIC from halting the 6502 for several cycles at the beginning of each scan line. Hit Shift-F8 in Altirra to see the DMA pattern shrink in comparison.

  • Like 3
Link to comment
Share on other sites

I did notice that last night, but didn't think it was a big problem because I knew main routine for dlist manipulation was working ok.

Turnes out I forgot to set those copies of zero row in every section. Fixed that one also.

 

Here is fixed version. Thanks for the tips Xuel!

Still moves up ;)

Link to comment
Share on other sites

Two short Questions:

 

1.) is MWP more efficient in char mode as well or only for bitmap?

As I am doing lots of charmode stuff, this would help me to cinsider if I have to look into MWP (again) :)

 

2.) similar the DMA-HSCROL-trick (12-15 instead of 0-3). Is it the same for charmode (ANTIC 4)?

if so, I'll check that as well.

 

 

@Popmilo: nice to see stuff being done! :) my ATARI project(s) is (are) stalled ATM :(

Edited by Creature XL
Link to comment
Share on other sites

well... still not sure :D but good to see something A8 wise coming from Serbija ;)

still need to get into it... maybe it will be usefull for my stuff, too...

Hehe, just wait and see. Based on some "private" testing done on my part, something awesome is coming out for Atari on Abbuc this year ;)

 

Besides that long term project (not able to share code till compo is over), I'm thinking to make a basic "scrolling bitmap game project" for anyone to use as soon as possible.

Nothing too complicated, just a simple main game loop, reading joystick, most common tile sized map (8x16 pixels I think), maybe in 160x192 and 160x96 resolutions (for smaller memory footprint and more cpu time).

What do you guys think, is 128x128 of 256 tiles enough for a gamemap ?

 

Beautiful. Smooth as silk now. :) Can't wait to see some fancy graphics scrolling by.

Oh.. It looks great in colors with proper tiles, I'll show it as soon as I figure out how to show enough and don't discover too much at the same time ;)

 

ps. Thanks for the hscrol tip. Switched it to 12-15. That will give me couple of cycles more for potential color changes.

What does "Shift-F8 in Altirra" do ? All I see is larger window size with more black around screen ?

 

Still moves up ;)

Yeah, it's supposed to do that :)

As Xuel mentioned, it'll get fixed by it self when proper tile drawing at edges gets thrown onto it.

 

1.) is MWP more efficient in char mode as well or only for bitmap?

@Popmilo: nice to see stuff being done! :) my ATARI project(s) is (are) stalled ATM :(

Well it can maybe save you around 1k of ram.

It is quite simple in char mode as you only need maximum of two LMSs and only to update 24-25 bytes at each 4th frame.

Think it maybe gives the most in narrow Mode D (128x96).

It takes only 40x96+47 bytes (less than 4K), so again only 2 LMSs and you get 50fps scrolling for practically nothing.

 

Bare in mind all this is without soft sprites or any kind of animation of tiles or such. There is lots more to think about.

Enough talking... Gotta draw some colored tiles ;)

Link to comment
Share on other sites

ps. Thanks for the hscrol tip. Switched it to 12-15. That will give me couple of cycles more for potential color changes.

What does "Shift-F8 in Altirra" do ? All I see is larger window size with more black around screen ?

 

You have to turn off PAL Blending. It adds an overlay that shows every cycle that is blocked by ANTIC DMA or DRAM refresh.

 

post-21021-0-08925600-1393268335_thumb.png

 

That portion circled in red will have fewer grey stripes when you use HSCROL 12-15.

Edited by Xuel
  • Like 1
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...