Hik's SGDK Experiments

SGDK only sub forum

Moderator: Stef

Hik
Very interested
Posts: 68
Joined: Thu Jul 30, 2015 11:39 pm
Location: Iceland

Hik's SGDK Experiments

Post by Hik » Sun Sep 06, 2015 6:35 pm

Here's my first working project;

sega_logo-a1.png

gfx.res

Code: Select all

IMAGE sega_logo_image "sega_logo-a1.png" -1
gfx.h

Code: Select all

#ifndef _GFX_H_
#define _GFX_H_

extern const Image sega_logo_image;

#endif // _GFX_H_
main.c

Code: Select all

#include <genesis.h>
#include "gfx.h"

//Sets default values for VDP register
//Cleans video RAM
//Loads 4 default palettes ; Grey, Red, Green and Blue
//Loads a default font for text print need
//Initializes input handling
//Resets sound and music
//Loads a default sound driver

int main( )
{
	// Disable interrupts when accessing VDP
    SYS_disableInts();
    // Initialization
    VDP_setScreenWidth320();
	VDP_setScreenHeight240();
	// Define variables
	u16 palette[64];
    u16 ind = TILE_USERINDEX;
	// Load image
    VDP_drawImageEx(APLAN, &sega_logo_image, TILE_ATTR_FULL(PAL0, FALSE, FALSE, FALSE, ind), 14, 11, FALSE, TRUE);
    ind += sega_logo_image.tileset->numTile;
	// Prepare palettes
    memcpy(&palette[16], sega_logo_image.palette->data, 16 * 2);
	VDP_setPalette(0, sega_logo_image.palette->data);
	//VDP process done - re-enable interrupts
	SYS_enableInts();

    while(1)
    {
		//Wait for screen refresh
        VDP_waitVSync();
    }
    return 0;
}
I'm starting off with simple stuff. The goal of this project was to display the sega logo like it appears at the start of most MD/Genesis games.
The tutorials were out of date so I had to go through the forum and SGDK samples to find the bits and pieces I needed to get it to work.
My biggest obstacle with this project was to get the palette to work. I decided to share my code so as to make things easier for new developers.
Upon running this to generate a rom you'll notice that the logo has no animation yet. I did get some animation ,but the images got messed up.
I think it has something to do with the tile arrangement or indexing. The frames are also displaying letters in between the image tiles.

Adding some text for testing purposes;

Code: Select all

//Writes "Test" above the sega logo image
VDP_setTextPalette(PAL2); //PAL0 = Grey/Custom ,PAL1 = Red ,PAL2 = Green ,PAL3 = Blue
VDP_drawText("Test", 14, 9);
Here's the code for the animation; (this code may have some issues)

gfx.res

Code: Select all

IMAGE frame1 "sega_anim-1.png" -1
IMAGE frame2 "sega_anim-2.png" -1
IMAGE frame3 "sega_anim-3.png" -1
IMAGE frame4 "sega_anim-4.png" -1
IMAGE frame5 "sega_anim-5.png" -1
IMAGE frame6 "sega_anim-6.png" -1
IMAGE frame7 "sega_anim-7.png" -1
IMAGE frame8 "sega_anim-8.png" -1
IMAGE frame9 "sega_anim-9.png" -1
IMAGE frame10 "sega_anim-10.png" -1
IMAGE frame11 "sega_anim-11.png" -1
IMAGE frame12 "sega_anim-12.png" -1
IMAGE frame13 "sega_anim-13.png" -1
IMAGE frame14 "sega_anim-14.png" -1
IMAGE frame15 "sega_anim-15.png" -1
IMAGE frame16 "sega_anim-16.png" -1
gfx.h

Code: Select all

#ifndef _GFX_H_
#define _GFX_H_

extern const Image frame1;
extern const Image frame2;
extern const Image frame3;
extern const Image frame4;
extern const Image frame5;
extern const Image frame6;
extern const Image frame7;
extern const Image frame8;
extern const Image frame9;
extern const Image frame10;
extern const Image frame11;
extern const Image frame12;
extern const Image frame13;
extern const Image frame14;
extern const Image frame15;
extern const Image frame16;

#endif // _GFX_H_
main.c

Code: Select all

#include <genesis.h>
#include "gfx.h"

//Sets default values for VDP register
//Cleans video RAM
//Loads 4 default palettes ; Grey, Red, Green and Blue
//Loads a default font for text print need
//Initializes input handling
//Resets sound and music
//Loads a default sound driver 
int main( )
{
	// Disable interrupts when accessing VDP
    SYS_disableInts();
    // Initialization
    VDP_setScreenWidth320();
	VDP_setScreenHeight240();
	// Load animation frames into an array
	const Image *images[16] = 
	{
      &frame1,
      &frame2,
      &frame3,
      &frame4,
      &frame5,
      &frame6,
      &frame7,
      &frame8,
      &frame9,
      &frame10,
      &frame11,
      &frame12,
      &frame13,
      &frame14,
      &frame15,
      &frame16
	};
	// Define variables
	u16 ind = TILE_USERINDEX;
	u16 i = 0;
	u16 pal = PAL0;
    u16 vpos = 0; //Vpos
    char str[8]; //
    u16 newInd = ind;
    u16 maxInd = newInd + 1080;
    intToStr(ind, str, 1); //
	VDP_setTextPlan(PLAN_A);
    VDP_drawText(str, 0, 0);
	
	//Animation
	for(i = 0; i < 16; i++)
	{
		Image *img = images[i]; //Pointer warning
        // Number of tiles for the current image
        u16 numTile = img->tileset->numTile;
		// Not enough VRAM space for the current image? Reset the index
        if ((ind + numTile) >= maxInd) 
		{
			ind = newInd;
		}
        u16 nextvpos = vpos ^ 0x20; //Vertical position fix
        VDP_drawImageEx(BPLAN, images[i], TILE_ATTR_FULL(pal, FALSE, FALSE, FALSE, ind), 14, vpos + 11, TRUE, TRUE);
		// Move to new image
        VDP_waitVSync();
        VDP_setVerticalScroll(PLAN_B, nextvpos * 8); //Vpos
			
		ind +=  images[i]->tileset->numTile;
        pal ^= 1;
        //waitTick(10);
		vpos = nextvpos; //Vpos
        waitTick(100);
        //ypos = nextypos;
	}	
	
	VDP_setTextPalette(PAL2);
	VDP_drawText("Test", 14, 9);

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

    while(1)
    {
	//Wait for screen refresh
        VDP_waitVSync();
    }
    return 0;
}
Last edited by Hik on Tue Sep 08, 2015 7:33 pm, edited 1 time in total.

matteus
Very interested
Posts: 336
Joined: Mon Feb 04, 2008 1:41 pm

Re: Hik's SGDK Experiments

Post by matteus » Mon Sep 07, 2015 9:49 am

Nice job! You could have done this as a sprite I think :)

Hik
Very interested
Posts: 68
Joined: Thu Jul 30, 2015 11:39 pm
Location: Iceland

Re: Hik's SGDK Experiments

Post by Hik » Mon Sep 07, 2015 12:12 pm

Does that work better? I thought sprites were mostly just used for objects moving on the screen ,like projectiles and stuff?
I'm still not sure what's causing the tiles to get shifted out of place ,they all stay within the area the image should appear in
but then there are these white letters in between. It starts off with fewer tiles visible and then adds in more visible tiles.

Hik
Very interested
Posts: 68
Joined: Thu Jul 30, 2015 11:39 pm
Location: Iceland

Re: Hik's SGDK Experiments

Post by Hik » Mon Sep 07, 2015 9:16 pm

I've changed the code to use a sprite instead of using the VDP_drawImageEx ,but I still haven't gotten the animation to work.
The sprite displays correctly in the right place so it looks the same as before. I used a spritesheet made from the 16 frames.
It only shows the first frame. Does the spritesheet image need animation information integrated into it for it to work?

Here's the updated code ;

gfx.res

Code: Select all

SPRITE sega_logo_sprite "sega_logo-spritesheet.png" 13 4 -1 30
gfx.h

Code: Select all

#ifndef _GFX_H_
#define _GFX_H_

#define ANIM_LOGO      0

extern SpriteDefinition sega_logo_sprite;

#endif // _GFX_H_
main.c

Code: Select all

#include <genesis.h>
#include "gfx.h"

//Sets default values for VDP register
//Cleans video RAM
//Loads 4 default palettes ; Grey, Red, Green and Blue
//Loads a default font for text print need
//Initializes input handling
//Resets sound and music
//Loads a default sound driver

// Sprite structure
Sprite sprites[2];

int main( )
{
	// Define variables
	u16 posx = 0x6F;
	u16 posy = 0x58;
	u16 palette[64];
	u16 ind;
	
	// Disable interrupts when accessing VDP
    SYS_disableInts();
    // Initialization
    VDP_setScreenWidth320();
	VDP_setScreenHeight240();
	// Init sprites engine
    SPR_init(256);

	// Init logo sprite
	ind = TILE_USERINDEX;
    SPR_initSprite(&sprites[0], &sega_logo_sprite, posx, posy, TILE_ATTR(PAL0, TRUE, FALSE, FALSE));
    SPR_update(sprites, 1);
	// Prepare palettes
	memcpy(&palette[16], sega_logo_sprite.palette->data, 16 * 2);
	VDP_setPalette(0, sega_logo_sprite.palette->data);
	//Animation
	SPR_setAnim(&sprites[0], ANIM_LOGO);
	
	VDP_setTextPalette(PAL2);
	VDP_drawText("Test", 14, 9);

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

    while(1)
    {
		//Wait for screen refresh
        VDP_waitVSync();
    }
    return 0;
}
Last edited by Hik on Tue Sep 08, 2015 7:33 pm, edited 1 time in total.

matteus
Very interested
Posts: 336
Joined: Mon Feb 04, 2008 1:41 pm

Re: Hik's SGDK Experiments

Post by matteus » Mon Sep 07, 2015 11:13 pm

Code: Select all

SPR_setAnim(&sprites[0], ANIM_LOGO);
    while(TRUE)
    {
            SPR_nextFrame(&sprites[0]);
            SPR_update(sprites, 1);
    }

Hik
Very interested
Posts: 68
Joined: Thu Jul 30, 2015 11:39 pm
Location: Iceland

Re: Hik's SGDK Experiments

Post by Hik » Tue Sep 08, 2015 12:25 am

Thanks ,that's what I was missing. The code works now ;

main.c

Code: Select all

#include <genesis.h>
#include "gfx.h"

//Sets default values for VDP register
//Cleans video RAM
//Loads 4 default palettes ; Grey, Red, Green and Blue
//Loads a default font for text print need
//Initializes input handling
//Resets sound and music
//Loads a default sound driver

// Sprite structure
Sprite sprites[2];

int main( )
{
	// Define variables
	u16 posx = 0x6F;
	u16 posy = 0x58;
	u16 palette[64];
	u16 ind;
	
	// Disable interrupts when accessing VDP
    	SYS_disableInts();
    	// Initialization
    	VDP_setScreenWidth320();
	VDP_setScreenHeight240();
	// Init sprites engine
    	SPR_init(256);

	// Init logo sprite
	ind = TILE_USERINDEX;
    	SPR_initSprite(&sprites[0], &sega_logo_sprite, posx, posy, TILE_ATTR(PAL0, TRUE, FALSE, FALSE));
   	//SPR_update(sprites, 1);
	// Prepare palettes
	memcpy(&palette[16], sega_logo_sprite.palette->data, 16 * 2);
	VDP_setPalette(0, sega_logo_sprite.palette->data);
	//Animation
	SPR_setAnim(&sprites[0], ANIM_LOGO);
	
	VDP_setTextPalette(PAL2);
	VDP_drawText("Test", 14, 9);

	//JOY_init();
	//JOY_setEventHandler(&inputHandler);

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

    while(1)
    {
	SPR_nextFrame(&sprites[0]);
        SPR_update(sprites, 1);
	//Wait for screen refresh
        VDP_waitVSync();
    }
    return 0;
}

Hik
Very interested
Posts: 68
Joined: Thu Jul 30, 2015 11:39 pm
Location: Iceland

Re: Hik's SGDK Experiments

Post by Hik » Tue Sep 08, 2015 9:46 pm

Here's a new code I've been working on for a simple direction input and text movement.
It works ,I'm thinking this is useful towards making simple games.

main.c

Code: Select all

#include <genesis.h>

// Defines variables
	int posx = 14;
	int posy = 9;

void myJoyHandler( u16 joy, u16 changed, u16 state) //state = pressed , changed = released
{
	if (joy == JOY_1)
	{
		if (state & BUTTON_LEFT)
		{
			posx--;
		}
		else if (state & BUTTON_RIGHT)
		{
			posx++;
		}
		else if (state & BUTTON_UP)
		{
			posy--;
		}
		else if (state & BUTTON_DOWN)
		{
			posy++;
		}
	}
}

int main( )
{	
	//Initialize joypad
	JOY_init();
	JOY_setEventHandler( &myJoyHandler );
	//Set text palette to green
	VDP_setTextPalette(PAL2);
	
	
	while(1)
	{
		//Clears the text from relative position of the 4 letter text
		VDP_clearText(posx+4, posy, 4);
		VDP_clearText(posx-4, posy, 4);
		VDP_clearText(posx, posy+1, 4);
		VDP_clearText(posx, posy-1, 4);
		//Draws the text
		VDP_drawText("Test", posx, posy);
		VDP_waitVSync();
	}
	return 0;
}

Hik
Very interested
Posts: 68
Joined: Thu Jul 30, 2015 11:39 pm
Location: Iceland

Re: Hik's SGDK Experiments

Post by Hik » Thu Sep 10, 2015 8:31 pm

I just made the basis for an in-game text editor. If you'd like the player to be able to input a name or a password ,you could use this.
(this is only the text function ,use the arrow keys while running it to see what it does) acting up on what is typed requires some
additional coding (like saving a name or giving an output if you got a password right or not).

main.c

Code: Select all

#include <genesis.h>

//Sets default values for VDP register
//Cleans video RAM
//Loads 4 default palettes ; Grey, Red, Green and Blue
//Loads a default font for text print need
//Initializes input handling
//Resets sound and music
//Loads a default sound driver

// Defines variables
	int posx = 14;
	int posy = 11;
	int texty = 1;

void myJoyHandler( u16 joy, u16 changed, u16 state) //state = pressed , changed = released
{
	if (joy == JOY_1)
	{
		if (state & BUTTON_LEFT)
		{
			posx--;
		}
		else if (state & BUTTON_RIGHT)
		{
			posx++;
		}
		else if (state & BUTTON_UP)
		{
			texty--;
		}
		else if (state & BUTTON_DOWN)
		{
			texty++;
		}
	}
}

int main( )
{	
	char letter[1];
	
	//Initialize joypad
	JOY_init();
	JOY_setEventHandler( &myJoyHandler );
	//Set text palette to green
	VDP_setTextPalette(PAL2);
	
	
	while(1)
	{
		if(texty < 1)
		{
			texty = 39;
		}
		
		if(texty > 39)
		{
			texty = 1;
		}
	
		switch(texty)
		{
			case 1:
			letter[1] = 'A';//A
			break;
			case 2:
			letter[1] = 'B';//B
			break;
			case 3:
			letter[1] = 'C';//C
			break;
			case 4:
			letter[1] = 'D';//D
			break;
			case 5:
			letter[1] = 'E';//E
			break;
			case 6:
			letter[1] = 'F';//F
			break;
			case 7:
			letter[1] = 'G';//G
			break;
			case 8:
			letter[1] = 'H';//H
			break;
			case 9:
			letter[1] = 'I';//I
			break;
			case 10:
			letter[1] = 'J';//J
			break;
			case 11:
			letter[1] = 'K';//K
			break;
			case 12:
			letter[1] = 'L';//L
			break;
			case 13:
			letter[1] = 'M';//M
			break;
			case 14:
			letter[1] = 'N';//N
			break;
			case 15:
			letter[1] = 'O';//O
			break;
			case 16:
			letter[1] = 'P';//P
			break;
			case 17:
			letter[1] = 'Q';//Q
			break;
			case 18:
			letter[1] = 'R';//R
			break;
			case 19:
			letter[1] = 'S';//S
			break;
			case 20:
			letter[1] = 'T';//T
			break;
			case 21:
			letter[1] = 'U';//U
			break;
			case 22:
			letter[1] = 'V';//V
			break;
			case 23:
			letter[1] = 'W';//W
			break;
			case 24:
			letter[1] = 'X';//X
			break;
			case 25:
			letter[1] = 'Y';//Y
			break;
			case 26:
			letter[1] = 'Z';//Z
			break;
			case 27:
			letter[1] = '0';//0
			break;
			case 28:
			letter[1] = '1';//1
			break;
			case 29:
			letter[1] = '2';//2
			break;
			case 30:
			letter[1] = '3';//3
			break;
			case 31:
			letter[1] = '4';//4
			break;
			case 32:
			letter[1] = '5';//5
			break;
			case 33:
			letter[1] = '6';//6
			break;
			case 34:
			letter[1] = '7';//7
			break;
			case 35:
			letter[1] = '8';//8
			break;
			case 36:
			letter[1] = '9';//9
			break;
			case 37:
			letter[1] = '!';//!
			break;
			case 38:
			letter[1] = '?';//?
			break;
			case 39:
			letter[1] = '-';//Spacebar
			break;
			default:
			letter[1] = '.';//Dot
			break;
		}
	
		//Draws the text
		VDP_drawText(&letter[1], posx, posy);
		VDP_waitVSync();
	}
	return 0;
}

Hik
Very interested
Posts: 68
Joined: Thu Jul 30, 2015 11:39 pm
Location: Iceland

Re: Hik's SGDK Experiments

Post by Hik » Mon Sep 14, 2015 12:25 am

I've been working on figuring out the controls and had the idea to make an interactive joypad graphic using two sprites.
The goal for this project was to have each button lit up on the graphic when given an input from the physical buttons.
Two directional buttons that are adjacent to eachother can be pressed at the same time to allow for 8 directional motion.
In addition to this ,the A ,B and C buttons could also be pressed while the directional buttons or "arrow keys" be in use.
The start button only works by itself (not while pressing A ,B or C) to simplify the graphic. I'm thinking of fixing that later.

Image Image

Here's the code ;

gfx.res

Code: Select all

IMAGE controller_image "controller-1.png" -1
SPRITE directions_sprite "directions.png" 8 8 -1 5
SPRITE buttons_sprite "button-states.png" 8 8 -1 5
gfx.h

Code: Select all

#ifndef _GFX_H_
#define _GFX_H_

extern const Image controller_image;
extern SpriteDefinition directions_sprite;
extern SpriteDefinition buttons_sprite;

#endif // _GFX_H_
main.c

Code: Select all

#include <genesis.h>
#include "gfx.h"

#define JOYPAD_NULL		0
#define JOYPAD_R		1
#define JOYPAD_RD		2
#define JOYPAD_D		3
#define JOYPAD_LD		4
#define JOYPAD_L		5
#define JOYPAD_LU		6
#define JOYPAD_U		7
#define JOYPAD_RU		8

#define JOYPAD_BTN		0
#define JOYPAD_STRT		1
#define JOYPAD_A		2
#define JOYPAD_B		3
#define JOYPAD_C		4
#define JOYPAD_AB		5
#define JOYPAD_BC		6
#define JOYPAD_ABC		7
#define JOYPAD_AC		8

//Sets default values for VDP register
//Cleans video RAM
//Loads 4 default palettes ; Grey, Red, Green and Blue
//Loads a default font for text print need
//Initializes input handling
//Resets sound and music
//Loads a default sound driver

// Sprite structure
Sprite sprites[2];

// Defines variables
	int jyp = 0;
	int btns = 0;

void inputHandler( u16 joy, u16 changed, u16 state) //state = pressed , changed = released
{
	if (joy == JOY_1)
	{
		//Directions
		if (state & BUTTON_LEFT)
		{
			jyp = 5; //West
			if (state & BUTTON_UP)
			{
				jyp = 6; //Northwest
			}
			else if (state & BUTTON_DOWN)
			{
				jyp = 4; //Southwest
			}
		}
		else if (state & BUTTON_UP)
		{
			jyp = 7; //North
			if (state & BUTTON_RIGHT)
			{
				jyp = 8; //Northeast
			}
			else if (state & BUTTON_LEFT)
			{
				jyp = 6; //Northwest
			}
		}
		else if (state & BUTTON_RIGHT)
		{
			jyp = 1; //East
			if (state & BUTTON_UP)
			{
				jyp = 8; //Northeast
			}
			else if (state & BUTTON_DOWN)
			{
				jyp = 2; //Southeast
			}
		}
		else if (state & BUTTON_DOWN)
		{
			jyp = 3; //South
			if (state & BUTTON_RIGHT)
			{
				jyp = 2; //Southeast
			}
			else if (state & BUTTON_LEFT)
			{
				jyp = 4; //Southwest
			}
		}
		else if (changed)
		{
			jyp = 0; //No direction
		}

		//Buttons (Start ,A ,B ,C)
		
		if (state & BUTTON_START)
		{
			btns = 1; //Start button is active
		}
		else if (state & BUTTON_A)
		{
			btns = 2; //Button A
			if (state & BUTTON_B)
			{
				btns = 5; //Button A + Button B
				if (state & BUTTON_C)
				{
					btns = 7; //Button A + Button B + Button C
				}
			}
			else if (state & BUTTON_C)
			{
				btns = 8; //Button A + Button C
				if (state & BUTTON_B)
				{
					btns = 7; //Button A + Button B + Button C
				}
			}
		}
		else if (state & BUTTON_B)
		{
			btns = 3; //Button B
			if (state & BUTTON_A)
			{
				btns = 5; //Button B + Button A
				if (state & BUTTON_C)
				{
					btns = 7; //Button A + Button B + Button C
				}
			}
			else if (state & BUTTON_C)
			{
				btns = 6; //Button B + Button C
				if (state & BUTTON_A)
				{
					btns = 7; //Button A + Button B + Button C
				}
			}
		}
		else if (state & BUTTON_C)
		{
			btns = 4; //Button C
			if (state & BUTTON_A)
			{
				btns = 8; //Button C + Button A
				if (state & BUTTON_B)
				{
					btns = 7; //Button A + Button B + Button C
				}
			}
			else if (state & BUTTON_B)
			{
				btns = 6; //Button C + Button B
				if (state & BUTTON_A)
				{
					btns = 7; //Button A + Button B + Button C
				}
			}
		}
		else if (changed)
		{
			btns = 0; //No buttons pressed
		}
	}
}

int main( )
{	
	u16 palette[64];
    u16 ind;
	
	// Disable interrupts when accessing VDP
    SYS_disableInts();
    // Initialization
    VDP_setScreenWidth320();
	VDP_setScreenHeight240();
	// Init sprites engine
    SPR_init(256);

	//Initialize joypad
	JOY_init();
	JOY_setEventHandler( &inputHandler );
	
	// load background
	ind = TILE_USERINDEX;
	VDP_drawImageEx(BPLAN, &controller_image, TILE_ATTR_FULL(PAL0, FALSE, FALSE, FALSE, ind), 8, 8, FALSE, TRUE);
    ind += controller_image.tileset->numTile;
	
	// VDP process done, we can re enable interrupts
    SYS_enableInts();
	
	// init sprites
    SPR_initSprite(&sprites[0], &directions_sprite, 64, 64, TILE_ATTR(PAL1, TRUE, FALSE, FALSE));
	SPR_initSprite(&sprites[1], &buttons_sprite, 116, 64, TILE_ATTR(PAL2, TRUE, FALSE, FALSE));
	
	memcpy(&palette[0], controller_image.palette->data, 16 * 2);
	VDP_setPalette(0, controller_image.palette->data);
	memcpy(&palette[16], directions_sprite.palette->data, 16 * 2);
	VDP_setPalette(1, directions_sprite.palette->data);
	memcpy(&palette[32], buttons_sprite.palette->data, 16 * 2);
	VDP_setPalette(2, buttons_sprite.palette->data);
	
	
	while(1)
	{
		switch(jyp)
		{
			case 0:
			{
				SPR_setAnim(&sprites[0], JOYPAD_NULL);
			}
			break;
			case 1:
			{
				SPR_setAnim(&sprites[0], JOYPAD_R);
			}
			break;
			case 2:
			{
				SPR_setAnim(&sprites[0], JOYPAD_RD);
			}
			break;
			case 3:
			{
				SPR_setAnim(&sprites[0], JOYPAD_D);
			}
			break;
			case 4:
			{
				SPR_setAnim(&sprites[0], JOYPAD_LD);
			}
			break;
			case 5:
			{
				SPR_setAnim(&sprites[0], JOYPAD_L);
			}
			break;
			case 6:
			{
				SPR_setAnim(&sprites[0], JOYPAD_LU);
			}
			break;
			case 7:
			{
				SPR_setAnim(&sprites[0], JOYPAD_U);
			}
			break;
			case 8:
			{
				SPR_setAnim(&sprites[0], JOYPAD_RU);
			}
			break;
			default:
			{
				SPR_setAnim(&sprites[0], JOYPAD_NULL);
			}
			break;
		}
		switch(btns)
		{
			case 0:
			{
				SPR_setAnim(&sprites[1], JOYPAD_BTN);
			}
			break;
			case 1:
			{
				SPR_setAnim(&sprites[1], JOYPAD_STRT);
			}
			break;
			case 2:
			{
				SPR_setAnim(&sprites[1], JOYPAD_A);
			}
			break;
			case 3:
			{
				SPR_setAnim(&sprites[1], JOYPAD_B);
			}
			break;
			case 4:
			{
				SPR_setAnim(&sprites[1], JOYPAD_C);
			}
			break;
			case 5:
			{
				SPR_setAnim(&sprites[1], JOYPAD_AB);
			}
			break;
			case 6:
			{
				SPR_setAnim(&sprites[1], JOYPAD_BC);
			}
			break;
			case 7:
			{
				SPR_setAnim(&sprites[1], JOYPAD_ABC);
			}
			case 8:
			{
				SPR_setAnim(&sprites[1], JOYPAD_AC);
			}
			break;
			default:
			{
				SPR_setAnim(&sprites[1], JOYPAD_BTN);
			}
			break;
		}
        
        // update sprites (only one to update here)
        SPR_update(sprites, 2);
		VDP_waitVSync();
	}
	return 0;
}


This project was also a success ,but I couldn't get all three buttons A ,B and C lit at the same time. Neither did A and C buttons
lit up when pressed at the same time. Maybe some of you could help me solve this?

Here's the rom ; Hik's-Joypad.bin

Hik
Very interested
Posts: 68
Joined: Thu Jul 30, 2015 11:39 pm
Location: Iceland

Re: Hik's SGDK Experiments

Post by Hik » Mon Dec 28, 2015 9:46 pm

I updated the joypad rom so that now the buttons Start ,A ,B and C can be pressed in any combination
while the arrow keys can also be pressed. I changed the graphics so that instead of using two sprites ,
I'm now using 4 sprites ; 1. Arrow keys - 2. Start button - 3. A and B buttons 4. - C button.

Here's the code ;

gfx.res

Code: Select all

IMAGE controller_image "controller-1.png" -1
SPRITE directions_sprite "directions.png" 8 8 -1 5
SPRITE buttons_sprite1 "button-start.png" 8 2 -1 5
SPRITE buttons_sprite2 "buttons-ab.png" 4 6 -1 5
SPRITE buttons_sprite3 "button-c.png" 4 6 -1 5
gfx.h

Code: Select all

#ifndef _GFX_H_
#define _GFX_H_

extern const Image controller_image;
extern SpriteDefinition directions_sprite;
extern SpriteDefinition buttons_sprite1;
extern SpriteDefinition buttons_sprite2;
extern SpriteDefinition buttons_sprite3;

#endif // _GFX_H_
main.c

Code: Select all

#include <genesis.h>
#include "gfx.h"

#define JOYPAD_NULL		0
#define JOYPAD_R		1
#define JOYPAD_RD		2
#define JOYPAD_D		3
#define JOYPAD_LD		4
#define JOYPAD_L		5
#define JOYPAD_LU		6
#define JOYPAD_U		7
#define JOYPAD_RU		8

#define JOYPAD_BTN		0
#define JOYPAD_STRT		1

#define JOYPAD_NONE		0
#define JOYPAD_A		1
#define JOYPAD_B		2
#define JOYPAD_AB		3

#define JOYPAD_N		0
#define JOYPAD_C		1

//Sets default values for VDP register
//Cleans video RAM
//Loads 4 default palettes ; Grey, Red, Green and Blue
//Loads a default font for text print need
//Initializes input handling
//Resets sound and music
//Loads a default sound driver

// Sprite structure
Sprite sprites[4];

// Defines variables
	int jyp = 0;
	int btns = 0;
	int btnab = 0;
	int btnc = 0;

void inputHandler( u16 joy, u16 changed, u16 state) //state = pressed , changed = released
{
	if (joy == JOY_1)
	{
		//Directions
		if (state & BUTTON_LEFT)
		{
			jyp = 5; //West
			if (state & BUTTON_UP)
			{
				jyp = 6; //Northwest
			}
			else if (state & BUTTON_DOWN)
			{
				jyp = 4; //Southwest
			}
		}
		else if (state & BUTTON_UP)
		{
			jyp = 7; //North
			if (state & BUTTON_RIGHT)
			{
				jyp = 8; //Northeast
			}
			else if (state & BUTTON_LEFT)
			{
				jyp = 6; //Northwest
			}
		}
		else if (state & BUTTON_RIGHT)
		{
			jyp = 1; //East
			if (state & BUTTON_UP)
			{
				jyp = 8; //Northeast
			}
			else if (state & BUTTON_DOWN)
			{
				jyp = 2; //Southeast
			}
		}
		else if (state & BUTTON_DOWN)
		{
			jyp = 3; //South
			if (state & BUTTON_RIGHT)
			{
				jyp = 2; //Southeast
			}
			else if (state & BUTTON_LEFT)
			{
				jyp = 4; //Southwest
			}
		}
		else if (changed)
		{
			jyp = 0; //No direction
		}

		//Button Start
		btns = 0; //No buttons pressed
		if (state & BUTTON_START)
		{
			btns = 1; //Start button is active
		}
		else if (changed)
		{
			btns = 0;
		}
		
		//Buttons A B
		if (state & BUTTON_A)
		{
			btnab = 1; //Button A
			if (state & BUTTON_B)
			{
				btnab = 3;
			}
		}
		else if (state & BUTTON_B)
		{
			btnab = 2; //Button B
			if (state & BUTTON_A)
			{
				btnab = 3;
			}
		}
		else if (changed)
		{
			btnab = 0;
		}
		
		//Button C
		if (state & BUTTON_C)
		{
			btnc = 1; //Button C
		}
		else if (changed)
		{
			btnc = 0;
		}
	}
}

int main( )
{	
	u16 palette[64];
    u16 ind;
	
	// Disable interrupts when accessing VDP
    SYS_disableInts();
    // Initialization
    VDP_setScreenWidth320();
	VDP_setScreenHeight240();
	// Init sprites engine
    SPR_init(256);

	//Initialize joypad
	JOY_init();
	JOY_setEventHandler( &inputHandler );
	
	// load background
	ind = TILE_USERINDEX;
	VDP_drawImageEx(BPLAN, &controller_image, TILE_ATTR_FULL(PAL0, FALSE, FALSE, FALSE, ind), 8, 8, FALSE, TRUE);
    ind += controller_image.tileset->numTile;
	
	// VDP process done, we can re enable interrupts
    SYS_enableInts();
	
	// init sprites
    SPR_initSprite(&sprites[0], &directions_sprite, 64, 64, TILE_ATTR(PAL0, TRUE, FALSE, FALSE));
	SPR_initSprite(&sprites[1], &buttons_sprite1, 116, 64, TILE_ATTR(PAL0, TRUE, FALSE, FALSE));
	SPR_initSprite(&sprites[2], &buttons_sprite2, 116, 80, TILE_ATTR(PAL0, TRUE, FALSE, FALSE));
	SPR_initSprite(&sprites[3], &buttons_sprite3, 148, 80, TILE_ATTR(PAL0, TRUE, FALSE, FALSE));
	
	memcpy(&palette[0], controller_image.palette->data, 16 * 2);
	VDP_setPalette(0, controller_image.palette->data);
	
	while(1)
	{
		switch(jyp)
		{
			case 0:
			{
				SPR_setAnim(&sprites[0], JOYPAD_NULL);
			}
			break;
			case 1:
			{
				SPR_setAnim(&sprites[0], JOYPAD_R);
			}
			break;
			case 2:
			{
				SPR_setAnim(&sprites[0], JOYPAD_RD);
			}
			break;
			case 3:
			{
				SPR_setAnim(&sprites[0], JOYPAD_D);
			}
			break;
			case 4:
			{
				SPR_setAnim(&sprites[0], JOYPAD_LD);
			}
			break;
			case 5:
			{
				SPR_setAnim(&sprites[0], JOYPAD_L);
			}
			break;
			case 6:
			{
				SPR_setAnim(&sprites[0], JOYPAD_LU);
			}
			break;
			case 7:
			{
				SPR_setAnim(&sprites[0], JOYPAD_U);
			}
			break;
			case 8:
			{
				SPR_setAnim(&sprites[0], JOYPAD_RU);
			}
			break;
			default:
			{
				SPR_setAnim(&sprites[0], JOYPAD_NULL);
			}
			break;
		}
		switch(btns)
		{
			case 0:
			{
				SPR_setAnim(&sprites[1], JOYPAD_BTN);
			}
			break;
			case 1:
			{
				SPR_setAnim(&sprites[1], JOYPAD_STRT);
			}
			break;
		}
		switch(btnab)
		{
			case 0:
			{
				SPR_setAnim(&sprites[2], JOYPAD_NONE);
			}
			break;
			case 1:
			{
				SPR_setAnim(&sprites[2], JOYPAD_A);
			}
			break;
			case 2:
			{
				SPR_setAnim(&sprites[2], JOYPAD_B);
			}
			break;
			case 3:
			{
				SPR_setAnim(&sprites[2], JOYPAD_AB);
			}
			break;
		}
		switch(btnc)
		{
			case 0:
			{
				SPR_setAnim(&sprites[3], JOYPAD_N);
			}
			break;
			case 1:
			{
				SPR_setAnim(&sprites[3], JOYPAD_C);
			}
			break;
		}
        
        // update sprites
        SPR_update(sprites, 4);
		VDP_waitVSync();
	}
	return 0;
}
And here's the updated rom in a zip file ; Hik's-Joypad.zip

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

Re: Hik's SGDK Experiments

Post by Stef » Tue Dec 29, 2015 12:06 am

Hey, thanks for the ROM, neat graphics :)

Hik
Very interested
Posts: 68
Joined: Thu Jul 30, 2015 11:39 pm
Location: Iceland

Re: Hik's SGDK Experiments

Post by Hik » Wed Dec 30, 2015 10:36 pm

You're welcome. Thanks ,I made the graphics as a pixel lineart based off a photo of the actual joypad.
I might make a 6 button pad version later but most games I've played only use the A ,B and C buttons.
Maybe I'll make a game at some point which uses the X ,Y ,Z buttons specificly with the other ones.

I'm thinking about experimenting with sound effects next. I saw a presentation about "juice" for games
which showed how much colors , effects and sound can liven up even the most simple games to make
them more enjoyable to play so I think sound is something I'll have to get into to make a good first game.

I'm reading up about the z80 and the YM2612. I also saw you made an XGM driver so I'm also looking into that.
I have some gym files and vgm files and have been exploring the trackers that are used to make music.
Would small size wav files work for simple sound effects as PCM? I'm wondering about the limits of the sound.

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

Re: Hik's SGDK Experiments

Post by Stef » Thu Dec 31, 2015 1:23 am

You can use any wav file for SFX (if you plan to use the XGM driver), the only limitation is rom size ;)

KanedaFr
Administrateur
Posts: 1139
Joined: Tue Aug 29, 2006 10:56 am
Contact:

Re: Hik's SGDK Experiments

Post by KanedaFr » Fri Jan 01, 2016 7:18 pm

FYI, it seems there are some glitches when you press multi buttons too fast

Hik
Very interested
Posts: 68
Joined: Thu Jul 30, 2015 11:39 pm
Location: Iceland

Re: Hik's SGDK Experiments

Post by Hik » Fri Jan 01, 2016 9:49 pm

KanedaFr wrote:FYI, it seems there are some glitches when you press multi buttons too fast
I pressed all the buttons as fast as I could and haven't found any glitches. (I've only tested it with Gens)

Can you show me what you mean?

Post Reply