+Gemintronic Posted November 1, 2013 Share Posted November 1, 2013 This my demo of smooth vertical scrolling using DATA statements. Right now it uses a 16x16 grid where each element holds 8 horizontal pixels. The trick: adjust the playfieldpos until an entire row needs updating. Use math (treat a single dimensional array like a 16x16 2d one) to find the x/y position of the element needed for every playfield row and update var16-47. So, two issues: * Some garbage pixels on the lowest visible row when scrolling. Pretty sure it's a bB thing and not correctable. * Collision isn't perfect when not aligned exactly with the playfield pixel. * Must refresh EVERY playfield var instead of just immediately needed rows or columns. If anyone can optimize it to do so please have a go! Every time I try bB scrambles the screen. The binary uses a VIC-20 style font I created. RRatRace2.bin RRatRace2.bas 6 Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted November 2, 2013 Author Share Posted November 2, 2013 Okay.. I'm especially numb today. I posted this in the general 2600 programming section instead of batari BASIC where it belongs.. can a kind moderator please move this? Quote Link to comment Share on other sites More sharing options...
raindog Posted November 2, 2013 Share Posted November 2, 2013 I'm guessing batari Basic doesn't have a 4- or 8-way scrolling kernel yet, which would mean you'd need RAM to do the horizontal part, redrawing the playfield offscreen into an array or something (I assume bB has arrays that don't need to be populated by data statements at compile time). Then you should be able to use that array instead of "world" as your playfield data in your existing code. The easiest way to horizontally scroll in assembly that I know of is just ROL/ROR to rotate the playfield data, checking the carry bit and ORing it with the first/last bit in the following byte to carry it over. I don't know what the equivalent code would look like in bB, but it wouldn't surprise me if assembly were actually easier or more concise for this, at least till someone comes up with an (n > 2)-way scrolling kernel for bB. If nothing else, you ought to be able to look at the released source for Princess Rescue to see how that does horizontal scrolling, and combine it with what you've done here. 1 Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted November 3, 2013 Author Share Posted November 3, 2013 I appreciate the insight raindog. I think the only way to do this fast enough might involve SeaGtGruffs pfhscroll library. Unfortunatly, that means that I will have to update the entire screen every playfield pixels worth of movement. So I would do exactly what I'm doing now but afterwards use pfhscroll to scroll in 8 more vars worth of playfield column data. My brain is trying to come up with a way to implement this. What I wish is for something that would quickly rotate information within a byte left or right without losing information. shiftleft a would make a that equals "%10000100" turn into "%00001001" shiftright b would make b that equals "%00111100" turn into "%00011110" %10000100 Quote Link to comment Share on other sites More sharing options...
raindog Posted November 3, 2013 Share Posted November 3, 2013 Well, that could probably be added easily to bB. This is pseudocode because I haven't written assembly in a few years: shiftLeft rol a bcc shiftLeftCarry+2 shiftLeftCarry ora #$01 shiftRight ror a bcc shiftRightCarry+2 shiftRightCarry ora #$80 For all I know, there's an even simpler/faster way to do it. But I don't know that you could use these for a full-playfield horizontal scroll since you'd want to carry over to the neighboring PF byte, not the current one. 1 Quote Link to comment Share on other sites More sharing options...
Omegamatrix Posted November 3, 2013 Share Posted November 3, 2013 If you are shifting a ram location, then there won't be any quick way to do it. You'll probably do something like this: ;rotate left 10 cycles lda zeropage asl adc #0 sta zeropage ;rotate right 13 cycles lda zeropage lsr zeropage rol sta zeropage ;rotate right 12 cycles lax zeropage lsr txa rol sta zeropage ;rotate right 11/12 cycles lda zeropage lsr bcc .noOr ora #$80 .noOr: sta zeropage It gets worse when you are trying to index ram. Quote Link to comment Share on other sites More sharing options...
bogax Posted November 3, 2013 Share Posted November 3, 2013 (edited) I appreciate the insight raindog. I think the only way to do this fast enough might involve SeaGtGruffs pfhscroll library. Unfortunatly, that means that I will have to update the entire screen every playfield pixels worth of movement. So I would do exactly what I'm doing now but afterwards use pfhscroll to scroll in 8 more vars worth of playfield column data. My brain is trying to come up with a way to implement this. What I wish is for something that would quickly rotate information within a byte left or right without losing information. shiftleft a would make a that equals "%10000100" turn into "%00001001" shiftright b would make b that equals "%00111100" turn into "%00011110" %10000100 I'm not sure exactly what you want. What's wrong with SeaGtGruff's scrolling? I don't think there's going to be any way to scroll horizontally that doesn't involve doing the Whole screen. The bytes in the screen area are alternately reversed so I think your best bet is to scroll a entire line at a time. In bB I think the best thing to do would be to scroll horizontally and then poke in the new column from ROM. If you're trying to do vertical scrolling from ROM it may be that shifting one line's worth of data into a buffer then vertically scrolling that into place would be about as fast and easy as anything. I haven't tryed it but I don't think it would be any faster to shift individual bytes then combine them to make a line. (possibly huge look up tables could be faster) I'd guess it would be possible to combine vertical and horizontal in to one routine. I'd try scrolling the new vertical line in to a buffer then scroll vertically while scrolling each line horizontally as I went. You'd want dedicated routines for each direction. Whether you picked up the new column as you went or filled it in after might depend on whether you were doing that in bB or in asm. I know the subject of reversing bytes has come up before. you can do it a bit at a time or with partial (nybble) look up tables or with full (byte) look up tables. My choice (for bB) would be by nybbles. function rev() temp2 = temp1 & $0F temp1 = temp1 / 16 temp1 = revhi[temp2] | revlo[temp1] return data revhi $00, $80, $40, $C0, $20, $A0, $60, $E0 $10, $90, $50, $D0, $30, $B0, $70, $F0 end data revlo $00, $08, $04, $0C, $02, $0A, $06, $0E $01, $09, $05, $0D, $03, $0B, $07, $0F end Here's code that scrolls (rotates actually) a single line COLUBK = $35 COLUPF = $55 playfield: ................................ .X.X.X.......................... ................................ ................................ ................................ ................................ ................................ ................................ ................................ ................................ end Main drawscreen a = a + 1 if a & $0F then Main if joy0right then gosub scroll_right if joy0left then gosub scroll_left goto Main scroll_right asm lda var7 rol ror var4 rol var5 ror var6 rol var7 end return scroll_left asm lda var4 rol ror var7 rol var6 ror var5 rol var4 end return edit here's code for the whole screen COLUBK = $35 COLUPF = $55 playfield: .X.X.X.......................... .X.X.X.......................... .X.X.X.......................... .X.X.X.......................... .X.X.X.......................... .X.X.X.......................... .X.X.X.......................... .X.X.X.......................... .X.X.X.......................... .X.X.X.......................... .X.X.X.......................... .X.X.X.......................... end Main drawscreen rem a = a + 1 rem if a & $0F then Main if joy0right then gosub scroll_right if joy0left then gosub scroll_left goto Main scroll_right asm lda var3 rol ror var0 rol var1 ror var2 rol var3 lda var7 rol ror var4 rol var5 ror var6 rol var7 lda var11 rol ror var8 rol var9 ror var10 rol var11 lda var15 rol ror var12 rol var13 ror var14 rol var15 lda var19 rol ror var16 rol var17 ror var18 rol var19 lda var23 rol ror var20 rol var21 ror var22 rol var23 lda var27 rol ror var24 rol var25 ror var26 rol var27 lda var31 rol ror var28 rol var29 ror var30 rol var31 lda var35 rol ror var32 rol var33 ror var34 rol var35 lda var39 rol ror var36 rol var37 ror var38 rol var39 lda var43 rol ror var40 rol var41 ror var42 rol var43 lda var47 rol ror var44 rol var45 ror var46 rol var47 end return scroll_left asm lda var0 rol ror var3 rol var2 ror var1 rol var0 lda var4 rol ror var7 rol var6 ror var5 rol var4 lda var8 rol ror var11 rol var10 ror var9 rol var8 lda var12 rol ror var15 rol var14 ror var13 rol var12 lda var16 rol ror var19 rol var18 ror var17 rol var16 lda var20 rol ror var23 rol var22 ror var21 rol var20 lda var24 rol ror var27 rol var26 ror var25 rol var24 lda var28 rol ror var31 rol var30 ror var29 rol var28 lda var32 rol ror var35 rol var34 ror var33 rol var32 lda var36 rol ror var39 rol var38 ror var37 rol var36 lda var40 rol ror var43 rol var42 ror var41 rol var40 lda var44 rol ror var47 rol var46 ror var45 rol var44 end return Edited November 3, 2013 by bogax Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted November 3, 2013 Author Share Posted November 3, 2013 I updated the first post with my success in getting westward scrolling going. Two big limitations: * The left side doesn't get a new set of data until 8 pixels have gone past. Pretty rough clipping there. * The playfield data must be symmetrical since the center columns get reversed. So, am I reading that the "best" way to reverse all the bits in a byte is to make a huge lookup table? ..and by reverse I mean %10100010 becomes %01000101 Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted November 5, 2013 Author Share Posted November 5, 2013 A further update: rough horizontal scrolling at top. Up to 7 or 8 playfield pixels wide gap appears when scrolling. A proper scroller would fill in the new column of playfield pixels every time. Also, for some weird reason the last row of playfield pixels now wants to freakin offset itself. sigh. Reversing bits in a byte is still a mystery so again: the playfield data must be symmetrical until I solve this. Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted November 9, 2013 Author Share Posted November 9, 2013 New version at top! Playfield data no longer has to be symmetrical. The horizontal scrolling is still rough because no new map data is being pulled until every 8 pixels. Using phfscroll feels like the right solution to scroll in the new world data but how to implement it is baffling me. Unless we're going over cycle this means 4 way scrolling is working: just not clipped very well at the edges. Quote Link to comment Share on other sites More sharing options...
bogax Posted November 9, 2013 Share Posted November 9, 2013 (edited) It's a pity the functions in bB are so damn primitiveHere's a function to supply a byte from your tableindexed by the function parameter so instead of temp4 = world[chunkb] var45 = rev(temp4) you'd dovar45 = wrev(chunkb) function wrev asm tax lda world,x and #$0F tay lda world,x lsr lsr lsr lsr tax lda revhi,y ora revlo,x rts end data revhi $00, $80, $40, $C0, $20, $A0, $60, $E0 $10, $90, $50, $D0, $30, $B0, $70, $F0 end data revlo $00, $08, $04, $0C, $02, $0A, $06, $0E $01, $09, $05, $0D, $03, $0B, $07, $0F end Of course, it's dedicated to the world table,so you can only use it with the world table.If you change the name of the table you'd haveto change it in the asm of the function.It's untested.There's nothing wrong with pfhscrollbut I think I'd use something less general purpose.Damn, this editor sucks. Edited November 9, 2013 by bogax Quote Link to comment Share on other sites More sharing options...
bogax Posted November 9, 2013 Share Posted November 9, 2013 Using phfscroll feels like the right solution to scroll in the new world data but how to implement it is baffling me. scroll vertically copy table data to the "blank" line thats left scroll the line with the new table data into postion relative to the screen using pfhscroll then use pfhscroll to scroll horizontally each time you use pfhscroll you'll have to find the correct data in the table to scroll in (except in the case of the table and screen being alligned while vertical scrolling) 1 Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted November 9, 2013 Author Share Posted November 9, 2013 bah. I tried using pfhscroll to scroll just one pixel at a time. Trouble is, I don't seem to be extracting the bits properly. Somehow pfhscroll just uses the first bit of the data element. My efforts to rotate a byte left or right has failed so far. I think my best chance is to use my hadjust variable to determine if pfhscroll should move left or right. Then I'll have to read in 8 more data elements from the respective side and do 8 more pfhscroll commands. MANY THANKS to bogax again for the wrev function. I've managed to streamline the code a bit. Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted November 10, 2013 Author Share Posted November 10, 2013 Okay folks! We've done it! First post as usual. Four way scrolling has been achieved. The only problem is JUST scrolling around is almost over cycle. I had to remove the last playfield row otherwise the calculations would cause things to go over cycle. I really wish this could be done tighter but I don't see how. Quote Link to comment Share on other sites More sharing options...
bogax Posted November 10, 2013 Share Posted November 10, 2013 (edited) Okay folks! We've done it! First post as usual. Four way scrolling has been achieved. The only problem is JUST scrolling around is almost over cycle. I had to remove the last playfield row otherwise the calculations would cause things to go over cycle. I really wish this could be done tighter but I don't see how. You don't have to keep copying data from the table to the screen and fixing it (reverseing it, scrolling it in to position) Most of the data for the playfield as it will be after scrolling is already in the playfield variables in pretty much the right place. Assuming you're scrolling one pixel at a time, there's one line you'll have to fix if you're scrolling vertically and one column of pixels you'll have scroll in if you're scrolling horizontally If you're scrolling both vertically and horizontally there might be some advantage to combining them in one operation but I'd start with doing them seperately probably scrolling vertically first then horizontally It seems reasonable to let hadjust range up to 7 to begin but eventually it should never have to be more than +-4. You'd need vertical scrolling routines that just copy playfield variables to other playfield variables. Be they unrolled or in for loops they should be faster and have more consistant timing than scrolling lines from the table into place. Once you've scrolled vertically you should need just one line from the table to fill/fix for the line in the new, scrolled playfield that wasn't in the old playfield before you scrolled vertically (assuming you're scrolling no more than one pixel at a time) Then you can do you're horizontal scrolling and hadjust should never be more than +-1 Edited November 10, 2013 by bogax Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted November 13, 2013 Author Share Posted November 13, 2013 I'm pretty sure this is as good as it gets for me. New code and binary at top. I reverted the redraw code to an earlier build that did not go over cycle when var44 - var47 (bottom row) was used. Now both the top and bottom clip SMOOOTHLY. Despite some tricks collision is still a bear. I've mitigated the issues but things a little sticky when not well aligned with the playfield. You'll notice the maze has 2 playfield pixel tall horizontal passages. Also, 5 playfield pixel wide vertical passages. batari didn't even try moving in fractional playfield pixels in his Rally-B demo. Quote Link to comment Share on other sites More sharing options...
bogax Posted November 17, 2013 Share Posted November 17, 2013 Darn you theloon, darn you all to heck!I set this scrolling stuff aside untillI could get a proper playfield editor going.How dare you tempt me But since I had your world data ..This (is mostly) what I was trying todiscribe.I think the only major difference is thatthis picks up the fill in column and shiftsit in when scrolling horizontally instead ofscrolling then filling it in.I just sort of banged this out so I don'tguarantee there's no bugs, but it seems to work.Except for the shifting I think it's all in bBit could undoubtedly be improved. I wasn't tryingto make it small or fast, I was trying to make itstraight forward and understandable.Of course it's set up for 16 byte by 16 byteworld data4way.bas 1 Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted March 3, 2015 Share Posted March 3, 2015 Did you update your code with what bogax posted or improve it in some other way? Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted May 27, 2015 Author Share Posted May 27, 2015 Did you update your code with what bogax posted or improve it in some other way? No. Bogax made his own improvements on an earlier build. The top post should have the most up-to-date code. It scrolls pretty smoothly now. 1 Quote Link to comment Share on other sites More sharing options...
+Lewis2907 Posted October 24, 2017 Share Posted October 24, 2017 This maybe over my head, but how hard is it to go from "16 byte by 16 byte world data" to 32 byte, 32 byte. Just wondering what part of the code you have to adjust, thanks. Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted October 24, 2017 Author Share Posted October 24, 2017 This maybe over my head, but how hard is it to go from "16 byte by 16 byte world data" to 32 byte, 32 byte. Just wondering what part of the code you have to adjust, thanks. I had to heavily lean on bogax for the scrolling code. The level data is specifically laid out so that editing playfield pixels from the source code was dead simple. Basically, every 1 or 0 is one playfield pixel. Trying to change the way the DATA statements are put together would mess with that. Quote Link to comment Share on other sites More sharing options...
+Lewis2907 Posted October 24, 2017 Share Posted October 24, 2017 Gemintronic, I found that out and it's nice. I am playing with it to convert the "Save Earth" over and some other open world games I have in mind. I am able to do Playfield detection in certain "Worlds" based upon if I need to create a border or something. Plus this code here saves a lot space vice the normal Playfield that I learned when I first came over to using Bb. I will play with on how to make 8 byte, 32 byte etc. If not I can work with the 16 byte. Plus the code works fine on AFP where I have decided to gear what I make work on. Bogax has helped me in the past especially with "Exit Flags" for Pac Man Eat n Run. Hopefully its a few simple tweaks here and there to make the Data World s smaller, larger or longer. Thanks again for sharing the code. It has helped me learn. I will need to learn assembly at some point to make it easier on me, thanks. 1 Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted October 24, 2017 Author Share Posted October 24, 2017 The best answer is to move to assembly. The next best answer is to use Mr SQLs vwBASIC as it has built in support for large playfields. http://atariage.com/forums/topic/239347-vwbasic/ My method here uses a LOT of CPU time. Quote Link to comment Share on other sites More sharing options...
bogax Posted October 27, 2017 Share Posted October 27, 2017 speaking for my code while you could undoubtedly speed it up in asm I don't think it would be that dramatic the first thing I'd do is unroll the vertical scrolling and you could do that in bB as to a 32 x 32 byte world you'ld need to change some constants. simplest would probably be to break out the world rows in to individual data statements you could then look up the data statement in a table and use a few bytes of asm to do the actual look up (because 32 x 32 is too big for a data statement) you might be able to jimmy it into sdata but I think that would bring some cruft and it really only needs a few bytes of asm some thing like data wrow0 some, stuff, other, stuff, more, stuff, etc end data wrow1 some, stuff, other, stuff, more, stuff, etc end data wrow2 some, stuff, other, stuff, more, stuff, etc end etc data wrow_addresslo <wrow0, <wrow1, <wrow2, <wrow3 end data wrowaddresshi >wrow0, >wrow1, >wrow2, >wrow3 end temp2 = wrow_addresslo[wrow_number] temp3 = wrow_addresshi[wrow_number] temp1 = index ; fetches your world data to temp1 asm ldy temp1 lda (temp2),y sta temp1 end 1 Quote Link to comment Share on other sites More sharing options...
Sprybug Posted November 4, 2017 Share Posted November 4, 2017 (edited) If you want to see how I did horizontal scrolling in Princess Rescue, just go to Random Terrain's Batari site, and he has my source code for it there, along with added documentation. You can find how I did my scrolling in there with the ScrollLeft and ScrollRight routines. I did use pfhscroll, but with some added code. When new data needed to show up, it would look at the new data I had in the level data table, using a pointer, to pick up the 2 new bytes, and then it would compare bit by bit with what the var screen variables had on the edge of the screen. If it didn't match up, it would flip the bit, saving time so it didn't redraw every bit on the edge of the screen. Edited November 4, 2017 by Sprybug 1 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.