From 80fa2df0b3c6db9501b9e36a0b48b1fb7eb0fb12 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Thu, 1 Nov 2012 21:41:55 -0400 Subject: [PATCH] Include stapgames in the testsuite New systemtap.examples/stapgames directory added with the supporting tapsets located in the 'tapset' subdirectory. All tests run with -p4 specified. * testsuite/systemtap.examples/stapgames/block.meta : block meta data * testsuite/systemtap.examples/stapgames/block.stp : break a ceiling of blocks * testsuite/systemtap.examples/stapgames/eater.meta : eater meta data * testsuite/systemtap.examples/stapgames/eater.stp : eat the .'s before being eaten * testsuite/systemtap.examples/stapgames/lifegame.meta : life meta data * testsuite/systemtap.examples/stapgames/lifegame.stp : watch a 'lifeform' morph and evolve * testsuite/systemtap.examples/stapgames/pingpong.meta : ping pong meta data * testsuite/systemtap.examples/stapgames/pingpong.stp : cursor bounces around terminal reflecting off edges * testsuite/systemtap.examples/stapgames/tapset/audio.stp : audio functionality * testsuite/systemtap.examples/stapgames/tapset/cursor.stp : cursor functionality and tracking * testsuite/systemtap.examples/stapgames/tapset/game.stp : seed values * testsuite/systemtap.examples/stapgames/tapset/gmtty.stp : tty functionality * testsuite/systemtap.examples/stapgames/tapset/input.stp : controlling game input --- .../systemtap.examples/stapgames/block.meta | 5 + .../systemtap.examples/stapgames/block.stp | 121 +++++++++++++ .../systemtap.examples/stapgames/eater.meta | 4 + .../systemtap.examples/stapgames/eater.stp | 162 ++++++++++++++++++ .../stapgames/lifegame.meta | 5 + .../systemtap.examples/stapgames/lifegame.stp | 54 ++++++ .../stapgames/pingpong.meta | 5 + .../systemtap.examples/stapgames/pingpong.stp | 34 ++++ .../stapgames/tapset/audio.stp | 93 ++++++++++ .../stapgames/tapset/cursor.stp | 60 +++++++ .../stapgames/tapset/game.stp | 31 ++++ .../stapgames/tapset/gmtty.stp | 48 ++++++ .../stapgames/tapset/input.stp | 118 +++++++++++++ 13 files changed, 740 insertions(+) create mode 100644 testsuite/systemtap.examples/stapgames/block.meta create mode 100755 testsuite/systemtap.examples/stapgames/block.stp create mode 100644 testsuite/systemtap.examples/stapgames/eater.meta create mode 100755 testsuite/systemtap.examples/stapgames/eater.stp create mode 100644 testsuite/systemtap.examples/stapgames/lifegame.meta create mode 100755 testsuite/systemtap.examples/stapgames/lifegame.stp create mode 100644 testsuite/systemtap.examples/stapgames/pingpong.meta create mode 100755 testsuite/systemtap.examples/stapgames/pingpong.stp create mode 100755 testsuite/systemtap.examples/stapgames/tapset/audio.stp create mode 100755 testsuite/systemtap.examples/stapgames/tapset/cursor.stp create mode 100755 testsuite/systemtap.examples/stapgames/tapset/game.stp create mode 100755 testsuite/systemtap.examples/stapgames/tapset/gmtty.stp create mode 100755 testsuite/systemtap.examples/stapgames/tapset/input.stp diff --git a/testsuite/systemtap.examples/stapgames/block.meta b/testsuite/systemtap.examples/stapgames/block.meta new file mode 100644 index 000000000..560e2fdde --- /dev/null +++ b/testsuite/systemtap.examples/stapgames/block.meta @@ -0,0 +1,5 @@ +Title: block breaker game +Keywords: stapgames +Description: A block game where you progressively break the ceiling blocks until clearing the level +test_check: stap -p4 -Itapset/ block.stp +test_installcheck: stap -p4 -Itapset/ block.stp diff --git a/testsuite/systemtap.examples/stapgames/block.stp b/testsuite/systemtap.examples/stapgames/block.stp new file mode 100755 index 000000000..c70aa97f3 --- /dev/null +++ b/testsuite/systemtap.examples/stapgames/block.stp @@ -0,0 +1,121 @@ +#!/usr/bin/env stap +# block breaker +# Copyright (C) 2008 Masami Hiramatsu +# +# This file is free software and is distributed under the terms of the GNU +# General Public License (GPL); either version 2, or (at your option) any +# later version. + +#TODO +# - count scores +# - reflection control +# - special items +# - more stages + +global b, bx, by, bar, dx, dy, dbar, sbar + +probe begin { + for (i = 1; i < 6; i++) + for (j = 0; j < 10; j++) + b[j,i] = 6 - i + bx = 20; by = 19; + dx = 1; dy = -1; dbar = 0 + bar = 18 + + cursor_cls() + for (i = 1; i < 6; i++) + printf("|[%02d][%02d][%02d][%02d][%02d][%02d][%02d][%02d][%02d][%02d]|\n", + b[0,i], b[1,i], b[2,i], b[3,i], b[4,i], b[5,i], + b[6,i], b[7,i], b[8,i], b[9,i]) + for (i = 5; i < 20; i++) + printf("|%40s|\n", " "); + cursor_move(bx+2, by); print("o") + cursor_move(bar+2, 20); print("=====") +} + +probe game.kbd { + if (down) { + if (code == GM_KBD_RIGHT) + dbar = 1 + else if (code == GM_KBD_LEFT) + dbar = -1 + } else + sbar = 1 +} + +probe timer.ms(100) { + if (dbar*dbar < 9) + dbar *= 2 +} + +function update_block(x,y) { + b[x,y] --; + if (b[x,y] == 0) { + delete b[x,y] + cursor_move(x*4+2,y); print(" ") + } else { + cursor_move(x*4+2,y); printf("[%02d]", b[x,y]) + } +} + +function hit_block() { + x = bx/4; y = by + if (b[x,y]) { + update_block(x,y) + dy = -dy + dx = -dx + bx += dx; by += dy + return 0; + } + x = bx/4; y = by+dy + if (y <= 0 || b[x,y]) { + if (b[x,y]) + update_block(x,y) + dy = -dy + } + y = by; x = (bx+dx)/4 + if (bx+dx < 0 || x >= 10 || b[x,y]) { + if (b[x,y]) + update_block(x,y) + dx = -dx + } +} + +function no_blocks() { + foreach ([x,y] in b) + return 0 + return 1 +} + +probe timer.ms(200) { + cursor_move(bx+2, by); print(" ") + cursor_move(bar+2, 20); print(" ") + + bar+= dbar; + if (sbar) { dbar = 0; sbar = 0 } + if (bar <= 0) { bar = 0; dbar = 0} + if (bar >= 35) { bar = 35; dbar = 0} + + bx += dx; by += dy + hit_block() + if (by == 19 && (bx >= bar && bx < bar + 5) ) { + dy = -dy; + } + if (by >= 21) + exit() + + if (no_blocks()) { + cursor_move(15,19) + println("Stage clear!") + exit() + } + cursor_move(bx+2, by); print("o") + cursor_move(bar+2, 20); print("=====") + cursor_move(43,20) +} + +probe end { + cursor_move(16, 10); + println("-GAME-OVER-") + cursor_move(1, 20); +} diff --git a/testsuite/systemtap.examples/stapgames/eater.meta b/testsuite/systemtap.examples/stapgames/eater.meta new file mode 100644 index 000000000..a71017645 --- /dev/null +++ b/testsuite/systemtap.examples/stapgames/eater.meta @@ -0,0 +1,4 @@ +Title: eater game +Keywords: stapgames +test_check: stap -p4 -Itapset/ eater.stp +test_installcheck: stap -p4 -Itapset/ eater.stp diff --git a/testsuite/systemtap.examples/stapgames/eater.stp b/testsuite/systemtap.examples/stapgames/eater.stp new file mode 100755 index 000000000..459468e66 --- /dev/null +++ b/testsuite/systemtap.examples/stapgames/eater.stp @@ -0,0 +1,162 @@ +#!/usr/bin/env stap +# jewel eater +# Copyright (C) 2008 Masami Hiramatsu +# +# This file is free software and is distributed under the terms of the GNU +# General Public License (GPL); either version 2, or (at your option) any +# later version. + +#TODO: +# - power jewel +# - increase snakes +# - don't stop eater +# - shortcut corner + +global pm=0, px=10, py=10, jewels=0 +global pkm[4], mv, map, data, sx, sy, sm, _c +global ph = 0 + +probe begin { + pkm[0] = ">" + pkm[1] = "<" + pkm[2] = "V" + pkm[3] = "A" + data[1] = "#######################" + data[2] = "##...................##" + data[3] = "#..#.###.#####.###.#..#" + data[4] = "#.##.o.#.......#.o.##.#" + data[5] = "#.####.#.#####.#.####.#" + data[6] = "#.....................#" + data[7] = "###.####.## ##.####.###" + data[8] = "##.......##U##.......##" + data[9] = "#..#.###.#####.#.###..#" + data[10] = "#.##.o.#.......#.o.##.#" + data[11] = "#.####.#.#####.###.##.#" + data[12] = "#.....................#" + data[13] = "#######################" + cursor_cls() + + for (y=1;y<14;y++) { + x=0 + c = substr(data[y], x, 1) + cursor_move(x+1,y) + while (c!="") { + x++ + map[x,y] = c + print(c) + c = substr(data[y], x, 1) + if (c == ".") + jewels++ + if (c == "U") { + sx[0]=x;sy[0]=y + sx[1]=x;sy[1]=y + } + } + } +} + +probe game.kbd { + if (down) { + mv = 1 + if (code == GM_KBD_LEFT) + pm = 0 + else if (code == GM_KBD_RIGHT) + pm = 1 + else if (code == GM_KBD_UP) + pm = 2 + else if (code == GM_KBD_DOWN) + pm = 3 + } +} + +function crit(x, y, tx, ty) { + dx = tx-x + dy = ty-y + if(map[x,y] != "#") + return dx*dx+dy*dy + return 1000000 +} + +function dir_snake(x, y, tx, ty, m) { + _c[0] = crit(x-1, y, tx, ty) + _c[1] = crit(x+1, y, tx, ty) + _c[2] = crit(x, y-1, tx, ty) + _c[3] = crit(x, y+1, tx, ty) + j=0 + tc = _c[0] + for (i=1;i<4;i++) { + if (_c[i] <= _c[j]) j = i + tc+=_c[i] + } + if (tc > 2000000 && _c[m]!=1000000) { + return m + } + return j +} + +function move_snake(i) { + if (i==0) { + tx = px; ty = py + } else if (i==1) { + tx = px; ty = py + if (pm&2) + ty += (pm&1)?3:-3 + else + tx += (pm&1)?3:-3 + } + sm[i] = dir_snake(sx[i], sy[i], tx, ty, sm[i]) + if (sm[i]&2) + dy = (sm[i]&1)?1:-1 + else + dx = (sm[i]&1)?1:-1 + cursor_move(sx[i], sy[i]); print(map[sx[i], sy[i]]) + sx[i]+=dx + sy[i]+=dy + cursor_move(sx[i], sy[i]); print("W") +} + +probe timer.ms(200) { + ph = 1 - ph + for (i=0;i<2;i++) + if (ph) { + move_snake(i) + } else { + cursor_move(sx[i], sy[i]); print("M") + if (sx[i] == px && sy[i] == py) + exit() + } + cursor_move(1,25) +} + +probe timer.ms(200) { + if (mv == 1) { + cursor_move(px,py); print(map[px,py]) + if (pm&2) + dy = (pm&1)?1:-1 + else + dx = (pm&1)?1:-1 + if (map[px+dx, py+dy] != "#") { + px += dx; py += dy + } + cursor_move(px,py); print(pkm[pm]) + if (map[px, py] == ".") { + jewels-- + if (jewels == 0) + exit() + map[px, py] = " " + } + mv = 0 + } else { + cursor_move(px,py); print("O") + } + cursor_move(1,25) +} + +probe end { + if (jewels == 0) { + cursor_move(1,10); print(" Game Clear ") + } else { + cursor_move(1,10); print(" Game Over! ") + } + cursor_move(1,25) +} diff --git a/testsuite/systemtap.examples/stapgames/lifegame.meta b/testsuite/systemtap.examples/stapgames/lifegame.meta new file mode 100644 index 000000000..f0a9e3cc5 --- /dev/null +++ b/testsuite/systemtap.examples/stapgames/lifegame.meta @@ -0,0 +1,5 @@ +Title: life game +Keywords: stapgames +Description: watch as your creation morphes into different forms +test_check: stap -p4 -Itapset/ lifegame.stp +test_installcheck: stap -p4 -Itapset/ lifegame.stp diff --git a/testsuite/systemtap.examples/stapgames/lifegame.stp b/testsuite/systemtap.examples/stapgames/lifegame.stp new file mode 100755 index 000000000..62103b1ad --- /dev/null +++ b/testsuite/systemtap.examples/stapgames/lifegame.stp @@ -0,0 +1,54 @@ +#!/usr/bin/env stap +# lifegame +# Copyright (C) 2008 Masami Hiramatsu +# +# This file is free software and is distributed under the terms of the GNU +# General Public License (GPL); either version 2, or (at your option) any +# later version. + +global X_MAX=15, Y_MAX=15 +global map, tmp +global t + +function showupdate() +{ + print("\033[1;1H\033[J") # clear screen + delete map + foreach([x,y] in tmp) { + printf("\033[%d;%dH", y+1, x+1) # move cursor + print("o") + map[x,y] = 1 + } + delete tmp +} + +function lookaround(x,y) +{ + return map[x-1,y-1] + map[x,y-1] + map[x+1,y-1] + + map[x-1,y ] + map[x+1,y ] + + map[x-1,y+1] + map[x,y+1] + map[x+1,y+1] +} + +probe timer.ms(10) { + t ++ + if (t == Y_MAX) { + showupdate() + t = -1 + next # skip to the next timer. + } + # updating just 1 line + y = t + for (x=0; x < X_MAX; x++) { + c = lookaround(x,y) + if (c == 3) tmp[x,y] = 1 + else if (c == 2 && [x,y] in map) tmp[x,y] = map[x,y] + } +} + +probe begin { + tmp[6,5] = 1; tmp[5,6] = 1; tmp[4,7] = 1; tmp[5,7] = 1 + tmp[6,7] = 1 + showupdate() + t = -1 +} + diff --git a/testsuite/systemtap.examples/stapgames/pingpong.meta b/testsuite/systemtap.examples/stapgames/pingpong.meta new file mode 100644 index 000000000..08b8add8d --- /dev/null +++ b/testsuite/systemtap.examples/stapgames/pingpong.meta @@ -0,0 +1,5 @@ +Title: pingpong game +Keywords: stapgames +Description: A simulated ball bounces around the terminal reflecting at the edges +test_check: stap -p4 -Itapset/ pingpong.stp +test_installcheck: stap -p4 -Itapset/ pingpong.stp diff --git a/testsuite/systemtap.examples/stapgames/pingpong.stp b/testsuite/systemtap.examples/stapgames/pingpong.stp new file mode 100755 index 000000000..ba117a92c --- /dev/null +++ b/testsuite/systemtap.examples/stapgames/pingpong.stp @@ -0,0 +1,34 @@ +#!/usr/bin/env stap +# Ping pong ball in tty window +# Run in a xterm and resize window +# Copyright (C) 2011 Masami Hiramatsu +# +# This file is free software and is distributed under the terms of the GNU +# General Public License (GPL); either version 2, or (at your option) any +# later version. + +global Row, Col +global dr = 1, dc = 1 + +probe begin { + Row = game_tty_ws_row()/2; Col = game_tty_ws_col()/2 +} + +probe timer.ms(50) { + Row += dr; Col += dc + if (Row >= game_tty_ws_row()) { + dr = -dr; Row = game_tty_ws_row() + } else if (Row <= 1) { + dr = -dr; Row = 1 + } + if (Col >= game_tty_ws_col()) { + dc = -dc; Col = game_tty_ws_col() + } else if (Col <= 1) { + dc = -dc; Col = 1 + } + ansi_clear_screen() + ansi_cursor_move(Col, Row) + print("@") +} + + diff --git a/testsuite/systemtap.examples/stapgames/tapset/audio.stp b/testsuite/systemtap.examples/stapgames/tapset/audio.stp new file mode 100755 index 000000000..5ac19586b --- /dev/null +++ b/testsuite/systemtap.examples/stapgames/tapset/audio.stp @@ -0,0 +1,93 @@ +# systemtap audio tapset +# Copyright (C) 2008 Masami Hiramatsu +# +# This file is free software and is distributed under the terms of the GNU +# General Public License (GPL); either version 2, or (at your option) any +# later version. + +%{ +#include +%} + +%( kernel_v >= "2.6.25" %? +function game_beep(hz:long, ms:long) +%{ + unsigned int tick = msecs_to_jiffies((unsigned int)THIS->ms); + kd_mksound((unsigned int)THIS->hz, tick); +%} +%) + +function game_nobeep() +{ + game_beep(0,0) +} + +global __GM_scale +global __GM_merody +global __GM_merody_nth +global __GM_merody_seq +global __GM_merody_cnt + +probe begin(-1001) { + __GM_scale["c"] = 262 + __GM_scale["c+"] = 277 + __GM_scale["d"] = 294 + __GM_scale["d+"] = 311 + __GM_scale["e"] = 330 + __GM_scale["f"] = 349 + __GM_scale["f+"] = 370 + __GM_scale["g"] = 392 + __GM_scale["g+"] = 415 + __GM_scale["a"] = 440 + __GM_scale["a+"] = 466 + __GM_scale["b"] = 494 + delete __GM_merody +} + +function game_tone(tone:string, nth:long, ms:long) +{ + if ([tone] in __GM_scale) { + tone2 = __GM_scale[tone]; + for (i=0;inth-3;i--) tone2/=2 + game_beep(tone2, ms) + } +} + +function game_merody(merody:string) +{ + i = 0 + delete __GM_merody + c = tokenize(merody, " ") + while (c != "") { + __GM_merody[i, 0] = c + c = tokenize("",",") + __GM_merody[i, 1] = c + c = tokenize(""," ") + i++ + } + __GM_merody_seq = 0 + __GM_merody_nth = 3 + __GM_merody_cnt = 1 +} + +probe timer.ms(64) { + if (__GM_merody_cnt-- > 0) next; + seq = __GM_merody_seq; + while ([seq, 0] in __GM_merody) { + c = __GM_merody[seq, 0] + l = strtol(__GM_merody[seq, 1], 10) + seq++ + if (c == ">") { + __GM_merody_nth += l + } else if (c == "<" ) { + __GM_merody_nth -= l + } else { + break; + } + } + game_tone(c, __GM_merody_nth, l*64) + __GM_merody_cnt = l + __GM_merody_seq = seq +} + diff --git a/testsuite/systemtap.examples/stapgames/tapset/cursor.stp b/testsuite/systemtap.examples/stapgames/tapset/cursor.stp new file mode 100755 index 000000000..8cc1639c0 --- /dev/null +++ b/testsuite/systemtap.examples/stapgames/tapset/cursor.stp @@ -0,0 +1,60 @@ +# ANSI Escape sequences +# Copyright (C) 2008 Masami Hiramatsu +# +# This file is free software and is distributed under the terms of the GNU +# General Public License (GPL); either version 2, or (at your option) any +# later version. + +/* + * cursor_move + * + * Move cursor to x-y position + */ +function cursor_move(x:long, y:long) +{ + printf("\033[%d;%dH", y, x) +} + +function cursor_cls() +{ + print("\033[1;1H\033[J") +} + +function cursor_show() +{ + print("\033[>5h") +} + +function cursor_hide() +{ + print("\033[>5I") +} + +function cursor_save() +{ + print("\033[s") +} + +function cursor_restore() +{ + print("\033[u") +} + +function cursor_set_color(parm1:long) +{ + printf("\033[%dm", parm1) +} +function cursor_set_color2(parm1:long, parm2:long) +{ + printf("\033[%d;%dm", parm1, parm2) +} +function cursor_set_color3(parm1:long, parm2:long, parm3:long) +{ + printf("\033[%d;%d;%dm", parm1, parm2, parm3) +} + +function cursor_reset_color() +{ + cursor_set_color2(0,0) +} + diff --git a/testsuite/systemtap.examples/stapgames/tapset/game.stp b/testsuite/systemtap.examples/stapgames/tapset/game.stp new file mode 100755 index 000000000..30b9097b3 --- /dev/null +++ b/testsuite/systemtap.examples/stapgames/tapset/game.stp @@ -0,0 +1,31 @@ +# Miscellaneous routines for games +# Copyright (C) 2008 Masami Hiramatsu +# +# This file is free software and is distributed under the terms of the GNU +# General Public License (GPL); either version 2, or (at your option) any +# later version. + +global __GM_rand_seed + +function game_srand(seed:long) +{ + __GM_rand_seed = seed +} + +function __game_lfsr(val:long) /* pure */ +%{ + u64 r = THIS->val; + r = (r >> 1) ^ ((-(r & 1ULL)) & 0xd800000000000000ULL); + THIS->__retvalue = r; +%} + +function game_rand() +{ + return __GM_rand_seed = __game_lfsr(__GM_rand_seed) +} + +function game_urand() +{ + rand = game_rand() + return rand<0?-rand:rand +} diff --git a/testsuite/systemtap.examples/stapgames/tapset/gmtty.stp b/testsuite/systemtap.examples/stapgames/tapset/gmtty.stp new file mode 100755 index 000000000..026e4a9a9 --- /dev/null +++ b/testsuite/systemtap.examples/stapgames/tapset/gmtty.stp @@ -0,0 +1,48 @@ +# TTY related routines for games +# Copyright (C) 2011 Masami Hiramatsu +# +# This file is free software and is distributed under the terms of the GNU +# General Public License (GPL); either version 2, or (at your option) any +# later version. + +global GM_tty_ws_row, GM_tty_ws_col, GM_tty_name + +# Initialize current TTY -- must be called from begin +function game_tty_init:long () +{ + tty = @cast(task_current(), "task_struct")->signal->tty + if (tty) { + namep = @cast(tty,"tty_struct")->name + GM_tty_name = kernel_string(namep) + GM_tty_ws_col = @cast(tty, "tty_struct")->winsize->ws_col + GM_tty_ws_row = @cast(tty, "tty_struct")->winsize->ws_row + } + return tty +} + +probe begin(-100) { + if (game_tty_init() == 0) { + print("Failed to get current tty\n") + exit() + } +} + +probe game.tty.resize = kernel.function("tty_do_resize") { + if (kernel_string($tty->name) == GM_tty_name) { + row = $ws->ws_row + col = $ws->ws_col + } +} + +probe game.tty.resize { + GM_tty_ws_row = row + GM_tty_ws_col = col +} + +function game_tty_ws_row:long () { + return GM_tty_ws_row +} + +function game_tty_ws_col:long () { + return GM_tty_ws_col +} diff --git a/testsuite/systemtap.examples/stapgames/tapset/input.stp b/testsuite/systemtap.examples/stapgames/tapset/input.stp new file mode 100755 index 000000000..b852e832f --- /dev/null +++ b/testsuite/systemtap.examples/stapgames/tapset/input.stp @@ -0,0 +1,118 @@ +# systemtap input tapset +# Copyright (C) 2008,2011 Masami Hiramatsu +# +# This file is free software and is distributed under the terms of the GNU +# General Public License (GPL); either version 2, or (at your option) any +# later version. + + +probe game.input = kernel.function("input_event") { + type = $type + code = $code + value = $value +} + +#TODO: convert keycode to char. + +# elemental gamepad keys ;-P +global GM_KBD_UP =103 +global GM_KBD_DOWN =108 +global GM_KBD_RIGHT=106 +global GM_KBD_LEFT =105 +global GM_KBD_Z =44 +global GM_KBD_X =45 +global GM_KBD_C =46 +global GM_KBD_ESC =1 +global GM_KBD_SPACE=57 + + +probe game.kbd = game.input { + if (type != 1 || code >= 256) next; + down = value +} + +probe game.kbd.down = game.kbd { + if (!down) next +} + +probe game.kbd.up = game.kbd { + if (down) next +} + +# mouse + +probe game.mouse = game.input { + if (!(type == 2 || + (type == 1 && (code & 0xfe0) != 0x100) ) ) next #EV_KEY +} + +probe game.mouse.rel = game.input { + if(type != 2) next #EV_REL + if(code == 0) dx = value + else if(code == 1) dy = value + else if(code == 8) dz = value +} + +global GM_mouse_abs +global GM_mouse_base_x, GM_mouse_base_y + +probe game.mouse.abs = game.input { + dx = dy = dz = 0 + if (type == 1 && code == 0x145 && value == 0) { + # Leave a finger -- Reset position + GM_mouse_base_x = 0 + GM_mouse_base_y = 0 + next + } else if (type != 3) next #EV_ABS + + if (code == 0) { + x = value + if (GM_mouse_base_x != 0) + dx = x - GM_mouse_base_x + GM_mouse_base_x = x + GM_mouse_abs[0] = value + } else if (code == 1) { + y = value + if (GM_mouse_base_y != 0) + dy = y - GM_mouse_base_y + GM_mouse_base_y = y + GM_mouse_abs[1] = value + } +} + +global GM_mouse_btn + +probe game.mouse.btn = game.input { + if (type != 1 || (code & 0xfe0) != 0x100) next #EV_KEY + button = code & 0xf + down = value + if (GM_mouse_btn[button] == down) next + GM_mouse_btn[button] = down +} + +global GM_mouse_pos + +probe game.mouse.rel, game.mouse.abs { + GM_mouse_pos[0] += dx + GM_mouse_pos[1] += dy + GM_mouse_pos[2] += dz +} + +function game_mouse_reset(x:long, y:long, z:long) { + GM_mouse_pos[0] = x + GM_mouse_pos[1] = y + GM_mouse_pos[2] = z +} + +function game_mouse_x:long() { + return GM_mouse_pos[0] +} + +function game_mouse_y:long() { + return GM_mouse_pos[1] +} + +function game_mouse_z:long() { + return GM_mouse_pos[2] +} + -- 2.43.5