#139939 - Diddl - Tue Sep 11, 2007 9:27 pm
I understand function of console with consoleInitDefault() and iprintf() and escape chars. But I have problems to understand colour palette things.
I want to write chars direct to screen. I have initialize code like this:
Code: |
BG_PALETTE_SUB[0xff] = RGB15(31,31,31);
consoleInitDefault((u16*)SCREEN_BASE_BLOCK_SUB(31), (u16*)CHAR_BASE_BLOCK_SUB(0), 16);
screen = (u16*)SCREEN_BASE_BLOCK_SUB(31); |
now I can directly write to screen with
Code: |
*(screen +column + row*MAX_COLS) = 0xf000 | chr; |
wonderful!
But I don't understand how to write chars with other colour than white on black. I thought I can initialize palette with
Code: |
BG_PALETTE_SUB[0xf2] = RGB15(0,0,31); // BLUE
BG_PALETTE_SUB[0xf1] = RGB15(0,31,0); // GREEN
BG_PALETTE_SUB[0xf0] = RGB15(31,0,0); // RED
|
But why is 0xf000 = white and why no other colour code does work for me? And is it possible to invert colour (write black on white)?
#139940 - Lick - Tue Sep 11, 2007 9:31 pm
I might be wrong, but I think the console uses only 2 palette entries. One for the background, one for the foreground. That means you can't have multiple foreground-colors, unless you write your own procedures for this.
_________________
http://licklick.wordpress.com
#139947 - Cearn - Tue Sep 11, 2007 11:22 pm
Diddl wrote: |
But why is 0xf000 = white and why no other colour code does work for me? |
0xf000 isn't white, it's the screen-entry code for using sub-palette 15 (i.e., palette indices 0xF0-0xFF) when using 4bpp tiled backgrounds (gbatek:screen data). consoleInitDefault() sets up the font's character data in VRAM so that the foreground pixels use the palette index 0xFF for the color. adding 15<<12 is necessary for 4bpp BGs, otherwise you'd use palette index 15 (0x0F). This is also the reason colors 0xF1 etc don't work: those aren't referenced by the character data. Color 0xF0 doesn't work because pixel values of 0 are transparent.
Diddl wrote: |
And is it possible to invert colour (write black on white)? |
The console uses color 0 for background and 255 for foreground. By changing these, you change the ink and background colors of the text. However, you will also change it for all the other pixels that make use of those colors, so be careful. A possible complication for color 0 is that it's the transparency index. If the text bg is the only one active this is alright because it's also used as the backdrop color, but if not, you'd need to modify the character data so that it doesn't use 0 anymore.
For example, orring all words of the characters in VRAM with 0xEEEEEEEE would result in the use of 0xnE for the background color and 0xnF for the foreground color. n is the sub-palette index here. Technically you'd have to use n=F because that's where the default foreground color (0xFF) is stored, but if you set up other sub-palette ranges, you can use any value for n. This provides you with a mechanism for using different colored text. This example from tonc shows how these things could be done.
If you want to see exactly how consoleInit(Default) works, get the libnds source and look under libnds/source/arm9/console.c.
#140011 - Diddl - Wed Sep 12, 2007 6:52 pm
Thank you very much! Now it's much clearer for me.
#140581 - Diddl - Mon Sep 17, 2007 9:59 pm
Thanks for your help. Textmode works fine for me now with different colors and very very fast.
Is it possible to use BOTH SCREENS same time for textmode applications and how can I do it? My textmode initialization is stolen from different sample applications:
Code: |
static u16 *screen;
int TextmodeInit()
{
int i, c, r, g, b;
videoSetMode(0); //not using the main screen
videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE); //sub bg 0 will be used to print text
vramSetBankC(VRAM_C_SUB_BG);
SUB_BG0_CR = BG_MAP_BASE(31);
// FILL COLOR PALETTE
for(i=0;i<16;i++)
{
c = i&8?0x1f:0x13;
b= i%2 * c;
r=(i/2)%2 * c;
g=(i/4)%2 * c;
BG_PALETTE_SUB[(i << 4)| 0xf] = RGB15(r,g,b);
}
consoleInitDefault((u16*)SCREEN_BASE_BLOCK_SUB(31), (u16*)CHAR_BASE_BLOCK_SUB(0), 16);
screen = (u16*)SCREEN_BASE_BLOCK_SUB(31);
consoleClear();
Test();
return 0;
}
|
#140776 - strager - Wed Sep 19, 2007 7:19 pm
Yes; to have it show up on the main screen, copy-paste your sub screen code and make necessary changes (remove SUB_ in some places, _SUB in others). Also, be sure to set the video mode properly for the main screen, as well as assign the main screen a VRAM bank.
#140790 - Diddl - Wed Sep 19, 2007 8:51 pm
oh, - so simple. thanks, now I understand the topic main and sub in this declerations!
I have problems to show change the background color. This font which libnds console uses is a 8KB binary (256 chars * 32 bytes, one char has 64 pixel, 2 pixel uses 1 byte) with only x0 and x1. InitConsole changes all 1 to F so color of letter is 4 and 4 bytes and I can choose between 16 colors (0f,1f,2f ... ff).
If I change font, - all 0 nibbles (4 bit) to e. So I could make 16 background colors (0e, 1e, 2e, ... fe). The problem with this, - I have only 16 combinations of color. cause first nibble is same for background and forground color, right? Is there another way to to it (without to use bitmap grafic mode)?
or is the only way to make 4 times the same font with different background colors?
#140795 - strager - Wed Sep 19, 2007 9:36 pm
Diddl wrote: |
If I change font, - all 0 nibbles (4 bit) to e. So I could make 16 background colors (0e, 1e, 2e, ... fe). The problem with this, - I have only 16 combinations of color. cause first nibble is same for background and forground color, right? Is there another way to to it (without to use bitmap grafic mode)?
or is the only way to make 4 times the same font with different background colors? |
If I understand you correctly, you want to change the background colour of each individual tile. You can't do this with the current method. If you change the data to read from palette index E, it will do just that; it won't change the background colour, only where the foreground colour is located.
To change the background colour, you want to change palette index 0. However, palette index 0 is transparent in 16-colour mode. You don't want a transparent background for those characters, I'd guess. You need to change the background index from 0 to something else, and change the colour palette entry to change the background.
Example of what the tile data is now:
Code: |
0000000F
000000FF
00000FFF
0000FFFF
000FFFFF
00FFFFFF
0FFFFFFF
FFFFFFFF |
These 0's are transparent, and the F's are your foreground colour. You want something like this:
Code: |
2222222F
222222FF
22222FFF
2222FFFF
222FFFFF
22FFFFFF
2FFFFFFF
FFFFFFFF |
Here, the 2's are the background and are not transparent.
I hope I'm clear. =X
#140946 - Diddl - Thu Sep 20, 2007 9:28 pm
Thanks for help.
I have now 14 colors on black and 2 invers (blue/yellow and white/red).
#141153 - Diddl - Sat Sep 22, 2007 5:35 pm
Need help again please ...
Code works fine on emulator. but on real NDS upper screen (main screen) is dark (displays nothing)???
Code: |
powerON( POWER_LCD | POWER_2D_A | POWER_2D_B );
// initialise the irq dispatcher
irqInit();
// a vblank interrupt is needed to use swiWaitForVBlank()
// since the dispatcher handles the flags no handler is required
irqSet(IRQ_VBLANK, VblankHandler);
irqEnable(IRQ_VBLANK);
videoSetMode(MODE_0_2D | DISPLAY_BG0_ACTIVE); //sub bg 0 will be used to print text
vramSetBankD(VRAM_D_MAIN_BG);
BG0_CR = BG_MAP_BASE(31);
videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE); //sub bg 0 will be used to print text
vramSetBankC(VRAM_C_SUB_BG);
SUB_BG0_CR = BG_MAP_BASE(31);
// FILL COLOR PALETTE
for(i=0;i<16;i++)
{
switch(i)
{
case 0:
col1 = RGB15(0x1f,0x1f,0); //YEL
col2 = RGB15(0,0,0x1f); //BLUE
break;
case 8:
col1 = RGB15(0x1f,0,0); //
col2 = RGB15(0x1f,0x1f,0x1f); //
break;
default:
c = i&8?0x1f:0x13;
b= i%2 * c;
r=(i/2)%2 * c;
g=(i/4)%2 * c;
col1 = RGB15(r,g,b);
col2 = RGB15(0,0,0);
break;
}
BG_PALETTE_SUB[(i << 4)| 0xf] = col1;
BG_PALETTE[(i << 4)| 0xf] = col1;
BG_PALETTE_SUB[(i << 4)| 0xe] = col2;
BG_PALETTE[(i << 4)| 0xe] = col2;
}
//consoleInitDefault((u16*)SCREEN_BASE_BLOCK_SUB(31), (u16*)CHAR_BASE_BLOCK_SUB(0), 16);
map = (u16*)SCREEN_BASE_BLOCK_SUB(31);
charBase = (u16*)CHAR_BASE_BLOCK_SUB(0);
bitDepth = 16;
consoleInit((u16*)default_font_bin, charBase, 256, 0, map, CONSOLE_USE_COLOR255, bitDepth);
consoleClear();
map = (u16*)SCREEN_BASE_BLOCK(31);
charBase = (u16*)CHAR_BASE_BLOCK(0);
bitDepth = 16;
consoleInit((u16*)default_font_bin, charBase, 256, 0, map, CONSOLE_USE_COLOR255, bitDepth);
consoleClear();
// SCREEN & ROW POINTER
screen1 = (u16*)SCREEN_BASE_BLOCK_SUB(31); //sub
screen2 = (u16*)SCREEN_BASE_BLOCK(31); //main
for(i=0; i<CONSOLE_HEIGHT; i++)
{
row[i] = screen2 + i * CONSOLE_WIDTH;
row[i +CONSOLE_HEIGHT] = screen1 + i * CONSOLE_WIDTH;
}
|
#141374 - Diddl - Mon Sep 24, 2007 8:34 pm
does no one has an idea why this code works only in emul (not on a real NDS)??
#141375 - strager - Mon Sep 24, 2007 8:39 pm
Diddl wrote: |
Code: | // SCREEN & ROW POINTER
screen1 = (u16*)SCREEN_BASE_BLOCK_SUB(31); //sub
screen2 = (u16*)SCREEN_BASE_BLOCK(31); //main
for(i=0; i<CONSOLE_HEIGHT; i++)
{
row[i] = screen2 + i * CONSOLE_WIDTH;
row[i +CONSOLE_HEIGHT] = screen1 + i * CONSOLE_WIDTH;
}
|
|
Where is the row variable coming from? It looks awful suspicious to me, and same goes with how it's used. Perhaps it isn't getting initialized properly?
#141383 - Diddl - Mon Sep 24, 2007 9:13 pm
row variable is for speed purposes, so I don't need to multiply every time I need to calculate a pointer to screen.
and of course i make one big screen from two screens. for my text function lib it appears like one big screen (32 columns * 48 rows).
it works fine in DSmuMe. lower screen works fine on my NDS. but upper screen is only black.
#141386 - GPFerror - Mon Sep 24, 2007 9:53 pm
maybe alpha bit needs to be set ?
Code: |
col1 = RGB15(r,g,b) | BIT(15);
col2 = RGB15(0,0,0) | BIT(15); |
Troy(GPF)
#141412 - tepples - Tue Sep 25, 2007 2:31 am
Alpha bits don't do anything in indexed 2D video on the GBA or DS. I maintain several DS programs that use 4-bit tiled modes: Lockjaw, libfat speed tester, RAC, and memtestARM (which uses the graphic engine from RAC). Nothing disappears when I don't turn on the alpha bit in the palette. Only color index 0 is treated as transparent.
As far as I can tell, in 2D video on the DS, the alpha bit applies only in 16-bit extended rotation backgrounds, where values 0x0000 through 0x7FFF are treated as transparent. Some of the PC-based DS emulators seem to follow the Game Boy Color practice of using the color value of the rearmost transparent pixel when all pixels in the stack are transparent; the DS does not. I haven't done exhaustive tests, but based on what I've seen on the GBA, I'd wager a guess that the DS instead uses the Game Boy Advance practice of always using palette entry 0.
Another thing is to make sure that you actually have VRAM mapped where you think you have VRAM mapped. I had sprites disappear in Lockjaw 0.34 when the libnds video header changed out from under me: it was mapping engine A's sprite VRAM where I wasn't expecting.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#141449 - Diddl - Tue Sep 25, 2007 7:15 pm
Yippee!
It works, I don't really understand what I did. But your advice with vram maybe was right. I have compared my code with other sample code and now it works fine on my NDS.
This is right initialization for BOTH screens:
Code: |
videoSetMode(MODE_0_2D | DISPLAY_BG0_ACTIVE); //sub bg 0 will be used to print text
BG0_CR = BG_MAP_BASE(31);
videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE); //sub bg 0 will be used to print text
SUB_BG0_CR = BG_MAP_BASE(31);
vramSetMainBanks(VRAM_A_MAIN_BG, VRAM_B_LCD, VRAM_C_SUB_BG, VRAM_D_LCD);
// FILL COLOR PALETTE
for(i=0;i<16;i++)
{
switch(i)
{
case 0:
col1 = RGB15(0x1f,0x1f,0); //YEL
col2 = RGB15(0,0,0x1f); //BLUE
break;
case 8:
col1 = RGB15(0x1f,0,0); //
col2 = RGB15(0x1f,0x1f,0x1f); //
break;
default:
c = i&8?0x1f:0x13;
b= i%2 * c;
r=(i/2)%2 * c;
g=(i/4)%2 * c;
col1 = RGB15(r,g,b);
col2 = RGB15(0,0,0);
break;
}
BG_PALETTE_SUB[(i << 4)| 0xf] = col1;
BG_PALETTE[(i << 4)| 0xf] = col1;
BG_PALETTE_SUB[(i << 4)| 0xe] = col2;
BG_PALETTE[(i << 4)| 0xe] = col2;
}
//consoleInitDefault((u16*)SCREEN_BASE_BLOCK_SUB(31), (u16*)CHAR_BASE_BLOCK_SUB(0), 16);
map = (u16*)SCREEN_BASE_BLOCK(31);
charBase = (u16*)CHAR_BASE_BLOCK(0);
bitDepth = 16;
consoleInit((u16*)default_font_bin, charBase, 256, 0, map, CONSOLE_USE_COLOR255, bitDepth);
//consoleClear();
map = (u16*)SCREEN_BASE_BLOCK_SUB(31);
charBase = (u16*)CHAR_BASE_BLOCK_SUB(0);
bitDepth = 16;
consoleInit((u16*)default_font_bin, charBase, 256, 0, map, CONSOLE_USE_COLOR255, bitDepth);
// SCREEN & ROW POINTER
screen1 = (u16*)SCREEN_BASE_BLOCK_SUB(31); //sub
screen2 = (u16*)SCREEN_BASE_BLOCK(31); //main
*screen1 = CharCol('#', COL_WHITE);
*screen2 = CharCol('#', COL_WHITE);
while(1);
|
#141533 - strager - Wed Sep 26, 2007 6:46 pm
Diddl wrote: |
row variable is for speed purposes, so I don't need to multiply every time I need to calculate a pointer to screen.
and of course i make one big screen from two screens. for my text function lib it appears like one big screen (32 columns * 48 rows). |
Try comparing the values in the row array, and compare the data pointed to by those pointers (which I am assuming they are; otherwise it didn't make any sense to me).
You don't lose much speed from the multiply; in reality, gcc compiles that as a shift left by five for the *32.
Eh, just noticed you posted your "solution" that didn't use the row variable. I guess that was what the problem was.
Maybe it would be best if you made a putChar(x, y, c) function for convenience and removing more possibilities of errors in the future.
#141539 - Diddl - Wed Sep 26, 2007 7:19 pm
strager wrote: |
Eh, just noticed you posted your "solution" that didn't use the row variable. I guess that was what the problem was.
Maybe it would be best if you made a putChar(x, y, c) function for convenience and removing more possibilities of errors in the future. |
no, this problem has nothing to do with the row pointers. I reduced the code to
Code: |
*screen1 = CharCol('#', COL_WHITE);
*screen2 = CharCol('#', COL_WHITE);
while(1); |
and changed the initialization code until working.
with old code the # only appears on lower (sub) screen. upper screen was blanc.