A way to switch palette colors using sgdk without asm
Moderator: Stef
-
- Very interested
- Posts: 158
- Joined: Sat May 12, 2012 7:37 pm
- Location: Ukraine
A way to switch palette colors using sgdk without asm
Do anyone know or maybe already tried:
Is it possible to change palette colors in hblank without asm injection? Just using sgdk.
I would like to implement high color images and don't want to dirty C code with asm injection.
Thanks a lot guys for any help.
P.S. If it is not possible the asm injection code (performing palette dma transfer) would be very appreciated.
Is it possible to change palette colors in hblank without asm injection? Just using sgdk.
I would like to implement high color images and don't want to dirty C code with asm injection.
Thanks a lot guys for any help.
P.S. If it is not possible the asm injection code (performing palette dma transfer) would be very appreciated.
-
- Very interested
- Posts: 3131
- Joined: Thu Nov 30, 2006 9:46 pm
- Location: France - Sevres
- Contact:
I forgot to mention the DMA in my PM which is the best solution for what you want to do :p
There is a method in SGDK : but in your case you cannot use it as you require more control and speed.
Also instead of using H Interrupt to update your palette i think you should use the HV counter in your main loop.
What you can do is prepare your DMA then waiting the good moment to start it.
Prepare the DMA :
Wait end of active period / start of blanking :
Here VLine correspond to the scanline where you want to change the palette and HEndActivePos the H position for end of active period (i am not sure about the number to use here and anyway you should tweak it to get best result).
then just trigger DMA in a single instruction :
That should do it...
There is a method in SGDK :
Code: Select all
VDP_doCRamDMA(from, to, len)
Also instead of using H Interrupt to update your palette i think you should use the HV counter in your main loop.
What you can do is prepare your DMA then waiting the good moment to start it.
Prepare the DMA :
Code: Select all
vu16 *pw;
vu32 *pl;
u32 vdp_data;
u16 hv_maxpos;
VDP_setAutoInc(2);
pw = (u16 *) GFX_CTRL_PORT;
// Setup DMA length (in word here)
len >>= 1;
*pw = 0x9300 + (len & 0xff);
newlen >>= 8;
*pw = 0x9400 + (len & 0xff);
// Setup DMA address
from >>= 1;
*pw = 0x9500 + (from & 0xff);
from >>= 8;
*pw = 0x9600 + (from & 0xff);
from >>= 8;
*pw = 0x9700 + (from & 0x7f);
// prepare DMA write
pl = (u32 *) GFX_CTRL_PORT;
vdp_data = GFX_DMA_CRAM_ADDR(adr)
Code: Select all
hv_maxpos = ((VLine - 1) << 8) | HEndActivePos);
while (GET_HVCOUNTER < hv_maxpos);
then just trigger DMA in a single instruction :
Code: Select all
*pl = vdp_data;
-
- Very interested
- Posts: 158
- Joined: Sat May 12, 2012 7:37 pm
- Location: Ukraine
Thanks a lot Stef.
It is bad but yet I am not such a cool mega drive coder to assemble it all together to make it work.
I can just stare at it and hope that it works - at least theoretically.
Maybe at some point in the future I will make it work. I hope the near future.
It is hard not to dive in assembly mess deeply and to get something special effects like the high color.
It is bad but yet I am not such a cool mega drive coder to assemble it all together to make it work.
I can just stare at it and hope that it works - at least theoretically.
Maybe at some point in the future I will make it work. I hope the near future.
It is hard not to dive in assembly mess deeply and to get something special effects like the high color.
-
- Very interested
- Posts: 3131
- Joined: Thu Nov 30, 2006 9:46 pm
- Location: France - Sevres
- Contact:
Maybe there are some mistakes in my code, i didn't tested it because i can't do it right now but at least you have the idea !greatkreator wrote:Thanks a lot Stef.
It is bad but yet I am not such a cool mega drive coder to assemble it all together to make it work.
I can just stare at it and hope that it works - at least theoretically.
Maybe at some point in the future I will make it work. I hope the near future.
It is hard not to dive in assembly mess deeply and to get something special effects like the high color.
Debugging code is not easy on megadrive, you can use GensKMod and use the KDebug features to trace your execution.
-
- Very interested
- Posts: 158
- Joined: Sat May 12, 2012 7:37 pm
- Location: Ukraine
I use vcounter and fill the palette using dma.
Original image:
The image I am able to reproduce so far (total 54 colours, 16 colours each tile line):
I couldn't use your help fully Stef. I cannot comprehend it yet.
Original image:
The image I am able to reproduce so far (total 54 colours, 16 colours each tile line):
Code: Select all
#include <genesis.h>
extern u16 palette_data[];
extern u16 index_data[];
u16 i;
void hinter();
int main() {
VDP_init();
VDP_setScreenWidth320();
VDP_setScreenHeight224();
VDP_setPlanSize(64, 64);
VDP_loadTileData(index_data, 1, 1120, 1);
setHBlankCallback(hinter);
VDP_setHIntCounter(8);
VDP_setHInterrupt(1);
for (;;) {
VDP_fillTileMapRectInc(APLAN, 1, 0, 0, 40, 28);
VDP_waitVSync();
}
return 0;
}
void hinter() {
u32 from = palette_data + ((GET_VCOUNTER >> 3) << 4);
VDP_setAutoInc(2);
vu16* pw = (u16*) GFX_CTRL_PORT;
*pw = 0x9300 + 16;
*pw = 0x9400 + 0;
*pw = 0x9500 + ((from >> 1) & 0xff);
*pw = 0x9600 + ((from >> 9) & 0xff);
*pw = 0x9700 + ((from >> 17) & 0x7f);
*((u32*)GFX_CTRL_PORT) = GFX_DMA_CRAM_ADDR(PAL0);
}
-
- Very interested
- Posts: 3131
- Joined: Thu Nov 30, 2006 9:46 pm
- Location: France - Sevres
- Contact:
The original image looks greatgreatkreator wrote:I use vcounter and fill the palette using dma.
Original image:
The image I am able to reproduce so far (total 54 colours, 16 colours each tile line):
...
I couldn't use your help fully Stef. I cannot comprehend it yet.
Your code is simple and "theoretically" nice but there are some small mistakes :
First you should set HIntCounter to 7 and not 8 if you want H-Int to happen each 8 scanline (they happen each 9 scanlines with your code).
Something sure is that some cpu cycles will be spent before CRAM DMA happen so your DMA won't really start at line 8 (for instance) but at line 10, this is another problem...
Another problem is that you are doing this :
Code: Select all
VDP_fillTileMapRectInc(APLAN, 1, 0, 0, 40, 28);
That is a big problem as your H-Int code will execute at same time and mess the VDP state so your writes to VDP will become totally out of control and corrupted...
You should never modify VDP data in your main loop if you do it in Interrupt callback and vice versa.
So what you have to do is calling the fillTile method only once at beginning then you only do work on the int handler.
Something similar to that :
Code: Select all
#include <genesis.h>
extern u16 palette_data[];
extern u16 index_data[];
void hinter();
int main() {
VDP_init();
VDP_setScreenWidth320();
VDP_setScreenHeight224();
VDP_setPlanSize(64, 64);
VDP_loadTileData(index_data, 1, 1120, 1);
VDP_fillTileMapRectInc(APLAN, 1, 0, 0, 40, 28);
setHBlankCallback(hinter);
VDP_setHIntCounter(8);
VDP_setHInterrupt(1);
for (;;) {
VDP_waitVSync();
}
return 0;
}
void hinter() {
VDP_doCRamDMA(palette_data + ((GET_VCOUNTER >> 3) << 4), 0, 16);
}
-
- Very interested
- Posts: 3131
- Joined: Thu Nov 30, 2006 9:46 pm
- Location: France - Sevres
- Contact:
By the way, if your original image is only 54 colors then you don't even need the palette change trick. You can simply use a background to display the 16 first colors, the second one for 16 more colors and then sprites for the missing ones... but now i'm telling it, i'm not sure that is easier than refreshing palette during hblank :p
-
- Very interested
- Posts: 2984
- Joined: Fri Aug 17, 2007 9:33 pm
Do like I did for my 512 color demo - set the horizontal scroll for each line, then set the entries in the name table so that the scroll makes it select a different palette for each line.Stef wrote:By the way, if your original image is only 54 colors then you don't even need the palette change trick. You can simply use a background to display the 16 first colors, the second one for 16 more colors and then sprites for the missing ones... but now i'm telling it, i'm not sure that is easier than refreshing palette during hblank :p
-
- Very interested
- Posts: 158
- Joined: Sat May 12, 2012 7:37 pm
- Location: Ukraine
Actually it is not a colorful enough image - theoretically about 400 colors may be used. The method you are talking about has substantial disadvantage: too much tiles are used - thus fullscreen image cannot be used. Of course you can do tricks to re-use tiles but anyway only 45-50 colors can be shown.Stef wrote:By the way, if your original image is only 54 colors then you don't even need the palette change trick. You can simply use a background to display the 16 first colors, the second one for 16 more colors and then sprites for the missing ones... but now i'm telling it, i'm not sure that is easier than refreshing palette during hblank :p
By the way my current version works only on a emulator.
The real hardware rejects it. I see few blinking lines only.
I really think about not walking on the edge. I am too afraid that my "masterpiece" can not work on some devices even if I would test it on my very bad Chinese clone well. That is why it is likely i would choose the second stable method you was talking about Stef.
-
- Very interested
- Posts: 158
- Joined: Sat May 12, 2012 7:37 pm
- Location: Ukraine
Am I right you are talking about the images that based on "RGB-like" lines?Chilly Willy wrote:Do like I did for my 512 color demo - set the horizontal scroll for each line, then set the entries in the name table so that the scroll makes it select a different palette for each line.Stef wrote:By the way, if your original image is only 54 colors then you don't even need the palette change trick. You can simply use a background to display the 16 first colors, the second one for 16 more colors and then sprites for the missing ones... but now i'm telling it, i'm not sure that is easier than refreshing palette during hblank :p
If so they look a little "special/strange" to me. Don't they?
I really would like to achieve old-classic-each-pixel-own-color result.
The very fast palette switch walks on the edge. I find it too risky.
I am inclined to use the layered stable way but not in full screen.
However if you Chilly Willy or you Stef have any ideas please tell me.
Thanks guys.
-
- Very interested
- Posts: 3131
- Joined: Thu Nov 30, 2006 9:46 pm
- Location: France - Sevres
- Contact:
True, that was just for a ~50 colors only image, if you want more, you'll have to use palette update on scanline.Stef wrote: Actually it is not a colorful enough image - theoretically about 400 colors may be used. The method you are talking about has substantial disadvantage: too much tiles are used - thus fullscreen image cannot be used. Of course you can do tricks to re-use tiles but anyway only 45-50 colors can be shown.
What version are you speaking about ? Did you tried to modify as i told you ? If you speak about your version, it just cannot work on real hardware as VDP writes are messed...By the way my current version works only on a emulator.
The real hardware rejects it. I see few blinking lines only.
Having that sort of effect working on real hardware is always more tricky than on emulator, i don't know how your chinese clone is accurate compared to real thing but indeed you may observe differences...I really think about not walking on the edge. I am too afraid that my "masterpiece" can not work on some devices even if I would test it on my very bad Chinese clone well. That is why it is likely i would choose the second stable method you was talking about Stef.
For the second method, i can't really give you more informations that i already did... You have almost all the code. Just need some timing tweaks.
-
- Very interested
- Posts: 2984
- Joined: Fri Aug 17, 2007 9:33 pm
Yes, it uses interleaved R, G, and B only pixels to do a direct color image. It's actually not too bad... better than I thought it would be. However, it is the technique of how to change palettes I thought you would be interested in, not the direct color rendering.greatkreator wrote:Am I right you are talking about the images that based on "RGB-like" lines?Chilly Willy wrote:Do like I did for my 512 color demo - set the horizontal scroll for each line, then set the entries in the name table so that the scroll makes it select a different palette for each line.Stef wrote:By the way, if your original image is only 54 colors then you don't even need the palette change trick. You can simply use a background to display the 16 first colors, the second one for 16 more colors and then sprites for the missing ones... but now i'm telling it, i'm not sure that is easier than refreshing palette during hblank :p
If so they look a little "special/strange" to me. Don't they?
I really would like to achieve old-classic-each-pixel-own-color result.
It's not a very fast palette switch - the palette entries are all set well ahead of time, and in my case, never change. Look at it this way:The very fast palette switch walks on the edge. I find it too risky.
I am inclined to use the layered stable way but not in full screen.
128x32 name table
Code: Select all
---------------------------------------------------------------
| | | | |
| 40x32 | 40x32 | 40x32 | |
| palette 0 | palette 1 | palette 2 | |
| | | | |
---------------------------------------------------------------
The extra 8 entries in the table could be put between the three sections to make scrolling possible, but a static display is as easy as you see above.
-
- Very interested
- Posts: 158
- Joined: Sat May 12, 2012 7:37 pm
- Location: Ukraine
-
- Very interested
- Posts: 2984
- Joined: Fri Aug 17, 2007 9:33 pm
Yeah, the map isn't wide enough to make four screens in 40 cell mode, just three and some change. I only needed two for my direct color mode. If you switched to 32 cell mode, then the map IS wide enough for all four palettes, but then you have to adjust everything for 256 wide instead of 320 wide.greatkreator wrote:Thanks Chilly Willy for the technique.
It is really interesting and elegant.
It has its own shortcomings(i mean less total color number per image than the rapid palette switch) but I will try to employ it in my project.
That's the "fun" of old consoles - trying to find the best way around the limits on what you can do.
-
- Very interested
- Posts: 158
- Joined: Sat May 12, 2012 7:37 pm
- Location: Ukraine