-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathinputs.lua
168 lines (135 loc) · 3.87 KB
/
inputs.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
do
local Inputs = torch.class('Inputs')
function Inputs.getMario()
local marioX = memory.readbyte(0x6D) * 0x100 + memory.readbyte(0x86)
local marioY = memory.readbyte(0x03B8)+16
local screenX = memory.readbyte(0x03AD)
local screenY = memory.readbyte(0x03B8)
return { x= marioX, y= marioY }
end
function Inputs.getTile(dx, dy, mario)
local x = mario.x + dx + 8
local y = mario.y + dy - 16
local page = math.floor(x/256)%2
local subx = math.floor((x%256)/16)
local suby = math.floor((y - 32)/16)
-- 0x0500-0x069F Current tile
-- From top to bottom and left to right
-- terrain is at 0x5B0-0x5CF and 0x680-0x69F (two rows)
-- 0x500-0x5DF First screen 16x13
-- 0x5E0-0x69F Second screen 16x13
local addr = 0x500 + page*13*16+suby*16+subx
if suby >= 13 or suby < 0 then
return -1
end
local tileContent = memory.readbyte(addr)
if tileContent ~= 0 then
return 1
else
return -1
end
end
function Inputs.getTiles(radius, mario)
mario = mario or Inputs.getMario()
local tiles = {}
for dx = -radius * 16, radius * 16, 16 do
for dy = -radius * 16, radius * 16, 16 do
tiles[#tiles+1] = Inputs.getTile(dx, dy, mario)
end
end
return tiles
end
function Inputs.getSprites()
local sprites = {}
for slot=0,4 do
-- 0x000F-0x0013 Enemy active?
local enemy = memory.readbyte(0xF+slot)
if enemy ~= 0 then
-- 0x006E-0x0072 Enemy horizontal position in level
-- 0x0087/B Enemy x position on screen
local inLevel = memory.readbyte(0x6E + slot)
local onScreen = memory.readbyte(0x87 + slot)
local ex = inLevel * 0x100 + onScreen
-- 0x00CF-0x00D3 Enemy y pos on screen (multiply with value at 0x00B6/A to get level y pos)
local ey = memory.readbyte(0xCF + slot) + 24
--emu.print(ex .. ' ' .. ey .. ' ' .. inLevel .. ' ' .. onScreen)
sprites[#sprites+1] = { x = ex, y = ey }
end
end
-- emu.print('Found ' .. #sprites .. ' sprites')
return sprites
end
function Inputs.getMarioScore()
-- 0x07DD-0x07E2 Mario score (1000000 100000 10000 1000 100 10)
local addresses = torch.range(0x7DD, 0x7E2)
local scores = { 1000000, 100000, 10000, 1000, 100, 10 }
local score = 0
-- FIXME!
for i = 1, addresses:size()[1] do
score = score + (scores[i] * memory.readbyte(addresses[i]))
end
return score
end
function Inputs.getMarioState()
-- 0x000E Player's state
local states = {
'Leftmost of screen',
'Climbing vine',
'Entering reversed-L pipe',
'Going down a pipe',
'Autowalk',
'Autowalk',
'Player dies',
'Entering area',
'Normal',
'Cannot move',
--' ',
'Dying',
'Palette cycling, can\'t move'
}
local stateCode = memory.readbyte(0xE)
return states[stateCode]
end
function Inputs.getTime()
-- 0x07F8/A Digits of time (100 10 1)
local addresses = torch.range(0x7F8, 0x7FA)
local digits = { 100, 10, 1 }
local time = 0
for i = 1, addresses:size(1) do
time = time + (digits[i] * memory.readbyte(addresses[i]))
end
return time
end
function Inputs.getInputs()
local mario = Inputs.getMario()
sprites = Inputs.getSprites()
local inputs = {}
for dy=-BoxRadius*16,BoxRadius*16,16 do
for dx=-BoxRadius*16,BoxRadius*16,16 do
inputs[#inputs+1] = 0
local tile = Inputs.getTile(dx, dy, mario)
if tile == 1 and mario.y + dy < 0x1B0 then
inputs[#inputs] = 1
end
for i = 1,#sprites do
local distx = math.abs(sprites[i].x - (mario.x + dx))
local disty = math.abs(sprites[i].y - (mario.y + dy))
if distx <= 8 and disty <= 8 then
inputs[#inputs] = -1
end
end
end
end
--mariovx = memory.read_s8(0x7B)
--mariovy = memory.read_s8(0x7D)
return inputs
end
function Inputs.getDistances(mario, sprites)
local distances = {}
for i = 1, #sprites do
table.insert(distances, utils.distance(mario, sprites[i]))
end
return distances
end
end
return Inputs