PVSnesLib  4.3.0
Documentation to code in C or ASM for the Nintendo SNES
Loading...
Searching...
No Matches
input/mouse/mouse.c
/*---------------------------------------------------------------------------------
snes mouse demo
-- alekmaul
Mouse support by DigiDwrf
---------------------------------------------------------------------------------*/
#include <snes.h>
extern char snesfont, snespal, cursorsprite, cursorsprite_end, cursorpal, buttonsmap, buttonstiles, buttonstiles_end, buttonspal;
char hex_string[4];
// Init some variables
u16 p1_mouse_x = 0x80;
u16 p1_mouse_y = 0x70;
u16 p2_mouse_x = 0x80;
u16 p2_mouse_y = 0x70;
u8 odd = 0;
bool mc_mem[2] = {false};
bool printed[2] = {false};
bool mouseDown_L[2] = {false};
bool mouseDown_R[2] = {false};
bool mouseDown_LR[2] = {false};
//---------------------------------------------------------------------------------
int main(void)
{
// Init cursors sprite
oamInitGfxSet(&cursorsprite, (&cursorsprite_end - &cursorsprite), &cursorpal, 48 * 2, 0, 0x0000, OBJ_SIZE16_L32);
// Initialize text console with our font
consoleInitText(0, 16 * 2, &snesfont, &snespal);
// Draw a wonderful text :P
consoleDrawText(11, 1, "MOUSE TEST");
// Enable mouse reading and set the initial mouse sensitivity
WaitForVBlank(); // Let's make sure we read mouse for the first time after initMouse()
if (mouseConnect[0] == false)
consoleDrawText(3, 5, "NO MOUSE PLUGGED ON PORT 0");
else
{
dmaCopyVram(&buttonsmap + 0x60, 0x6188, 0x0A); // SLOW button pressed
dmaCopyVram(&buttonsmap + 0xA0, 0x61A8, 0x0A); // SLOW button pressed
dmaCopyVram(&buttonsmap + 0x4A, 0x618D, 0x16); // released buttons
dmaCopyVram(&buttonsmap + 0x8A, 0x61AD, 0x16); // released buttons
consoleDrawText(5, 5, "MOUSE PLUGGED ON PORT 0");
}
if (mouseConnect[1] == false)
consoleDrawText(3, 17, "NO MOUSE PLUGGED ON PORT 1");
else
{
dmaCopyVram(&buttonsmap + 0x60, 0x6308, 0x0A); // SLOW button pressed
dmaCopyVram(&buttonsmap + 0xA0, 0x6328, 0x0A); // SLOW button pressed
dmaCopyVram(&buttonsmap + 0x4A, 0x630D, 0x16); // released buttons
dmaCopyVram(&buttonsmap + 0x8A, 0x632D, 0x16); // released buttons
consoleDrawText(5, 17, "MOUSE PLUGGED ON PORT 1");
}
// Init background
bgSetGfxPtr(0, 0x2000);
bgSetGfxPtr(1, 0x4000);
bgSetMapPtr(0, 0x6800, SC_32x32);
bgSetMapPtr(1, 0x6000, SC_32x32);
// Draw buttons for speed change
bgInitTileSet(1, &buttonstiles, &buttonspal, 1, (&buttonstiles_end - &buttonstiles), 16 * 2, BG_16COLORS, 0x4000);
// Now Put in 16 color mode
setMode(BG_MODE1, 0);
// Wait for nothing :P
while (1)
{
odd++;
// Optimize Draw text by printing new text just once
if (mouseConnect[0] != mc_mem[0])
printed[0] = true;
mc_mem[0] = mouseConnect[0];
// Update display with current mouse
if (mouseConnect[0] == false)
{
if (printed[0])
{
consoleDrawText(3, 5, "NO MOUSE PLUGGED ON PORT 0");
consoleDrawText(11, 7, " ");
consoleDrawText(7, 10, " ");
printed[0] = false;
}
oamSetVisible(0, OBJ_HIDE); // Hide 1p cursor
}
else
{
// We transform raw acceleration values into coordinates for OAM. Firt bit tell us mouse direction and the rest tell us how much fast it goes.
if (mouse_x[0] & 0x80)
p1_mouse_x -= mouse_x[0] & 0x7F;
else
p1_mouse_x += mouse_x[0] & 0x7F;
if (mouse_y[0] & 0x80)
p1_mouse_y -= mouse_y[0] & 0x7F;
else
p1_mouse_y += mouse_y[0] & 0x7F;
// And set some boundaries
if (p1_mouse_x > 0xFF00)
p1_mouse_x = 0;
if (p1_mouse_x > 0xFF)
p1_mouse_x = 0xFF;
if (p1_mouse_y > 0xFF00)
p1_mouse_y = 0;
if (p1_mouse_y > 0xEF)
p1_mouse_y = 0xEF;
oamSet(0, p1_mouse_x, p1_mouse_y, 3, 0, 0, 0, mouseConnect[1]);
if (printed[0])
{
consoleDrawText(3, 5, " MOUSE PLUGGED ON PORT 0 ");
consoleDrawText(11, 7, "X: Y:");
printed[0] = false;
}
if (mouseConnect[1] == false)
odd = 1;
if ((odd & 0x01) && (mouseButton[0] == false))
{
sprintf(hex_string, "%02X", p1_mouse_x);
consoleDrawText(13, 7, hex_string);
sprintf(hex_string, "%02X", p1_mouse_y);
consoleDrawText(19, 7, hex_string);
}
// mousePressed works as turbo switch, it will be 1 until it gets released, and then it goes back to 0. Good for dragging or writing.
switch (mousePressed[0])
{
case mouse_L:
if (mouseDown_L[0] == false)
{
consoleDrawText(7, 10, "LEFT BUTTON PRESSED ");
mouseDown_L[0] = true;
mouseDown_R[0] = false;
mouseDown_LR[0] = false;
}
break;
case mouse_R:
if (mouseDown_R[0] == false)
{
consoleDrawText(7, 10, "RIGHT BUTTON PRESSED");
mouseDown_L[0] = false;
mouseDown_R[0] = true;
mouseDown_LR[0] = false;
}
break;
case mouse_L + mouse_R:
if (mouseDown_LR[0] == false)
{
consoleDrawText(7, 10, "BOTH BUTTONS PRESSED");
mouseDown_L[0] = false;
mouseDown_R[0] = false;
mouseDown_LR[0] = true;
}
break;
}
}
// Optimize Draw text by printing new text just once
if (mouseConnect[1] != mc_mem[1])
printed[1] = true;
mc_mem[1] = mouseConnect[1];
if (mouseConnect[1] == false)
{
if (printed[1])
{
consoleDrawText(3, 17, "NO MOUSE PLUGGED ON PORT 1");
consoleDrawText(11, 19, " ");
consoleDrawText(7, 22, " ");
printed[1] = false;
}
oamSetVisible(4, OBJ_HIDE); // Hide 2p cursor
}
else
{
// We transform raw acceleration values into coordinates for OAM. Firt bit tell us mouse direction and the rest tell us how much fast it goes.
if (mouse_x[1] & 0x80)
p2_mouse_x -= mouse_x[1] & 0x7F;
else
p2_mouse_x += mouse_x[1] & 0x7F;
if (mouse_y[1] & 0x80)
p2_mouse_y -= mouse_y[1] & 0x7F;
else
p2_mouse_y += mouse_y[1] & 0x7F;
// And set some boundaries
if (p2_mouse_x > 0xFF00)
p2_mouse_x = 0;
if (p2_mouse_x > 0xFF)
p2_mouse_x = 0xFF;
if (p2_mouse_y > 0xFF00)
p2_mouse_y = 0;
if (p2_mouse_y > 0xEF)
p2_mouse_y = 0xEF;
oamSet(4, p2_mouse_x, p2_mouse_y, 3, 0, 0, 0, mouseConnect[0] << 1);
if (printed[1])
{
consoleDrawText(3, 17, " MOUSE PLUGGED ON PORT 1 ");
consoleDrawText(11, 19, "X: Y:");
printed[1] = false;
}
if (mouseConnect[0] == false)
odd = 0;
if (((odd & 0x01) == 0) && (mouseButton[1] == false))
{
sprintf(hex_string, "%02X", p2_mouse_x, p2_mouse_y);
consoleDrawText(13, 19, hex_string);
sprintf(hex_string, "%02X", p2_mouse_y);
consoleDrawText(19, 19, hex_string);
}
// mousePressed works as turbo switch, it will be 1 until it gets released, and then it goes back to 0. Good for dragging or writing.
switch (mousePressed[1])
{
case mouse_L:
if (mouseDown_L[1] == false)
{
consoleDrawText(7, 22, "LEFT BUTTON PRESSED ");
mouseDown_L[1] = true;
mouseDown_R[1] = false;
mouseDown_LR[1] = false;
}
break;
case mouse_R:
if (mouseDown_R[1] == false)
{
consoleDrawText(7, 22, "RIGHT BUTTON PRESSED");
mouseDown_L[1] = false;
mouseDown_R[1] = true;
mouseDown_LR[1] = false;
}
break;
case mouse_L + mouse_R:
if (mouseDown_LR[1] == false)
{
consoleDrawText(7, 22, "BOTH BUTTONS PRESSED");
mouseDown_L[1] = false;
mouseDown_R[1] = false;
mouseDown_LR[1] = true;
}
break;
}
}
// mouseButton works as a one frame value, so it gets released shortly after pressing the button. Good for clicking stuff that need to be called once, like buttons.
// mouseButton is 0 if there is no mouse connected
if (mouseButton[0] & mouse_L)
{
// Let's choose speed setting
if ((p1_mouse_y > 0x5E) && (p1_mouse_y < 0x6C))
{
if ((p1_mouse_x > 0x44) && (p1_mouse_x < 0x64))
{
mouseSetSensitivity(0, MOUSE_SLOW); // Queue a set sensitivity command
}
if ((p1_mouse_x > 0x6C) && (p1_mouse_x < 0x94))
{
mouseSetSensitivity(0, MOUSE_MEDIUM); // Queue a set sensitivity command
}
if ((p1_mouse_x > 0x9C) && (p1_mouse_x < 0xBC))
{
mouseSetSensitivity(0, MOUSE_FAST); // Queue a set sensitivity command
}
}
}
if (mouseButton[1] & mouse_L)
{
// Let's choose speed setting
if ((p2_mouse_y > 0xBE) && (p2_mouse_y < 0xCC))
{
if ((p2_mouse_x > 0x44) && (p2_mouse_x < 0x64))
{
mouseSetSensitivity(1, MOUSE_SLOW); // Queue a set sensitivity command
}
if ((p2_mouse_x > 0x6C) && (p2_mouse_x < 0x94))
{
mouseSetSensitivity(1, MOUSE_MEDIUM); // Queue a set sensitivity command
}
if ((p2_mouse_x > 0x9C) && (p2_mouse_x < 0xBC))
{
mouseSetSensitivity(1, MOUSE_FAST); // Queue a set sensitivity command
}
}
}
// START VBLANK CODE
if (mouseConnect[0])
{
dmaCopyVram(&buttonsmap + 0x40, 0x6188, 0x20); // released buttons
dmaCopyVram(&buttonsmap + 0x80, 0x61A8, 0x20); // released buttons
// Show reported sensitivity
switch (mouseSensitivity[0])
{
case MOUSE_SLOW:
dmaCopyVram(&buttonsmap + 0x60, 0x6188, 0x0A); // SLOW button pressed
dmaCopyVram(&buttonsmap + 0xA0, 0x61A8, 0x0A); // SLOW button pressed
break;
dmaCopyVram(&buttonsmap + 0x6A, 0x618D, 0x0C); // NORMAL button pressed
dmaCopyVram(&buttonsmap + 0xAA, 0x61AD, 0x0C); // NORMAL button pressed
break;
case MOUSE_FAST:
dmaCopyVram(&buttonsmap + 0x76, 0x6193, 0x0A); // FAST button pressed
dmaCopyVram(&buttonsmap + 0xB6, 0x61B3, 0x0A); // FAST button pressed
break;
}
if (mousePressed[0] == false)
dmaFillVram(&buttonsmap, 0x6940, 0x40); // wipe text
}
else
{
dmaFillVram(&buttonsmap + 0x40, 0x6188, 0x20); // remove buttons
dmaFillVram(&buttonsmap + 0x80, 0x61A8, 0x20); // remove buttons
}
if (mouseConnect[1])
{
dmaCopyVram(&buttonsmap + 0x40, 0x6308, 0x20); // released buttons
dmaCopyVram(&buttonsmap + 0x80, 0x6328, 0x20); // released buttons
switch (mouseSensitivity[1])
{
case MOUSE_SLOW:
dmaCopyVram(&buttonsmap + 0x60, 0x6308, 0x0A); // SLOW button pressed
dmaCopyVram(&buttonsmap + 0xA0, 0x6328, 0x0A); // SLOW button pressed
break;
dmaCopyVram(&buttonsmap + 0x6A, 0x630D, 0x0C); // NORMAL button pressed
dmaCopyVram(&buttonsmap + 0xAA, 0x632D, 0x0C); // NORMAL button pressed
break;
case MOUSE_FAST:
dmaCopyVram(&buttonsmap + 0x76, 0x6313, 0x0A); // FAST button pressed
dmaCopyVram(&buttonsmap + 0xB6, 0x6333, 0x0A); // FAST button pressed
break;
}
if (mousePressed[1] == false)
dmaFillVram(&buttonsmap, 0x6AC0, 0x40); // wipe text
}
else
{
dmaFillVram(&buttonsmap + 0x40, 0x6308, 0x20); // remove buttons
dmaFillVram(&buttonsmap + 0x80, 0x6328, 0x20); // remove buttons
}
// END VBLANK CODE
}
return 0;
}
void bgSetGfxPtr(u8 bgNumber, u16 address)
Definition of each background address.
void bgSetDisable(u8 bgNumber)
Disable a BG in the actual SNES mode.
void bgSetMapPtr(u8 bgNumber, u16 address, u8 mapSize)
Change Background Map address.
void bgInitTileSet(u8 bgNumber, u8 *tileSource, u8 *tilePalette, u8 paletteEntry, u16 tileSize, u16 paletteSize, u16 colorMode, u16 address)
Initializes a Tile Set and Loads the Tile GFX into VRAM.
void consoleSetTextVramAdr(u16 vramfont)
Change text graphics address (4K aligned)
void consoleInitText(u8 palnum, u8 palsize, u8 *tilfont, u8 *palfont)
Initialize the Text System.
void consoleDrawText(u16 x, u16 y, char *fmt,...)
Output formatted string on a screen (tiles mode)
void consoleSetTextOffset(u16 offsetfont)
Change text Background map address for display (must be BG address)
void consoleSetTextVramBGAdr(u16 offsetfont)
Change text Background map address for display (must be BG address)
void dmaFillVram(u8 *source, u16 address, u16 size)
fill the source data to destination using channel 0 of DMA available channels in half words
void dmaCopyVram(u8 *source, u16 address, u16 size)
copy data from source to destination using channel 0 of DMA available channels in half words
u8 mouseConnect[2]
1 if Mouse present
u8 mouse_y[2]
Mouse vertical displacement. daaaaaaa, d = direction (1: up, 0: down), a = acceleration.
void initMouse(u8 sensitivity)
Enable mouse reading and set the initial mouse sensitivity.
u8 mouse_x[2]
Mouse horizontal displacement. daaaaaaa, d = direction (1: left, 0: right), a = acceleration.
u8 mouseButton[2]
Mouse buttons that are pressed on this frame (Click mode).
u8 mouseSensitivity[2]
Mouse sensitivity.
#define mouse_L
SNES Mouse Left button mask.
Definition input.h:132
#define mouse_R
SNES Mouse Right button mask.
Definition input.h:133
@ MOUSE_FAST
fast sensitivity
Definition input.h:88
@ MOUSE_SLOW
slow sensitivity
Definition input.h:86
@ MOUSE_MEDIUM
medium sensitivity
Definition input.h:87
u8 mousePressed[2]
Mouse buttons that are currently pressed, stays until is unpressed (Turbo mode).
void mouseSetSensitivity(u16 port, u8 sensitivity)
Queue a set mouse sensitivity command (to be executed on the next VBlank).
void WaitForVBlank(void)
Waits for a VBlank interrupt.
the master include file for snes applications.
#define OBJ_SIZE16_L32
default OAM size 16x16 (SM) and 32x32 (LG) pix for OBJSEL register
Definition sprite.h:42
void oamSetVisible(u16 id, u8 hide)
Hide or show a sprite.
void oamInitGfxSet(u8 *tileSource, u16 tileSize, u8 *tilePalette, u16 paletteSize, u8 tilePaletteNumber, u16 address, u8 oamsize)
Initializes a sprites Gfx and Loads the GFX into VRAM.
void oamSet(u16 id, u16 xspr, u16 yspr, u8 priority, u8 hflip, u8 vflip, u16 gfxoffset, u8 paletteoffset)
sets an oam entry to the supplied values
void setScreenOn(void)
Put screen On.
void setMode(u8 mode, u8 size)
Set the SNES hardware to operate in new display mode.