diff --git a/pvsneslib/include/snes/pad.h b/pvsneslib/include/snes/pad.h index 3b613360..7b53495f 100644 --- a/pvsneslib/include/snes/pad.h +++ b/pvsneslib/include/snes/pad.h @@ -64,6 +64,16 @@ extern u16 pad_keysold[2]; extern u16 pad_keysrepeat[2]; extern u8 snes_mplay5; /*!< \brief 1 if MultiPlay5 connected */ +extern u8 snes_mouse; /*!< \brief 1 if Mouse is going to be used */ + +extern u8 mouseConnect[2]; /*! \brief 1 if Mouse present */ +extern u8 mouseButton[2]; /*! \brief 1 if button is pressed, stays for a bit and then it gets released (Click mode). */ +extern u8 mousePressed[2]; /*! \brief 1 if button is pressed, stays until is unpressed (Turbo mode). */ +extern u8 mouse_x[2], mouse_y[2]; /*! \brief Mouse acceleration. daaaaaaa, d = direction (0: up/left, 1: down/right), a = acceleration. */ +extern u8 mouseSpeedSet[2]; /*! \brief Mouse speed setting. 0: slow, 1: normal, 2: fast */ + +#define mouse_L 0x01 /*! \brief SNES Mouse Left button mask.*/ +#define mouse_R 0x02 /*! \brief SNES Mouse Right button mask.*/ /*! \def REG_JOYxLH @@ -109,7 +119,7 @@ extern u8 snes_mplay5; /*!< \brief 1 if MultiPlay5 connected */ #define REG_JOYxLH(a) (((vuint16 *)0x4218)[(a)]) /*! \fn scanPads() - \brief Wait for pad ready and read pad values in . + \brief Wait for pad ready and read pad values in. */ void scanPads(void); @@ -147,8 +157,19 @@ void padsClear(u16 value); void detectMPlay5(void); /*! \fn scanMPlay5() - \brief Wait for multiplayer5 pads ready and read pad values in . + \brief Wait for multiplayer5 pads ready and read pad values in. */ void scanMPlay5(void); +/*! \fn mouseRead(void) + \brief Wait for mouse ready and read mouse values in. +*/ +void mouseRead(void); + +/*! \fn MouseSpeedChange(u8 port) + \brief Set mouse hardware speed (populate mouseSpeed[] first). + \param port Specify wich port to use (0-1) +*/ +void MouseSpeedChange(u8 port); + #endif // SNES_PADS_INCLUDE diff --git a/pvsneslib/source/consoles.asm b/pvsneslib/source/consoles.asm index b8139762..f62229dd 100644 --- a/pvsneslib/source/consoles.asm +++ b/pvsneslib/source/consoles.asm @@ -383,6 +383,12 @@ consoleVblank: beq + jsl scanMPlay5 bra cvbloam ++ lda snes_mouse + beq + + jsl mouseRead + lda mouseConnect + and mouseConnect + 1 ; If both ports have a mouse plugged, it will skip pad controller reading + bne cvbloam + jsl scanPads cvbloam: @@ -438,9 +444,12 @@ consoleInit: lda.w #0 ; Begin counting vblank sta.w snes_vblank_count + sta.w mouseConnect ; Mouse init + sep #$20 sta scr_txt_dirty ; Nothing to print on screen sta snes_mplay5 ; For Pad function + sta snes_mouse ; Set mouse usage disabled by default phb pha diff --git a/pvsneslib/source/pads.asm b/pvsneslib/source/pads.asm index 282d369f..bce18ccd 100644 --- a/pvsneslib/source/pads.asm +++ b/pvsneslib/source/pads.asm @@ -91,6 +91,31 @@ scope_sinceshot dsb 2 .ENDS +;--------------------------------------------------------------------------------- +; Mouse Driver Routine (Ver 1 .00) +;--------------------------------------------------------------------------------- + +.RAMSECTION ".reg_mouse" BANK 0 SLOT 1 + +snes_mouse db ; for lib use. Tells the system to initialize mouse usage +mouseConnect dsb 2 ; Mouse connection ports (D0=4016, D0=4017) + +mouseSpeedSet dsb 2 ; Mouse speed setting +mouse_sp dsb 2 ; Mouse speed + +mouseButton dsb 2 ; Mouse button trigger +mousePressed dsb 2 ; Mouse button turbo + +mouse_y dsb 2 ; Mouse Y direction +mouse_x dsb 2 ; Mouse X direction + +mouse_sb dsb 2 ; Previous switch status + +connect_st dsb 2 + +.ENDS + + .BASE BASE_0 .SECTION ".pads0_text" SUPERFREE @@ -119,7 +144,9 @@ scanPads: lda REG_JOY1L ; read joypad register #1 bit #$0F ; catch non-joypad input beq + ; (bits 0-3 should be zero) - lda.b #$0 + sep #$20 + lda #$0 + rep #$20 +: sta pad_keys ; store 'current' state eor pad_keysold ; compute 'down' state from bits that and pad_keys ; have changed from 0 to 1 @@ -128,7 +155,9 @@ scanPads: lda REG_JOY2L ; read joypad register #2 bit #$0F ; catch non-joypad input beq + ; (bits 0-3 should be zero) - lda.b #$0 + sep #$20 + lda #$0 + rep #$20 +: sta pad_keys+2 ; store 'current' state eor pad_keysold+2 ; compute 'down' state from bits that and pad_keys+2 ; have changed from 0 to 1 @@ -583,4 +612,215 @@ NoScope: plp ; return from input check rts +.ENDS + +;--------------------------------------------------------------------------------- + +;* mouse_read + +;--------------------------------------------------------------------------------- + +;* If this routine is called every frame, then the mouse status will be set +;* to the appropriate registers. +;* INPUT +;* None (Mouse key read automatically) +;* OUTPUT +;* Connection status (mouse_con) D0=1 Mouse connected to Joyl +;* D1=1 Mouse connected to Joy2 +;* Switch (mousePressed,1) D0=left switch turbo +;* D1=right switch turbo +;* Switch (mouseButton,1) D0=left switch trigger +;* D1=right switch trigger +;* Mouse movement (ball) value +;* (mouse_x) D7=0 Positive turn, D7=1 Negative turn +;* D6-D0 X movement value +;* (mouse_y) D7=0 Positive turn, D7=1 Negative turn +;* D6-D0 X movement value + +;--------------------------------------------------------------------------------- + +.SECTION ".mouse_text" SUPERFREE + +;--------------------------------------------------------------------------------- +; void mouseRead(void) +mouseRead: + php + sep #$30 + phb + phx + phy + + lda #$00 ; Set Data Bank to 0 + pha + plb + +_10: + lda REG_HVBJOY + and #$01 + bne _10 ; Automatic read ok? + + ldx #$01 + lda REG_JOY2L ; Joy2 + jsr mouse_data + + lda connect_st+1 + beq _20 + + jsr speed_change + stz connect_st+1 + + bra _30 + +_20: + dex + lda REG_JOY1L ; Joy1 + + jsr mouse_data + + lda connect_st + beq _30 + + jsr speed_change + stz connect_st + +_30: + ply + plx + plb + plp + rtl + +mouse_data: + + sta tcc__r0 ; (421A / 4218 saved to reg0) + and.b #$0F + cmp.b #$01 ; Is the mouse connected? + beq _m10 + + stz mouseConnect,x ; No connection. + + stz mouseButton,x + stz mousePressed,x + stz mouse_x,x + stz mouse_y,x + + rts +_m10: + lda mouseConnect,x ; When mouse is connected, speed will change. + bne _m20 ; Previous connection status + ; (mouse.com judged by lower 1 bit) + lda #$01 ; Connection check flag on + sta mouseConnect,x + sta connect_st,x + rts +_m20: + rep #$10 + ldy #16 ; Read 16 bit data. + sep #$10 +_m30: + lda REG_JOYA,x + + lsr a + rol mouse_x,x + rol mouse_y,x + dey + bne _m30 + + stz mousePressed,x + + rol tcc__r0 + rol mousePressed,x + rol tcc__r0 + rol mousePressed,x ; Switch turbo + + lda mousePressed,x + eor mouse_sb,x ; Get switch trigger + bne _m40 + + stz mouseButton,x + + rts +_m40: + lda mousePressed,x + sta mouseButton,x + sta mouse_sb,x + + rts + +;--------------------------------------------------------------------------------- +; void MouseSpeedChange(u8 port) +MouseSpeedChange: + php + sep #$30 + phb + phx + phy + + lda #$00 ; Set Data Bank to 0 + pha + plb + + lda 8,s ; Set port + tax + + jsr speed_change + + ply + plx + plb + plp + rtl + +speed_change: + php + sep #$30 + + lda mouseConnect,x + beq _s25 + + lda #$10 + sta tcc__r0h +_s10: + lda #$01 + sta REG_JOYA + lda REG_JOYA,x ; Speed change (1 step) + stz REG_JOYA + + lda #$01 ; Read speed data. + sta REG_JOYA ; Shift register clear. + lda #$00 + sta REG_JOYA + + sta mouse_sp,x ; Speed register clear. + + ldy #10 ; Shift register read has no meaning +_s20: + lda REG_JOYA,x + dey + bne _s20 + + lda REG_JOYA,x ; Read speed + + lsr a + rol mouse_sp,x + + lda REG_JOYA, x + + lsr a + rol mouse_sp,x + lda mouse_sp,x + + cmp mouseSpeedSet,x ; Set speed or not? + + beq _s30 + + dec tcc__r0h ; For error check + bne _s10 +_s25: + lda #$80 ; Speed change error. + sta mouse_sp,x +_s30: + plp + rts + .ENDS \ No newline at end of file diff --git a/snes-examples/pads/mouse/Makefile b/snes-examples/pads/mouse/Makefile new file mode 100644 index 00000000..28f6ac0d --- /dev/null +++ b/snes-examples/pads/mouse/Makefile @@ -0,0 +1,30 @@ +ifeq ($(strip $(PVSNESLIB_HOME)),) +$(error "Please create an environment variable PVSNESLIB_HOME by following this guide: https://github.com/alekmaul/pvsneslib/wiki/Installation") +endif + +include ${PVSNESLIB_HOME}/devkitsnes/snes_rules + +.PHONY: bitmaps all + +#--------------------------------------------------------------------------------- +# ROMNAME is used in snes_rules file +export ROMNAME := mouse + +all: bitmaps $(ROMNAME).sfc + +clean: cleanBuildRes cleanRom cleanGfx + +#--------------------------------------------------------------------------------- +pvsneslibfont.pic: pvsneslibfont.bmp + @echo convert font with no tile reduction ... $(notdir $@) + $(GFXCONV) -s 8 -o 2 -u 16 -p -t bmp -i $< + +cursor.pic: cursor.png + @echo convert sprites ... $(notdir $@) + $(GFXCONV) -s 16 -o 48 -u 16 -p -t png -i $< + +buttons.pic: buttons.png + @echo convert graphics ... $(notdir $@) + $(GFXCONV) -s 8 -o 7 -u 16 -p -e 1 -m -t png -i $< + +bitmaps : pvsneslibfont.pic cursor.pic buttons.pic diff --git a/snes-examples/pads/mouse/buttons.png b/snes-examples/pads/mouse/buttons.png new file mode 100644 index 00000000..c2be1d02 Binary files /dev/null and b/snes-examples/pads/mouse/buttons.png differ diff --git a/snes-examples/pads/mouse/cursor.png b/snes-examples/pads/mouse/cursor.png new file mode 100644 index 00000000..ed95989e Binary files /dev/null and b/snes-examples/pads/mouse/cursor.png differ diff --git a/snes-examples/pads/mouse/data.asm b/snes-examples/pads/mouse/data.asm new file mode 100644 index 00000000..fa89e619 --- /dev/null +++ b/snes-examples/pads/mouse/data.asm @@ -0,0 +1,28 @@ +.include "hdr.asm" + +.section ".rodata1" superfree + +snesfont: +.incbin "pvsneslibfont.pic" + +snespal: +.incbin "pvsneslibfont.pal" + +cursorsprite: +.incbin "cursor.pic" +cursorsprite_end: + +cursorpal: +.incbin "cursor.pal" + +buttonsmap: +.incbin "buttons.map" + +buttonstiles: +.incbin "buttons.pic" +buttonstiles_end: + +buttonspal: +.incbin "buttons.pal" + +.ends diff --git a/snes-examples/pads/mouse/hdr.asm b/snes-examples/pads/mouse/hdr.asm new file mode 100644 index 00000000..9cf154d2 --- /dev/null +++ b/snes-examples/pads/mouse/hdr.asm @@ -0,0 +1,46 @@ +;==LoRom== ; We'll get to HiRom some other time. + +.MEMORYMAP ; Begin describing the system architecture. + SLOTSIZE $8000 ; The slot is $8000 bytes in size. More details on slots later. + DEFAULTSLOT 0 ; There's only 1 slot in SNES, there are more in other consoles. + SLOT 0 $8000 ; Defines Slot 0's starting address. + SLOT 1 $0 $2000 + SLOT 2 $2000 $E000 + SLOT 3 $0 $10000 +.ENDME ; End MemoryMap definition + +.ROMBANKSIZE $8000 ; Every ROM bank is 32 KBytes in size +.ROMBANKS 8 ; 2 Mbits - Tell WLA we want to use 8 ROM Banks + +.SNESHEADER + ID "SNES" ; 1-4 letter string, just leave it as "SNES" + + NAME "LIBSNES MOUSE INPUT " ; Program Title - can't be over 21 bytes, + ; "123456789012345678901" ; use spaces for unused bytes of the name. + + SLOWROM + LOROM + + CARTRIDGETYPE $00 ; $00 = ROM only $02 = ROM+SRAM, see WLA documentation for others + ROMSIZE $08 ; $08 = 2 Mbits, see WLA doc for more.. + SRAMSIZE $00 ; $00 = No Sram, $01 = 16 kbits, see WLA doc for more.. + COUNTRY $01 ; $01 = U.S. $00 = Japan, that's all I know + LICENSEECODE $00 ; Just use $00 + VERSION $00 ; $00 = 1.00, $01 = 1.01, etc. +.ENDSNES + +.SNESNATIVEVECTOR ; Define Native Mode interrupt vector table + COP EmptyHandler + BRK EmptyHandler + ABORT EmptyHandler + NMI VBlank + IRQ EmptyHandler +.ENDNATIVEVECTOR + +.SNESEMUVECTOR ; Define Emulation Mode interrupt vector table + COP EmptyHandler + ABORT EmptyHandler + NMI EmptyHandler + RESET tcc__start ; where execution starts + IRQBRK EmptyHandler +.ENDEMUVECTOR diff --git a/snes-examples/pads/mouse/mouse.c b/snes-examples/pads/mouse/mouse.c new file mode 100644 index 00000000..6cda3c65 --- /dev/null +++ b/snes-examples/pads/mouse/mouse.c @@ -0,0 +1,421 @@ +/*--------------------------------------------------------------------------------- + + + snes mouse demo + -- alekmaul + + Mouse support by DigiDwrf + + +---------------------------------------------------------------------------------*/ +#include + +#ifndef MOUSE_SPEED +#define MOUSE_SPEED + +#define slow 0 +#define normal 1 +#define fast 2 + +#endif + +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}; +bool speedset[2] = {true}; + +//--------------------------------------------------------------------------------- +int main(void) +{ + // Initialize SNES + consoleInit(); + + snes_mouse = true; // Let's tell the system we're using mouse bios (after init) + + // we set mouse speed, or it will just output a random speed. We can change it later manually + mouseSpeedSet[0] = slow; + mouseSpeedSet[1] = slow; + + // Init cursors sprite + oamInitGfxSet(&cursorsprite, (&cursorsprite_end - &cursorsprite), &cursorpal, 48 * 2, 0, 0x0000, OBJ_SIZE16_L32); + + // Initialize text console with our font + consoleSetTextVramBGAdr(0x6800); + consoleSetTextVramAdr(0x3000); + consoleSetTextOffset(0x0100); + consoleInitText(0, 16 * 2, &snesfont, &snespal); + + // Draw a wonderful text :P + consoleDrawText(11, 1, "MOUSE TEST"); + + WaitForVBlank(); // Let's make sure we read mouse for the first time + + 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(4, 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(4, 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); + bgSetDisable(2); + + // Wait for nothing :P + setScreenOn(); + + 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]) + { + WaitForVBlank(); + 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]) + { + WaitForVBlank(); + 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]) + { + WaitForVBlank(); + 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]) + { + WaitForVBlank(); + 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; + } + } + + WaitForVBlank(); + + // 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. + if (mouseConnect[0]) + { + 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)) + { + mouseSpeedSet[0] = slow; + speedset[0] = true; + MouseSpeedChange(0); // Let's tell the mouse we want to change speed. mouseSpeedSet[] has to be populated first. + } + if ((p1_mouse_x > 0x6C) && (p1_mouse_x < 0x94)) + { + mouseSpeedSet[0] = normal; + speedset[0] = true; + MouseSpeedChange(0); // Let's tell the mouse we want to change speed. mouseSpeedSet[] has to be populated first. + } + if ((p1_mouse_x > 0x9C) && (p1_mouse_x < 0xBC)) + { + mouseSpeedSet[0] = fast; + speedset[0] = true; + MouseSpeedChange(0); // Let's tell the mouse we want to change speed. mouseSpeedSet[] has to be populated first. + } + } + } + + if (speedset[0]) + { + dmaCopyVram(&buttonsmap + 0x40, 0x6188, 0x20); // released buttons + dmaCopyVram(&buttonsmap + 0x80, 0x61A8, 0x20); // released buttons + + switch (mouseSpeedSet[0]) + { + case slow: + dmaCopyVram(&buttonsmap + 0x60, 0x6188, 0x0A); // SLOW button pressed + dmaCopyVram(&buttonsmap + 0xA0, 0x61A8, 0x0A); // SLOW button pressed + break; + case normal: + dmaCopyVram(&buttonsmap + 0x6A, 0x618D, 0x0C); // NORMAL button pressed + dmaCopyVram(&buttonsmap + 0xAA, 0x61AD, 0x0C); // NORMAL button pressed + break; + case fast: + dmaCopyVram(&buttonsmap + 0x76, 0x6193, 0x0A); // FAST button pressed + dmaCopyVram(&buttonsmap + 0xB6, 0x61B3, 0x0A); // FAST button pressed + break; + } + speedset[0] = false; + } + + if (mousePressed[0] == false) + dmaFillVram(&buttonsmap, 0x6940, 0x40); // wipe text + } + else if (speedset[0] == false) + { + dmaFillVram(&buttonsmap + 0x40, 0x6188, 0x20); // remove buttons + dmaFillVram(&buttonsmap + 0x80, 0x61A8, 0x20); // remove buttons + speedset[0] = true; + } + + if (mouseConnect[1]) + { + 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)) + { + mouseSpeedSet[1] = slow; + speedset[1] = true; + MouseSpeedChange(1); // Let's tell the mouse we want to change speed. mouseSpeedSet[] has to be populated first. + } + if ((p2_mouse_x > 0x6C) && (p2_mouse_x < 0x94)) + { + mouseSpeedSet[1] = normal; + speedset[1] = true; + MouseSpeedChange(1); // Let's tell the mouse we want to change speed. mouseSpeedSet[] has to be populated first. + } + if ((p2_mouse_x > 0x9C) && (p2_mouse_x < 0xBC)) + { + mouseSpeedSet[1] = fast; + speedset[1] = true; + consoleMesenBreakpoint(); + MouseSpeedChange(1); // Let's tell the mouse we want to change speed. mouseSpeedSet[] has to be populated first. + } + } + } + + if (speedset[1]) + { + dmaCopyVram(&buttonsmap + 0x40, 0x6308, 0x20); // released buttons + dmaCopyVram(&buttonsmap + 0x80, 0x6328, 0x20); // released buttons + + switch (mouseSpeedSet[1]) + { + case slow: + dmaCopyVram(&buttonsmap + 0x60, 0x6308, 0x0A); // SLOW button pressed + dmaCopyVram(&buttonsmap + 0xA0, 0x6328, 0x0A); // SLOW button pressed + break; + case normal: + dmaCopyVram(&buttonsmap + 0x6A, 0x630D, 0x0C); // NORMAL button pressed + dmaCopyVram(&buttonsmap + 0xAA, 0x632D, 0x0C); // NORMAL button pressed + break; + case fast: + dmaCopyVram(&buttonsmap + 0x76, 0x6313, 0x0A); // FAST button pressed + dmaCopyVram(&buttonsmap + 0xB6, 0x6333, 0x0A); // FAST button pressed + break; + } + speedset[1] = false; + } + + if (mousePressed[1] == false) + dmaFillVram(&buttonsmap, 0x6AC0, 0x40); // wipe text + } + else if (speedset[1] == false) + { + dmaFillVram(&buttonsmap + 0x40, 0x6308, 0x20); // remove buttons + dmaFillVram(&buttonsmap + 0x80, 0x6328, 0x20); // remove buttons + speedset[1] = true; + } + } + return 0; +} \ No newline at end of file diff --git a/snes-examples/pads/mouse/pvsneslibfont.bmp b/snes-examples/pads/mouse/pvsneslibfont.bmp new file mode 100644 index 00000000..71bc2193 Binary files /dev/null and b/snes-examples/pads/mouse/pvsneslibfont.bmp differ