28 January 2020, 16:21 | #1 |
Registered User
Join Date: Feb 2018
Location: Northumberland, UK
Posts: 272
|
Double Buffer & Hardware Scroll
Hi!
So I'm moving onto something a bit more tricky and as usual I've become a bit confused. Hoping someone can point me in the right direction: I'm currently using Photon's MiniStartup code as a basis for my setup, as found here: Photons MiniStartup I think I understand it in that it's setting up two screens of allocated memory in chip ram and swapping them out at the beginning of the main loop by changing the bitplane pointers in the copper to point to each individual screen. However, what I can't figure out is how to implement a hardware scroll using this example. What I understand about that is you use a wider screen of say 336 pixels, draw into that offscreen column, and then set a hardware scroll value of between 0 and 15 to smoothly slide those new graphics into place. For the life of me though, I can't figure out how to marry up both the double-buffering (as in these examples) and the hardware scroll. Should I just ditch this double-buffering technique and look at some of the other example on the internet, I've read and understand Dave Jones' example which was published in Amiga Format, with a double wide screen, but it's far and away from what I'm working with now. Any pointers, tips, examples or links to documentation would be great. Thanks :-) |
28 January 2020, 16:28 | #2 |
Registered User
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,408
|
The first step is in realizing that it doesn't matter what buffer you want to scroll - the steps stay the same. If you understand how to scroll one buffer, you also understand how to scroll another buffer. The second step is realizing that scrolling and double buffering are independent of one another.
Double buffering is just switching between two different buffers (usually) every frame*. Scrolling is just drawing into an offscreen column and then setting a hardware scroll value to slide the graphics into place (I'm using your example here, there are other ways of scrolling). To marry the two together, you draw to the offscreen column of both buffers rather than just the one. Then, you glide the new data into place by changing the shift value. While you do this, you switch between the two buffers every frame. Something like this:
Edit: I do have some sample code in assembly that shows horizontal scrolling if you like it, but it's mixed in with other effects so might not be what you're looking for. Check out http://powerprograms.nl/amiga/dpl-fastbobs.html for one such example. *) I put this as simplified as possible to remove distractions such as blitting/restoring bobs Last edited by roondar; 28 January 2020 at 17:39. |
28 January 2020, 20:59 | #3 |
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
|
Hmm. Maybe it's easier, also for the understanding, to treat the buffers completely independant.
I have usually a data structure of bitplane pointers and scroll-value for each of the two buffers. The main loop just says: scroll to offset x. Then you will take your current (invisible) buffer and calculate the new bitplane pointers and scroll value for it. Depending on the difference to the old position (entered a new tile column?) you start blitting new tiles into the border. That's how I do it in my games. Every buffer runs a game of its own and is updated every second frame. |
29 January 2020, 11:44 | #4 |
Registered User
Join Date: Sep 2019
Location: Essen/Germany
Age: 55
Posts: 463
|
If I understand it correctly, when using an offscreen column, there wouldn't even be a need of double buffering, right?
I was also thinking about how to do scrolling of big areas, and a problem that I have is, how to organize the data properly. If the whole level fits in chipmem as a single chunk, then scrolling should be fairly easy, because you just have to adjust pointers accordingly. Double buffering should also be not needed in this case, right? |
29 January 2020, 12:14 | #5 | |
Registered User
Join Date: Oct 2015
Location: Landsberg / Germany
Posts: 526
|
Quote:
So, for a start may I suggest to focus on a single buffered approach, maybe adding some sprite objects. That´s much easier to handle, and your motivation will benefit from goodlooking, flickerless results within a foreseeable amount of time. |
|
29 January 2020, 12:32 | #6 |
Registered User
Join Date: Feb 2018
Location: Northumberland, UK
Posts: 272
|
Thanks for all the replies lads, I really appreciate the time you give.
I'll have a look at simplifying things, but in the meantime I'm currently banging my head with the blitter. But that's a different story |
29 January 2020, 13:17 | #7 |
Moderator
Join Date: Nov 2004
Location: Eksjö / Sweden
Posts: 5,602
|
The buffer list only contains screen pointers to start with - it can be expanded to a structure per buffer, containing scroll offset coordinates, a pointer to a list of sprite coordinates, or anything you can imagine that should be double buffered.
This then allows you to prepare all things that should be on screen in the next frame - it doesn't have to be only memory chunks containing bitmap data: copper splits, color changes, sprites, etc. To do this, you have to modify the actual buffer swap for the increased structure size, and add handling code where the bitplane pointers are written. |
29 January 2020, 14:38 | #8 |
Registered User
Join Date: Feb 2018
Location: Northumberland, UK
Posts: 272
|
Ok, so I need to step back a bit here because before I can bother myself with scrolling something I'm blitting into a hidden column I actually need to get something, ANYTHING, to blit onto the screen.
Using the same setup as before, with the DrawBuffer and ViewBuffer I have the following code: Code:
Tile_Width EQU 16 Tile_Height EQU 16 Tile_ByteWidth EQU Tile_Width/8 Tile_VerticalSize EQU Tile_Height*DisplayDepth Tile_HorizontalSize EQU Tile_ByteWidth/2 ******************************************************************************* BlitTile: bsr WaitBlitter lea Tiles,a0 lea DrawBuffer,a1 move.l #$09f00000,BLTCON0(a6) ;A->D copy, no shifts, ascending mode move.l #-1,BLTAFWM(a6) ;no masking of first/last word move.w #0,BLTAMOD(a6) ;A modulo=bytes to skip between lines move.w #38,BLTDMOD(a6) ;D modulo move.l a0,BLTAPTH(a6) ;source graphic top left corner move.l a1,BLTDPTH(a6) ;destination top left corner move.w #Tile_VerticalSize,BLTSIZV(a6) move.w #Tile_HorizontalSize,BLTSIZH(a6) rts ******************************************************************************* SECTION ChipData,DATA_C ;declared data that must be in chipmem ******************************************************************************* Tiles: INCLUDE "data/level.1.tiles.asm" What I don't understand is the BLTAMOD and BLTDMOD modulo. I am under the impression that BLTAMOD is the source modulo, so the tile I want to blit and BLTDMOD is the screen modulo which I want to blit to. BLTAMOD: 0 as each tile is 16bits wide, or 2 bytes, so 2 - 2. BLTAMOD: 38 bytes per bitplaneline, 40 - 2 Running this I just get a hung amiga which continually draws random data up the screen. Any help would be greatly appreciated Thanks Edit: Here's the settings I'm using in PicCon to save my tiles using the AutoScan option: Also, Copper is setup thus: Code:
******************************************************************************* SECTION ChipData,DATA_C ;declared data that must be in chipmem ******************************************************************************* Copper: dc.w FMODE,$000c ; 1x fetch mode, 64 pixel wide sprites dc.w DIWSTRT,$2c91 ; horizontally centered 288x224 display window dc.w DIWSTOP,$0cb1 dc.w DDFSTRT,$38 ; standard DDFSTRT and DDFSTOP for 320x256 dc.w DDFSTOP,$d0 ; in 1x fetch mode, includes 16 pixels border around whole screen dc.w BPL1MOD,$c8 ; 200 dc.w BPL2MOD,$c8 ; 200 dc.w BPLCON0,$6200 dc.w BPLCON1,$0000 dc.w BPLCON2,$0200 BplPtrs: dc.w BPL1PTH,$0000 dc.w BPL1PTL,$0000 dc.w BPL2PTH,$0000 dc.w BPL2PTL,$0000 dc.w BPL3PTH,$0000 dc.w BPL3PTL,$0000 dc.w BPL4PTH,$0000 dc.w BPL4PTL,$0000 dc.w BPL5PTH,$0000 dc.w BPL5PTL,$0000 dc.w BPL6PTH,$0000 dc.w BPL6PTL,$0000 Palette: INCBIN "data/level.1.palette.bin" dc.w BPLCON3,$0000 dc.w COLOR00,$0000 dc.w BPLCON3,$0200 dc.w COLOR00,$0000 SpritePtrs: dc.w SPR0PTH,$0000 dc.w SPR0PTL,$0000 dc.w SPR1PTH,$0000 dc.w SPR1PTL,$0000 dc.w SPR2PTH,$0000 dc.w SPR2PTL,$0000 dc.w SPR3PTH,$0000 dc.w SPR3PTL,$0000 dc.w SPR4PTH,$0000 dc.w SPR4PTL,$0000 dc.w SPR5PTH,$0000 dc.w SPR5PTL,$0000 dc.w SPR6PTH,$0000 dc.w SPR6PTL,$0000 dc.w SPR7PTH,$0000 dc.w SPR7PTL,$0000 dc.w $ffdf,$fffe ;allow VPOS>$ff dc.w $ffff,$fffe ;magic value to end copperlist CopperE: Last edited by DanielAllsopp; 29 January 2020 at 15:09. |
29 January 2020, 17:22 | #9 |
Registered User
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,408
|
Two small questions to aid you with debugging this:
The modulo value doesn't look to be a problem. It simply means it'll skip 38 bytes per line, which is not nearly enough to cause crashes or overruns when blitting to the top left of the screen. If a modulo value that small is wrong, it'll generally cause a distortion instead of a crash. Edit, I checked the photon startup code you point to in the OP and found this: Code:
********** Fastmem Data ********** DrawBuffer: dc.l Screen2 ;pointers to buffers to be swapped ViewBuffer: dc.l Screen Last edited by roondar; 29 January 2020 at 17:35. |
29 January 2020, 17:40 | #10 | |
Registered User
Join Date: Feb 2018
Location: Northumberland, UK
Posts: 272
|
Quote:
So, making those changes I do indeed get no crash now, but nothing is blitted to the screen, even if I change the DIWSTRT and DIWSTOP to remove the borders at either side. Still, not crashing is a good place to be. I'll try and work out why I'm not getting anything on screen now. Do the options for the tile output look right to you? Interleaved, No Blitterwords and btye aligned? I'm using AGA with 64bit wide sprites, but still in 1x Fetch Mode. |
|
29 January 2020, 17:54 | #11 |
Registered User
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,408
|
I've never used PicCon so I can't be 100% sure, but interleaved is normally fine and even if it weren't you'd still get something drawn - unless the entire file is filled with zeros.
When you don't see a result after blitting and you're certain Blitter DMA is active, I find there's generally one of the following things going on:
Without the rest of the source it's a bit of a guess, but I'd guess the problem is the destination address. Are you sure the buffer is being shown after the blit? Have you tried adding an offset so that the blit should appear roughly halfway down the screen? |
29 January 2020, 18:16 | #12 | |
Registered User
Join Date: Feb 2018
Location: Northumberland, UK
Posts: 272
|
Quote:
I had mistakenly set the Code:
lea Tiles,a0 Anyway, I'll soldier on with more tinkering until I become stuck again. Thanks a lot! |
|
29 January 2020, 19:03 | #13 |
Registered User
Join Date: Sep 2019
Location: Essen/Germany
Age: 55
Posts: 463
|
Are you doing a Ghosts'n Goblins port?
|
29 January 2020, 19:07 | #14 |
Registered User
Join Date: Feb 2018
Location: Northumberland, UK
Posts: 272
|
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Game development using C and sys functions, double buffer problem | balrogsoft | Coders. C/C++ | 7 | 28 December 2022 21:32 |
ScrollVPort double buffer problem with garbage pixels | balrogsoft | Coders. General | 5 | 29 May 2014 12:31 |
Double buffer copper?? | h0ffman | Coders. General | 8 | 19 July 2011 19:10 |
Vsync Fullscreen and Double Buffer, incorrect frame rate? | rsn8887 | support.WinUAE | 1 | 07 April 2011 20:43 |
Hardware Scroll tutorial? | Lonewolf10 | Coders. Tutorials | 14 | 24 January 2011 00:08 |
|
|