Page 6 of 10
Posted: Fri Feb 21, 2014 10:02 am
by Stef
SGDK only support 4bit or 8bit PNG right now.
I could add support for 2bit or 1bit later but anyway i will have to convert to 4bpp internally. Even if your PNG has only two colors you need to save it as 4bpp PNG at least, some tools authorize that, others not :-/ You may try to manually add some unused colors in the palette to force it.
Posted: Fri Feb 21, 2014 10:08 am
by matteus
Stef wrote:SGDK only support 4bit or 8bit PNG right now.
I could add support for 2bit or 1bit later but anyway i will have to convert to 4bpp internally. Even if your PNG has only two colors you need to save it as 4bpp PNG at least, some tools authorize that, others not :-/ You may try to manually add some unused colors in the palette to force it.
I tried 2bit and now understand why it wasn't working

Cool I'll add a 8x8 cube of additional colours to the bottom corner of each single colour animation frame for now.
I could just do the fade in software via a palette increment but I want to keep it simple for now!
I hope you add 2bit and 1bit support soon, I know its ridiculous really given you could just do a background colour but I need it haha
Posted: Fri Feb 21, 2014 12:20 pm
by matteus
I have a question. The code example below is obviously fictional but say I had a series of images in res each one was a frame number: frame1, frame2, frame3, frame4, etc.
Is there a way I can do a for loop for each frame without having to manually enter the code over and over again?
Code: Select all
for (i = 0; i < 10; i++)
{
// load background
ind = TILE_USERINDEX;
// set present plan
int setPlan = 0; // 0 = PLAN A, 1 = PLAN B
if setPlan == 0) {
//set frameI to equal the frame within the loop
&frameI = frame + i
// draw image
VDP_drawImageEx(APLAN, &frameI, TILE_ATTR_FULL(PAL0, FALSE, FALSE, FALSE, ind), 22, 5, FALSE, TRUE);
ind += frameI.tileset->numTile;
// set pallettes
VDP_setPalette(0, frameI.palette->data);
setPlan = 1;
} else {
// draw image
VDP_drawImageEx(BPLAN, &frameI, TILE_ATTR_FULL(PAL1, FALSE, FALSE, FALSE, ind), 22, 5, FALSE, TRUE);
ind += frameI.tileset->numTile;
// set pallettes
VDP_setPalette(1, frameI.palette->data);
setPlan = 0;
}
// wait
waitTick(150);
}
I could create a method to make each call but I'd prefer a nice loop.
Posted: Fri Feb 21, 2014 1:05 pm
by Stef
You can use a const array of image pointers:
Code: Select all
const Image *images[NUM_IMAGE] = {
&image1,
&image2,
&image3,
&image4,
...
}
then do:
Code: Select all
for(i = 0; i < NUM_IMAGE; i++)
{
VDP_drawImageEx(APLAN, images[i], TILE_ATTR_FULL(PAL0, FALSE, FALSE, FALSE, ind), 22, 5, FALSE, TRUE);
...
}
Posted: Fri Feb 21, 2014 1:14 pm
by matteus
Stef wrote:You can use a const array of image pointers:
Code: Select all
const Image *images[NUM_IMAGE] = {
&image1,
&image2,
&image3,
&image4,
...
}
then do:
Code: Select all
for(i = 0; i < NUM_IMAGE; i++)
{
VDP_drawImageEx(APLAN, images[i], TILE_ATTR_FULL(PAL0, FALSE, FALSE, FALSE, ind), 22, 5, FALSE, TRUE);
...
}
I'm confused we pass a pointer to the drawImageEx method but directly reference things in the main

I'm guessing this is a memory management thing
Would:
Code: Select all
for(i = 0; i < NUM_IMAGE; i++)
{
Image currentImage = images[i]
VDP_drawImageEx(APLAN, images[i], TILE_ATTR_FULL(PAL0, FALSE, FALSE, FALSE, ind), 22, 5, FALSE, TRUE);
ind += currentImage.tileset->numTile;
// set pallettes
VDP_setPalette(1, currentImage.palette->data);
}
or
Code: Select all
for(i = 0; i < NUM_IMAGE; i++)
{
VDP_drawImageEx(APLAN, images[i], TILE_ATTR_FULL(PAL0, FALSE, FALSE, FALSE, ind), 22, 5, FALSE, TRUE);
ind += images[i].tileset->numTile;
// set pallettes
VDP_setPalette(1, images[i].palette->data);
}
Work?
Posted: Fri Feb 21, 2014 1:24 pm
by matteus
Silly me I remember you saying in theory all I need is that one line for things to work >_< I'll give it a go later!
Posted: Fri Feb 21, 2014 4:13 pm
by Stef
1 line to display a single image yeah.
Not to do an animation :p
I forgot about the palette change, you have to keep the pal info in a variable.
So you can do :
to switch palette at each frame.
This should work :
Code: Select all
pal = PAL0;
ypos = 0;
for(i = 0; i < NUM_IMAGE; i++)
{
u16 nextypos = ypos ^ 0x20;
VDP_setVerticalScroll(APLAN, vpos);
VDP_drawImageEx(APLAN, images[i], TILE_ATTR_FULL(pal, FALSE, FALSE, FALSE, ind), 22, vpos + 5, TRUE, TRUE);
ind += images[i]->tileset->numTile;
pal ^= 1;
ypos = nextypos;
}
Problems you are talking about now is more C related programming issues that megadrive programming itself.
Posted: Fri Feb 21, 2014 4:23 pm
by matteus
Stef wrote:1 line to display a single image yeah.
Not to do an animation :p
I forgot about the palette change, you have to keep the pal info in a variable.
So you can do :
to switch palette at each frame.
This should work :
Code: Select all
pal = PAL0;
for(i = 0; i < NUM_IMAGE; i++)
{
VDP_drawImageEx(APLAN, images[i], TILE_ATTR_FULL(pal, FALSE, FALSE, FALSE, ind), 22, 5, TRUE, TRUE);
ind += images[i]->tileset->numTile;
pal ^= 1;
}
Problems you are talking about now is more C related programming issues that megadrive programming itself.
Haha so my drawImageEx technique is frowned upon for animation?

I just want to get something up and running and then I'll switch to using the scrolling pane buffer method using a similar loop

Posted: Fri Feb 21, 2014 4:47 pm
by Stef
oh i again forgot something, indeed the scrolling stuff is missing...
Here is the complete code :
Code: Select all
pal = PAL0;
ypos = 0;
for(i = 0; i < NUM_IMAGE; i++)
{
u16 nextypos = ypos ^ 0x20;
VDP_setVerticalScroll(APLAN, vpos);
VDP_drawImageEx(APLAN, images[i], TILE_ATTR_FULL(pal, FALSE, FALSE, FALSE, ind), 22, vpos + 5, TRUE, TRUE);
ind += images[i]->tileset->numTile;
pal ^= 1;
ypos = nextypos;
}
I used vertical scroll but the idea is the same.
Posted: Fri Feb 21, 2014 4:58 pm
by matteus
Stef wrote:oh i again forgot something, indeed the scrolling stuff is missing...
Here is the complete code :
Code: Select all
pal = PAL0;
ypos = 0;
for(i = 0; i < NUM_IMAGE; i++)
{
u16 nextypos = ypos ^ 0x20;
VDP_setVerticalScroll(APLAN, vpos);
VDP_drawImageEx(APLAN, images[i], TILE_ATTR_FULL(pal, FALSE, FALSE, FALSE, ind), 22, vpos + 5, TRUE, TRUE);
ind += images[i]->tileset->numTile;
pal ^= 1;
ypos = nextypos;
}
I used vertical scroll but the idea is the same.
ha-ha oh wow thank you!

You do know once I've figured out how to do all this I'll be moving onto learning about sprites

Posted: Fri Feb 21, 2014 5:55 pm
by Chilly Willy
matteus wrote:matteus wrote:I'm getting an new error when processing the pngs:
"1 bpp PNG not supported"
So by optimising my PNGS to be less than 16 colours have I shot myself in the foot?
Pretty much. Since 16 color is the only pixel mode on the MD, it's the only format supported.

Posted: Fri Feb 21, 2014 9:00 pm
by matteus
Video update
https://www.youtube.com/watch?v=tDjrtof ... ata_player
Updated with code
I've got nasty background flicker I'm guessing its to do with the palette changing every frame and the background colour being wired into it?
Any suggestions?
Posted: Sun Feb 23, 2014 6:38 pm
by matteus
So everything goes fine until I hit frame 36. I repeated frame 36 to see it had a problem but found none. Is it possible I'm running out of VRAM or something? and if so how'd I clear the vram out during the loop to have it successfully work?
Code: Select all
#include <genesis.h>
#include "gfx.h"
#include "music.h"
int main()
{
// initialization
VDP_setScreenWidth320();
const Image *images[46] = {
&frame1,
&frame2,
&frame3,
&frame4,
&frame5,
&frame6,
&frame7,
&frame8,
&frame9,
&frame10,
&frame11,
&frame12,
&frame13,
&frame14,
&frame15,
&frame16,
&frame17,
&frame18,
&frame19,
&frame20,
&frame21,
&frame22,
&frame23,
&frame24,
&frame25,
&frame26,
&frame27,
&frame28,
&frame29,
&frame30,
&frame31,
&frame32,
&frame33,
&frame34,
&frame35,
&frame36,
&frame36,
&frame36,
&frame36,
&frame36,
&frame36,
&frame36,
&frame36,
&frame36,
&frame36,
&frame36,
};
u16 ind;
// music
//SND_startPlay_PCM(thundercats_music, sizeof(thundercats_music), SOUND_RATE_32000, SOUND_PAN_CENTER, FALSE);
u16 i = 0;
u16 pal = PAL0;
u16 ypos = 0;
u16 vpos = 0;
ind += images[0]->tileset->numTile;
VDP_setBackgroundColor(0);
for(i = 0; i < 46; i++)
{
u16 nextypos = ypos ^ 0x20;
VDP_setVerticalScroll(APLAN, vpos);
VDP_drawImageEx(APLAN, images[i], TILE_ATTR_FULL(pal, FALSE, FALSE, FALSE, ind), 6, vpos + 4, TRUE, TRUE);
ind += images[i]->tileset->numTile;
pal ^= 1;
ypos = nextypos;
waitTick(50);
}
while(1)
{
VDP_waitVSync();
}
return 0;
}
Posted: Mon Feb 24, 2014 12:32 am
by matteus
Code: Select all
if ((ind + images[i]->tileset->numTile) > 1310) {
ind = images[i]->tileset->numTile;
} else {
ind += images[i]->tileset->numTile;
}
makeshift fix for now lol

Posted: Mon Feb 24, 2014 8:57 am
by Stef
Exactly ! you were just running out of VRAM.
A nasty fix is just to roll over VRAM, when you rise the memory limit just restart to TILE_USERINDEX (more or less what you did).