Draw image

SGDK only sub forum

Moderator: Stef

Post Reply
orlanrod
Very interested
Posts: 99
Joined: Fri Sep 25, 2015 7:46 pm

Draw image

Post by orlanrod » Tue Sep 29, 2015 12:35 am

I'm having an issue with what i think is corruption with a drawn image's palette. The player is rendered correctly, but when i draw the background it looks corrupt and not using its own palette. Here is the code bellow. I used the example sprite code.

// set all palette
VDP_setPalette(PAL0, bgb_image.palette->data);
VDP_setPalette(PAL2, jason_sprite.palette->data);


// load background

VDP_drawImage(VDP_PLAN_B, &bgb_image, 0, 0);


// init jason sprite
SPR_initSprite(&sprites[0], &jason_sprite, 4, 4, TILE_ATTR(PAL2, TRUE, FALSE, FALSE));
SPR_update(sprites, 1);

// prepare palettes
memcpy(&palette[0], bgb_image.palette->data, 16 * 2);
memcpy(&palette[32], jason_sprite.palette->data, 16 * 2);

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: Draw image

Post by Stef » Tue Sep 29, 2015 9:02 am

How many tiles you reserve for the sprite engine (SPR_init(..) call) ?
Also i don't understand what you are doing with the palette preparation after actually setting them ?

orlanrod
Very interested
Posts: 99
Joined: Fri Sep 25, 2015 7:46 pm

Re: Draw image

Post by orlanrod » Tue Sep 29, 2015 11:38 am

Stef wrote:How many tiles you reserve for the sprite engine (SPR_init(..) call) ?
Also i don't understand what you are doing with the palette preparation after actually setting them ?
It's set to 256, but now i set it to 0 and still nothing. The background image i am trying to draw is 1024x1024

Here is the full main code

#include <genesis.h>
#include <vdp.h>
#include <vdp_pal.h>
#include <gfx.h>

#define ANIM_STANDSIDES 0
#define ANIM_WALKSIDES 1
#define ANIM_SLEEPSIDES 3
#define ANIM_STANDDOWN 4
#define ANIM_WALKDOWN 5
#define ANIM_SLEEPDOWN 6
#define ANIM_STANDUP 7
#define ANIM_WALKUP 8

#define MIN_POSX FIX32(10)
#define MAX_POSX FIX32(400)
#define MIN_POSY FIX32(10)
#define MAX_POSY FIX32(400)



// forward
static void handleInput();
static void joyEvent(u16 joy, u16 changed, u16 state);

static void updateAnim();
static void updateCamera(fix32 x, fix32 y);

// sprites structure
Sprite sprites[2];

fix32 camx;
fix32 camy;
fix32 posx;
fix32 posy;
fix32 movx;
fix32 movy;
s16 xorder;
s16 yorder;
u16 current_anim;


u16 php = 99; //player hp
u16 psp = 0; //player special power.
char str[8];


int main()
{
u16 palette[64];
u16 ind;

// disable interrupt when accessing VDP
SYS_disableInts();
// initialization
VDP_setScreenWidth320();

// init sprites engine
SPR_init(0);

VDP_setPaletteColors(0, palette_black, 64);

// load background
ind = TILE_USERINDEX;
VDP_drawImageEx(BPLAN, &bgb_image, TILE_ATTR_FULL(PAL0, FALSE, FALSE, FALSE, ind), 0, 0, FALSE, TRUE);
ind += bgb_image.tileset->numTile;

// VDP process done, we can re enable interrupts
SYS_enableInts();

camx = -1;
camy = -1;
posx = 150;
posy = 100;
xorder = 0;
yorder = 0;
current_anim = 0;


// init jason sprite
SPR_initSprite(&sprites[0], &jason_sprite, posx, posy, TILE_ATTR(PAL2, TRUE, FALSE, FALSE));
SPR_update(sprites, 1);

// prepare palettes
memcpy(&palette[0], bgb_image.palette->data, 16 * 2);
memcpy(&palette[32], jason_sprite.palette->data, 16 * 2);

// fade in
VDP_fadeIn(0, (3 * 16) - 1, palette, 20, FALSE);

JOY_setEventHandler(joyEvent);

while(TRUE)
{
handleInput();

updateAnim();
updateCamera(camx, camy);


//VDP_drawText("Hello World!", 1, 1);

// update sprites (only one to update here)
SPR_update(sprites, 1);

VDP_waitVSync();
}

return 0;
}

static void updateCamera(fix32 x, fix32 y)
{
fix32 cx = x;
fix32 cy = y;
VDP_setHorizontalScroll(PLAN_B, cx);
VDP_setVerticalScroll(PLAN_B, cy);

u16 value = JOY_readJoypad(JOY_1);
if ((value & BUTTON_RIGHT) && camx > -352) camx -= 1;
if ((value & BUTTON_LEFT) && camx < -1) camx += 1;
if ((value & BUTTON_UP) && camy > -1) camy -= 1;
if ((value & BUTTON_DOWN) && camy < 256) camy += 1;

}

static void updateAnim()
{
if (current_anim == ANIM_WALKSIDES) SPR_setAnim(&sprites[0], ANIM_WALKSIDES);
if (current_anim == ANIM_WALKUP) SPR_setAnim(&sprites[0], ANIM_WALKUP);
if (current_anim == ANIM_WALKDOWN) SPR_setAnim(&sprites[0], ANIM_WALKDOWN);

if (yorder == 0 && xorder == -1) current_anim = ANIM_WALKSIDES;

if (yorder == 0 && xorder == +1) current_anim = ANIM_WALKSIDES;

if (yorder == -1 && xorder == 0) current_anim = ANIM_WALKUP;

if (yorder == +1 && xorder == 0) current_anim = ANIM_WALKDOWN;

if (yorder == 0 && xorder == 0)
{
if (current_anim == ANIM_WALKSIDES) SPR_setAnim(&sprites[0], ANIM_STANDSIDES);
if (current_anim == ANIM_WALKUP) SPR_setAnim(&sprites[0], ANIM_STANDUP);
if (current_anim == ANIM_WALKDOWN) SPR_setAnim(&sprites[0], ANIM_STANDDOWN);
}
}


static void handleInput()
{
u16 value = JOY_readJoypad(JOY_1);

if ((value & BUTTON_RIGHT) && posx < 300 && camx <= -352)
{
posx += 1;
SPR_setPosition(&sprites[0], posx, posy);
}

if ((value & BUTTON_RIGHT) && posx < 150)
{
posx += 1;
SPR_setPosition(&sprites[0], posx, posy);
}

if ((value & BUTTON_RIGHT))
{
SPR_setAttribut(&sprites[0], TILE_ATTR(PAL2,TRUE,FALSE,FALSE));
}

if ((value & BUTTON_LEFT) && posx > 5 && camx >= -1)
{
posx -= 1;
SPR_setPosition(&sprites[0], posx, posy);
}

if ((value & BUTTON_LEFT) && posx > 150)
{
posx -= 1;
SPR_setPosition(&sprites[0], posx, posy);
}

if ((value & BUTTON_LEFT))
{
SPR_setAttribut(&sprites[0], TILE_ATTR(PAL2,TRUE,FALSE,TRUE));
}

if (value & BUTTON_LEFT) xorder = -1;
else if (value & BUTTON_RIGHT) xorder = +1;
else xorder = 0;


if ((value & BUTTON_UP) && posy > 5 && camy >= -1)
{
posy -= 1;
SPR_setPosition(&sprites[0], posx, posy);
}

if ((value & BUTTON_DOWN) && posy < 240 && camy >= 256)
{
posy += 1;
SPR_setPosition(&sprites[0], posx, posy);
}

if (value & BUTTON_UP) yorder = -1;
else if (value & BUTTON_DOWN) yorder = +1;
else yorder = 0;
}

static void joyEvent(u16 joy, u16 changed, u16 state)
{
// START button state changed
if (changed & BUTTON_START)
{

}

}

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: Draw image

Post by Stef » Tue Sep 29, 2015 12:33 pm

Your code is correct, i think the problem comes from your background image which excess the tile capacity in VRAM. The sprite engine will consume 256 tiles by default, leaving about 1200 for the background. If your 1024x1024 image consume more than 1200 different tiles then you're done :-/
Also now i am thinking about it, 1024x1024 is above the plan size (64x64 tiles = 512x512) so that might be your problem.
To handle large image like that you need to first upload the tiles to VRAM :

Code: Select all

ind_tileset = TILE_USERINDEX;
// load image tileset with DMA
VDP_loadTileSet(bgb_image.tileset, ind_tileset, TRUE);
Then load sub part of your image map in the background plan depending the current camera / scrolling position :

Code: Select all

VDP_setMapEx(BPLAN, bgb_image.map, TILE_ATTR_FULL(PAL0, FALSE, FALSE, FALSE, ind_tileset), PlanXPosInTile, PlanYPosInTile, MapXPosInTile, MapYPosInTile, MapWidthInTile, MapHeigthInTile);
Be careful with bgb_image.map, if the map is compressed then the VDP_setMapEx(..) method will unpack it each time so it's better to unpack it first if needed with :

Code: Select all

Map *map = unpackMap(bgb_image.map, NULL);
and use the map variable then :)

orlanrod
Very interested
Posts: 99
Joined: Fri Sep 25, 2015 7:46 pm

Re: Draw image

Post by orlanrod » Wed Sep 30, 2015 8:42 am

Stef wrote:Your code is correct, i think the problem comes from your background image which excess the tile capacity in VRAM. The sprite engine will consume 256 tiles by default, leaving about 1200 for the background. If your 1024x1024 image consume more than 1200 different tiles then you're done :-/
Also now i am thinking about it, 1024x1024 is above the plan size (64x64 tiles = 512x512) so that might be your problem.
To handle large image like that you need to first upload the tiles to VRAM :

Code: Select all

ind_tileset = TILE_USERINDEX;
// load image tileset with DMA
VDP_loadTileSet(bgb_image.tileset, ind_tileset, TRUE);
Then load sub part of your image map in the background plan depending the current camera / scrolling position :

Code: Select all

VDP_setMapEx(BPLAN, bgb_image.map, TILE_ATTR_FULL(PAL0, FALSE, FALSE, FALSE, ind_tileset), PlanXPosInTile, PlanYPosInTile, MapXPosInTile, MapYPosInTile, MapWidthInTile, MapHeigthInTile);
Be careful with bgb_image.map, if the map is compressed then the VDP_setMapEx(..) method will unpack it each time so it's better to unpack it first if needed with :

Code: Select all

Map *map = unpackMap(bgb_image.map, NULL);
and use the map variable then :)
Thanks, that works great. Performance! 8D

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: Draw image

Post by Stef » Wed Sep 30, 2015 1:20 pm

Glad you got it to work :)

orlanrod
Very interested
Posts: 99
Joined: Fri Sep 25, 2015 7:46 pm

Re: Draw image

Post by orlanrod » Wed Sep 30, 2015 6:58 pm

Stef wrote:Glad you got it to work :)
How would i update the map already drawn? Like say, revealing the next tile column, while removing the back tile column if the player moves right. I'm trying to tie it to the player's movement, so it increments/decrements as the player walks.

orlanrod
Very interested
Posts: 99
Joined: Fri Sep 25, 2015 7:46 pm

Re: Draw image

Post by orlanrod » Wed Sep 30, 2015 8:16 pm

Nevermind, i got it working. Thanks.

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: Draw image

Post by Stef » Thu Oct 01, 2015 7:44 am

I would say that you need to handle that part by software and correctly update part of map into the hardware tilemap, that is all up to the game engine and its implementation ;)

orlanrod
Very interested
Posts: 99
Joined: Fri Sep 25, 2015 7:46 pm

Re: Draw image

Post by orlanrod » Mon Oct 05, 2015 4:32 am

It seems the tilemap is not displaying 16+ a few pixels on top of the screen (using Gens emulator) I have the vdp set at 224 height.

int PlanXPosInTile = 0;
int PlanYPosInTile = -3;
int MapXPosInTile = 0;
int MapYPosInTile = 0;
int MapWidthInTile = 40;
int MapHeightInTile = 28;

indb = TILE_USERINDEX;
VDP_loadTileSet(bgb_image.tileset, indb, TRUE);
VDP_setMapEx(BPLAN, map, TILE_ATTR_FULL(PAL0, FALSE, FALSE, FALSE, indb), PlanXPosInTile, PlanYPosInTile, MapXPosInTile, MapYPosInTile, MapWidthInTile, MapHeightInTile);
indb += bgb_image.tileset->numTile;

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: Draw image

Post by Stef » Mon Oct 05, 2015 8:28 am

Do you mean they have background color ? If yes that is just Gens display using the PAL vertical resolution (240) so in NTSC resolution (224) you always have top and bottom blank areas... Of course on a real TV that does not necessary display the same.

orlanrod
Very interested
Posts: 99
Joined: Fri Sep 25, 2015 7:46 pm

Re: Draw image

Post by orlanrod » Mon Oct 05, 2015 3:27 pm

Stef wrote:Do you mean they have background color ? If yes that is just Gens display using the PAL vertical resolution (240) so in NTSC resolution (224) you always have top and bottom blank areas... Of course on a real TV that does not necessary display the same.
Yeah, i am using NTSC.

I was thinking of changing the tilemap ypos to -1 but that causes corruption for some reason. It does not if i do +1, but the map is pushed further up the screen. Trying to push down the tilemap so it displays the remaining 16+ pixels.

ronin68k
Interested
Posts: 29
Joined: Mon Nov 02, 2015 5:28 am
Location: Krasnodar, Russia

Re: Draw image

Post by ronin68k » Thu Sep 29, 2016 10:03 pm

Hi! Talking about image.tileset->numTile, can i get image tileset from array?
For example, we have an array of BG images...
const void ImageArray[]=
{
&image0,
&image1,
&image2,
&image3
};


i can use ImageArray with VDP_drawImage and this will work fine.

But now, i should tell the program, what tileset to use.
ind += ImageArray.tileset->numTile just won't work, cuz tileset is not a structure thing.

Is there a way to solve this problem? So i won't have to write imageX.tileset->numTile for each image.
Thank you! :*

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: Draw image

Post by Stef » Thu Sep 29, 2016 10:17 pm

I don't get it: if you have an array of BG iamges then you should declare the array that way:

Code: Select all

const [b]Image[/b] ImageArray[]=
{
&image0,
&image1,
&image2,
&image3
};
So you could use the normal tileset structure inside.

ronin68k
Interested
Posts: 29
Joined: Mon Nov 02, 2015 5:28 am
Location: Krasnodar, Russia

Re: Draw image

Post by ronin68k » Thu Sep 29, 2016 11:08 pm

Hi, Stef! Thanks for the reply. After some time, i got it to work.
I made 2 arrays, one for VDP_drawImage - const * Arr_images[]
and (thank you for advice) another one for tileset - const Image Arr_imageMaps[].
Somehow, rendering more than 1 picture causes glitches to second one... weird, but thanks anyway :)

Post Reply