Posted: Wed Jan 18, 2012 7:50 am
SGDK 0.9 Supports 6 buttons?
Sega Megadrive/Genesis development
https://gendev.spritesmind.net/forum/
Unfortunately not yet, only 3 buttons joypad are supported right now.Mixail wrote:SGDK 0.9 Supports 6 buttons?
It is a pity.KanedaFr wrote:short answer : no
long answer : not yet.
I have a WIP update for 6 buttons, TPlay, EA and mouse support.
I also bought a pink justifier to add justifier support too (and still looking for a cheap menacer)
But since I can't test it on real hardware, it's waiting on my hard drive for 1 year now
because I have a SMD but no time to fix it and I keep my money for the hostingMixail wrote:It is a pity.
Why not to buy Flash cartridge for the test?
You could easily make it yourself with the help of VDP_waitVSync()What function in SDK 0.9 is similar to function "void sleepFrames (u16 frames);"
sleepFrames (100); ???KanedaFr wrote:Mixail wrote:It is a pity.
You could easily make it yourself with the help of VDP_waitVSync()
Code: Select all
void sleepFrames(u16 frame)
{
while (frames--)
VDP_waitVSync();
}
Code: Select all
static u16 readJoypad(u16 joy)
{
vu8 *pb;
u16 i, j, k;
if (joy < 2)
{
pb = (u8 *) (0xA10003 + (joy * 2));
if (portSupport[joy] == JOY_SUPPORT_3BTN)
{
asm("move.b #0x00,(%2)\n\t"
"nop\n\t"
"nop\n\t"
"move.b (%2),%0\n\t"
"move.b #0x40,(%2)\n\t"
"lsl.b #2,%0\n\t"
"andi.w #0xC0,%0\n\t"
"move.b (%2),%1\n\t"
"andi.w #0x3F,%1\n\t"
"or.b %1,%0\n\t"
"eori.b #0xFF,%0\n\t"
: "=d" (i), "=d" (j)
: "a" (pb)
: );
return i;
}
if (portSupport[joy] == JOY_SUPPORT_6BTN)
{
asm("move.b #0x00,(%3)\n\t"
"nop\n\t"
"nop\n\t"
"move.b (%3),%0\n\t"
"move.b #0x40,(%3)\n\t"
"lsl.w #8,%0\n\t"
"move.b (%3),%0\n\t"
"move.w %0,%1\n\t"
"move.b #0x00,(%3)\n\t"
"nop\n\t"
"nop\n\t"
"move.b (%3),%0\n\t"
"move.b #0x40,(%3)\n\t"
"lsl.w #8,%0\n\t"
"move.b (%3),%0\n\t"
"move.b #0x00,(%3)\n\t"
"nop\n\t"
"nop\n\t"
"move.b (%3),%0\n\t"
"move.b #0x40,(%3)\n\t"
"lsl.w #8,%0\n\t"
"move.b (%3),%0\n\t"
"move.w %0,%2\n\t"
"move.b #0x00,(%3)\n\t"
"nop\n\t"
"nop\n\t"
"move.b (%3),%0\n\t"
"move.b #0x40,(%3)\n\t"
"lsl.w #8,%0\n\t"
"move.b (%3),%0\n\t"
"andi.w #0x0F00,%0\n\t"
"cmpi.w #0x0F00,%0\n\t"
"beq.b common\n\t"
"move.w #0x010F,%2\n"
"common:\n\t"
"lsl.b #4,%2\n\t"
"lsl.w #4,%2\n\t"
"andi.w #0x303F,%1\n\t"
"move.b %1,%2\n\t"
"lsr.w #6,%1\n\t"
"or.w %1,%2\n\t"
"eori.w #0x1FFF,%2\n\t"
: "=d" (i), "=d" (j), "=d" (k)
: "a" (pb)
: );
return k;
}
}
else if (joy < 6) // teamplay 1
{
// not yet supported
return 0;
}
else if (joy < 9) // teamplay 2
{
// not yet supported
return 0;
}
return 0;
}
Code: Select all
JOY_setSupport(PORT_1, JOY_SUPPORT_6BTN);
JOY_update();
if ((JOY_readJoypad(JOY_1) & 0xF000) != 0x1000)
JOY_setSupport(PORT_1, JOY_SUPPORT_3BTN);
Chilly Willy wrote:For six button support, try this:
That should work... it's based on working code and compiles without error - I even examined the generated assembly. However, there's no joystick test example and I'm too lazy to make one.Code: Select all
static u16 readJoypad(u16 joy) { vu8 *pb; u16 i, j, k; if (joy < 2) { pb = (u8 *) (0xA10003 + (joy * 2)); if (portSupport[joy] == JOY_SUPPORT_3BTN) { asm("move.b #0x00,(%2)\n\t" "nop\n\t" "nop\n\t" "move.b (%2),%0\n\t" "move.b #0x40,(%2)\n\t" "lsl.b #2,%0\n\t" "andi.w #0xC0,%0\n\t" "move.b (%2),%1\n\t" "andi.w #0x3F,%1\n\t" "or.b %1,%0\n\t" "eori.b #0xFF,%0\n\t" : "=d" (i), "=d" (j) : "a" (pb) : ); return i; } if (portSupport[joy] == JOY_SUPPORT_6BTN) { asm("move.b #0x00,(%3)\n\t" "nop\n\t" "nop\n\t" "move.b (%3),%0\n\t" "move.b #0x40,(%3)\n\t" "lsl.w #8,%0\n\t" "move.b (%3),%0\n\t" "move.w %0,%1\n\t" "move.b #0x00,(%3)\n\t" "nop\n\t" "nop\n\t" "move.b (%3),%0\n\t" "move.b #0x40,(%3)\n\t" "lsl.w #8,%0\n\t" "move.b (%3),%0\n\t" "move.b #0x00,(%3)\n\t" "nop\n\t" "nop\n\t" "move.b (%3),%0\n\t" "move.b #0x40,(%3)\n\t" "lsl.w #8,%0\n\t" "move.b (%3),%0\n\t" "move.w %0,%2\n\t" "move.b #0x00,(%3)\n\t" "nop\n\t" "nop\n\t" "move.b (%3),%0\n\t" "move.b #0x40,(%3)\n\t" "lsl.w #8,%0\n\t" "move.b (%3),%0\n\t" "andi.w #0x0F00,%0\n\t" "cmpi.w #0x0F00,%0\n\t" "beq.b common\n\t" "move.w #0x010F,%2\n" "common:\n\t" "lsl.b #4,%2\n\t" "lsl.w #4,%2\n\t" "andi.w #0x303F,%1\n\t" "move.b %1,%2\n\t" "lsr.w #6,%1\n\t" "or.w %1,%2\n\t" "eori.w #0x1FFF,%2\n\t" : "=d" (i), "=d" (j), "=d" (k) : "a" (pb) : ); return k; } } else if (joy < 6) // teamplay 1 { // not yet supported return 0; } else if (joy < 9) // teamplay 2 { // not yet supported return 0; } return 0; }
![]()
Remember that JOY_Init() sets both ports to 3 button mode. You need to call JOY_setSupport(port, JOY_SUPPORT_6BTN) to switch to 6 button reading. The function will then return all the buttons as already defined in joy.h. If you read a 3 button stick in 6 button mode, it still works, but it's slower than using 3 button mode. You can tell 3 button sticks from 6 button by reading the port in 6 button mode - if there really is a 6 buttons stick there, the upper nibble is a 1, otherwise it's a 0. So you might do something like this:
That sets port 1 to 6 button, checks if there is a six button pad, and turns it back to 3 button if there isn't.Code: Select all
JOY_setSupport(PORT_1, JOY_SUPPORT_6BTN); JOY_update(); if ((JOY_readJoypad(JOY_1) & 0xF000) != 0x1000) JOY_setSupport(PORT_1, JOY_SUPPORT_3BTN);
Code: Select all
void JOY_init()
{
vu8 *pb;
/* set the port bits direction */
pb = (u8 *) 0xa10009;
*pb = 0x40;
pb += 2;
*pb = 0x40;
pb += 2;
*pb = 0x40;
/* set the port bits value */
pb = (u8 *) 0xa10003;
*pb = 0x40;
pb += 2;
*pb = 0x40;
pb += 2;
*pb = 0x40;
memset(joyState, 0, sizeof(joyState));
portSupport[PORT_1] = JOY_SUPPORT_3BTN;
portSupport[PORT_2] = JOY_SUPPORT_3BTN;
joyEventCB = NULL;
}
Code: Select all
static u16 readJoypad(u16 joy)
{
vu8 *pb;
u16 i, j, k;
if (joy < 2)
{
pb = (u8 *) (0xA10003 + (joy * 2));
if (portSupport[joy] == JOY_SUPPORT_3BTN)
{
asm("move.b #0x00,(%2)\n\t"
"nop\n\t"
"nop\n\t"
"move.b (%2),%0\n\t"
"move.b #0x40,(%2)\n\t"
"lsl.b #2,%0\n\t"
"andi.w #0xC0,%0\n\t"
"move.b (%2),%1\n\t"
"andi.w #0x3F,%1\n\t"
"or.b %1,%0\n\t"
"eori.b #0xFF,%0\n\t"
: "=d" (i), "=d" (j)
: "a" (pb)
: "0" );
return i;
}
if (portSupport[joy] == JOY_SUPPORT_6BTN)
{
asm("move.b #0x00,(%3)\n\t"
"nop\n\t"
"nop\n\t"
"move.b (%3),%0\n\t"
"move.b #0x40,(%3)\n\t"
"lsl.w #8,%0\n\t"
"move.b (%3),%0\n\t"
"move.w %0,%1\n\t"
"move.b #0x00,(%3)\n\t"
"nop\n\t"
"nop\n\t"
"move.b (%3),%0\n\t"
"move.b #0x40,(%3)\n\t"
"lsl.w #8,%0\n\t"
"move.b (%3),%0\n\t"
"move.b #0x00,(%3)\n\t"
"nop\n\t"
"nop\n\t"
"move.b (%3),%0\n\t"
"move.b #0x40,(%3)\n\t"
"lsl.w #8,%0\n\t"
"move.b (%3),%0\n\t"
"move.w %0,%2\n\t"
"move.b #0x00,(%3)\n\t"
"nop\n\t"
"nop\n\t"
"move.b (%3),%0\n\t"
"move.b #0x40,(%3)\n\t"
"lsl.w #8,%0\n\t"
"move.b (%3),%0\n\t"
"andi.w #0x0F00,%0\n\t"
"cmpi.w #0x0F00,%0\n\t"
"beq.b common\n\t"
"move.w #0x010F,%2\n"
"common:\n\t"
"lsl.b #4,%2\n\t"
"lsl.w #4,%2\n\t"
"andi.w #0x303F,%1\n\t"
"move.b %1,%2\n\t"
"lsr.w #6,%1\n\t"
"or.w %1,%2\n\t"
"eori.w #0x1FFF,%2\n\t"
: "=d" (i), "=d" (j), "=d" (k)
: "a" (pb)
: "0" );
return k;
}
}
else if (joy < 6) // teamplay 1
{
// not yet supported
return 0;
}
else if (joy < 9) // teamplay 2
{
// not yet supported
return 0;
}
return 0;
}
Code: Select all
#define BUTTON_X 0x0400
#define BUTTON_Y 0x0200
#define BUTTON_Z 0x0100
Code: Select all
#include "genesis.h"
static void printButton(char c, u16 state);
static void showPortState();
static u16 posY, posX;
int main(int cold_start)
{
JOY_setSupport(PORT_1, JOY_SUPPORT_6BTN);
VDP_waitVSync();
VDP_waitVSync();
if ((JOY_readJoypad(JOY_1) & 0xF000) != 0x1000)
JOY_setSupport(PORT_1, JOY_SUPPORT_3BTN);
JOY_setSupport(PORT_2, JOY_SUPPORT_6BTN);
VDP_waitVSync();
VDP_waitVSync();
if ((JOY_readJoypad(JOY_2) & 0xF000) != 0x1000)
JOY_setSupport(PORT_2, JOY_SUPPORT_3BTN);
VDP_setScreenWidth320();
VDP_setHInterrupt(0);
VDP_setHilightShadow(0);
VDP_setPaletteColor(PAL1, 15, 0x0888);
VDP_setTextPalette(0);
VDP_drawText("Current Joy Port State", 10, 1);
VDP_clearTileMapRect(APLAN, 0, 3, 40, 8);
showPortState();
while(1)
{
showPortState();
VDP_waitVSync();
}
}
static void printButton(char c, u16 state)
{
char temp[2];
temp[0] = c;
temp[1] = 0;
VDP_setTextPalette(state ? 1 : 0);
VDP_drawText(temp, posX, posY);
posX += 2;
}
static void showPortState()
{
u16 i;
posY = 5;
for(i = JOY_1; i <= JOY_2; i++)
{
u16 value;
posX = 2;
VDP_setTextPalette(0);
VDP_drawText((i == JOY_1) ? "port 1:" : "port 2:", posX, posY);
posX += 8;
value = JOY_readJoypad(i);
printButton('U', value & BUTTON_UP);
printButton('D', value & BUTTON_DOWN);
printButton('L', value & BUTTON_LEFT);
printButton('R', value & BUTTON_RIGHT);
printButton('A', value & BUTTON_A);
printButton('B', value & BUTTON_B);
printButton('C', value & BUTTON_C);
printButton('S', value & BUTTON_START);
if ((value & 0xF000) == 0x1000)
{
/* six button pad */
printButton('X', value & BUTTON_X);
printButton('Y', value & BUTTON_Y);
printButton('Z', value & BUTTON_Z);
printButton('M', value & BUTTON_MODE);
}
posY++;
}
}
Code: Select all
JOY_setSupport(PORT_1, JOY_SUPPORT_6BTN);
JOY_setSupport(PORT_2, JOY_SUPPORT_6BTN);
VDP_waitVSync();
VDP_waitVSync();
if ((JOY_readJoypad(JOY_1) & 0xF000) != 0x1000)
JOY_setSupport(PORT_1, JOY_SUPPORT_3BTN);
if ((JOY_readJoypad(JOY_2) & 0xF000) != 0x1000)
JOY_setSupport(PORT_2, JOY_SUPPORT_3BTN);
Code: Select all
int main(int cold_start)
{
JOY_setSupport(PORT_1, JOY_SUPPORT_6BTN);
JOY_setSupport(PORT_2, JOY_SUPPORT_6BTN);
VDP_waitVSync();
VDP_waitVSync();
if ((JOY_readJoypad(JOY_1) & 0xF000) != 0x1000)
JOY_setSupport(PORT_1, JOY_SUPPORT_3BTN);
if ((JOY_readJoypad(JOY_2) & 0xF000) != 0x1000)
JOY_setSupport(PORT_2, JOY_SUPPORT_3BTN);
VDP_setScreenWidth320();
VDP_setHInterrupt(0);
VDP_setHilightShadow(0);
VDP_setPaletteColor(PAL1, 15, 0x0888);
VDP_setTextPalette(0);
VDP_drawText("Current Joy Port State", 10, 1);
VDP_clearTileMapRect(APLAN, 0, 3, 40, 8);
while(1)
{
showPortState();
VDP_waitVSync();
}
}