#132171 - yellowstar - Sun Jun 24, 2007 1:10 am
I am having a differen't problem now.(Differen't from this problems in this post and forward)
See this post for details.
I need some help with Double Buffers,
for both screens.
The way I am doing it dosen't work.
What is the correct way to do it?
Here is the setup I am using:
On the main screen,
I have a red background,
which dosen't do anything yet.
I am not having any problems
with this screen.
On the sub screen,
I have a red background,
which displays the graphics.
The following is not the
problems I am having right now.
See my second post for my new problems.
The source code has been deleted in this post,
as it is old. The new source code is in my second post.
Here are the problems I am having:
These problems are only on the sub screen.
1.
The graphic is flickering.
Only part of the graphic is flickering.
Only approx. 8 pixels of the graphic is flickering.
The part that is flickering is from the bottom of the screen
to appox. 8 pixels up.
2.
Most of the graphic has the background color(red)
on it.
It seems that the background color is only on
one color on the image.(the image is paletted.)
That color is the main color,
that is, that color is used more than the other colors.
Here's the code I am using:
Note that this is the whole thing.
taskbar2 and taskbar3 is the graphics,
and bak is the red background
which is used to clear the backgrounds.
The back buffers are cleared in the draw function.
Last edited by yellowstar on Fri Apr 11, 2008 8:54 pm; edited 17 times in total
#132173 - Cydrak - Sun Jun 24, 2007 4:04 am
Ahh... VRAM mapping. Harbringer of many colorful adventures.
The main and subscreens are entirely separate, and can't share banks. Sub BGs can only use up to 128K--so there is no BMP_BG_BASE(8/9/etc), and the base is relative to C or H. Try using 0 and 3, just like your main ones.
Secondly, C and H map the same BG area, 0x06200000. If you try to combine them, you get... exactly what you asked for (roughly BGdata = Cdata | Hdata), but probably not what you want. I ran into this myself, by forgetting to unmap H--found it hilarious personally. :-)
Also you don't have to set up four BGs, unless you want all four buffers onscreen.
#132302 - yellowstar - Mon Jun 25, 2007 6:36 pm
Thanks, Cydrak!
It works now!
But now I have a new problem.
When I tried copying some image data to
a position in the sub screen back buffer,
it dosen't work.
I am using 16 bit writes, not 8 bit writes.
I am not having the following problem anymore,
but I am still having problems.
See my 4th post below this one for details.
The source in this post is for the current problems
I am having.
On the sub screen, it displays
the background,
and on top of it,
instead of the image,
it displays 2 red bars with lines through
them.
These bars conver the whole screen,
except the middle of the screen.
For example:
(X is the bars, ^ is the normal parts of the screen.)
XXXXXXXXXXXXXX
XXXXXXXXXXXXXX
XXXXXXXXXXXXXX
XXXXXXXXXXXXXX
XXXXXXXXXXXXXX
^^^^^^^^^^^^^
^^^^^^^^^^^^^
^^^^^^^^^^^^^
^^^^^^^^^^^^^
XXXXXXXXXXXXXX
XXXXXXXXXXXXXX
XXXXXXXXXXXXXX
XXXXXXXXXXXXXX
XXXXXXXXXXXXXX
Here's the code I am using:
This code is the same code as the above,
except the double buffers works.
taskbar_raw is the image.
Here's the new code:
Code: |
__attribute__((section (".ewram"),long_call))
void scpy(void* in_dst, const void *in_src, unsigned int length)
{
u16 *src = (u16 *)in_src;
u16 *dst = (u16 *)in_dst;
for(; length > 0; length--)
*dst++ = *src++;
}
void vcopy(u16* source, u16 *target, size_t s_offset, size_t t_offset, size_t size)
{
//Copys source starting at s_offset to target starting at t_offset with
//size size.
//This Copy works with VRAM, OAM, and backgrounds.
if(copy_type == CT_SCPY)
scpy(&target[(int)t_offset],&source[(int)s_offset],(size_t)size);
if(copy_type == CT_DMA)
dmaCopy(&source[(int)s_offset],&target[(int)t_offset],size);
}
void VCopy(u16* source, u16 *target, size_t s_offset, size_t t_offset, size_t size,size_t target_width, size_t source_width)
{
if(beforeVRAM)
{
if(t_offset!=0)
{
for(int i=0; i < (int)t_offset; i++)
target[i] = target[i];
}
}
if(linear)
{
for(size_t i=0; i < size; i+= source_width)
vcopy(source,target,s_offset + i,t_offset + i,source_width);
}
if(!linear)
vcopy(source,target,s_offset,t_offset,size);
if(afterVRAM)
{
if((t_offset + size)!=256)
{
for(int i=(int)(t_offset+size); i < (int)256*256; i++)
target[i] = target[i];
}
}
}
|
This goes in the draw function:
Code: |
if(section == S_TOP)
VCopy((u16*)TASKBAR3_RAW,video_buffer_main,0,0,(size_t)TASKBAR3_RAW_size,256,256);
if(section == S_MIDDLE)
VCopy((u16*)TASKBAR3_RAW,video_buffer_main,0,256*32,(size_t)TASKBAR3_RAW_size,256,256);
if(section == S_BOTTOM)
VCopy((u16*)TASKBAR3_RAW,video_buffer_main,0,256*(192 - 96),(size_t)TASKBAR3_RAW_size,256,256);
|
Here is the whole thing:
This is the same as the above,
except the double buffers works,
and it has my current problem in it.
Code: |
#include <nds.h>
#include <string.h>
#include <malloc.h>
#include "PALETTE_RAW.h"
#include "TASKBAR_RAW.h"
#include "TASKBAR2_RAW.h"
#include "TASKBAR3_RAW.h"
#include "BAK_RAW.h"
#include "BAK2_RAW.h"
#define DEBUG
u16 *video_buffer_main = (u16*)BG_BMP_RAM(0);
u16 *video_buffer_sub = (u16*)BG_BMP_RAM_SUB(0);
__attribute__((section (".ewram"),long_call))
void scpy(void* in_dst, const void *in_src, unsigned int length)
{
u16 *src = (u16 *)in_src;
u16 *dst = (u16 *)in_dst;
for(; length > 0; length--)
*dst++ = *src++;
}
void vcopy(u16* source, u16 *target, size_t s_offset, size_t t_offset, size_t size)
{
//Copys source starting at s_offset to target starting at t_offset with
//size size.
//This Copy works with VRAM, OAM, and backgrounds.
if(copy_type == CT_SCPY)
scpy(&target[(int)t_offset],&source[(int)s_offset],(size_t)size);
if(copy_type == CT_DMA)
dmaCopy(&source[(int)s_offset],&target[(int)t_offset],size);
}
void VCopy(u16* source, u16 *target, size_t s_offset, size_t t_offset, size_t size,size_t target_width, size_t source_width)
{
if(beforeVRAM)
{
if(t_offset!=0)
{
for(int i=0; i < (int)t_offset; i++)
target[i] = target[i];
}
}
if(linear)
{
for(size_t i=0; i < size; i+= source_width)
vcopy(source,target,s_offset + i,t_offset + i,source_width);
}
if(!linear)
vcopy(source,target,s_offset,t_offset,size);
if(afterVRAM)
{
if((t_offset + size)!=256)
{
for(int i=(int)(t_offset+size); i < (int)256*256; i++)
target[i] = target[i];
}
}
}
void Init()
{
#ifdef DEBUG
if(!fatInitDefault())
return;
#endif
}
void Draw()
{
dmaCopy(BAK_RAW,video_buffer_sub,256*256);
dmaCopy(BAK_RAW,video_buffer_main,256*256);
if(section == S_TOP)
VCopy((u16*)TASKBAR3_RAW,video_buffer_main,0,0,(size_t)TASKBAR3_RAW_size,256,256);
if(section == S_MIDDLE)
VCopy((u16*)TASKBAR3_RAW,video_buffer_main,0,256*32,(size_t)TASKBAR3_RAW_size,256,256);
if(section == S_BOTTOM)
VCopy((u16*)TASKBAR3_RAW,video_buffer_main,0,256*(192 -28),(size_t)TASKBAR3_RAW_size,256,256);
}
int main(void)
{
powerON(POWER_ALL);
irqInit();
irqEnable(IRQ_VBLANK);
videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);
videoSetModeSub(MODE_5_2D | DISPLAY_BG3_ACTIVE);
vramSetBankA(VRAM_A_MAIN_BG);
//Init main bg
BG3_CR = BG_BMP8_256x256 | BG_BMP_BASE(0) | BG_PRIORITY(3);
//No rotation and no scale
BG3_XDX = 1 << 8;
BG3_XDY = 0;
BG3_YDX = 0;
BG3_YDY = 1 << 8;
BG3_CX = 0;
BG3_CY = 0;
vramSetBankB(VRAM_B_MAIN_BG);
vramSetBankH(VRAM_H_SUB_BG);
vramSetBankI(VRAM_I_SUB_BG);
vramSetBankC(VRAM_C_SUB_BG);
//Init sub
SUB_BG3_CR = BG_BMP8_256x256 | BG_BMP_BASE(0) | BG_PRIORITY(3);
//No rotation and no scale
SUB_BG3_XDX = 1 << 8;
SUB_BG3_XDY = 0;
SUB_BG3_YDX = 0;
SUB_BG3_YDY = 1 << 8;
SUB_BG3_CX = 0;
SUB_BG3_CY = 0;
BG_PALETTE_SUB[8] = RGB15(0,0,31) & (~BIT(15));
BG_PALETTE_SUB[0] = RGB15(0,0,0) | BIT(15);
BG_PALETTE[0] = RGB15(0,0,0) | BIT(15);
//memcpy(BG_PALETTE,PALETTE_RAW,PALETTE_RAW_size);
memcpy(BG_PALETTE_SUB,PALETTE_RAW,PALETTE_RAW_size);
memcpy(BG_PALETTE,PALETTE_RAW,PALETTE_RAW_size);
dmaCopy(BAK_RAW,video_buffer_main,256*256);
//memcpy(video_buffer_sub_buff,bak_raw,256*256);
dmaCopy(BAK_RAW,video_buffer_sub,256*256);
Init();
while(1)
{
Draw();
swiWaitForVBlank();
}
return 0;
}
|
Last edited by yellowstar on Mon Oct 01, 2007 7:29 pm; edited 8 times in total
#132323 - Cydrak - Mon Jun 25, 2007 10:26 pm
Look a bit closer--I mentioned my problem for a reason. Most probably you're using a launcher, either loading off the card or over wifi. When that starts your program, you can't assume it resets everything.
Particularly, unused banks need to be set VRAM_*_LCD. Not much else comes to mind, so that would be the first thing to try...
(Btw, it'd be vastly more helpful, if you posted the important excerpts and cleaned up your formatting. People are liable to skip what they can't or don't have time to read...)
#132327 - yellowstar - Mon Jun 25, 2007 10:54 pm
I am using a DS-X.
I am using the Instant Boot
feature, and it dosen't matter
if I use it, or boot it normally,
it still won't work.
I tried mapping all the VRAM banks to LCD,
and clearing them, but that didn't work.
Last edited by yellowstar on Mon Oct 01, 2007 7:31 pm; edited 1 time in total
#132334 - Cydrak - Mon Jun 25, 2007 11:49 pm
Hunh. The vertical bars sound like 16bpp or maybe tilemap data, but you say you're overwriting it, so...
Code: |
void VCopy(u16* source, u16 *target, size_t s_offset, size_t t_offset, size_t size) |
s_offset, t_offset, size ... what units did you mean these to be? 8 bits? 16 bits? (Pointer arithmetic goes by the size of the type.)
Also, is there some significance to using dmaCopy vs. VCopy?
What format is the raw data? (e.g. given the VIDMO #define, did you switch away from 16bpp at some point?)
I'd zero (SUB_)BG3_CX and CY, the scroll for the bitmaps, while you're at it.
#132471 - yellowstar - Wed Jun 27, 2007 2:43 am
The VCopy function is supposed to be like memcpy,
except it is used to copy 16 bit data.
The raw data is paletted image data.
It is 8 bit format in the file.
I removed the VIDMO define,
as what I wanted to use it for
wouldn't work.
I have quit using VCopy.
I now using dmaCopy.(the new VCopy uses a buffer, in which dmaCopy is used for the copying.)
When I started using dmaCopy, the bars dissappeared!
I am now using a buffer.(see below)
I tried making a 256*256 buffer in VRAM.(doesen't matter were I put the buffer, VRAM or RAM, it still dosen't work.But I get
different results.)
The VCopy function, when called,
would clear that buffer by copying a transparent image unto it.
Then it would copy the source data onto that buffer.
Next it would copy the buffer to the target.(VRAM)
But I am still having problems.
I get different results when I put the buffer in VRAM and RAM.
These are still problems with the sub screen.
Here are the results for RAM:
256x256 image(size of my backgrounds):
It works.
The one I am trying to get to work is below this one.
none 256x256 image(256x256 is size of my backgrounds.)(actual size of image is 256x28.):
Only problems for this one.
1.
The whole screen is black, except part of the top of it.
(Sub Palette index 0 is the black transparent color which is
used to clear the buffer. There is also another non-transparent black color
in the palette. Changing either of them dosen't do anything,
so the black color being displayed isn't either of those colors
in the palette.).
2.
The part of the screen that isn't black is flickering.
It is flickering fast.
3.
The part of the screen that isn't black is the background color.(red)
This part of the screen is basicly the top bar, which got moved up to the top of the screen.(the bottom bar is gone.)
The bar is half of its original size.
I'm not sure if it has lines through it,
as it is flickering to fast to tell.
It appears it dosen't have lines through it,
but it's flickering to fast to be sure.
Here are the results for VRAM:
256x256 image(size of my backgrounds):
Problems:
1.
It is also displaying the top bar again,
except its height is half of what was before.
2.
The images, and the bar is flickering.
3.
It is displaying 2 copies of my image,
which it is not supposed to do.
For the first image,
it is displaying half of it.
The top of it is at the bottom of the bar.
This image is not supposed to be displayed.
4.
Both of the images are tinted the background color.(red)
It appears that there are horizontal lines, colored the background color,(red)
on both of the images.
none 256x256 image(256x256 is size of my backgrounds.)(actual size of image is 256x28.):
The results and problems for this one is similar to the
one similar to this in the RAM section.
Only problems for this one.
1.
The whole screen is black, except part of the top of it.
(Sub Palette index 0 is the black transparent color which is
used to clear the buffer. There is also another non-transparent black color
in the palette. Changing either of them dosen't do anything,
so the black color being displayed isn't either of those colors
in the palette.).
2.
The part of the screen that isn't black is flickering. This one is flickering
alot slower than the other.
3.
The part of the screen that isn't black is the background color.(red)
This part of the screen is basicly the top bar, which got moved up to the top of the screen.(the bottom bar is gone.)
The bar is half of its original size.
It has horizontal lines through it, colored the background color(red).
The new source is in the my second post.
Last edited by yellowstar on Mon Oct 01, 2007 7:31 pm; edited 1 time in total
#135379 - yellowstar - Sun Jul 22, 2007 11:11 pm
Does anybody know of any examples,
or any open source applications,
that uses backgrounds,
for both screens,
and double buffers?
That should help a lot,
but looking at an app's source
might not help much.
Last edited by yellowstar on Mon Oct 01, 2007 7:32 pm; edited 1 time in total
#135727 - yellowstar - Wed Jul 25, 2007 8:38 pm
I am now using a differen't method.
But it still won't work right.
Now,
my VCopy function does the following:
1. Loops through the VRAM data that is before
the target position, and reads the value at
the current position, then it writes
that value to the current position.
2. Copies the data.
3. Here, it does the same thing
as in the first step,
except in this step it loops through
the data after the data that is copied.
My vcopy function handles copying
in the data.(Second step.)
Here's my problems:
(DMA is vcopy with the dmaCopy version, and 16 bit
is vcopy with the 16 bit copying version.)
Top:(index 0)
DMA:
There appears to be red horizontal lines(background color)
through the image.
It also appears to be flickering.
The image is also colored red.(the background color)
Only the color which is used the most in that image
is colored red.
16 bit:
Same as DMA,
except this one has a dark red bar below it,
like the bars near the top of this topic,
except this one's height is the same as the
image's height.
Middle:(Not index 0 index, 32 pixels down.)
DMA:
Fine,
no problems.
16 bit:
Same as DMA,
except there is a black
bar the the same width
and height as the image
below where the image is displayed.
On that bar,
there is a few non-black pixels on it.
Bottom:
DMA:
Same as the top for DMA,
except it is on the bottom,
and it is 28 pixels higher than
it is supposed it be.(the hight of the image.)
16 bit:
Same as the top for 16 bit,
except it is in the same spot as DMA.
Source code
is in my above post,
which contains the source code.
Last edited by yellowstar on Mon Oct 01, 2007 7:33 pm; edited 1 time in total
#135874 - yellowstar - Thu Jul 26, 2007 10:18 pm
Does anybody know of any open source librarys,
which handles paletted backgrounds?
I tried commenting out the
code for the first and last steps in VCopy,
but that didn't do anything.
I tried using a modified version of bytecpy,
but that didn't work:
Code: |
__attribute__((section (".ewram"),long_call))
void scpy(void* in_dst, const void *in_src, unsigned int length)
{
u16 *src = (u16 *)in_src;
u16 *dst = (u16 *)in_dst;
for(; length > 0; length--)
*dst++ = *src++;
}
|
Last edited by yellowstar on Mon Oct 01, 2007 7:33 pm; edited 1 time in total
#138579 - yellowstar - Sat Aug 25, 2007 10:50 pm
I have finally found out what was wrong with it!
I must have been not mapping enough VRAM for the buffers!
I didn't test it, though.
Instead, I copyed the source, and started an new project/program.
I removed the back buffering.
I also have it working on both screens.
This is for screenshots,
since the display capture can only capture
on the main screen.
Now that I can take screenshots,
I am going to post links(in this post)
to images showing each of the problems,
except the one on the sub screen,
since I don't have the code for taking screenshots
of the sub screen.
I also have made it easy testing.
I have added code so that it easy to
test and take screenshots of problems.
Before which copying function used and ect,(dma or scpy)
was hard coded.
Now all I have to do to change that stuff is,
press the assocated button.
I tried implementing a scanline-by-scanline copying method.
It would copy each scanline in the image one-by-one,
to the target. Each scanline copyed into the target
is supposed to be below the one before it.
But it won't work.
The SCpy function won't work.
Here's my problems:
When I try to display the image on the bottom part of the screen,
it won't display the image anywhere.
When I try to use the SCpy copy function,
I get a black bar below the image,
with some stuff on it.
Pic Top middle
When I try to use the scanline-by-scanline copying method,
I get a black bar with stuff below it.(seems differen't than above)
Also, there is red,(background color)
horizontal lines through both the image and bar.
They are vertically a pixel apart.
Pic Top Middle
When I try to use both the SCpy copying function,
and the scanline-by-scanline copying function,
I get the same result as for when I only use
the SCpy copying function.
For the sub screen,
I get the same results as the main screen,(above)
except there's this additional problem:
When the image is in the middle,
there is a copy of it about 32 pixels down.
UPDATE Now the normal colored image is gone,
and this wrong image is still there.UPDATE
The copy's main colors are red.(background color)
(By main colors I mean the colors that are used the most.)
Since this is on the sub screen,
I can't take a screenshot of it,(this is because I don't have
the code for this)
but it probably isn't needed.
Source code is in the above post with the source code.
Here's the important pieces of code:
VRAM and backgrounds init
Code: |
//At top of main source code file
u16 *video_buffer_main = (u16*)BG_BMP_RAM(0);
u16 *video_buffer_sub = (u16*)BG_BMP_RAM_SUB(0);
..
vramSetBankA(VRAM_A_MAIN_BG);
//Init main bg
BG3_CR = BG_BMP8_256x256 | BG_BMP_BASE(0) | BG_PRIORITY(3);
//No rotation and no scale
BG3_XDX = 1 << 8;
BG3_XDY = 0;
BG3_YDX = 0;
BG3_YDY = 1 << 8;
BG3_CX = 0;
BG3_CY = 0;
vramSetBankB(VRAM_B_MAIN_BG);
vramSetBankD(VRAM_D_LCD);//For screenshots
//Init sub
SUB_BG3_CR = BG_BMP8_256x256 | BG_BMP_BASE(0) | BG_PRIORITY(3);
//No rotation and no scale
SUB_BG3_XDX = 1 << 8;
SUB_BG3_XDY = 0;
SUB_BG3_YDX = 0;
SUB_BG3_YDY = 1 << 8;
SUB_BG3_CX = 0;
SUB_BG3_CY = 0;
BG_PALETTE_SUB[8] = RGB15(0,0,31) & (~BIT(15));
BG_PALETTE_SUB[0] = RGB15(0,0,0) | BIT(15);
BG_PALETTE[0] = RGB15(0,0,0) | BIT(15);
//memcpy(BG_PALETTE,PALETTE_RAW,PALETTE_RAW_size);
memcpy(BG_PALETTE_SUB,PALETTE_RAW,PALETTE_RAW_size);
memcpy(BG_PALETTE,PALETTE_RAW,PALETTE_RAW_size);
dmaCopy(BAK_RAW,video_buffer_main,256*256);
//memcpy(video_buffer_sub_buff,bak_raw,256*256);
dmaCopy(BAK_RAW,video_buffer_sub,256*256);
|
VCopy and ect:
Code: |
__attribute__((section (".ewram"),long_call))
void scpy(void* in_dst, const void *in_src, unsigned int length)
{
u16 *src = (u16 *)in_src;
u16 *dst = (u16 *)in_dst;
for(; length > 0; length--)
*dst++ = *src++;
}
void vcopy(u16* source, u16 *target, size_t s_offset, size_t t_offset, size_t size)
{
//Copys source starting at s_offset to target starting at t_offset with
//size size.
//This Copy works with VRAM, OAM, and backgrounds.
if(copy_type == CT_SCPY)
scpy(&target[(int)t_offset],&source[(int)s_offset],(size_t)size);
if(copy_type == CT_DMA)
dmaCopy(&source[(int)s_offset],&target[(int)t_offset],size);
}
void VCopy(u16* source, u16 *target, size_t s_offset, size_t t_offset, size_t size,size_t target_width, size_t source_width)
{
if(beforeVRAM)
{
if(t_offset!=0)
{
for(int i=0; i < (int)t_offset; i++)
target[i] = target[i];
}
}
if(linear)
{
for(size_t i=0; i < size; i+= source_width)
vcopy(source,target,s_offset + i,t_offset + i,source_width);
}
if(!linear)
vcopy(source,target,s_offset,t_offset,size);
if(afterVRAM)
{
if((t_offset + size)!=256)
{
for(int i=(int)(t_offset+size); i < (int)256*256; i++)
target[i] = target[i];
}
}
}
|
Draw function:
Code: |
void Draw()
{
dmaCopy(BAK_RAW,video_buffer_sub,256*256);
dmaCopy(BAK_RAW,video_buffer_main,256*256);
if(!screen)
{
if(section == S_TOP)
VCopy((u16*)TASKBAR3_RAW,video_buffer_main,0,0,(size_t)TASKBAR3_RAW_size,256,256);
if(section == S_MIDDLE)
VCopy((u16*)TASKBAR3_RAW,video_buffer_main,0,256*32,(size_t)TASKBAR3_RAW_size,256,256);
if(section == S_BOTTOM)
VCopy((u16*)TASKBAR3_RAW,video_buffer_main,0,256*(192 - 28),(size_t)TASKBAR3_RAW_size,256,256);
}
else
{
if(section == S_TOP)
VCopy((u16*)TASKBAR3_RAW,video_buffer_sub,0,0,(size_t)TASKBAR3_RAW_size,256,256);
if(section == S_MIDDLE)
VCopy((u16*)TASKBAR3_RAW,video_buffer_sub,0,256*32,(size_t)TASKBAR3_RAW_size,256,256);
if(section == S_BOTTOM)
VCopy((u16*)TASKBAR3_RAW,video_buffer_sub,0,256*(192 - 28),(size_t)TASKBAR3_RAW_size,256,256);
}
}
|
Last edited by yellowstar on Mon Oct 01, 2007 7:34 pm; edited 2 times in total
#138790 - yellowstar - Wed Aug 29, 2007 3:13 am
I have fixed the source code.
Before the video buffer for the sub screen was wrong(the parameter was 1 instead of 0, fixed),
and the sub background base was 1 instead of 0.(fixed)
Now, on the sub screen, at the bottom,
it does the same thing, except the normal colored image is gone.
If nobody noticed,
I have posted links to screenshots of the main screen.
I don't have sub screen screenshots, because,
I don't have the code for this.(Would somebody post
a link or something with the code for this?)
Would somebody please reply in this topic?
I can't make much homebrew until this program works. :(
Last edited by yellowstar on Mon Oct 01, 2007 7:34 pm; edited 1 time in total
#139336 - yellowstar - Tue Sep 04, 2007 9:45 pm
I got the sub screen to behave just like the main screen.
So, now that extra problem is fixed.
I fixed it by not mapping the extra VRAM banks
I was mapping.
Would somebody please help me?
I can't make hardly any homebrew,
until this is solved.
Last edited by yellowstar on Mon Oct 01, 2007 7:35 pm; edited 1 time in total
#139354 - HyperHacker - Wed Sep 05, 2007 1:02 am
That garbage below your image looks like you're copying twice as much data into VRAM as you should be. Make sure you're not passing number of bytes to something that expects number of words.
The scanline copying method looks like it's advancing both the source and destination by 2 lines instead of one, skipping every second line. Again, this might be because you've used number of bytes where you should be using number of words.
_________________
I'm a PSP hacker now, but I still <3 DS.
#139419 - yellowstar - Thu Sep 06, 2007 12:50 am
HyperHacker wrote: |
That garbage below your image looks like you're copying twice as much data into VRAM as you should be. Make sure you're not passing number of bytes to something that expects number of words.
The scanline copying method looks like it's advancing both the source and destination by 2 lines instead of one, skipping every second line. Again, this might be because you've used number of bytes where you should be using number of words. |
When I tried changing SCpy to following,
it still isn't correct. Click the link for a screenshot.
Code: |
__attribute__((section (".ewram"),long_call))
void scpy(void* in_dst, const void *in_src, unsigned int length)
{
u8 *src = (u8 *)in_src;
u16 *dst = (u16 *)in_dst;
for(; length > 0; length--)
*dst++ = (u16)*src++;//It dosen't matter if I typecast
//this or not, it still won't fix it.
}
|
Link
My image is an paletted image.
So, when copying the image,(only the source,
target is always 16 bit)
with 16 bit,
it copys twice as much data than
it should be.
But, when I use the above,
it dosen't.
So, after passing the end of the image data,
it is using data that it shouldn't be,
resulting in garbage.
Last edited by yellowstar on Mon Oct 01, 2007 7:36 pm; edited 1 time in total
#139423 - nce - Thu Sep 06, 2007 1:13 am
Hi,
I haven't read all the thread but for this problem I think that you can do that easily with this
Code: |
__attribute__((section (".ewram"),long_call))
void scpy(void* in_dst, const void *in_src, unsigned int length)
{
u16 *src = (u16 *)in_src;
u16 *dst = (u16 *)in_dst;
length >>= 1;
for(; length > 0; length--)
*dst++ = *src++;
} |
of course working if your image has a width multiple of 2. otherwise, you'll have to do something like
Code: |
u8* src = (u8 *)in_src;
u16 *dst = (u16 *)in_dst;
u8* src1 = src+1;
for...
*dst++ =( (*src1 )<<8) | (*src);
src+=2 ; src1+=2;
//and the last one
*dst = ((*src )<<8) | (*dst & 0xff );
|
_________________
-jerome-
#139426 - yellowstar - Thu Sep 06, 2007 2:41 am
nce wrote: |
Hi,
I haven't read all the thread but for this problem I think that you can do that easily with this
Code: | __attribute__((section (".ewram"),long_call))
void scpy(void* in_dst, const void *in_src, unsigned int length)
{
u16 *src = (u16 *)in_src;
u16 *dst = (u16 *)in_dst;
length >>= 1;
for(; length > 0; length--)
*dst++ = *src++;
} |
of course working if your image has a width multiple of 2. |
My image is like that.
Thank's, it worked!
Last edited by yellowstar on Mon Oct 01, 2007 7:24 pm; edited 1 time in total
#141926 - yellowstar - Mon Oct 01, 2007 7:19 pm
I have found out something.
Whenever I try to make it draw
the image 1 pixel below the middle position,
it won't draw it.
#141940 - nce - Tue Oct 02, 2007 12:44 am
If drawing on frame 0 2 4 s working but 1 3 5 not it's probably a probleme of accessing memory...
If destination buffer is a 8bit buffer you can map it as a 16bit only on pair bit...
Code: |
8bit : 0 1 2 3 4 5 6 7 8
16bit : 0 - 1 - 2 - 3 - 4
|
So you can say something like (u16) 8bit0 or (u16) 8bit2
but it's not possible to tell (u16) 8bit 1 because the 8bit1 is not align on 16bit.....
hope it help
EDIT :: Sorry ; Why do I wrote "frame" here ?? I was probably sleeping ...
I mean : working at pixel position 0 2 4 ... and not 1 2 3 ....
_________________
-jerome-
Last edited by nce on Wed Oct 03, 2007 4:23 am; edited 1 time in total
#142002 - yellowstar - Tue Oct 02, 2007 11:31 pm
I don't think it's an frame problem.
There isn't any flickering, or anything like that.
I noticed another thing.
When I tried to make the image go down more,
eventually the image was displayed on the bottom screen.
(It's supposed to stay on the top screen.)
#142010 - yellowstar - Wed Oct 03, 2007 2:53 am
I have uploaded archives of the source and binary
of this program.
Source Binary
There is debugging functions in this.
See the controls.txt file for the keys.
Here's some controls which aren't in the archives:
Press R and L to move the image(when in the last section)
down and up, by one pixel.(dosen't work)
#142016 - nce - Wed Oct 03, 2007 4:41 am
Sorry for the mistake about the "frame" word I've put there, while it's not at all what I wanted to say ....
It's a probably a problem of memory mapping ...
I read fastly your code ( I'm at work no much time ).
The only guess I have here is this :
Your image background is define as a 8bit buffer, and when copying your data you copy them as 16bit.... that means that if you try ( not sure you do ) to acces backgroundbuffer[1] and try to map it on u16, it's impossible. because backgroundbuffer[1] is not align to a 16bit format, while backgroundbuffer[0] and backgroundbuffer[2] (...) are.
I'm more clear here than my first time?
_________________
-jerome-
#142047 - yellowstar - Wed Oct 03, 2007 8:42 pm
Thanks for the help.
I thought only 16 bit writes
are allowed for VRAM.
Also,
the 8-bit setting for the backgrounds are
for palettes.
I tried changing scpy to the following,
but that didn't do anything.
Code: |
__attribute__((section (".ewram"),long_call))
void scpy(void* in_dst, const void *in_src, unsigned int length)
{
u8 *src = (u8*)in_src;
u16 *dst = (u16 *)in_dst;
length >>= 1;
for(; length > 0; length--)
*dst++ = (u16)*src++;
}
|
#142060 - nce - Thu Oct 04, 2007 12:46 am
I don't remember if I have ever do any write with 8 bit map on vram, but I remember that I wrote some 'sprite' system on top of an extended background and I probably did that this way....
what you wrote is wrong because you are trying to copy 16bit into 8bit with you code, meaning that you'll lose half of your data. what you can write is this ( but again maybe it will not work )
Code: |
__attribute__((section (".ewram"),long_call))
void scpy(void* in_dst, const void *in_src, unsigned int length)
{
u8 *src = (u8*)in_src;
u8 *dst = (u8 *)in_dst;
for(; length > 0; length--)
*dst++ = *src++;
} |
twice slower of course...
but be sure that you never try to align on a 16bit before this call... I saw in your code that this function is called after some offset on memory and stuff like that... so the problem could come from this.
If I find a little time, I'll look if I still have my own code somewhere on a backup, and if it's readable I'll post it here, so you can have a look....
_________________
-jerome-
#142107 - nce - Thu Oct 04, 2007 2:54 pm
I found what I've written when I was doing some test...
As you said, I'm mapping the data on a 16 bit, and I can set a sprite only on even position for x
( as I'm doing something like ( buffer + ( x >> 1 ) ) , that's means that I 'll write the sprite only on position 0 2 4 .... )
any way if you want to have a look at my code, feel free :
( I usualy comment everything, knowing that if I want to come back on that 1 year later it's much easier to reenter in )
source
( not sure this can help you )
if you realy need to be able to copy your data at position 1 , you'll be force to do something like reading the 16 bit buffer at position 0 changing the 8 bit you want and write back the 16 bit
ps : this code will not compile as this, while some function are link to my thread system ...
_________________
-jerome-
#142136 - yellowstar - Thu Oct 04, 2007 11:16 pm
I changed the code so it uses 8-bit now.
So, all the copying and ect. uses 8-bit now.
But, now in scpy mode,
it won't display anything.
When scpy uses 16-bit,
it displays the image,
but, it is in the wrong position.
For the middle position,(both modes, DMA and SCPY)
it is displaying the image
so its top is near the top position
image's bottom.
EDIT: I have updated the downloads.
#145403 - yellowstar - Wed Nov 14, 2007 10:55 pm
Anyone?
I tried changing (typecast)
the target to 16-bit, and
source to 8-bit.(image is 8-bit, in file)
But, that won't work either.
Code: |
__attribute__((section (".ewram"),long_call))
void scpy(void* in_dst, const void *in_src, unsigned int length)
{
u8 *src = (u8*)in_src;
u16 *dst = (u16 *)in_dst;
length >>= 1;
for(; length > 0; length--)
*dst++ = (u16)*src++;
}
|
Any other examples and such?
What is the correct way to
do this, with the SCpy
and DMA methods?
#145467 - yellowstar - Fri Nov 16, 2007 1:56 am
Anybody?
I got it working again.(SCpy)
(I never knew before that every 16-bit value
for 8-bit BG BPP mode has values for 2 pixels.)(In VRAM,
for BGs.)
As I said before,
does anybody know
of any examples on this?
Code: |
__attribute__((section (".ewram"),long_call))
void scpy(void* in_dst, const void *in_src, unsigned int length)
{
u8 *src = (u8*)in_src;
u16 *dst = (u16 *)in_dst;
u16 temp=0;
u8 pix1;
u8 pix2;
length >>= 1;
for(; length > 0; length--)
{
pix1=*src++;
pix2=*src++;
temp= pix1 | (pix2<<8);
*dst++ = temp;
}
}
|
#145469 - Lick - Fri Nov 16, 2007 2:28 am
View topic
8-bit bmp background!
_________________
http://licklick.wordpress.com
#145470 - yellowstar - Fri Nov 16, 2007 2:41 am
That's the wrong URL.(it goes to the DS dev forum)
Don't you mean this topic?(The 512x512 8-bit BG topic)
That's where I found the
correct way to do my scpy method.(I tried
something similar to it,(before I saw the example posted there)
But it didn't work right.)
#149412 - yellowstar - Sat Jan 19, 2008 9:35 pm
I got this to work with this image. But, when I try a 32x32 image, otherwise...
The original downloads have been removed. Here's the new download, which
contains both the source and binaries.
The screen shot is included in the download. However, here's a mirror of that screen shot. Also, here's an mirror of the original image. The original image is in Data2/taskbar3.bmp(Note that this isn't a task bar anymore for this image)
See the data directory for the palette and the RAW directories.
The displayed image is an ~4xSCREEN_WIDTH image.
It doesn't matter if SCpy or DMA is used for copying, or if the scanline
copying is used. It looks like it is doing the normal, non-scanline copying
method. It seems to copy the first scanline onto the wanted scanline. But,
it now copies the next line unto the same scanline. It keeps targeting the same scanline until it reaches the edge of the screen, then
it goes to the next scanline.
About the original issue:
Indeed, it was an alignment problem. The image was u8*, while the bg
ram was u16*. Once I switched the bg to u8* everywhere but SCpy,
it worked. The image was disappearing because it was being put someplace in the bg VRAM, which could have been seen if the bg was position in the right place. The bg ram being u16* caused that.
EDIT: I solved this problem. But, the image is distorted whenever the image width is not a multiple of 2. I'll post about it after I try nce's code.
#149635 - yellowstar - Wed Jan 23, 2008 3:12 am
I've solved the previous problem. Now, I'm having another problem.
We're getting really close to 100% solving this for good!
The image is fine when the width is a multiple of 2. But, not so when
otherwise. The results for SCPY and DMA are significantly different.
(These links are the new screen shots. The screen shot with the download has been removed. The download has been updated)
(The binaries have been removed from the download. That only has the source now. You must compile it to get the binaries.)
Look at the screen shots for the explanation.
SCPY uses nce's code.
Code: |
//Is I an multiple of 2? Used for scpy.
bool IsM2(int I)
{
int i=2;
if(I<i)return 0;//It's not an multiple of 2 if it's smaller than 2!
while(i<I)
{
i+=2;
if(i==I)return 1;
}
return 0;
}
__attribute__((section (".ewram"),long_call))
void scpy(void* in_dst, const void *in_src, unsigned int length)
{
if(0)//Only use the second block of code
{
//Multiple of 2 code
}
else
{
//Non-multiple of 2 code
//This is nce's code
u8* src = (u8 *)in_src;
u16 *dst = (u16 *)in_dst;
u8* src1 = src+1;
length >>= 1;
for(; length > 1; length--)
{
*dst++ =( (*src1 )<<8) | (*src);
src+=2 ; src1+=2;
}
//and the last one
*dst = ((*src )<<8) | (*dst & 0xff );
}
}
void vcopy(u8* source, u8 *target, size_t s_offset, size_t t_offset, size_t size)
{
//Copys source starting at s_offset to target starting at t_offset with
//size size.
//This Copy works with VRAM, OAM, and backgrounds.
if(copy_type == CT_SCPY)
scpy(&target[(int)t_offset],&source[(int)s_offset],(size_t)size);
if(copy_type == CT_DMA)
dmaCopy(&source[(int)s_offset],&target[(int)t_offset],size);
}
void VCopy(u8* source, u16 *target, size_t s_offset, size_t t_offset, size_t size,size_t target_width, size_t source_width)
{
if(linear)
{
size_t I=0;
for(size_t i=0; i < size; i+= source_width)
{
vcopy((u8*)source,(u8*)target,s_offset + i,t_offset + I,source_width);
I+=target_width;
}
}
if(!linear)
vcopy((u8*)source,(u8*)target,s_offset,t_offset,size);
}
|
Last edited by yellowstar on Thu Jan 24, 2008 2:23 am; edited 1 time in total
#149644 - nce - Wed Jan 23, 2008 8:14 am
Hi yellowstar,
When I gave you that small code back then it was more a way to think, I've never test it so I can't be sure it's correct :(
at first I was thinking about a casting probleme u16 = u8 A<<8 | u8 B ( there is a chance that it will do A<<8 = 0 (offset the 8 in a 8bits data). and 0 | B = B ) But if it was like that you'll have one pixel correct one pixel unchanged...
the distortion part looks more like a bug I had myself once: I was wrongly computing the offset for the next scanline. you may think of something like your image is 5pixels width but you wrote 6pixels
the fact that it looks like repeating twice the picture side to side is harder to understand. maybe you set your length twice the size of the real image ? it looks like copying the first line then next to that copying the seconde line and then going to the next scanline ( don't forget that you are not incrementing by src++ but by src+=2 )
but it should give you garbage after the middle of the picture....
I hope you'll find the problem :)
_________________
-jerome-
#149667 - elhobbs - Wed Jan 23, 2008 5:25 pm
in scpy in nce's code you forgot to adjust length from u8 to u16. as evidence the image is twice as wide as it should be and the right image is shifted up one pixel - so you are drawing the next scan line next to the current scan line. as a note the current code does not properly handle unaligned destinations or odd width sizes properly.
I am guessing that this is clipped from a larger project ( so I am seeing it out of context), but it seams rather complex for such a simple operation.
#149694 - yellowstar - Thu Jan 24, 2008 2:52 am
I have added the length code. The source has been updated.(In the previous post)
The SCPY result is almost the same as DMA, except for a red/background color vertical line through it.
The screenshots have been updated: SCPY DMA
The download has been updated
@elhobbs:
??? Switching the length var's type wouldn't change anything... It's a unsigned int/size_t.
elhobb wrote: |
but it seams rather complex for such a simple operation.
|
That's a fast way to do a division by 2 operation... Most compilers convert
such divisions to this code.
#149706 - nce - Thu Jan 24, 2008 5:33 am
yellowstar wrote: |
elhobb wrote: |
but it seams rather complex for such a simple operation.
|
That's a fast way to do a division by 2 operation... Most compilers convert
such divisions to this code. |
elhobb was speaking about the code it self not the >>1 :)
not sure both screenshot have been updated :) scpy and dma looks quite different to me :)
the red line feel like we are copying stuff in the wrong order here (like writting 2 1 4 3 6 5) try doing this then :
Code: |
for(; length > 1; length--)
{
*dst++ =( (*src )<<8) | (*src1);
src+=2 ; src1+=2;
}
//and the last one
*dst = (*src ) | ((*dst & 0xff )<<8);
// OR
*dst = (*src ) | (*dst & 0xff00 );
|
I've inverted src and src1
I told you I've never tested it :)
_________________
-jerome-
#149722 - elhobbs - Thu Jan 24, 2008 2:04 pm
the vertical line is a result of improperly handling non-even destination and width horizontal values. the code should like somehing like his. obviously this is not complete code but the comments should make it clear what needs to happen.
Code: |
u8 *src8;//source 8 bit pixels
u8 *dest8;//unaligned destination 8 bit
u16 *dest16//aligned destination 16 bit
u16 pixel16;//temporary for holding two 8 bit pixels
dest16 = dest8;
if (dest8 & 1)
{
dest16 = dest8 -1;
//handle single pixel write
//read both pixels from the destination
pixel16 = *dest16
//we want to keep the first byte
pixel16 &= 0xff;
//and replace the second byte
pixel16 |= ((*src8++)<<8);
//and write both values back
*dest16++ = pixel16;
}
length16 = length>>1;
//now the destination will be aligned to 16bit value
//so handle all of the two pixel writes we can
while(length16)
{
pixel16= *src8++;
pixel16 |= ((*src8++)<<8);
*dest16++ = pixel16;
length16--;
}
//if the length is odd then write the last byte
if(length&1)
{
//handle single pixel write
//read both pixels
pixel16 = *dest16
//we want to keep the second byte
pixel16 &= 0xff00;
//and replace the first byte
pixel16 |= *src8++;
//and write both values back
*dest16++ = pixel16;
}
|
#149764 - yellowstar - Fri Jan 25, 2008 1:26 am
The SCPY image is the same as DMA when using nce's original code.(Multiple of 2 code)(Even though the image is not a power of 2)
But, when using the non-power of 2 code, this happens.
(The new code)
This happens with elhobbs code.(It's basicly the same code as he posted)
As you can see, some of the right side of the image is chopped off, but still with the same distortion.
When decreasing the length by 2, the image resembles the wanted image better, but it's still wrong.
#149774 - yellowstar - Fri Jan 25, 2008 4:22 am
Here's some debugging data via FAT:(DMA)
Code: |
Scanline 1 T 0x6000000 S 0x206bb6c Length 30
Scanline 2 T 0x6000100 S 0x206bb8a Length 30
Scanline 3 T 0x6000200 S 0x206bba8 Length 30
Scanline 4 T 0x6000300 S 0x206bbc6 Length 30
Scanline 5 T 0x6000400 S 0x206bbe4 Length 30
Scanline 6 T 0x6000500 S 0x206bc02 Length 30
Scanline 7 T 0x6000600 S 0x206bc20 Length 30
Scanline 8 T 0x6000700 S 0x206bc3e Length 30
Scanline 9 T 0x6000800 S 0x206bc5c Length 30
Scanline 10 T 0x6000900 S 0x206bc7a Length 30
Scanline 11 T 0x6000a00 S 0x206bc98 Length 30
Scanline 12 T 0x6000b00 S 0x206bcb6 Length 30
Scanline 13 T 0x6000c00 S 0x206bcd4 Length 30
Scanline 14 T 0x6000d00 S 0x206bcf2 Length 30
Scanline 15 T 0x6000e00 S 0x206bd10 Length 30
Scanline 16 T 0x6000f00 S 0x206bd2e Length 30
Scanline 17 T 0x6001000 S 0x206bd4c Length 30
Scanline 18 T 0x6001100 S 0x206bd6a Length 30
Scanline 19 T 0x6001200 S 0x206bd88 Length 30
Scanline 20 T 0x6001300 S 0x206bda6 Length 30
Scanline 21 T 0x6001400 S 0x206bdc4 Length 30
Scanline 22 T 0x6001500 S 0x206bde2 Length 30
Scanline 23 T 0x6001600 S 0x206be00 Length 30
Scanline 24 T 0x6001700 S 0x206be1e Length 30
Scanline 25 T 0x6001800 S 0x206be3c Length 30
Scanline 26 T 0x6001900 S 0x206be5a Length 30
Scanline 27 T 0x6001a00 S 0x206be78 Length 30
Scanline 28 T 0x6001b00 S 0x206be96 Length 30
Scanline 29 T 0x6001c00 S 0x206beb4 Length 30
Scanline 30 T 0x6001d00 S 0x206bed2 Length 30
|
The target is fine. So is the source...
#149775 - yellowstar - Fri Jan 25, 2008 4:39 am
I'm now using a new image. Here's the original.
Here's the new DMA screenshot.
EDIT:
One thing I noticed is that the top part is 15 pixels, instead of the wanted 16.
I wonder where these black lines are coming from... This image doesn't even have black...(Neither does the palette)
#150317 - yellowstar - Fri Feb 01, 2008 9:21 pm
Anybody?
I'm going to PM several other members about this problem.
#150328 - tepples - Sat Feb 02, 2008 3:53 am
I think .bmp rounds the width of each scanline up to some even number of bytes, and that's where the black line is coming from.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#150353 - yellowstar - Sat Feb 02, 2008 8:24 pm
tepples wrote: |
I think .bmp rounds the width of each scanline up to some even number of bytes, and that's where the black line is coming from. |
That's the format I'm using. Looks like I need to use another format...
By the way, you are on the list of people I was going to PM, tepples.(But I'm still going to PM if the replies to this topic stops.)
#150360 - yellowstar - Sun Feb 03, 2008 2:21 am
ALMOST done!
What you suggested tepples worked! Not only did it remove the black lines, it also fixed the distortion problem! Now, the image is drawn almost perfectly!(But only one stationary)(But I had to use the original SCPY code.(nce's original code))
(I switched from bmp to pcx. I wanted to use png or tga, but gfx2gba doesn't work with those formats. And I'm not using grit. I tried that, and I did NOT like it. gfx2gba readme says it supports tga, but it does not. I just get the unsupported format error with those formats.)
There's a minor problem with the background color being yellow, instead of the red I want... Hopefully that will be an easy-to-fix problem...
When I constantly move the image in any direction, some parts of the image
are shifted.(SCPY/DMA copy mode doesn't matter)
Moving down = Down-right section of image is shifted down by about 2 pixels, with some white pixels drawn to the left of it.
Moving up = Down-right section of image is shifted down by about 1 pixel, with some white pixels drawn to the left of it.
Moving left = Top-left section of image is shifted left by about 2 pixels, without any white pixels.
Moving right = N/A(The top-right section's color is the same as the background, making it hard to see if this movement is affected.)
Here's a screenshot. This one doesn't contain any useful debugging info however. I am going to add screenshots of the all of the above movement graphic problems, after I I fix that background color problem. I had that problem before... I had to do some hackery to fix it...
#150708 - yellowstar - Mon Feb 11, 2008 2:12 am
Anybody?
I can't show any screenshots... This problem only happens when the image is moving, and it can't move when taking a screenshot... I can't use any Emu, as this problem doesn't appear in them. This problem is in a old backup of this program, also.
#151495 - yellowstar - Wed Feb 27, 2008 9:55 pm
Anybody?
#151507 - tepples - Thu Feb 28, 2008 4:34 am
Camcorder?
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#151586 - yellowstar - Sat Mar 01, 2008 12:04 am
Didn't think about that. There's a new Vista laptop here,(Not mine :( )
and it has a really good Web Cam built-in.(Capture video with it, if I'm get permission...)(And there's a new Vista desktop here, which replaced my old Compaq Win98. No Web Cam in that one though. No more anything about Win98 from me, here, anymore.)
And I'd have to wait on slow Dial-Up to upload...
#151680 - yellowstar - Mon Mar 03, 2008 5:20 am
That camera didn't work. I couldn't see anything wrong when looking through it. I'll try the Web Cam soon.
I'm trying to capture screenshots which work with moving images, but it won't work. Even with a still image. I get yellow on the top half of the shot, black on the bottom.
Code: |
u8 capture_buffer[256];
u16 capture_buffer2[256];
bool taking_screenshot=0;
u16 *screenshot_buffer = NULL;
int screenshot_pos=0;
void TakeScreenshot()
{
if(screenshot_buffer==NULL)
screenshot_buffer = (u16*)malloc(256*192*2);
screenshot_pos=0;
swiWaitForVBlank();
taking_screenshot=1;//Start capturing. The following function takes care of the rest.
}
void HBlank_interrupt()
{
if(hblank_wait){hblank_wait=0;return;}
if(taking_screenshot)
{
dmaCopy(&video_buffer_main[screenshot_pos],capture_buffer,256);
for(int i=0; i<256; i++)capture_buffer2[i]=(u16)capture_buffer[i];
dmaCopy(capture_buffer2,&(((u8*)screenshot_buffer)[screenshot_pos]),256);
screenshot_pos+=256;
if(screenshot_pos>=192*256)taking_screenshot=0;
if(!taking_screenshot)
{
//dmaCopy(VRAM_D,screenshot_buffer,256*192*2);
FILE *f = NULL;
char str[256];
char str2[256];
char str3[256];
strcpy(str,"");
strcpy(str2,"");
strcpy(str3,"");
sprintf(str2,"%s",str3);//copy_type?"SCPY":"DMA"
sprintf(str,"/%sscreenshot.bin",str2);
f = fopen(str,"wb");
fwrite(screenshot_buffer,2,256*192,f);
fclose(f);
sprintf(str,"/%sscreenshot.bmp",str2);
screenshotbmp(str, screenshot_buffer);
//if(screenshot_buffer)
//free(screenshot_buffer);
//taking_screenshot=0;
}
}
}
|
#151995 - yellowstar - Fri Mar 07, 2008 11:40 pm
Tried both a camera and that Web Cam, but both failed. I heard somebody here has access to the Nitro screenshot kit.(Not sure if it can take videos)
However, my graphics converter crashed,(gfx2gba)
and I was forced to switch to something else.(GRIT)
However, it doesn't work as I want. It doesn't merge the palettes. So,
I can't use it right now. I'm working on a way to get around this.
BUT!
Even worse!
My DS-X, the only homebrew device that I have, BROKE. It fell on the floor, while it was in my DS.(USB cord connected and everything)
It's about the same age as my backgrounds problem, 8-months. My DS-X is bent. The lights on it doesn't stay on when connected to a computer. Those lights, in that case, means the DS-X is connected to the computer. It seems it still works after the light come on, then goes back off. But, my DS doesn't recognize it anymore. However, I managed to backup everything on it.
This DS-X cost me $130. Fortunately, the retailer is supposed to handle the warranty. When they don't, the DS-X team will take care of it. I haven't investigated this yet.(About whether they we take care of warranty)
#152012 - HyperHacker - Sat Mar 08, 2008 4:50 am
The warranty covers you dropping it and breaking it? That's one heck of a warranty.
_________________
I'm a PSP hacker now, but I still <3 DS.
#152013 - yellowstar - Sat Mar 08, 2008 5:10 am
HyperHacker wrote: |
The warranty covers you dropping it and breaking it? That's one heck of a warranty. |
Hopefully. What I said about the warranty is about in most cases.
EDIT:
I asked if the warranty covers a broken DS-X, on the DS-X support tracker. Time to wait...
#152378 - yellowstar - Fri Mar 14, 2008 4:44 pm
Maybe it would work, or possiblely do something else, if I start using double-buffers again...
I recently tried emulating this with the latest DeSUme, and it the result look kindof like the problem on DS. I tried capturing a video of it.(Not built-in, some other software I found before this)
The video is around 5 MB... And I'm stuck with Dial-Up... I might get around to it eventually... (It's on my other computer. This emu I used dosen't work on this XP I am using right now... I have WiFi setup on this XP, via the Nintendo dongle and official drivers. That is temporary. It will be replaced by another dongle, for homebrew. And with WiFi running on this computer, it's a bad idea to be downloading/uploading with Dial-Up and WiFi...)
#153682 - yellowstar - Thu Apr 03, 2008 10:03 pm
I have found a trick to get my DS-X to work on DS.(Still waiting on a response from support tracker...)
Here's the trick: I have the USB cord plugged into the DS-X, but not the computer. Next I push the end of the cord,(The end at the DS-X)
towards the DS, then keep my finger in that position until it finishes loading the homebew.(It's like the Games 'n Music nightmare all over again...)
I have tested my new version of this problem, with Double Buffers. Now, all I see is the background, not the image that's supposed to be displayed...
(I tried changing it to be similar to dovoto's tutorial, but nothing changed for the displayed images...)
(I tried decreasing BG_MAX, but the displayed image was wrong, among other things. And since dovoto said that that's supposed to be 3, I decided not to post about what happened with that.)
Code: |
#define BG_MAX 4
u8 *video_buffer_main = (u8*)BG_BMP_RAM(0);
u8 *video_buffer_sub = (u8*)BG_BMP_RAM_SUB(0);
bool which_buffer=1;
void SwapBuffers()
{
if(which_buffer)
{
video_buffer_main = (u8*)BG_BMP_RAM(BG_MAX);
video_buffer_sub = (u8*)BG_BMP_RAM_SUB(BG_MAX);
BG3_CR = BG_BMP8_256x256 | BG_BMP_BASE(0) | BG_PRIORITY(3);
SUB_BG3_CR = BG_BMP8_256x256 | BG_BMP_BASE(0) | BG_PRIORITY(3);
}
else
{
video_buffer_main = (u8*)BG_BMP_RAM(0);
video_buffer_sub = (u8*)BG_BMP_RAM_SUB(0);
BG3_CR = BG_BMP8_256x256 | BG_BMP_BASE(BG_MAX) | BG_PRIORITY(3);
SUB_BG3_CR = BG_BMP8_256x256 | BG_BMP_BASE(BG_MAX) | BG_PRIORITY(3);
}
which_buffer = !which_buffer;
}
int main(void)
{
powerON(POWER_ALL);
irqInit();
irqEnable(IRQ_VBLANK);
videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);
videoSetModeSub(MODE_5_2D | DISPLAY_BG3_ACTIVE);
vramSetBankA(VRAM_A_MAIN_BG);
//Init main bg
BG3_CR = BG_BMP8_256x256 | BG_BMP_BASE(BG_MAX) | BG_PRIORITY(3);
//No rotation and no scale
BG3_XDX = 1 << 8;
BG3_XDY = 0;
BG3_YDX = 0;
BG3_YDY = 1 << 8;
BG3_CX = 0;
BG3_CY = 0;
vramSetBankD(VRAM_D_LCD);//For screenshots
vramSetBankC(VRAM_C_SUB_BG);
//Init sub
SUB_BG3_CR = BG_BMP8_256x256 | BG_BMP_BASE(BG_MAX) | BG_PRIORITY(3);
//No rotation and no scale
SUB_BG3_XDX = 1 << 8;
SUB_BG3_XDY = 0;
SUB_BG3_YDX = 0;
SUB_BG3_YDY = 1 << 8;
SUB_BG3_CX = 0;
SUB_BG3_CY = 0;
dmaCopy(BAK_RAW,video_buffer_main,256*256);
dmaCopy(BAK_RAW,(u8*)BG_BMP_RAM(BG_MAX),256*256);
dmaCopy(BAK_RAW,video_buffer_sub,256*256);
dmaCopy(BAK_RAW,(u8*)BG_BMP_RAM_SUB(BG_MAX),256*256);
while(1)
{
swiWaitForVBlank();
SwapBuffers();
Draw();
Step();
}
return 0;
}
|
#153739 - yellowstar - Fri Apr 04, 2008 10:01 pm
I got the Double Buffers working. But, now it's doing exactly the same thing that it was doing before.(The graphic problem when the image is moving)
(By the way, I updated the code in the above post)
I tried changing the code so it only displays only one scanline, but had the same movement problem...
Help!
EDIT:
Removed statement stating that the scanlines were cut in half. One of the squares in the image is the same color as the background, so the scanlines looked like they were cut in half.
EDIT2:
I tried the following, but still NOTHING changed, even with only drawing one scanline! HELP!
Remember, whether or not the image's width is a power of 2 or not, doesn't change anything.
Code: |
void VCopy(u8* source, u8 *target, size_t s_offset, size_t t_offset, size_t size,size_t target_width, size_t source_width)
{
size_t so, to;
so=s_offset;
to=t_offset;
if(linear)
{
size_t I=0;
size_t i=0;
for(i=0; i < size; i+= source_width)
{
//vcopy(source,target,so+i,to+I,source_width);
dmaCopy(&source[(int)so+i],&target[(int)to+I],(uint32)source_width);
I+=target_width;
}
}
if(!linear)
vcopy(source,target,so,to,size);
}
|
#153830 - yellowstar - Mon Apr 07, 2008 12:37 am
I tried changing the speed var to 2, instead of 1, but that didn't help anything. It must not be an alignment problem...(speed is a var that dictates the number of pixels the image moves every vblank if it's supposed to move)
Anybody?
EDIT:
I discovered something.
When I attempt to make it display only the first pixel of the image, that causes major chaos. Nothing appears on the main screen, where the pixel is supposed to appear.
On the sub screen, the whole screen is flickering. About 32 pixels down, there's this thin purple-ish bar stretching across the screen. At the bottom, there's this black bar that looks like the original image I was using at first,(The Win98 taskbar)
except it's inverted.(Mainly black for most of the image)
Above that is a short purple bar, stretching across the screen. And above that bar is some black stuff.
Nothing is displayed on either screen when I try to switch screens, or copy modes.
This buggy gfx2gba turned my background color from yellow to green...(This happened when I was editing the graphic files)
(I can live with it)
#154134 - yellowstar - Fri Apr 11, 2008 8:53 pm
I fixed that one-pixel problem:
Code: |
void vcopy(u8* source, u8 *target, size_t s_offset, size_t t_offset, size_t size)
{
//Copys source starting at s_offset to target starting at t_offset with
//size size.
//This Copy works with VRAM, OAM, and backgrounds.
/*u16 *Tar = (u16*)&target[(int)t_offset];
*Tar = 1 | 1 >> 8;
return; <------ Tried this code, but same-old-same-old problem*/
if((t_offset+1)%2==0)
{
u16 temp=0;
u16 *tar = (u16*)&target[(int)t_offset];
temp = (u16)target[(int)t_offset];
temp |= ((u16)source[(int)s_offset]) >> 8;
*tar = temp;
t_offset++;
s_offset++;
size--;
}
else if(size==1)
{
u16 temp=0;
u16 *tar = (u16*)&target[(int)t_offset];
temp |= ((u16)source[(int)s_offset]);
temp |= (u16)target[(int)t_offset] >> 8;
*tar = temp;
t_offset++;
s_offset++;
return;
}
if(copy_type == CT_SCPY)
scpy(&target[(int)t_offset],&source[(int)s_offset],size);
if(copy_type == CT_DMA)
{
dmaCopy(&source[(int)s_offset],&target[(int)t_offset],(uint32)size);
}
}
}
|
Is it legal for a homebrewer, to help another homebrewer by using the official Nitro Capture toolkit to capture a video of a 9-month-old problem?(Can that toolkit capture videos?)
(In other words, would it be legal for another person here to help me, and capture a video with that toolkit of this problem?)
I tried using dmaCopy to capture screenshots of both the front and back buffers, but still nothing. I tried clearing the back buffer 10 times instead of once, but the program really slowed down, and the glitch still was there.
gbatek wrote: |
Capture provides a couple of interesting effects.
Another example would be to capture Engine A output, the captured image can be displayed (via VRAM Display mode) in the following frames, simultaneously the new Engine A output can be captured, blended with the old captured image; in that mode moved objects will leave traces on the screen; this method works with a single LCDC-allocated VRAM block.
|
That sounds alot like my backgrounds problem. It's leaving blended traces of the moving image on the background.(I haven't tried that example though)
EDIT:
Here's the updated source, with the binary included.
Here's the .nds binary.
#154333 - yellowstar - Mon Apr 14, 2008 10:32 pm
My DS-X is done for. I finally got a response for DS-X support,(I was waiting on my support person, for a response from his superiors about fixing it)
and they said no. It was my fault it broke, so, no.
#154367 - yellowstar - Tue Apr 15, 2008 4:21 am
I went through the Patater guide, and found some things about DMA:
Patater wrote: |
When using DMA to copy from main memory, do not forget to flush main memory before using DMA. Another issue to consider would be that in the middle of a DMA, the main CPUs are prevented from using certain memory hardware.
|
I always thought DMA froze the processors while at work? If Patater is correct, that doesn't happen? Flush? He only flushed in OAM updating, unlike what he himself said. I attempted adding code to flush cache, and waiting for DMA to finish, at every DMA ocerance, but still nothing changed. What all would be locked during DMA?
Some wackiness with VRAM and numbers:
To hold one 256x256 8-bit bg in VRAM, I need 65536 bytes of space. That's 4 blocks; Unlike what some examples say, they say index 3, I find 4. And examples say I only need Bank A, those numbers say I need another one, too. Double buffers take 131072 bytes, that more than what Bank A can handle. Mapping another bank to MAIN_BG doesn't help my problems; Why? Also, why do the examples say what the do, when they seem to be wrong? Or am I wrong?
I edited my code so the back buffer isn't cleared every frame. Here's the results: It still misbehaved with the same glitches as before, but with what you'd expect when not clearing buffers. Now for another wacky glitch: When moving the image to the right,(or +down/up to, so down-right/down-up)
there is a 1-pixel wide gap left one pixel to the left of the image. And when the image stops moving, there's a 2-pixel gap to the left.(This gap's color is the background color)
Here's a screenshot.(Note this only has the above glitches, not the main ones)
Here's the whole code, cut into differnt code blocks:
Code: |
#include <nds.h>
#include <string.h>
#include <malloc.h>
#include "PALETTE_RAW.h"
#include "TASKBAR3_RAW.h"
#include "BAK_RAW.h"
#define DEBUG
#define CT_DMA 0
#define CT_SCPY 1
bool copy_type = CT_DMA;
bool linear = 1;//If true, copy the image in by
//copying the each scanline(horizontal line) in the
//image to the target one-by-one.
bool screen = 0;//screen to which the image is copyed to.
//0 for top, 1 for bottom.
int x = 0;
int y = 0;
int speed=1;
#include "debug.h"
#define BG_MAX 4
u8 *video_buffer_main = (u8*)BG_BMP_RAM(0);
//u8 *video_buffer_main_buf = (u8*)BG_BMP_RAM(0);
u8 *video_buffer_sub = (u8*)BG_BMP_RAM_SUB(0);
//u8 *video_buffer_sub_buf = (u8*)BG_BMP_RAM_SUB(0);
bool which_buffer=1;
//Section moved to next section of code in post
void Init()
{
fatInitDefault();
}
void Draw()
{
u8 *target=NULL;
u8 *image = (u8*)TASKBAR3_RAW;
size_t image_size = (size_t)TASKBAR3_RAW_size;
size_t target_width, source_width;
target_width=SCREEN_WIDTH; source_width=30;
if(!screen)target=video_buffer_main;
if(screen)target=video_buffer_sub;
//This block right here is commented out for when not clearing the buffers
DC_FlushAll();
dmaCopy((u16*)BAK_RAW,video_buffer_main,256*256);
while(dmaBusy(3));DC_FlushAll();
dmaCopy((u16*)BAK_RAW,video_buffer_sub,256*256);
while(dmaBusy(3));DC_FlushAll();
VCopy(image,target,0,(size_t)((256*y)+x),image_size,target_width,source_width);
}
void SwapBuffers()
{
if(which_buffer)
{
video_buffer_main = (u8*)BG_BMP_RAM(BG_MAX);
video_buffer_sub = (u8*)BG_BMP_RAM_SUB(BG_MAX);
BG3_CR = BG_BMP8_256x256 | BG_BMP_BASE(0);
SUB_BG3_CR = BG_BMP8_256x256 | BG_BMP_BASE(0);
}
else
{
video_buffer_main = (u8*)BG_BMP_RAM(0);
video_buffer_sub = (u8*)BG_BMP_RAM_SUB(0);
BG3_CR = BG_BMP8_256x256 | BG_BMP_BASE(BG_MAX);
SUB_BG3_CR = BG_BMP8_256x256 | BG_BMP_BASE(BG_MAX);
}
which_buffer = !which_buffer;
}
int main(void)
{
powerON(POWER_ALL);
irqInit();
irqEnable(IRQ_VBLANK);
videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);
videoSetModeSub(MODE_5_2D | DISPLAY_BG3_ACTIVE);
vramSetBankA(VRAM_A_MAIN_BG);
//Init main bg
BG3_CR = BG_BMP8_256x256 | BG_BMP_BASE(BG_MAX);
//No rotation and no scale
BG3_XDX = 1 << 8;
BG3_XDY = 0;
BG3_YDX = 0;
BG3_YDY = 1 << 8;
BG3_CX = 0;
BG3_CY = 0;
vramSetBankB(VRAM_B_MAIN_BG);
//vramSetBankH(VRAM_H_SUB_BG);
//vramSetBankI(VRAM_I_SUB_BG);
vramSetBankD(VRAM_D_LCD);//For screenshots
vramSetBankC(VRAM_C_SUB_BG);
//Init sub
SUB_BG3_CR = BG_BMP8_256x256 | BG_BMP_BASE(BG_MAX);
//No rotation and no scale
SUB_BG3_XDX = 1 << 8;
SUB_BG3_XDY = 0;
SUB_BG3_YDX = 0;
SUB_BG3_YDY = 1 << 8;
SUB_BG3_CX = 0;
SUB_BG3_CY = 0;
DC_FlushAll();
memcpy(BG_PALETTE_SUB, PALETTE_RAW, PALETTE_RAW_size);
DC_FlushAll();
memcpy(BG_PALETTE, PALETTE_RAW, PALETTE_RAW_size);
DC_FlushAll();
dmaCopy(BAK_RAW,video_buffer_main,256*256);
while(dmaBusy(3));
DC_FlushAll();
dmaCopy(BAK_RAW,(u8*)BG_BMP_RAM(BG_MAX),256*256);while(dmaBusy(3));DC_FlushAll();
dmaCopy(BAK_RAW,video_buffer_sub,256*256);while(dmaBusy(3));DC_FlushAll();
dmaCopy(BAK_RAW,(u8*)BG_BMP_RAM_SUB(BG_MAX),256*256);while(dmaBusy(3));DC_FlushAll();
Init();
while(1)
{
swiWaitForVBlank();
Step();
SwapBuffers();
Draw();
}
return 0;
}
|
Code: |
//n=nce's
//e=elhobbs
inline void nscpy(void* in_dst, const void *in_src, unsigned int length);
inline void escpy(void* in_dst, const void *in_src, unsigned int length);
__attribute__((section (".ewram"),long_call))
inline void scpy(void* in_dst, const void *in_src, unsigned int length)
{
//escpy(in_dst,in_src,length);
nscpy(in_dst,in_src,length);
}
inline void nscpy(void* in_dst, const void *in_src, unsigned int length)
{
if(1)
{
u8 *src = (u8*)in_src;
u16 *dst = (u16 *)in_dst;
u16 temp=0;
u8 pix1;
u8 pix2;
length >>= 1;
for(; length > 0; length--)
{
pix1=*src++;
pix2=*src++;
temp= pix1 | (pix2<<8);
*dst++ = temp;
}
}
else
{
//This is nce's code
u8* src = (u8 *)in_src;
u16 *dst = (u16 *)in_dst;
u8* src1 = src+1;
length >>= 1;
for(; length > 1; length--)
{
*dst++ =( (*src )<<8) | (*src1);
src+=2 ; src1+=2;
}
//and the last one
//*dst = (*src ) | ((*dst & 0xff )<<8);
// OR
//*dst = (*src ) | (*dst & 0xff00 );
//*dst = (*src ) | ((*dst<<8));
}
}
inline void escpy(void* in_dst, const void *in_src, unsigned int length)
{
u8 *src8=(u8*)in_src;//source 8 bit pixels
u8 *dest8=(u8*)in_dst;//unaligned destination 8 bit
u16 *dest16;//aligned destination 16 bit
u16 pixel16=0;//temporary for holding two 8 bit pixels
bool is_odd=0;
dest16 = (u16*)dest8;
is_odd=(length & 1)?1:0;
if (is_odd)
{
/*dest16 = ((u16*)(dest8-1));
//handle single pixel write
//read both pixels from the destination
pixel16 = *dest16;
//we want to keep the first byte
pixel16 &= 0xff;
//and replace the second byte
pixel16 |= ((*src8++)<<8);
//and write both values back
*dest16++ = pixel16;
length--;*/
}
length = length>>1;
//now the destination will be aligned to 16bit value
//so handle all of the two pixel writes we can
for(; length > 1; length--)
{
pixel16= *src8++;
pixel16 |= ((*src8++)<<8);
*dest16++ = pixel16;
}
/*for(; length > 1; length--)
{
*dst++ =( (*src )<<8) | (*src1);
src+=2 ; src1+=2;
}*/
//if the length is odd then write the last byte
if(is_odd)
{
//handle single pixel write
//read both pixels
pixel16 = *dest16;
//we want to keep the second byte
pixel16 &= 0xff00;
//and replace the first byte
pixel16 |= *src8++;
//and write both values back
*dest16++ = pixel16;
}
}
|
Code: |
inline void vcopy(u8* source, u8 *target, size_t s_offset, size_t t_offset, size_t size)
{
//Copys source starting at s_offset to target starting at t_offset with
//size size.
//This Copy works with VRAM, OAM, and backgrounds.
DC_FlushAll();
if((t_offset+1)%2==0)
{
u16 temp=0;
u16 *tar = (u16*)&target[(int)t_offset];
temp = (u16)target[(int)t_offset];
temp |= ((u16)source[(int)s_offset]) >> 8;
*tar = temp;
t_offset++;
s_offset++;
size--;
}
else if(size==1)
{
u16 temp=0;
u16 *tar = (u16*)&target[(int)t_offset];
temp |= ((u16)source[(int)s_offset]);
temp |= (u16)target[(int)t_offset] >> 8;
*tar = temp;
t_offset++;
s_offset++;
return;
}
if(copy_type == CT_SCPY)
scpy(&target[(int)t_offset],&source[(int)s_offset],size);
if(copy_type == CT_DMA)
{
dmaCopy(&source[(int)s_offset],&target[(int)t_offset],(uint32)size);
while(dmaBusy(3));
}
DC_FlushAll();
}
void VCopy(u8* source, u8 *target, size_t s_offset, size_t t_offset, size_t size,size_t target_width, size_t source_width)
{
//Is it an odd length?
size_t so, to;
so=s_offset;
to=t_offset;
if(linear)
{
size_t I=0;
size_t i=0;
for(i=0; i < size; i+= source_width)
{
vcopy(source,target,so+i,to+I,source_width);
//dmaCopy(&source[(int)so+i],&target[(int)to+I],(uint32)source_width);
I+=target_width;
}
}
if(!linear)
vcopy(source,target,so,to,size);
}
|
Last edited by yellowstar on Wed Apr 16, 2008 8:25 pm; edited 3 times in total
#154414 - yellowstar - Tue Apr 15, 2008 10:58 pm
I feel like people are ignoring this topic... Nobody has replied to the actual problems in a long time...(The graphical problems)
(My patience is wearing extremely thin in case nobody noticed...)
Anyway:
DeSmume reports that DISPCNT is contantly changing, why, and what is that register? Is it the old DISPLAY_CR?
I tried changing the Flush command in vcopy to Invalidate, but still nothing changed.
Everybody, if anybody is reading this, how would you do this? How would you write code to draw a 8-bit image on a bg when the image doesn't fill the whole bg?(Whole demo please, if possible)
Now I know why people hate the PAlib source code... I downloaded the source, and I hate it too. One of the sick things I noticed right away that he hit enter twice for each line. I tried to have Windows search for the function used for writing 8-bit pixels, but I couldn't find it anywhere! Arghh... As in:
Code: |
int a;
int b;
int c;
void mycode()
{
a=0;
b=1;
c=a+b;
}
|
#154508 - yellowstar - Thu Apr 17, 2008 2:43 am
I mentioned elsewhere I was going to do a rewrite of this thing. I have finished the rewrite. But, this monster of a problem STILL exists! Argghhh!(I'm going nuts!)(That's only with this bg thing)
Perhaps it has to do with how I'm clearing the video buffer...
The way I'm doing it right now, is: I have a 8-bit image that has palette index 0. When I clear, I copy this image to the video buffer:
Code: |
dmaCopy((u8*)BAK_RAW,video_buffer_main,256*256);
|
What's the usual/normal way of clearing video buffers? How would you do it, fellow DS devs?
Hmmm... These glitches prevail even when not clearing... I still want to know the above however.
The code is MUCH simpler, and yet, still bugged:
(SCpy code removed, that was backed up in the old versions)
(Double buffers removed too)
Code: |
#include <nds.h>
#include <string.h>
#include <malloc.h>
#include "PALETTE_RAW.h"
#include "TASKBAR3_RAW.h"
#include "BAK_RAW.h"
#include "debug.h"
u8 *video_buffer_main = (u8*)BG_BMP_RAM(0);
int speed = 1;
int x=0;
int y=0;
void VCopy(u8 *source, u8 *target, int position, int size, int source_width, int target_width)
{
int i, I;
i=0; I=0;
//target = &target[position];
//((u16*)target)[position] = 2 | 2 >> 8; //Even this line won't work!
for(i=0; i<size; i+=source_width)
{
DC_FlushAll();
dmaCopy(&source[i],&target[position+I],(u32)source_width);
while(dmaBusy(3));
I+=target_width;
}
}
void Draw()
{
DC_FlushAll();
dmaCopy((u8*)BAK_RAW,video_buffer_main,256*256);
while(dmaBusy(3));
VCopy((u8*)TASKBAR3_RAW,video_buffer_main,(y*256)+x, (int)TASKBAR3_RAW_size, 30, 256);
}
void Step()
{
scanKeys();
if(keysHeld() & KEY_RIGHT)x+=speed;
if(keysHeld() & KEY_LEFT)x-=speed;
if(keysHeld() & KEY_DOWN)y+=speed;
if(keysHeld() & KEY_UP)y-=speed;
}
int main(void)
{
powerON(POWER_ALL);
irqInit();
irqEnable(IRQ_VBLANK);
videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);
vramSetMainBanks(VRAM_A_MAIN_BG, VRAM_B_MAIN_BG,
VRAM_C_LCD , VRAM_D_LCD);
BG3_CR = BG_BMP8_256x256 | BG_BMP_BASE(0);
// these are rotation backgrounds so you must set the rotation attributes:
// these are fixed point numbers with the low 8 bits the fractional part
// this basicaly gives it a 1:1 translation in x and y so you get a nice flat bitmap
BG3_XDX = 1 << 8;
BG3_XDY = 0;
BG3_YDX = 0;
BG3_YDY = 1 << 8;
// our bitmap looks a bit better if we center it so scroll down (256 - 192) / 2
BG3_CX = 0;
BG3_CY = 0;
DC_FlushAll();
dmaCopy((u8*)BAK_RAW,video_buffer_main,256*256);
while(dmaBusy(3));
DC_FlushAll();
dmaCopy((u8*)PALETTE_RAW,BG_PALETTE,256*2);
while(dmaBusy(3));
while(1)
{
swiWaitForVBlank();
Draw();
Step();
}
return 0;
}
|
#154559 - yellowstar - Fri Apr 18, 2008 3:34 am
Here's some videos.
1
2
3
There's other videos, but those aren't done...(Dial-Up)
(And two are corrupted on the server)
How am I supposed to do this? That is, what is the normal way of drawing images on 8-bit bgs, when the image doesn't fill the entire bg? And/Or, how do you do it, fellow ds devs?
Last edited by yellowstar on Fri Apr 18, 2008 7:59 pm; edited 1 time in total
#154592 - Lord Graga - Fri Apr 18, 2008 7:53 pm
#154593 - yellowstar - Fri Apr 18, 2008 8:06 pm
Fixed. The url tag won't work right when there's spaces in the url. And I guess I tried removing the space, and that produced the 404.
These videos were taken the same way I mentioned eariler. The videos have graphic glitches. One issue is that Desmume leaves stuff on the image that shouldn't be there, and that doesn't happen on hw. Notice the junk/disturbance trailing the image when it's moving; that's the problem.
#154598 - yellowstar - Fri Apr 18, 2008 10:53 pm
I discovered when I skip frames, those glitches seem to disappear, as long as I skip at least 8 frames. Also, I discovered that dmaCopy automatically waits for dma to finish - so no need for dma waiting code. This is a general VRAM/BG problem. It doesn't matter what I use - dma or a simple 16 bit write, it is glitched. Does VRAM have a cache? If so, how do I disable it, if possible?
Code: |
int frame_skip=0;
void main()
{
while(1)
{
swiWaitForVBlank();
frame_skip++;
if(frame_skip<8)continue;
frame_skip=0;//Set it to zero when we have skipped 8 frames
...
}
}
|
#154639 - yellowstar - Sat Apr 19, 2008 5:41 pm
I have discovered that VRAM doesn't have cache activated by default. Activating it would only cause more problems. But still, how would I activate the cache?
Is there anybody out there that's doing what I'm doing, or has successfully written such code?
#154659 - yellowstar - Sun Apr 20, 2008 12:52 am
I successfully followed a tutorial on tile map bgs. And I attempted to write code to use tile map bgs as framebuffers/ext rot bgs. And course that failed. Same graphic glitches as this. Plus a distorted image, and slow framerate.
How do the official games/SDK draw stuff on the screen? How do you guys do it? How am I supposed to do it? What am I supposed to use for this?(What kind of bgs?)
Here's the code:
Code: |
#include <nds.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "palette_raw.h"
#include "bak_raw.h"
#include "taskbar3_raw.h"
#include "debug.h"
u8 *tilememory = (u8*)BG_TILE_RAM(1);
u16 *mapmemory = (u16*)BG_MAP_RAM(0);
u8 *video_buffer_main;
int x, y, speed;
//u8 redTile[64]
void Init()
{
for(int i=0; i<32*32; i++)
mapmemory[i]=i;
u16 *tilem = (u16*)tilememory;
for(int i=0; i<2048; i++)
tilem[i]=0;
}
void Update()
{
int si, oi, tilew, tileh, line;
si=0; oi=0; tilew=0; tileh=0; line=0;
DC_FlushAll();
for(tileh=0; tileh<32; tileh++)
{
for(tilew=0; tilew<32; tilew++)
{
for(line=0; line<8; line++)
{
dmaCopy(&video_buffer_main[si],&tilememory[oi],8);
si+=256; oi+=8;
}
si-=256*8; si+=8;
}
//si-=8;
si+=256*8;
}
}
void VCopy(u8 *source, u8 *target, int position, int size, int source_width, int target_width)
{
int i, I;
i=0; I=0;
//target = &target[position];
DC_FlushAll();
//((u16*)target)[position] = 2 | 2 >> 8;
//DC_FlushAll();
for(i=0; i<size; i+=source_width)
{
dmaCopy(&source[i],&target[position+I],(u32)source_width);
I+=target_width;
}
}
int main(void)
{
irqInit();
irqEnable(IRQ_VBLANK);
int i=0;
videoSetMode(MODE_0_2D | DISPLAY_BG0_ACTIVE);
vramSetBankA(VRAM_A_MAIN_BG);
vramSetBankD(VRAM_D_LCD);
fatInitDefault();
video_buffer_main = (u8*)malloc(256*256);
x=0; y=0; speed=1;
Init();
BG0_CR = BG_COLOR_256 | BG_MAP_BASE(0) | BG_TILE_BASE(1);
DC_FlushAll();
dmaCopy(palette_raw,BG_PALETTE,256*2);
DC_FlushAll();
dmaCopy((u8*)bak_raw,video_buffer_main,256*256);
//dmaCopy(redTile, tilememory, 64);
//dmaCopy(greenTile, tilememory + 64, 64);
while(1)
{
swiWaitForVBlank();
DC_FlushAll();
dmaCopy((u8*)bak_raw,video_buffer_main,256*256);
DC_FlushAll();
VCopy((u8*)taskbar3_raw,video_buffer_main,(y*256)+x,(int)taskbar3_raw_size,30,256);
Update();
scanKeys();
if(keysHeld() & KEY_DOWN)y+=speed;
if(keysHeld() & KEY_UP)y-=speed;
if(keysHeld() & KEY_RIGHT)x+=speed;
if(keysHeld() & KEY_LEFT)x-=speed;
if(x<0)x=0;
if(y<0)y=0;
if(x>256-30)x=256-30;
if(y>192-30)y=192-30;
Step();
//dmaCopy(redTile, tilememory, 64);
//dmaCopy(greenTile, tilememory + 64, 64);
}
return 0;
}
|
#155184 - yellowstar - Sat Apr 26, 2008 3:32 am
Sorry for all this ranting, anger, and such. I really shouldn't be posting with such things residing in those posts. Starting now, I'll try to remain calm.
Desmume, the latest one, correctly emulates this problem. The last version released by YopYop, before he had to quit, did it correctly also. I have yet to try the oldest version available on the web site, but I have a feeling whatever is causing this, was correctly emulated from the start. I'd like to know what that is...
EDIT:
My hunch was wrong, fortunately. Desmume 0.3.0 doesn't do it right, 0.3.3 does. Now how to contact him... That's really convenient, right on the front page of the web site. Hopefully he still checks that E-Mail address...
EDIT2:
Well, I sent him an E-Mail. Hopefully he still checks that address...
#155775 - yellowstar - Sun May 04, 2008 1:54 am
I have discovered something.
Expert from a PM to another member:
The moving image is jumpy on emus - wonder if that's an issue on hw? That's only visible when your looking at it up close with magnification. And the results look about the same in emus as emulators, so maybe it's being jumping for whatever reason is the problem?
(Would be nice if I could capture videos on hardware... I could check if it's jumpy on hw also...)
#156124 - yellowstar - Wed May 07, 2008 12:45 am
Another member offered to take some captures of this problem, on both emulator and hardware. The emu capture seems to be more accurate then the hardware, however. Web cam's fault, that's all.
Emulator capture
Hw capture 1
Hw capture 2
Snapshot of the moving image
#156237 - TwentySeven - Wed May 07, 2008 11:15 pm
Please don't tell me you're refering to the crappy lcd response time on the DS.. and the "ghosting" you get from it.
#156246 - yellowstar - Thu May 08, 2008 1:04 am
?
You mean you've been tortured by this kind of problem too? Do you know of any work arounds? Any idea how long it takes it respond? (My tests say that might be the next-to-impossible-to-use-rate-of-7-frames)
OpenTTD uses 8-bit bgs without a problem...
#156252 - DensitY - Thu May 08, 2008 1:20 am
um yeah..
the ghosting isn't a code bug, its just the response time on the LCD screen on the DS is really low, possibly 25ms or higher. Back when LCD monitors first started coming out on PC, they were virtually useless for first person perspective shooters because of the slow response time. you guessed it ghosting. these days most LCD monitor's have response time of 8ms to 2ms, so ghosting is pretty much non existant.
#156255 - yellowstar - Thu May 08, 2008 1:47 am
Don't you mean high? :-)
I googled and found some info... Big difference between DS and the normal LCD... How would refresh rate and response time, tie together? Wonder how long a DS vblank is...
#156320 - tepples - Thu May 08, 2008 9:53 pm
GBATEK says the DS video signal is 355x263 pixels, and the video hardware renders one pixel every 6 FSB cycles. (The DS's FSB is 33.5 MHz.) Of course, only 256x192 pixels are visible on each screen; the rest are blanking.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#156333 - yellowstar - Thu May 08, 2008 10:30 pm
tepples wrote: |
GBATEK says the DS video signal is 355x263 pixels, and the video hardware renders one pixel every 6 FSB cycles. (The DS's FSB is 33.5 MHz.) Of course, only 256x192 pixels are visible on each screen; the rest are blanking. |
I guess the defination of FSB would fit with this? How long does it take the DS to render one whole frame?(From the top scanline to bottom, excluding the vblank time)
What I really want to know, is, does the pixels completely change from the old to new colors, by the time the video hardware gets to rendering that pixel again?
#156340 - Maxxie - Thu May 08, 2008 10:46 pm
yellowstar wrote: |
tepples wrote: | GBATEK says the DS video signal is 355x263 pixels, and the video hardware renders one pixel every 6 FSB cycles. (The DS's FSB is 33.5 MHz.) Of course, only 256x192 pixels are visible on each screen; the rest are blanking. |
I guess the defination of FSB would fit with this? How long does it take the DS to render one whole frame?(From the top scanline to bottom, excluding the vblank time)
|
1/60th second * 192/355
(if tepples numbers are correct)
Quote: |
What I really want to know, is, does the pixels completely change from the old to new colors, by the time the video hardware gets to rendering that pixel again? |
It should. Reaction times should be somewhere at 10th of ms. Each pixel however is driven once every 1/60th (~16.7ms).
However our eyes do not only determinate the intensity of a pixel by the actual level the pixel is driven too, but also by the timefraction it drives this level. This leads - unlike crts which pixels allways are only active a very short time - that the previous color mixes with the new color in our view.
Modern displays (for PCs and TVs) reduce this by over or underdriving a pixel depending on the previous color before adjusting to the requested brightness.
#156349 - yellowstar - Thu May 08, 2008 11:05 pm
Maxxie wrote: |
that the previous color mixes with the new color in our view
Modern displays (for PCs and TVs) reduce this by over or underdriving a pixel depending on the previous color before adjusting to the requested brightness. |
So it's our human eyes that create this effect, and I need to figure out a way to hide this. Sounds like I should try to do that with my code. But how? This is 8-bit bgs, and code would get complicated & expensive with using palette... Perhaps I could fiddle with BLEND_CR and similar things...
#156352 - silent_code - Thu May 08, 2008 11:10 pm
ghosting is pretty bad in locco rocco on the psp (obviously it's on the psp...).
but i haven't seen it as bad as in yellowstar's test on the nds. looks like motion blur!
#156355 - Maxxie - Thu May 08, 2008 11:18 pm
While it is theoretical possible to hide that effect per software (by inverse filtering) if you have exact knowledge on the timings and enough calculation time per pixel it remains a problem on the physical layer. (Other hw solutions would be backlight scattering, black striping, or scanning backlights)
Since on the NDS you do not have the resource to calculate the needed adjustments in time, no there is no real way to prevent the movement blur by software means.
#156362 - yellowstar - Thu May 08, 2008 11:47 pm
So 8-bit bgs are useless for what I want, so you say... In my opinion, that would mean don't use them at all... Don't the official games use 8-bit bgs? How do they fix this?(I was thinking before this is an hw issue. But why even have 8-bit bgs in the hw if you can't use it right? GBA compatibility maybe...)
I read that with BLEND_CR, I could only blend two bgs. So I would have two bgs: The first one would be the new, the other the old. The first frame would only render to the old bg. After that, it would always render to the the new, then on the following frames, it would copy the bg to the old bg, before rendering. Now I just need to code and try it...
EDIT:
That didn't work... Looks like I'm stuck with 16-bit bgs... If anybody has any ideas on hiding this, please say so.
#156372 - Maxxie - Fri May 09, 2008 12:25 am
The mode you use has nothing at all to do with the problem.
You can try to conceal it, but it will still remain. The less contrast you use i.e. the less you will notice it. The slower movement the less you will notice it and so on.
BUT you CAN NOT influence the physical limits of the display or your eyes which are responsible for the motion blur on a LCD Display
#156377 - yellowstar - Fri May 09, 2008 3:20 am
Well, the problem shows even when only moving at 1 pixel per vblank. So if the scene would be dark, or would have similar colors, it would be fine... That still wouldn't work for me very often.
#156394 - silent_code - Fri May 09, 2008 11:59 am
have you tried to use "real world" data? because your example data is rather "synthetic", it exaggerates the effect pretty much.
i've got a suggestion: download megaETK and check if that suffers from the effect as much as your example. :^)
Last edited by silent_code on Fri May 09, 2008 2:23 pm; edited 3 times in total
#156397 - Lazy1 - Fri May 09, 2008 12:37 pm
LCD Ghosting is quite noticeable on the secret level in episode 1 of Wolfenstein 3D.
The teal doors and purple walls combine to make a weird blue smearing effect.
Oddly enough this only seems to happen on the DSLite.
Why did they go with a screen with a higher response time anyway?
#156411 - silent_code - Fri May 09, 2008 2:24 pm
EDIT: corrected to BGR and bottom -> top. yes, tepples, you're right. thanks!
@ Lazy1: production cost maybe? or they have selected another manufacturer?
(disclaimer: i don't have an ndsl myself, but iirc:) the ndsl screens are both BGR now. the ("phat") nds' screens were technically identical, the top one was just rotated 180?, thus making it RGB - looking closely at the border regions of the nds' screens, you will see it easily.
that indicates a rather "big" change in technical design (think of the hacks some have made to display subpixel fonts correctly, which needed adjustment for the top screen!)
has anyone info about the rgb/bgr issue? i might be wrong on this (it's from year old memory and as we all know, memory fails us quite often!) ;^p i guess looking closely at an ndsl would do the trick. :^)
the reasons for such a move are not known to me. "and still, i wonder..." :^)
Last edited by silent_code on Fri May 09, 2008 8:54 pm; edited 1 time in total
#156439 - tepples - Fri May 09, 2008 8:25 pm
Lazy1 wrote: |
Oddly enough this only seems to happen on the DSLite.
Why did they go with a screen with a higher response time anyway? |
In cheap LCDs, sometimes there's a tradeoff between contrast and response time. The PSP LCD response time is slow, and so is that of the DS Lite, but the colors are a lot brighter than on the original DS.
As for RGB vs. BGR: The GBC, GBA, and DS Lite are BGR. The original DS is BGR on the touch screen and RGB on the top screen. I haven't checked the Game Boy micro.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#156440 - yellowstar - Fri May 09, 2008 9:08 pm
@silent: Well, all I have is emulators, but I couldn't see any effect with Desmume, or no$gba.(Those emus emulate the effect correctly)(broken card) (If it uses 8-bit bgs like how I want, wonder if there's source code...)(Couldn't find any source when I googled though.)
@all: Which screen the image is displayed on, and whether it's on a phat or Lite doesn't help anything. It shows up better on a Lite however.