Last active
December 24, 2015 17:39
-
-
Save stadaki/6837214 to your computer and use it in GitHub Desktop.
Tetris ktap script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ktap | |
# | |
# Tetris KTAP Script | |
# | |
# Copyright (C) 2013/OCT/05 Tadaki SAKAI | |
# | |
# based on stapgames (Systemtap Game Collection) | |
# https://github.com/mhiramat/stapgames/blob/master/games/tetris.stp | |
# | |
# - Requirements | |
# Kernel Configuration: CONFIG_KPROBE_EVENT=y | |
# CONFIG_EVENT_TRACING=y | |
# CONFIG_PERF_EVENTS=y | |
# CONFIG_DEBUG_FS=y | |
# CPU Architecture : x86_64 | |
# | |
# - Setup | |
# $ sudo mount -t debugfs none /sys/kernel/debug/ | |
# | |
# $ git clone https://github.com/ktap/ktap | |
# $ cd ktap | |
# $ make 2>&1 | tee ../make.log | |
# $ sudo make load | |
# $ sudo sh -c 'echo 50000 > /sys/module/ktapvm/parameters/max_exec_count' | |
# | |
# - Run Tetris | |
# $ sudo ./ktap samples/game/tetris.kp | |
# | |
# | |
# global value | |
# | |
var empty = -1 | |
var key_code = 0 | |
var point = 0 | |
var block_number = 0 | |
var height = 0 | |
var height_update = 0 | |
var destination_position = {} | |
var block_data0 = {} | |
var block_data1 = {} | |
var block_data2 = {} | |
var block_data3 = {} | |
var block_data4 = {} | |
var block_data5 = {} | |
var block_data6 = {} | |
var block_table = {} | |
var display_buffer = {} | |
# | |
# utils | |
# | |
function rand(max) { | |
r = gettimeofday_us() | |
if (r < 0) { | |
r = r * -1 | |
} | |
return r % max | |
} | |
function update_display() { | |
for (i = 0, 239, 1) { | |
if ((i % 12 - 11) != 0) { | |
tmp = "" | |
} else { | |
tmp = "\n" | |
} | |
if (display_buffer[240 + i] == empty) { | |
printf(" %s", tmp) | |
} else { | |
color = display_buffer[240 + i] + 40 | |
ansi.set_color2(color, color) | |
printf(" %s", tmp) | |
ansi.reset_color() | |
} | |
# clear the display buffer | |
display_buffer[240 + i] = display_buffer[i] | |
} | |
printf("%d\n",point) | |
} | |
# | |
# Initialize | |
# | |
# Create blocks | |
# block is represented by the position from the center. | |
# Every block has "L" part in the center except for a bar. | |
block_data0[0] = -11 # non-"L" part for each block | |
block_data1[0] = -24 | |
block_data2[0] = 2 | |
block_data3[0] = 13 | |
block_data4[0] = -13 | |
block_data5[0] = -1 | |
block_data6[0] = 2 | |
block_table[0] = block_data0 | |
block_table[1] = block_data1 | |
block_table[2] = block_data2 | |
block_table[3] = block_data3 | |
block_table[4] = block_data4 | |
block_table[5] = block_data5 | |
block_table[6] = block_data6 | |
for (i = 0, len(block_table) - 1, 1) { | |
# common "L" part | |
block_table[i][1] = 0 | |
block_table[i][2] = 1 | |
block_table[i][3] = -12 | |
} | |
block_table[6][3] = -1 # bar is not common | |
# Position: 1 row has 12 columns, | |
# and (x, y) is represented by h = x + y * 12.p | |
height = 17 # First block position (center) | |
for (i = 0, 240, 1) { | |
# Wall and Floor (sentinel) | |
if (((i % 12) < 2) || (i > 228)) { | |
tmp = 7 # White | |
} else { | |
tmp = empty | |
} | |
display_buffer[i - 1] = tmp | |
display_buffer[240 + i - 1] = tmp | |
} | |
block_number = rand(7) | |
ansi.clear_screen() | |
# | |
# Key Input | |
# | |
trace probe:kbd_event handle=%di event_type=%si event_code=%dx value=%cx { | |
# Only can run it in x86_64 | |
# | |
# Register follow x86_64 call conversion: | |
# | |
# x86_64: | |
# %rcx 4 argument | |
# %rdx 3 argument | |
# %rsi 2 argument | |
# %rdi 1 argument | |
var event_code = arg4 | |
var value = arg5 | |
if (value != 0) { | |
if ((event_code - 4) != 0) { | |
key_code = event_code | |
} | |
} | |
} | |
# | |
# timer | |
# | |
tick-200ms { | |
ansi.clear_screen() | |
f = 0 # move/rotate flag | |
if (key_code != 0) { # if key is pressed | |
if(key_code != 103) { #move left or right | |
# d: movement direction | |
if ((key_code - 105) != 0) { | |
if ((key_code - 106) != 0) { | |
d = 0 | |
} else { | |
d = 1 | |
} | |
} else { | |
d = -1 | |
} | |
for (i = 0, 3, 1) { # check if the block can be moved | |
# destination is free | |
if (display_buffer[height + | |
block_table[block_number][i] + d] | |
!= empty) { | |
f = 1 | |
} | |
} | |
# move if destinations of every block are free | |
if (f == 0) { | |
height = height + d | |
} | |
} else { # rotate | |
for (i = 0, 3, 1) { # check if block can be rotated | |
# each block position | |
p = block_table[block_number][i] | |
# destination x pos(p/12 rounded) | |
v = (p * 2 + 252) / 24 - 10 | |
w = p - v * 12 # destination y pos | |
# destination position | |
destination_position[i] = w * 12 - v | |
# check if desetination is free | |
if (display_buffer[height + | |
destination_position[i]] != empty) { | |
f = 1 | |
} | |
} | |
if (f == 0) { | |
# rotate if destinations of every block | |
# are free | |
for (i = 0, 3, 1) { | |
block_table[block_number][i] = | |
destination_position[i] | |
} | |
} | |
} | |
} | |
key_code = 0 # clear the input key | |
f = 0 | |
for (i = 0, 3, 1) { # drop 1 row | |
# check if destination is free | |
p = height + block_table[block_number][i] | |
if (display_buffer[12 + p] != empty) { | |
f = 1 | |
} | |
# copy the moving block to display buffer | |
display_buffer[240 + p] = block_number | |
} | |
if ((f == 1) && (height == 17)) { | |
update_display() | |
exit() # exit if there are block at initial position | |
} | |
height_update = !height_update | |
if (height_update != 0) { | |
if(f != 0) { # the block can't drop anymore | |
for (i = 0, 3, 1) { | |
# fix the block | |
display_buffer[height + | |
block_table[block_number][i]] = block_number | |
} | |
# determin the next block | |
block_number = rand(7) | |
height = 17 # make the block to initial position | |
} else { | |
height = height + 12 # drop the block 1 row | |
} | |
} | |
k = 1 | |
for (i = 18, 0, -1) { #check if line is filled | |
# search for filled line | |
j = 10 | |
while ((j > 0) && | |
(display_buffer[i * 12 + j] != empty)) { | |
j = j - 1 | |
} | |
if (j == 0) { # filled! | |
# add a point: 1 line - 1 point, ..., tetris - 10points | |
point = point + k | |
k = k + 1 | |
# drop every upper block | |
j = (i + 1) * 12 | |
i = i + 1 | |
while (j > 2 * 12) { | |
j = j - 1 | |
display_buffer[j] = display_buffer[j - 12] | |
} | |
} | |
} | |
update_display() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment