Skip to content

Commit

Permalink
[msx2] joystick support
Browse files Browse the repository at this point in the history
  • Loading branch information
pvmm committed Aug 9, 2022
1 parent c02a40c commit 605e967
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 52 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
build/
.*.swp
venv
36 changes: 24 additions & 12 deletions common/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,16 @@ inline void title_screen_update(minefield* mf)
// TODO: platform dependent title screen, animations, music etc.
draw_title_screen(mf);

uint8_t input = input_read(KEYBOARD);
if (input == MINE_INPUT_IGNORED) {
return;
uint8_t input = MINE_INPUT_IGNORED;
for (uint8_t source = 0; source <= JOY_4; ++source) {
input = input_read(source);
if (input != MINE_INPUT_IGNORED)
break;
}
debug("\nkey code = ", input);
if (input == MINE_INPUT_IGNORED)
return;

debug("\nkey code = ", input);
switch (input) {
case MINE_INPUT_OPEN:
case MINE_INPUT_OPEN_BLOCK:
Expand Down Expand Up @@ -143,12 +147,16 @@ inline void game_over_update(minefield* mf)
draw_minefield_contents(mf);
#endif

uint8_t input = input_read(KEYBOARD);
if (input == MINE_INPUT_IGNORED) {
return;
uint8_t input = MINE_INPUT_IGNORED;
for (uint8_t source = 0; source <= JOY_4; ++source) {
input = input_read(source);
if (input != MINE_INPUT_IGNORED)
break;
}
debug("\nkey code = ", input);
if (input == MINE_INPUT_IGNORED)
return;

debug("\nkey code = ", input);
switch (input) {
case MINE_INPUT_OPEN:
case MINE_INPUT_OPEN_BLOCK:
Expand Down Expand Up @@ -177,12 +185,16 @@ inline void gameplay_update(minefield* mf)
update_counter(mf);
#endif /* ENABLE_COUNTER */

uint8_t input = input_read(KEYBOARD);
if (input == MINE_INPUT_IGNORED) {
return;
uint8_t input = MINE_INPUT_IGNORED;
for (uint8_t source = 0; source <= JOY_4; ++source) {
input = input_read(source);
if (input != MINE_INPUT_IGNORED)
break;
}
debug("\nkey code = ", input);
if (input == MINE_INPUT_IGNORED)
return;

debug("\nkey code = ", input);
update_gameplay_input(mf, input);
}

Expand Down
23 changes: 23 additions & 0 deletions platforms/msx2/debugdevice.tcl
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
proc test_joystick1 {} {
global keyjoystick1
set keyjoystick1.triga 1
set keyjoystick1.trigb 2
set keyjoystick1.up W
set keyjoystick1.down S
set keyjoystick1.left A
set keyjoystick1.right D
plug joyporta keyjoystick1
}

proc test_joystick2 {} {
global keyjoystick1
set keyjoystick1.triga 1
set keyjoystick1.trigb 2
set keyjoystick1.up W
set keyjoystick1.down S
set keyjoystick1.left A
set keyjoystick1.right D
plug joyportb keyjoystick1
}

proc pause {{value 0}} {
global use_pause
if {$use_pause && $value == 0xff} { debug break }
Expand All @@ -15,5 +37,6 @@ if { [info exists ::env(DEBUG)] } {
debug set_watchpoint write_io {0x2e} {} {pause $::wp_last_value}
}

# Click on the middle button to confine mouse pointer inside OpenMSX window.
bind "mouse button2 down" toggle grabinput
plug joyporta mouse
44 changes: 42 additions & 2 deletions platforms/msx2/input.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
#include "common.h"


uint8_t source_mouse = 0xff;


static uint8_t keyboard_read_row(uint8_t row) __z88dk_fastcall __naked
{
row; assert(row <= 10);
Expand Down Expand Up @@ -50,12 +53,49 @@ static uint8_t keyboard_read()
}


static joydata joy;


static uint8_t joystick_read(uint8_t source)
{
uint8_t input = read_raw_joyport(source);

if (!(input & (1 << 0))) {
return MINE_INPUT_UP;
}
if (!(input & (1 << 1))) {
return MINE_INPUT_DOWN;
}
if (!(input & (1 << 2))) {
return MINE_INPUT_LEFT;
}
if (!(input & (1 << 3))) {
return MINE_INPUT_RIGHT;
}
if (!(input & (1 << 4))) {
return MINE_INPUT_OPEN;
}
if (!(input & (1 << 5))) {
return MINE_INPUT_FLAG;
}
return MINE_INPUT_IGNORED;
}


uint8_t input_read(uint8_t source)
{
static uint8_t wait_joy[3] = {0};

if (source == KEYBOARD)
return keyboard_read();

/* not implemented yet */
// distinguish mouse input from joystick input
else if (source < JOY_3 && source_mouse == 0xff) {
uint8_t* tick = &wait_joy[source];
if ((*tick)++ >= 30) {
*tick = 0;
return joystick_read(source);
}
}
return MINE_INPUT_IGNORED;
}

Expand Down
7 changes: 4 additions & 3 deletions platforms/msx2/mouse.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
#include "minefield.h"


/* mouse data */
static struct mouse mouse;
joydata mouse;

/* contextual mouse data */
static int x = 84;
static int y = 33;
static bool l_pressed = false;
Expand All @@ -18,7 +19,7 @@ static bool ignored = false;

void update_mouse(minefield* mf, uint8_t source)
{
read_mouse(&mouse, source);
read_joyport(&mouse, source);

x -= mouse.dx;
if (x > 255) x = 255;
Expand Down
57 changes: 38 additions & 19 deletions platforms/msx2/mouselib.asm
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
; int8_t search_mouse()
; void read_mouse(struct mouse* mouse, uint8_t source) __sdcccall(0)
; void read_raw_joyport(uint8_t source) __z88dk_fastcall

.globl read_mouse
.globl _search_mouse
.globl _read_joyport

REGWTP = 0xA0 ; register write port
VALWTP = 0xA1 ; value write port
Expand All @@ -16,35 +18,36 @@ IO_REG2 = 15

_search_mouse::
ld de, #PORT1 ; DE = mouse on port 1
ld b, #LONG_WAIT ; first delay is the longest
ld b, #LONG_WAIT ; first delay is longer
call search_device0
cp #0xff
jp z, port2 ; device not found? Searching on port 2
or a ; mouse signature?
ld a, #1
ld l, #1
ret z ; signature found, return "1" for mouse port 1
ld a, e
ld l, e
ret ; return x offset
port2:
ld de, #PORT2 ; DE = mouse on port 2
call search_device
cp #0xff
ld l, a
ret z ; return -1: device not found or it's a joystick
or a ; mouse signature?
ld a, #2
ld l, #2
ret z ; signature found, return "2" for mouse port 2
xor a
ret ; ignore input
ld l, #0
ret ; ignore input (return "0")

search_device:
ld b, #SHORT_WAIT
search_device0:
call get_mouse_data0 ; read bits 7-4 of the offset
call get_joy_data0 ; read bits 7-4 of the offset
ld hl, #saved_tmp_data
ld (hl), a ; save x offset 1/2
or #0xc0 ; clear bits b7/b6
ld c, a ; c <- byte1
call get_mouse_data ; read bits 3-0 of the offset
call get_joy_data ; read bits 3-0 of the offset
inc hl
ld (hl), a ; save x offset 2/2
or #0xc0
Expand All @@ -62,9 +65,10 @@ search_device0:
rlca
or #0x3f
and d ; a <- (byte1 << 2 | 0x3f) & (byte1 << 4 | 0x0f) & byte2
ld l, a
ret ; return device id fingerprint

_read_mouse::
_read_joyport::
push ix
ld ix, #2
add ix, sp
Expand All @@ -75,10 +79,10 @@ _read_mouse::

ld de, #PORT1 ; DE = 01310h for mouse in port 1 (D = 00010011b, E = 00010000b)
and #2
jr z, read_mouse
jr z, read_cached_joyport
ld de, #PORT2 ; DE = 06C20h for mouse in port 2 (D = 01101100b, E = 00100000b)

read_mouse:
read_cached_joyport:
ld ix, #saved_tmp_data
ld a, 0(ix) ; read previously stored x offset used in detection
and #0xf
Expand All @@ -93,14 +97,14 @@ read_mouse:

ld (hl), a ; save to mouse data struct (1/4)
inc hl
call get_mouse_data ; read bits 7-4 of the y offset
call get_joy_data ; read bits 7-4 of the y offset
and #0xf
rlca
rlca
rlca
rlca ; adjust y offset's higher bits
ld c, a ; save as temp data
call get_mouse_data ; read bits 3-0 of the y offset
call get_joy_data ; read bits 3-0 of the y offset
; can read mouse button bit 4 = left button / bit 5 = right button
ld b, a
and #0xf
Expand Down Expand Up @@ -130,9 +134,25 @@ read_mouse:
pop ix
ret

get_mouse_data:
_read_raw_joyport::
ld a, l ; a <- l (z88dk_fastcall)
ld de, #PORT1 ; DE = 01310h for mouse in port 1 (D = 00010011b, E = 00010000b)
and #2
ld b, #LONG_WAIT ; first delay is longer
jr z, read_joyport
ld de, #PORT2 ; DE = 06C20h for mouse in port 2 (D = 01101100b, E = 00100000b)
read_joyport:
call get_joy_data0 ; read bits 7-4 of joystick
call get_joy_data ; read bits 5-0 of the joystick
and #0x3f
ld l, a ; z88dk_fastcall return register
ld b, #LONGER_WAIT
call wait
ret

get_joy_data:
ld b, #SHORT_WAIT
get_mouse_data0:
get_joy_data0:
di
ld a, #IO_REG2
out (#REGWTP), a ; read PSG register 15 for mouse
Expand Down Expand Up @@ -171,6 +191,5 @@ wait_loop3: ; R800 extra wait 2/2
.area DATA

saved_tmp_data:
.db 0xff
.db 0xff

.db #0xff
.db #0xff
15 changes: 11 additions & 4 deletions platforms/msx2/msx2.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef MSX2_H
#define MSX2_H

#include "game.h"
#include <stdint.h>

/* __sdcccall function attribute on SDCC 4.1.12 and later */
Expand Down Expand Up @@ -87,18 +88,24 @@ void put_sprite_attr(struct sprite_attr *src, uint8_t index) SDCCCALL0;
/* search for plugged mouse device */
int8_t search_mouse();

/* structure for storing mouse data */
struct mouse {
/* structure for storing mouse or joystick data */
typedef struct {
int8_t dx;
int8_t dy;
uint8_t l_button; /* 1 = OFF, 2 = ON */
uint8_t r_button; /* 1 = OFF, 2 = ON */
};
} joydata;

void read_joyport(joydata* data, uint8_t source) SDCCCALL0;

void read_mouse(struct mouse* mouse, uint8_t source) SDCCCALL0;
uint8_t read_raw_joyport(uint8_t source) __z88dk_fastcall;

void put_mouse(uint8_t x, uint8_t y);

void hide_mouse();

inline void update_mouse(minefield* mf, uint8_t source);

inline void update_joystick(uint8_t source);

#endif /* MSX2_H */
Loading

0 comments on commit 605e967

Please sign in to comment.