mirror of
https://github.com/libretro/RetroArch.git
synced 2026-11-11 11:21:38 -10:00
The pointer store took a touch to be there when its packed position was not 0. A contact at the window's origin packs to 0, so a finger down at 0,0 was not a touch: the pointer read the mouse and was not pressed, and a lightgun aiming at the first touch aimed at the mouse. DirectInput, raw input and SDL3 went by whether the contact existed before they published, so for them this was a regression. Where a contact is, whether there is one and whether it is down are three things, and input_driver_publish_touches() takes them separately: a position, a bit in @present, a bit in @down. A contact at 0,0 is one; one that has lifted may keep its place, there and not down - a finger's last place under Wayland, a pen in the air under SDL3. DirectInput, raw input and SDL3's fingers say each contact they list is there. Wayland keeps the rule it had, which is its own and is now written where it belongs: a place at 0,0 is how the desktop reports a mouse button, and is not a touch. pointer_frame_test: a touch down at the origin, one lifted there, a place with none, the viewport's edges, sparse places, the mouse's fallback, the lightgun's choice, a pen in the air at the origin.
494 lines
26 KiB
C
494 lines
26 KiB
C
/* Oracle for input/input_pointer_frame.h: the frontend's answers for the
|
|
* mouse, the pointer and the lightgun's aim, from what an input driver
|
|
* published at its poll.
|
|
*
|
|
* The header is included as input_driver.c includes it, with a viewport
|
|
* and a translation of this test's own that count how often they are
|
|
* asked - which is the point of the store: a device is placed in the
|
|
* viewport once a poll, however many values are read.
|
|
*
|
|
* 1. the mouse: motion, place in the window, buttons, the second port's
|
|
* device, a port with none;
|
|
* 2. a wheel notch reads the same every time in its frame;
|
|
* 3. the pointer from a mouse standing for three touches, and for one;
|
|
* 4. real touches: a place with a touch reads the touch, one that is
|
|
* down is pressed, a lifted one keeps its place and is pressed only
|
|
* as the mouse says; a place with none reads the mouse;
|
|
* 5. the lightgun's aim reports off-screen where the pointer holds to
|
|
* the edge;
|
|
* 6. one viewport fetch a poll, one translation a device and kind;
|
|
* 7. a poll in which nothing is published: the driver is to be asked;
|
|
* 8. ports reading by Mouse Index, a port with no mouse still reading a
|
|
* real touch, and the kind of device each mouse was last read as;
|
|
* 9. only the mouse by index with the pointer and the lightgun every
|
|
* port's, and the lightgun aiming at the first touch;
|
|
* 10. how many pointers are down;
|
|
* 11. the pointer placed off-screen as the lightgun is;
|
|
* 12. a touch read alone: a pen in the air;
|
|
* 13. the poll's viewport, asked for once a poll;
|
|
* 14. a touch's place, its presence and whether it is down are three
|
|
* things: a touch at 0,0, one lifted there, a place with none,
|
|
* the viewport's edges, sparse places, the lightgun. */
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdint.h>
|
|
#include <boolean.h>
|
|
#include <libretro.h>
|
|
|
|
#include "input/input_driver.h"
|
|
#include "gfx/video_driver.h"
|
|
|
|
static unsigned failures, vp_asked, translations;
|
|
#define CHECK(cond, msg) do { if (!(cond)) { failures++; \
|
|
printf("FAIL %s\n", msg); } } while (0)
|
|
|
|
/* A 200x100 viewport at 0,0 of a 200x100 screen. In it a position is
|
|
* itself; outside, held to the edge or -0x8000 as asked. The screen
|
|
* position is the position plus 1000, to tell the two apart. */
|
|
bool video_driver_get_viewport_info(struct video_viewport *vp)
|
|
{
|
|
vp_asked++;
|
|
vp->pos = VIDEO_POS_PACK(0, 0);
|
|
vp->dims = VIDEO_SCALE_PACK(200, 100);
|
|
vp->full_dims = VIDEO_SCALE_PACK(200, 100);
|
|
return true;
|
|
}
|
|
|
|
bool video_driver_translate_coord_viewport(struct video_viewport *vp,
|
|
int x, int y, uint32_t *res_pos, uint32_t *res_screen_pos,
|
|
bool report_oob)
|
|
{
|
|
int vx = x, vy = y;
|
|
translations++;
|
|
(void)vp;
|
|
if (x < 0 || x >= 200)
|
|
vx = report_oob ? -0x8000 : (x < 0 ? 0 : 199);
|
|
if (y < 0 || y >= 100)
|
|
vy = report_oob ? -0x8000 : (y < 0 ? 0 : 99);
|
|
*res_pos = VIDEO_POS_PACK(vx, vy);
|
|
*res_screen_pos = VIDEO_POS_PACK(x + 1000, y + 1000);
|
|
return true;
|
|
}
|
|
|
|
bool input_driver_pointer_is_offscreen(int16_t x, int16_t y)
|
|
{ return x == -0x8000 || y == -0x8000; }
|
|
|
|
/* Port 0's Mouse Index is 1, port 1's is 0, port 2's is a mouse that is
|
|
* not there. */
|
|
unsigned input_mouse_port_index(unsigned port)
|
|
{ return port == 0 ? 1 : (port == 1 ? 0 : 7); }
|
|
|
|
#include "input/input_pointer_frame.h"
|
|
|
|
/* @count places, each with a contact; @down says which are pressed. */
|
|
static void touches_set(const uint32_t *pos, unsigned count, unsigned down)
|
|
{
|
|
input_pointer_touches_set(pos, count, (1u << count) - 1, down);
|
|
}
|
|
|
|
static int16_t rd(unsigned port, unsigned device, unsigned idx, unsigned id)
|
|
{
|
|
int16_t v = -1;
|
|
if (!input_pointer_frame_read(port, device, idx, id, &v))
|
|
return -2; /* the driver is to be asked */
|
|
return v;
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
input_pointer_frame_t f[2];
|
|
uint32_t touch[3];
|
|
uint32_t pos = 0;
|
|
|
|
memset(f, 0, sizeof(f));
|
|
f[0].pos = VIDEO_POS_PACK(40, 30);
|
|
f[0].rel = VIDEO_POS_PACK(-3, 7);
|
|
f[0].buttons = INPUT_POINTER_RIGHT | INPUT_POINTER_WHEEL_DOWN;
|
|
f[1].pos = VIDEO_POS_PACK(5, 6);
|
|
f[1].buttons = INPUT_POINTER_LEFT;
|
|
|
|
/* 7 (before anything is published) */
|
|
input_pointer_frames_clear();
|
|
CHECK(rd(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_X) == -2
|
|
&& rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X) == -2
|
|
&& !input_pointer_frame_pos(0, RETRO_DEVICE_MOUSE, 0, &pos),
|
|
"nothing published: the driver is to be asked");
|
|
|
|
/* 1 */
|
|
input_pointer_frames_set(f, 2, INPUT_POINTERS_MOUSE_3_TOUCHES);
|
|
CHECK(rd(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_X) == -3
|
|
&& rd(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_Y) == 7,
|
|
"the mouse's motion");
|
|
CHECK(rd(0, RARCH_DEVICE_MOUSE_SCREEN, 0, RETRO_DEVICE_ID_MOUSE_X) == 40
|
|
&& rd(0, RARCH_DEVICE_MOUSE_SCREEN, 0, RETRO_DEVICE_ID_MOUSE_Y) == 30,
|
|
"the mouse's place in the window");
|
|
CHECK(input_pointer_frame_pos(0, RARCH_DEVICE_MOUSE_SCREEN, 0, &pos)
|
|
&& pos == VIDEO_POS_PACK(40, 30)
|
|
&& input_pointer_frame_pos(0, RETRO_DEVICE_MOUSE, 0, &pos)
|
|
&& pos == VIDEO_POS_PACK(-3, 7),
|
|
"the packed position is the published word");
|
|
CHECK( rd(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_RIGHT) == 1
|
|
&& rd(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_LEFT) == 0
|
|
&& rd(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_MIDDLE) == 0
|
|
&& rd(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_BUTTON_4) == 0,
|
|
"the mouse's buttons");
|
|
CHECK( rd(1, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_LEFT) == 1
|
|
&& rd(1, RARCH_DEVICE_MOUSE_SCREEN, 0, RETRO_DEVICE_ID_MOUSE_X) == 5,
|
|
"the second port reads the second device");
|
|
CHECK( rd(2, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_LEFT) == 0
|
|
&& rd(2, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_RIGHT) == 0,
|
|
"a port with no device reads nothing, and not the driver");
|
|
CHECK( rd(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B) == -2
|
|
&& rd(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_a) == -2
|
|
&& rd(0, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_TRIGGER) == -2,
|
|
"pads, keys and the lightgun's buttons are still the driver's");
|
|
|
|
/* 2 */
|
|
CHECK( rd(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_WHEELDOWN) == 1
|
|
&& rd(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_WHEELDOWN) == 1
|
|
&& rd(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_WHEELDOWN) == 1
|
|
&& rd(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_WHEELUP) == 0,
|
|
"a wheel notch reads the same every time in its frame");
|
|
|
|
/* 3: a mouse for three touches - any button; right or middle; middle */
|
|
CHECK( rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X) == 40
|
|
&& rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_Y) == 30
|
|
&& rd(0, RARCH_DEVICE_POINTER_SCREEN, 0, RETRO_DEVICE_ID_POINTER_X) == 1040,
|
|
"the pointer is where the translation puts the mouse");
|
|
CHECK( rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED) == 1
|
|
&& rd(0, RETRO_DEVICE_POINTER, 1, RETRO_DEVICE_ID_POINTER_PRESSED) == 1
|
|
&& rd(0, RETRO_DEVICE_POINTER, 2, RETRO_DEVICE_ID_POINTER_PRESSED) == 0
|
|
&& rd(0, RETRO_DEVICE_POINTER, 3, RETRO_DEVICE_ID_POINTER_PRESSED) == 0
|
|
&& rd(1, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED) == 1
|
|
&& rd(1, RETRO_DEVICE_POINTER, 1, RETRO_DEVICE_ID_POINTER_PRESSED) == 0,
|
|
"a mouse standing for three touches");
|
|
/* ...and for one: the left button */
|
|
input_pointer_frames_set(f, 2, 0);
|
|
CHECK( rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED) == 0
|
|
&& rd(1, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED) == 1
|
|
&& rd(1, RETRO_DEVICE_POINTER, 1, RETRO_DEVICE_ID_POINTER_PRESSED) == 0
|
|
&& rd(1, RETRO_DEVICE_POINTER, 1, RETRO_DEVICE_ID_POINTER_X) == 0,
|
|
"a mouse standing for one touch");
|
|
|
|
/* 6 */
|
|
input_pointer_frames_set(f, 2, INPUT_POINTERS_MOUSE_3_TOUCHES);
|
|
vp_asked = translations = 0;
|
|
rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X);
|
|
rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_Y);
|
|
rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED);
|
|
rd(0, RETRO_DEVICE_POINTER, 1, RETRO_DEVICE_ID_POINTER_PRESSED);
|
|
rd(0, RETRO_DEVICE_POINTER, 2, RETRO_DEVICE_ID_POINTER_PRESSED);
|
|
rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_IS_OFFSCREEN);
|
|
rd(0, RARCH_DEVICE_POINTER_SCREEN, 0, RETRO_DEVICE_ID_POINTER_X);
|
|
input_pointer_frame_pos(0, RETRO_DEVICE_POINTER, 0, &pos);
|
|
CHECK(vp_asked == 1 && translations == 1,
|
|
"eight pointer reads: one viewport fetch, one translation");
|
|
rd(0, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X);
|
|
rd(0, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y);
|
|
rd(0, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN);
|
|
CHECK(vp_asked == 1 && translations == 2,
|
|
"the lightgun's aim after them: no fetch, one translation more");
|
|
rd(1, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X);
|
|
CHECK(vp_asked == 1 && translations == 3,
|
|
"a second device: no fetch, one translation more");
|
|
rd(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_X);
|
|
rd(0, RARCH_DEVICE_MOUSE_SCREEN, 0, RETRO_DEVICE_ID_MOUSE_X);
|
|
CHECK(vp_asked == 1 && translations == 3, "the mouse needs neither");
|
|
input_pointer_frames_set(f, 2, INPUT_POINTERS_MOUSE_3_TOUCHES);
|
|
rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X);
|
|
CHECK(vp_asked == 2 && translations == 4, "the next poll places it afresh");
|
|
|
|
/* 5: out of the viewport the pointer holds to the edge, the gun says so */
|
|
f[0].pos = VIDEO_POS_PACK(250, 30);
|
|
input_pointer_frames_set(f, 2, INPUT_POINTERS_MOUSE_3_TOUCHES);
|
|
CHECK( rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X) == 199
|
|
&& rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_IS_OFFSCREEN) == 0
|
|
&& rd(0, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X) == -0x8000
|
|
&& rd(0, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y) == 30
|
|
&& rd(0, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN) == 1
|
|
&& rd(0, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_X) == -3,
|
|
"out of the viewport: the pointer holds to the edge, the lightgun is off-screen");
|
|
f[0].pos = VIDEO_POS_PACK(40, 30);
|
|
|
|
/* 4: touch 0 down at 60,70; touch 1 lifted, last at 80,90; no touch 2 */
|
|
touch[0] = VIDEO_POS_PACK(60, 70);
|
|
touch[1] = VIDEO_POS_PACK(80, 90);
|
|
touch[2] = 0;
|
|
f[0].buttons = INPUT_POINTER_MIDDLE;
|
|
input_pointer_frames_set(f, 1, INPUT_POINTERS_MOUSE_3_TOUCHES);
|
|
/* places 0 and 1 hold a contact; place 2 holds none */
|
|
input_pointer_touches_set(touch, 3, 3, 1 << 0);
|
|
CHECK( rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X) == 60
|
|
&& rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_Y) == 70
|
|
&& rd(0, RARCH_DEVICE_POINTER_SCREEN, 0, RETRO_DEVICE_ID_POINTER_Y) == 1070
|
|
&& rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED) == 1,
|
|
"a touch that is down: its place, pressed");
|
|
CHECK( rd(0, RETRO_DEVICE_POINTER, 1, RETRO_DEVICE_ID_POINTER_X) == 80
|
|
&& rd(0, RETRO_DEVICE_POINTER, 1, RETRO_DEVICE_ID_POINTER_PRESSED) == 1,
|
|
"a lifted touch keeps its place, and is pressed as the mouse says");
|
|
CHECK( rd(0, RETRO_DEVICE_POINTER, 2, RETRO_DEVICE_ID_POINTER_X) == 40
|
|
&& rd(0, RETRO_DEVICE_POINTER, 2, RETRO_DEVICE_ID_POINTER_PRESSED) == 1,
|
|
"a place with no touch reads the mouse");
|
|
CHECK(input_pointer_frame_pos(3, RETRO_DEVICE_POINTER, 0, &pos)
|
|
&& pos == VIDEO_POS_PACK(60, 70)
|
|
&& input_pointer_frame_pos(0, RARCH_DEVICE_POINTER_SCREEN, 1, &pos)
|
|
&& pos == VIDEO_POS_PACK(1080, 1090),
|
|
"the packed pointer position, and one mouse is every port's");
|
|
f[0].buttons = 0;
|
|
input_pointer_frames_set(f, 1, INPUT_POINTERS_MOUSE_3_TOUCHES);
|
|
/* places 0 and 1 hold a contact; place 2 holds none */
|
|
input_pointer_touches_set(touch, 3, 3, 1 << 0);
|
|
CHECK( rd(0, RETRO_DEVICE_POINTER, 1, RETRO_DEVICE_ID_POINTER_PRESSED) == 0
|
|
&& rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED) == 1,
|
|
"with no button held only the touch that is down is pressed");
|
|
|
|
/* 8: by Mouse Index - port 0 reads device 1, port 1 device 0 */
|
|
f[0].buttons = INPUT_POINTER_RIGHT;
|
|
f[1].buttons = INPUT_POINTER_LEFT;
|
|
input_pointer_frames_set(f, 2, INPUT_POINTERS_BY_MOUSE_INDEX);
|
|
touches_set(touch, 1, 1 << 0);
|
|
CHECK( rd(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_LEFT) == 1
|
|
&& rd(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_RIGHT) == 0
|
|
&& rd(1, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_RIGHT) == 1
|
|
&& rd(1, RARCH_DEVICE_MOUSE_SCREEN, 0, RETRO_DEVICE_ID_MOUSE_X) == 40,
|
|
"by Mouse Index: a port reads the device at its index");
|
|
CHECK( rd(2, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_LEFT) == 0
|
|
&& rd(2, RARCH_DEVICE_MOUSE_SCREEN, 0, RETRO_DEVICE_ID_MOUSE_X) == 0
|
|
&& rd(2, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X) == 0,
|
|
"by Mouse Index: a port whose mouse is not there reads nothing");
|
|
CHECK( rd(2, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X) == 60
|
|
&& rd(2, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED) == 1
|
|
&& rd(2, RETRO_DEVICE_POINTER, 1, RETRO_DEVICE_ID_POINTER_PRESSED) == 0
|
|
&& input_pointer_frame_pos(2, RETRO_DEVICE_POINTER, 0, &pos)
|
|
&& pos == VIDEO_POS_PACK(60, 70),
|
|
"a port with no mouse still reads a real touch, and only that");
|
|
touches_set(touch, 0, 0);
|
|
CHECK( rd(2, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED) == 0
|
|
&& rd(2, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X) == 0,
|
|
"with no mouse and no touch a pointer reads nothing");
|
|
/* the kind each device was last read as: port 0 is device 1 */
|
|
rd(0, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X);
|
|
rd(1, RARCH_DEVICE_POINTER_SCREEN, 0, RETRO_DEVICE_ID_POINTER_X);
|
|
CHECK(input_pointers.read_as[1] == RETRO_DEVICE_LIGHTGUN
|
|
&& input_pointers.read_as[0] == RARCH_DEVICE_POINTER_SCREEN,
|
|
"each device records the kind it was last read as");
|
|
input_pointer_frame_pos(0, RETRO_DEVICE_MOUSE, 0, &pos);
|
|
input_pointer_frames_set(f, 2, INPUT_POINTERS_BY_MOUSE_INDEX);
|
|
CHECK(input_pointers.read_as[1] == RETRO_DEVICE_MOUSE
|
|
&& input_pointers.read_as[0] == RARCH_DEVICE_POINTER_SCREEN,
|
|
"and keeps it over the next poll");
|
|
|
|
/* 9: only the mouse by index; the pointer and the gun every port's.
|
|
* Port 2's mouse is not there, port 1's index is 0. */
|
|
f[0].pos = VIDEO_POS_PACK(40, 30);
|
|
f[0].buttons = INPUT_POINTER_LEFT;
|
|
input_pointer_frames_set(f, 1, INPUT_POINTERS_BY_MOUSE_INDEX
|
|
| INPUT_POINTERS_AIM_EVERY_PORT | INPUT_POINTERS_GUN_AT_TOUCH);
|
|
touches_set(touch, 0, 0);
|
|
CHECK( rd(2, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_LEFT) == 0
|
|
&& rd(2, RARCH_DEVICE_MOUSE_SCREEN, 0, RETRO_DEVICE_ID_MOUSE_X) == 0
|
|
&& rd(1, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_LEFT) == 1,
|
|
"aim every port's: the mouse still goes by the port's index");
|
|
CHECK( rd(2, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X) == 40
|
|
&& rd(2, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED) == 1
|
|
&& rd(2, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X) == 40
|
|
&& rd(2, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y) == 30,
|
|
"aim every port's: the pointer and the lightgun read the mouse on any port");
|
|
/* the gun at the first touch while there is one; out of the viewport
|
|
* it is off-screen */
|
|
touch[0] = VIDEO_POS_PACK(60, 70);
|
|
touches_set(touch, 1, 1 << 0);
|
|
vp_asked = translations = 0;
|
|
CHECK( rd(0, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X) == 60
|
|
&& rd(0, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y) == 70
|
|
&& rd(0, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN) == 0
|
|
&& input_pointer_frame_pos(0, RETRO_DEVICE_LIGHTGUN, 0, &pos)
|
|
&& pos == VIDEO_POS_PACK(60, 70)
|
|
&& vp_asked == 0 && translations == 1,
|
|
"the lightgun aims at the first touch: one translation, the poll's viewport");
|
|
touch[0] = VIDEO_POS_PACK(260, 70);
|
|
touches_set(touch, 1, 1 << 0);
|
|
CHECK( rd(0, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN) == 1
|
|
&& rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X) == 199,
|
|
"a touch out of the viewport: the gun is off-screen, the pointer at the edge");
|
|
touches_set(touch, 0, 0);
|
|
CHECK( rd(0, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X) == 40,
|
|
"with no touch the lightgun aims at the mouse");
|
|
/* without the flag a touch does not move the gun */
|
|
touch[0] = VIDEO_POS_PACK(60, 70);
|
|
input_pointer_frames_set(f, 1, INPUT_POINTERS_MOUSE_3_TOUCHES);
|
|
touches_set(touch, 1, 1 << 0);
|
|
CHECK( rd(0, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X) == 40,
|
|
"a driver that does not say so: the lightgun stays on the mouse");
|
|
|
|
/* 10: how many pointers are down - the touches that are, else the
|
|
* mouse standing for one */
|
|
f[0].pos = VIDEO_POS_PACK(40, 30);
|
|
f[0].buttons = INPUT_POINTER_LEFT;
|
|
touch[0] = VIDEO_POS_PACK(60, 70);
|
|
touch[1] = VIDEO_POS_PACK(80, 90);
|
|
input_pointer_frames_set(f, 1, 0);
|
|
touches_set(touch, 2, 3);
|
|
CHECK(rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_COUNT) == 2,
|
|
"the count is the touches that are down");
|
|
touches_set(touch, 0, 0);
|
|
CHECK(rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_COUNT) == 1,
|
|
"with no touch the count is the mouse's, its button held");
|
|
f[0].buttons = 0;
|
|
input_pointer_frames_set(f, 1, 0);
|
|
vp_asked = translations = 0;
|
|
CHECK(rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_COUNT) == 0
|
|
&& vp_asked == 0 && translations == 0,
|
|
"nothing down counts none, and the count places nothing");
|
|
|
|
/* 11: the pointer placed as the lightgun is - off-screen outside */
|
|
f[0].pos = VIDEO_POS_PACK(250, 30);
|
|
input_pointer_frames_set(f, 1, INPUT_POINTERS_POINTER_OFFSCREEN);
|
|
CHECK( rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X) == -0x8000
|
|
&& rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_Y) == 30
|
|
&& rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_IS_OFFSCREEN) == 1,
|
|
"an off-screen pointer says so where the driver has it so");
|
|
touch[0] = VIDEO_POS_PACK(60, 170);
|
|
touches_set(touch, 1, 1);
|
|
CHECK( rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X) == 60
|
|
&& rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_Y) == -0x8000
|
|
&& rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_IS_OFFSCREEN) == 1
|
|
&& rd(0, RARCH_DEVICE_POINTER_SCREEN, 0, RETRO_DEVICE_ID_POINTER_Y) == 1170,
|
|
"and so does a touch");
|
|
f[0].pos = VIDEO_POS_PACK(40, 30);
|
|
|
|
/* 12: a touch read alone - a pen in the air is not pressed by the
|
|
* mouse's button, and counts none */
|
|
f[0].buttons = INPUT_POINTER_LEFT;
|
|
touch[0] = VIDEO_POS_PACK(60, 70);
|
|
input_pointer_frames_set(f, 1, INPUT_POINTERS_TOUCH_ALONE);
|
|
touches_set(touch, 1, 0);
|
|
CHECK( rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X) == 60
|
|
&& rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED) == 0
|
|
&& rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_COUNT) == 0,
|
|
"a touch read alone: lifted, the mouse's button does not press it");
|
|
touches_set(touch, 1, 1);
|
|
CHECK( rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED) == 1
|
|
&& rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_COUNT) == 1,
|
|
"a touch read alone: down, it is pressed");
|
|
touches_set(touch, 0, 0);
|
|
CHECK( rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X) == 40
|
|
&& rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED) == 1
|
|
&& rd(0, RETRO_DEVICE_POINTER, 1, RETRO_DEVICE_ID_POINTER_PRESSED) == 0,
|
|
"a touch read alone: with none, the mouse stands for the first");
|
|
/* without the flag a lifted touch is pressed as the mouse says */
|
|
input_pointer_frames_set(f, 1, 0);
|
|
touches_set(touch, 1, 0);
|
|
CHECK( rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED) == 1,
|
|
"a driver that does not say so: a lifted touch is pressed as the mouse says");
|
|
|
|
/* 7 */
|
|
input_pointer_frames_clear();
|
|
CHECK(rd(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_RIGHT) == -2
|
|
&& rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED) == -2,
|
|
"a poll in which nothing is published: the driver is to be asked");
|
|
|
|
/* 14: where a touch is, whether it is there, and whether it is down
|
|
* are three things. The mouse is at 40,30 with no button held. */
|
|
f[0].pos = VIDEO_POS_PACK(40, 30);
|
|
f[0].buttons = 0;
|
|
/* a touch down at the window's origin is a touch */
|
|
touch[0] = VIDEO_POS_PACK(0, 0);
|
|
input_pointer_frames_set(f, 1, INPUT_POINTERS_GUN_AT_TOUCH);
|
|
input_pointer_touches_set(touch, 1, 1, 1);
|
|
CHECK( rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED) == 1
|
|
&& rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X) == 0
|
|
&& rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_Y) == 0
|
|
&& rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_COUNT) == 1
|
|
&& input_pointer_frame_pos(0, RETRO_DEVICE_POINTER, 0, &pos)
|
|
&& pos == VIDEO_POS_PACK(0, 0),
|
|
"a touch down at 0,0 is pressed and at 0,0, not the mouse's");
|
|
CHECK( rd(0, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X) == 0
|
|
&& rd(0, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y) == 0,
|
|
"the lightgun aims at a touch at 0,0, not at the mouse");
|
|
/* lifted at the origin, its place kept: there, not pressed */
|
|
input_pointer_frames_set(f, 1, INPUT_POINTERS_GUN_AT_TOUCH);
|
|
input_pointer_touches_set(touch, 1, 1, 0);
|
|
CHECK( rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED) == 0
|
|
&& rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X) == 0
|
|
&& rd(0, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X) == 0,
|
|
"a touch lifted at 0,0 keeps its place and is not pressed");
|
|
/* not there at all: the mouse answers, whatever the place holds */
|
|
touch[0] = VIDEO_POS_PACK(60, 70);
|
|
input_pointer_frames_set(f, 1, INPUT_POINTERS_GUN_AT_TOUCH);
|
|
input_pointer_touches_set(touch, 1, 0, 0);
|
|
CHECK( rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X) == 40
|
|
&& rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED) == 0
|
|
&& rd(0, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X) == 40,
|
|
"a place with no contact reads the mouse, whatever position it holds");
|
|
/* down said without there: not a touch */
|
|
input_pointer_frames_set(f, 1, 0);
|
|
input_pointer_touches_set(touch, 1, 0, 1);
|
|
CHECK( rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED) == 0
|
|
&& rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_COUNT) == 0,
|
|
"a place that is down but not there is not a touch");
|
|
/* at the viewport's edges: its first and last pixel, both down */
|
|
touch[0] = VIDEO_POS_PACK(0, 99);
|
|
touch[1] = VIDEO_POS_PACK(199, 0);
|
|
input_pointer_frames_set(f, 1, 0);
|
|
input_pointer_touches_set(touch, 2, 3, 3);
|
|
CHECK( rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X) == 0
|
|
&& rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_Y) == 99
|
|
&& rd(0, RETRO_DEVICE_POINTER, 1, RETRO_DEVICE_ID_POINTER_X) == 199
|
|
&& rd(0, RETRO_DEVICE_POINTER, 1, RETRO_DEVICE_ID_POINTER_Y) == 0
|
|
&& rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED) == 1
|
|
&& rd(0, RETRO_DEVICE_POINTER, 1, RETRO_DEVICE_ID_POINTER_PRESSED) == 1
|
|
&& rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_COUNT) == 2,
|
|
"touches on the viewport's edges, an axis at 0 each");
|
|
/* sparse places: 0 empty, 1 down at the origin, 2 empty. The mouse
|
|
* stands for three touches and its middle button is held. */
|
|
touch[0] = VIDEO_POS_PACK(0, 0);
|
|
touch[1] = VIDEO_POS_PACK(0, 0);
|
|
touch[2] = VIDEO_POS_PACK(0, 0);
|
|
f[0].buttons = INPUT_POINTER_MIDDLE;
|
|
input_pointer_frames_set(f, 1, INPUT_POINTERS_MOUSE_3_TOUCHES);
|
|
input_pointer_touches_set(touch, 3, 1 << 1, 1 << 1);
|
|
CHECK( rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X) == 40
|
|
&& rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED) == 1
|
|
&& rd(0, RETRO_DEVICE_POINTER, 1, RETRO_DEVICE_ID_POINTER_X) == 0
|
|
&& rd(0, RETRO_DEVICE_POINTER, 1, RETRO_DEVICE_ID_POINTER_PRESSED) == 1
|
|
&& rd(0, RETRO_DEVICE_POINTER, 2, RETRO_DEVICE_ID_POINTER_X) == 40
|
|
&& rd(0, RETRO_DEVICE_POINTER, 2, RETRO_DEVICE_ID_POINTER_PRESSED) == 1
|
|
&& rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_COUNT) == 1,
|
|
"sparse places: the one with a contact reads it, the others the mouse");
|
|
/* the lightgun goes by the first place only */
|
|
f[0].buttons = 0;
|
|
input_pointer_frames_set(f, 1, INPUT_POINTERS_GUN_AT_TOUCH);
|
|
input_pointer_touches_set(touch, 3, 1 << 1, 1 << 1);
|
|
CHECK( rd(0, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X) == 40,
|
|
"the lightgun aims at the first place's touch, and with none there at the mouse");
|
|
/* a pen in the air at the origin, read alone */
|
|
f[0].buttons = INPUT_POINTER_LEFT;
|
|
input_pointer_frames_set(f, 1, INPUT_POINTERS_TOUCH_ALONE);
|
|
input_pointer_touches_set(touch, 1, 1, 0);
|
|
CHECK( rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X) == 0
|
|
&& rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED) == 0
|
|
&& rd(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_COUNT) == 0,
|
|
"a pen in the air at 0,0 is there, at 0,0, and not pressed by the mouse");
|
|
f[0].buttons = 0;
|
|
|
|
/* 13: the poll's viewport, for a driver that places its own touches:
|
|
* asked for once however often it is wanted, and afresh each poll */
|
|
input_pointer_frames_clear();
|
|
vp_asked = 0;
|
|
CHECK(input_pointer_viewport() && input_pointer_viewport()
|
|
&& input_pointer_viewport() && vp_asked == 1,
|
|
"the poll's viewport is asked for once");
|
|
input_pointer_frames_clear();
|
|
CHECK(input_pointer_viewport() && vp_asked == 2,
|
|
"and afresh after the next poll");
|
|
|
|
if (failures)
|
|
{
|
|
printf("FAIL pointer_frame_test: %u failure(s)\n", failures);
|
|
return 1;
|
|
}
|
|
printf("PASS pointer_frame_test\n");
|
|
return 0;
|
|
}
|