#2002 - krozen - Mon Jan 27, 2003 4:36 pm
Hello,
I am writing an application that flips between buffers in mode 4 to produce smooth scrolling. My current function to clear the buffer looks like so Code: |
for (i = 0; i<160 ; i++)
{
for ( j = 0 ; j<120 ; j++)
{
theVideoBuffer[((i<<7) - (i<<3)) + j] = ((paletteMem[0]<<8) + paletteMem[0]);
}
} |
It works (sort of!), but it is so slow. Is there any way of just clearing the buffer in one swoop. Can you create a black background, say, and just point the buffer at it, thus clearing it, and then drawing to it?
Thanks for your help!
#2005 - velvetfr - Mon Jan 27, 2003 5:12 pm
Hi,
yes, can be done quite easily ... by using one of the DMA channel, the destination address would be your screen buffer you want to clear, the source address would point to your pixel value you want to clear the buffer with. You have to set the DMA cntl register to not incrementing the source address, and you should have a nitty clrscr.
#2006 - velvetfr - Mon Jan 27, 2003 5:15 pm
... also, I forgot, you have to set the DMA count register to the number of words or halfwords (depending on the DMA cntl bit you set to) to be the buffer screen size.
Sorry not to give you any code lines with this, but the main idea is that, so it should be now easy for you (by picking some nitty documentation like gbatek, or CowBytes) to implement.
#2009 - krozen - Mon Jan 27, 2003 5:49 pm
cheers, ill look into that
#2010 - col - Mon Jan 27, 2003 7:09 pm
krozen wrote: |
Hello,
I am writing an application that flips between buffers in mode 4 to produce smooth scrolling. |
Is there any particular reason why you're using a bitmapped mode?
As I'm sure you know, scrolling is free in tile modes and you get layers and effects for free as well. Its also possible to setup a tile mode so that you can plot pixels to it, this will be slower than plotting to a bitmapped mode, but offsetting that against scrolling in bitmapped mode....
cheers
col
#2017 - ampz - Mon Jan 27, 2003 7:57 pm
Why do you need to clear the buffer? just write the new frame into the buffer. No need to clear it before you update it.
And I agree with 'col', depending you your application a textmode might give you better performance. However, it's quite a bit more complicated than a bitmap mode.
I really don't understand why Nintendo didn't add hardware scrolling to the bitmap modes... it's a very simple thing to do in hardware (just preload the adr-counter with a constant), but hard to do in software.
#2019 - Splam - Mon Jan 27, 2003 8:34 pm
There is hardware scrolling, just no extra area outside the screen to draw to (like the extra tiles in tile mode) but you can make your own "border" with a window and update a few pixels per frame.
#2022 - ampz - Mon Jan 27, 2003 9:08 pm
The bitmap modes doesn't wrap around. That's means the scaling/rotation reference points can't be used for scrolling.
(EDIT)
#2032 - Splam - Tue Jan 28, 2003 1:26 am
Sorry, didn't explain myself very well. You use the time it takes to scroll the bg through the "border" area to update your other buffer then swap. Saves moving a whole screen of data each frame. Do 1/4 of a screen per frame and have a 4 pixel window.
#2048 - krozen - Tue Jan 28, 2003 11:23 am
Hello,
That DMA example worked well. Thank you! Im actually writing a pseudo 3-d engine (2.5d?) for my final year project in college. I suppose you could call it a voxel landscape engine, but that term is just thrown around so much. I need to scrolling to draw the new scene to the back buffer , while the other one is being displayed. I have it all writtin in C at the minute, at it runs smoothly enough. Im trying to speed it up at the minute by removing as many multiplications and division as i can. I know one is not meant to do this, i shud really open another topic, but does anyone have any ideas for fast mults and divisions. I have everythin working in fixed point math at the minute.
Cheers
#2049 - Quirky - Tue Jan 28, 2003 11:54 am
Don't use divisions. And if you must, use the bios div rather than /. That's the best advice I've read on the subject. This code from devrs.com is an example of how to do integer divide in the bios..
Code: |
// Do an integer division using GBA BIOS fast division SWI code.
// by Jeff F., 2002-Apr-27
GCC 2.9/3.0 Version
void FastIntDivide (signed long Numer, signed long Denom, signed long *Result, signed long *Remainder)
{
asm volatile
(
" mov r0,%2 \n"
" mov r1,%3 \n"
" swi 0x60000 \n" //NOTE!!!!! Put 6 here for Thumb C Compiler mode.
" ldr r2,%0 \n" // Put 0x60000 there for ARM C Compiler mode.
" str r0,[r2] \n"
" ldr r2,%1 \n"
" str r1,[r2] \n"
: "=m" (Result), "=m" (Remainder) // Outputs
: "r" (Numer), "r" (Denom) // Inputs
: "r0","r1","r2","r3" // Regs crushed & smushed
);
}
|
#2050 - krozen - Tue Jan 28, 2003 12:00 pm
Thank you,
I tried to use that code before. But couldnt get it working. How does that function actually return anything, seeing as it is a void? How would i assign the return value of that function to, say, a unsigned integer? Thanks again! :)
#2057 - Splam - Tue Jan 28, 2003 3:41 pm
The results are returned in here
signed long *Result, signed long *Remainder
so you'd have signed long Result and signed long Remainder declared in your code and upon calling that routine they are filled. Upon returning you then just use them as normal Result and Remainder.