12 October 2019, 19:36 | #1 |
Registered User
Join Date: Jan 2016
Location: Santa Cruz/US
Posts: 48
|
Comprehensive guide to Bobs
Hello all. Since there's a new thread about bobs I thought I would wrap up this post that I started a while back.
I've never seen a comprehensive guide on how to create bobs and have them move over a background. For a beginner there are several gotchas and here's my attempt at describing how it works. In the very simplest form, a bob is just a simple blit of graphics data (source channel A) onto the screen (destination channel D), using minterm $9f0. Many people probably wouldn't call this a bob though, since it isn't moving. The first gotcha is that the destination address can only be a multiple of 16 pixels. In order to place the bob on any x position you need to use the shift blitter operation, and shift the bob up to 15 pixels to the right. You then run into the next gotcha - if you shift data to the right it gets shifted into the left again. To get around that you need to add 16 pixels of blank space at the end of each bob line, i.e. your bob graphics is 16px wider than it normally would be. Now, if you want a bob with multiple colors you need to do a blit for every bitplane. That can become expensive so you can instead define your screen and bob graphics in interleaved mode, when a single (albeit bigger) blit is enough. If your screen has a background it gets more complex, since the simple blit will overwrite the background for the bob pixels that are meant to be transparent. You then do what is referred to as a "Cookie-Cutter" blit. For Source A you point to an outline of the bob, which then acts like a mask. Source B is set to the bob graphics, Source C is the background, and Destination D is also the background, and the minterm used is $fca. If you use interleaved mode the mask needs to be duplicated for each bitplane, which is a drawback with the interleaved mode. To move a bob you need to blit it to the new position, but the problem is that the graphics for the previous position will then still be shown on the screen. If you don't have a background you can simply clear the area of the previous position before blitting to the new position, e.g. using the blitter. But if you have a background you need to instead restore the background of the previous bob position. One way to do this is to use a buffer that stores the previous background for each bob. Here are the steps needed to be done every time you want to move a bob: 1. Restore the background of the previous position by copying from the buffer to the screen. Not necessary if the bob hasn't move yet. 2. Copy the background where you're going to blit into the buffer. 3. Blit the bob using the Cookie-Cutter blit. Note that #1 and #2 can be done with simple A->D blits. If the background is static you can instead restore the background by keeping a copy of the background graphics in a separate, read-only, buffer. Before you blit the bob to the new position you restore the background of the previous position by copying from the buffer to the screen, using a simple A->D blit. Finally, if you draw a lot of things on the screen there may not be enough time to do that in one frame. You can then use a double buffering scheme. You essentially have two screens, each stored in a buffer. One that is shown and one that you draw on. Every vertical blank you flip the bitplane pointers to point to the buffer you just drew on, and then you draw on the other one. If you restore the background of each bobs by storing off the previous bob position it gets a little more complex, since you now actually need to use two previous position buffers, one for each screen. OK, that's what I have so far. If the background scrolls it gets more complicated - I haven't really thought through that yet. And I also know that roondar has an article on "fast bobs" using dual playfields, which I haven't processed yet. Thoughts/Comments? |
13 October 2019, 13:59 | #2 |
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
|
Describes it very well!
It makes clear why you always need one additional word for the width, which sometimes confuses new developers. |
13 October 2019, 20:59 | #3 |
Registered User
Join Date: Oct 2019
Location: Eydelstedt / Germany
Age: 44
Posts: 114
|
Agree. Very nice description! Thanks! But there are still (at the moment ) two things I don't understand.
1. Why does my bob setting/buffering/clearing routines work perfectly? I do not use 16 additional pixels to the right of my bob. It's only 16x16. I am confused . And maybe this brings me to the second question.. 2. How do these BLTAFWM and BLTALWM registers work. Everywhere I read that these registers are used to ignore the first or last word of each line, because the shifting e.g. to the right shifts zeros in from the left. But when I extend my bob 16 pixels to the right, i guess that if the area is empty it contains all zeros. What is the problem then if zeroes are shifted in from the left. Can anyone explain this? Greetings Christian |
13 October 2019, 22:03 | #4 |
Registered User
Join Date: Feb 2018
Location: London / UK
Posts: 112
|
1. Is the bob static? Try moving the bob on the screen and you should see what the issue is. For example if you have your bob at the top left corner at 0,0 then the 16 bit wide bob will be in the first 2 bytes of the bitplane. But if you'd like to draw the bob one pixel to the right (so at 1,0) it won't be in the first 2 bytes anymore. The last pixel will be in the 3rd byte of that bitplane. And then you need to pad to words as that's what blitter uses so 4 bytes / 32 pixels.
2. You don't need it for bobs. But for example if you are drawing a rectangle of any size you'd probably want to use these registers. The blitter will only copy words / 16 pixels but you can set these registers to fine tune the left (first word of a line) and right (last) edges of the rectangle to be at any pixel position. |
13 October 2019, 22:38 | #5 | ||
Registered User
Join Date: Oct 2019
Location: Eydelstedt / Germany
Age: 44
Posts: 114
|
Quote:
move.w #40-4,$60(a5) ; BLTCMOD move.w #-2,$62(a5) ; BLTBMOD move.w #-2,$64(a5) ; BLTAMOD move.w #40-4,$66(a5) ; BLTDMOD move.w #(16*64)+2,$58(a5) ; BLTSIZE When I chose the 16x32 bob (with empty area on the right), I have to use a 16x32 mask (thus, also contains the empty area on the right side), and set move.w #0,$62(a5) ; BLTBMOD move.w #0,$64(a5) ; BLTAMOD to get the same result. The only issue I see, is when the bob leaves the screen on the left/right/top/bottom of the screen (I want to let the bob come into the opposite side if it leaves the screen boundries). But that problem I have with both configurations. Quote:
|
||
13 October 2019, 22:42 | #6 | |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
|
Quote:
The reason is here: move.w #-2,$62(a5) ; BLTBMOD move.w #-2,$64(a5) ; BLTAMOD and: move.w #(16*64)+2,$58(a5) ; BLTSIZE You write a 32bits x bobs, cut it to valid 16bits and then modulo -2 realign the data. |
|
13 October 2019, 22:51 | #7 |
Registered User
Join Date: Oct 2019
Location: Eydelstedt / Germany
Age: 44
Posts: 114
|
Yes...ok. But is there anything wrong with it? It works, and my masks and buffers only have to be of size 16x16.
|
13 October 2019, 22:56 | #8 |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
|
|
17 November 2020, 20:53 | #9 |
Registered User
Join Date: Apr 2018
Location: Germany
Posts: 189
|
I want to blit an interleaved bob into an interleaved view.
As far as I know for non-interleaved, planar blits the BLTAMOD and BLTSIZE are calculated as follows: Code:
BLTSIZE = height * 64 + wordWidth BLTAMOD = (destinationWidth - blitWindowWidth) / 8 I suppose at least BLTSIZE must be changed for an interleaved blit. As instead 'depth x small-sized-blit' only one bigger-sized-blit is done. So would the following work for interleaved? Code:
BLTSIZE = (Height * 64 + WordWidth) * depth Last edited by thyslo; 18 November 2020 at 11:57. |
18 November 2020, 00:41 | #10 |
OCS forever!
Join Date: Mar 2019
Location: Birmingham, UK
Posts: 418
|
BLTSIZE = ((height * depth)*64) + wordwidth
Think of it as making your blit of increased height. |
18 November 2020, 18:47 | #11 |
Registered User
Join Date: Apr 2018
Location: Germany
Posts: 189
|
I changed this and now it finally works:-) Thank you!
|
18 November 2020, 20:12 | #12 |
Registered User
Join Date: Sep 2019
Location: Essen/Germany
Age: 55
Posts: 463
|
If the Bob has to be at least 16x16, does this mean that, if you want to print i.e. 8x8 characters, it should be done with CPU? I guess in case of text output, setting each character up for blitting might cause to much overhead anyway, right?
Very usefull thread! Thanks for posting this info. |
19 November 2020, 19:51 | #13 | |
Registered User
Join Date: Sep 2017
Location: Kansas, USA
Posts: 324
|
The minimum size for a blit is a single word, 16 bits. If you want to make a smaller blit you just mask out the unwanted data and shift it while doing the blit, which is exactly how the HRM explains things:
Quote:
|
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Appiah's comprehensive 15KHz monitors list of caveat emptor | appiah4 | support.Hardware | 148 | 26 August 2022 17:18 |
Guide: WinUAE PPC OS 4.0 Classic Install Guide (Beta 12+) | BinoX | support.WinUAE | 170 | 22 April 2021 11:37 |
Comprehensive RPG List ? | Washac | request.Other | 2 | 02 February 2018 12:27 |
Comprehensive list of supported joysticks? | rams | support.Hardware | 6 | 05 November 2013 08:04 |
Is there a comprehensive FAQ to run HD games in WinUAE? | Aegothis | support.WinUAE | 0 | 20 February 2005 03:35 |
|
|