English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Asm / Hardware

 
 
Thread Tools
Old 28 January 2020, 16:21   #1
DanielAllsopp
Registered User
 
DanielAllsopp's Avatar
 
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 :-)
DanielAllsopp is offline  
Old 28 January 2020, 16:28   #2
roondar
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:
  1. Update bitplane pointers to the next buffer
  2. Update scroll value
  3. Draw tiles as needed to the offscreen column of both buffers
  4. Update the offset into the buffers as needed
Note that this is almost identical to single buffer scrolling. The only difference is drawing the extra column to two buffers rather than one and that you switch the buffers around every frame rather than having one which doesn't switch.

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.
roondar is offline  
Old 28 January 2020, 20:59   #3
phx
Natteravn
 
phx's Avatar
 
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.
phx is offline  
Old 29 January 2020, 11:44   #4
sparhawk
Registered User
 
sparhawk's Avatar
 
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?
sparhawk is offline  
Old 29 January 2020, 12:14   #5
buzzybee
Registered User
 
Join Date: Oct 2015
Location: Landsberg / Germany
Posts: 526
Quote:
Originally Posted by sparhawk View Post
If I understand it correctly, when using an offscreen column, there wouldn't even be a need of double buffering, right?
Exactly. Double (or Tripple) Buffering is basically needed if you use the blitter to draw stuff onscreen.

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.
buzzybee is offline  
Old 29 January 2020, 12:32   #6
DanielAllsopp
Registered User
 
DanielAllsopp's Avatar
 
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
DanielAllsopp is offline  
Old 29 January 2020, 13:17   #7
Photon
Moderator
 
Photon's Avatar
 
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.
Photon is offline  
Old 29 January 2020, 14:38   #8
DanielAllsopp
Registered User
 
DanielAllsopp's Avatar
 
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"
Display is 320x256x6, with the KillEHB bit set. The tiles are 16x16x6.

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.
DanielAllsopp is offline  
Old 29 January 2020, 17:22   #9
roondar
Registered User
 
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,408
Two small questions to aid you with debugging this:
  1. I'm assuming the screen works just fine if you don't blit anything?
  2. What exactly is the value of A1?
I'm asking the second question because without the rest of the source I can't tell if Drawbuffer is a pointer, or a block of memory. If it's the first, I understand why it'll crash (for pointers in the source you can't use lea but rather must use move.l). If it's a block of memory, more digging is needed

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
In this case you can't use a lea instruction as that calculates the address of the label DrawBuffer. This is not what you want, you want to point the Blitter to the address stored at the address pointed to by the label DrawBuffer. Change the lea to a move.l and it should work.

Last edited by roondar; 29 January 2020 at 17:35.
roondar is offline  
Old 29 January 2020, 17:40   #10
DanielAllsopp
Registered User
 
DanielAllsopp's Avatar
 
Join Date: Feb 2018
Location: Northumberland, UK
Posts: 272
Quote:
Originally Posted by roondar View Post
Two small questions to aid you with debugging this:
  1. I'm assuming the screen works just fine if you don't blit anything?
  2. What exactly is the value of A1?
I'm asking the second question because without the rest of the source I can't tell if Drawbuffer is a pointer, or a block of memory. If it's the first, I understand why it'll crash (for pointers in the source you can't use lea but rather must use move.l). If it's a block of memory, more digging is needed

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. 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
In this case you can't use a lea instruction as that calculates the address of the label DrawBuffer. This is not what you want, you want to point the Blitter to the address stored at the address pointed to by the label DrawBuffer. Change the lea to a move.l and it should work.
Aha, there's another little tip I can add to my bank of knowledge. Thanks for that.

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.
DanielAllsopp is offline  
Old 29 January 2020, 17:54   #11
roondar
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:
  1. Wrong source address
  2. Wrong destination address
  3. Wrong Blitter settings (usually mask/minterm)
  4. The source is empty (a surprisingly common error of mine is to forget to actually put some source data in. Blitting all zero's is not very impressive )
  5. Something else happens after the blit that erases the result (usually an error in restoring bobs causes this, could also be a screen clear, etc)
Looking at the code you provided, it seems to me that the Blitter settings ought to be correct. The mask is fine, the minterm is also fine. If the modulo is incorrect (which I don't think it is at first glance) you'd still see something.

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?
roondar is offline  
Old 29 January 2020, 18:16   #12
DanielAllsopp
Registered User
 
DanielAllsopp's Avatar
 
Join Date: Feb 2018
Location: Northumberland, UK
Posts: 272
Quote:
Originally Posted by roondar View Post
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:
  1. Wrong source address
  2. Wrong destination address
  3. Wrong Blitter settings (usually mask/minterm)
  4. The source is empty (a surprisingly common error of mine is to forget to actually put some source data in. Blitting all zero's is not very impressive )
  5. Something else happens after the blit that erases the result (usually an error in restoring bobs causes this, could also be a screen clear, etc)
Looking at the code you provided, it seems to me that the Blitter settings ought to be correct. The mask is fine, the minterm is also fine. If the modulo is incorrect (which I don't think it is at first glance) you'd still see something.

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?
You sir are an absolute scholar and a gentleman. My hat is off to you for helping with such silly questions. Here's what I was looking for:



I had mistakenly set the
Code:
lea Tiles,a0
to a move.l too which of course wasn't correct.

Anyway, I'll soldier on with more tinkering until I become stuck again. Thanks a lot!
DanielAllsopp is offline  
Old 29 January 2020, 19:03   #13
sparhawk
Registered User
 
sparhawk's Avatar
 
Join Date: Sep 2019
Location: Essen/Germany
Age: 55
Posts: 463
Are you doing a Ghosts'n Goblins port?
sparhawk is offline  
Old 29 January 2020, 19:07   #14
DanielAllsopp
Registered User
 
DanielAllsopp's Avatar
 
Join Date: Feb 2018
Location: Northumberland, UK
Posts: 272
Quote:
Originally Posted by sparhawk View Post
Are you doing a Ghosts'n Goblins port?
Haha, no, I don't think my game making skills would stretch that far. I'm just using the sprites and tiles for my ASM tinkering on as they're readily available and they look kinda cool.
DanielAllsopp is offline  
 


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

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 16:03.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.13141 seconds with 15 queries