Move a ton of constants into a separate file.

This commit is contained in:
Empathic Qubit 2021-04-29 20:19:56 -04:00
parent 5c03d02c0e
commit 4158876854
13 changed files with 186 additions and 146 deletions

View file

@ -50,5 +50,6 @@ If you want a better idea of what's going on with the tile and sprite calculatio
## TODO
- [x] Incur penalty for non-hazardous enemy collisions to encourage neutralizing Klobber
- [ ] Award for picking up items
- [ ] Make enemies neutral when held? (Klobber, Click-Clack, etc.)
- [ ] Multiple nets to handle different contexts s/a clicking map items

10
bsnes-launch.lua Normal file
View file

@ -0,0 +1,10 @@
local base = string.gsub(@@LUA_SCRIPT_FILENAME@@, "(.*[/\\])(.*)", "%1")
local config = dofile(base.."/config.lua")
-- Breakpoint format: <addr>[-<addr end>][=<value>][:<rwx>[:<source>]]
-- rwx = read / write / execute flags
-- source = cpu, smp, vram, oam, cgram, sa1, sfx, sgb
--bsnes --show-debugger --break-immediately ~/neat-donk/rom.sfc
io.popen('bsnes --show-debugger --break-immediately "'..config.ROM..'"')

View file

@ -17,6 +17,7 @@ _M.ROM = _M.ScriptDir .. "/rom.sfc"
Rearrange for other savestates. (will be redone soon)
--]]
_M.State = {
-- W1.1 Pirate Panic
"PiratePanic.lsmv",
"PiratePanicDitch.lsmv",
"PiratePanicKremcoin.lsmv",

View file

@ -1,6 +1,9 @@
local base = string.gsub(@@LUA_SCRIPT_FILENAME@@, "(.*[/\\])(.*)", "%1")
local set_timer_timeout, memory, memory2, gui, input, bit = memory, memory2, gui, input, bit, set_timer_timeout
local util = dofile(base.."/util.lua")
local mem = dofile(base.."/mem.lua")
local spritelist = dofile(base.."/spritelist.lua")
local game = dofile(base.."/game.lua")
local config = dofile(base.."/config.lua")
@ -8,45 +11,32 @@ local config = dofile(base.."/config.lua")
spritelist.InitSpriteList()
spritelist.InitExtSpriteList()
FG_COLOR = 0x00ffffff
BG_COLOR = 0x99000000
ENEMY_SIZE = 64
TILEDATA_POINTER = 0x7e0098
TILE_SIZE = 32
TILE_RADIUS = 5
SPRITE_BASE = 0x7e0de2
SOLID_LESS_THAN = 0x7e00a0
DIDDY_X_VELOCITY = 0x7e0e02
DIDDY_Y_VELOCITY = 0x7e0e06
DIXIE_X_VELOCITY = 0x7e0e60
DIXIE_Y_VELOCITY = 0x7e0e64
STAGE_NUMBER = 0x7e08a8
STAGE_NUMBER_MOVEMENT = 0x7e08c8
CAMERA_X = 0x7e17ba
CAMERA_Y = 0x7e17c0
CAMERA_MODE = 0x7e054f
TILE_COLLISION_MATH_POINTER = 0x7e17b2
VERTICAL_POINTER = 0xc414
PARTY_X = 0x7e0a2a
PARTY_Y = 0x7e0a2c
local CAMERA_MODE = 0x7e054f
local DIDDY_X_VELOCITY = 0x7e0e02
local DIDDY_Y_VELOCITY = 0x7e0e06
local DIXIE_X_VELOCITY = 0x7e0e60
local DIXIE_Y_VELOCITY = 0x7e0e64
local FG_COLOR = 0x00ffffff
local BG_COLOR = 0x99000000
local TILE_RADIUS = 5
count = 0
detailsidx = -1
jumping = false
helddown = false
floatmode = false
rulers = true
pokemon = false
pokecount = 0
showhelp = false
locked = false
lockdata = nil
incsprite = 0
questionable_tiles = false
local count = 0
local detailsidx = -1
local jumping = false
local helddown = false
local floatmode = false
local rulers = true
local pokemon = false
local pokecount = 0
local showhelp = false
local locked = false
local lockdata = nil
local incsprite = 0
local questionable_tiles = false
font = gui.font.load(base.."font.font")
local font = gui.font.load(base.."font.font")
function text(x, y, msg, fg, bg)
local function text(x, y, msg, fg, bg)
if fg == nil then
fg = FG_COLOR
end
@ -136,26 +126,27 @@ function on_input (subframe)
end
end
function get_sprite(base_addr)
local cameraX = memory.readword(CAMERA_X) - 256
local cameraY = memory.readword(CAMERA_Y) - 256
local x = memory.readword(base_addr + 0x06)
local y = memory.readword(base_addr + 0x0a)
local function get_sprite(base_addr)
local offsets = mem.offset.sprite
local cameraX = memory.readword(mem.addr.cameraX) - 256
local cameraY = memory.readword(mem.addr.cameraY) - 256
local x = memory.readword(base_addr + offsets.x)
local y = memory.readword(base_addr + offsets.y)
return {
base_addr = string.format("%04x", base_addr),
screenX = x - 256 - cameraX,
screenY = y - 256 - cameraY - TILE_SIZE / 3,
control = memory.readword(base_addr),
screenY = y - 256 - cameraY - mem.size.tile / 3,
control = memory.readword(base_addr + offsets.control),
draworder = memory.readword(base_addr + 0x02),
x = x,
y = y,
jumpheight = memory.readword(base_addr + 0x0e),
style = memory.readword(base_addr + 0x12),
jumpHeight = memory.readword(base_addr + offsets.jumpHeight),
style = memory.readword(base_addr + offsets.style),
currentframe = memory.readword(base_addr + 0x18),
nextframe = memory.readword(base_addr + 0x1a),
state = memory.readword(base_addr + 0x1e),
velox = memory.readsword(base_addr + 0x20),
veloy = memory.readsword(base_addr + 0x24),
velocityX = memory.readsword(base_addr + offsets.velocityX),
velocityY = memory.readsword(base_addr + offsets.velocityY),
velomaxx = memory.readsword(base_addr + 0x26),
velomaxy = memory.readsword(base_addr + 0x2a),
motion = memory.readword(base_addr + 0x2e),
@ -176,8 +167,8 @@ function get_sprite(base_addr)
}
end
function sprite_details(idx)
local base_addr = idx * 94 + SPRITE_BASE
local function sprite_details(idx)
local base_addr = idx * mem.size.sprite + mem.addr.spriteBase
local sprite = get_sprite(base_addr)
@ -197,11 +188,11 @@ function sprite_details(idx)
end
if locked and lockdata == nil then
lockdata = memory.readregion(base_addr, 94)
lockdata = memory.readregion(base_addr, mem.size.sprite)
end
if lockdata ~= nil and locked then
memory.writeregion(base_addr, 94, lockdata)
memory.writeregion(base_addr, mem.size.sprite, lockdata)
end
text(0, 0, "Sprite "..idx..(locked and " (Locked)" or "")..":\n\n"..util.table_to_string(sprite))
@ -256,26 +247,26 @@ Sprite Details:
"Up"
}
local cameraX = memory.readword(CAMERA_X) - 256
local cameraY = memory.readword(CAMERA_Y) - 256
local cameraX = memory.readword(mem.addr.cameraX) - 256
local cameraY = memory.readword(mem.addr.cameraY) - 256
local cameraDir = memory.readbyte(CAMERA_MODE)
local direction = directions[cameraDir+1]
local vertical = memory.readword(TILE_COLLISION_MATH_POINTER) == VERTICAL_POINTER
local vertical = memory.readword(mem.addr.tileCollisionMathPointer) == mem.addr.verticalPointer
local partyX = memory.readword(PARTY_X)
local partyY = memory.readword(PARTY_Y)
local partyX = memory.readword(mem.addr.partyX)
local partyY = memory.readword(mem.addr.partyY)
local partyTileOffset = game.tileOffsetCalculation(partyX, partyY, vertical)
local stats = string.format([[
%s camera %d,%d
Vertical: %s
Tile offset: %04x
Stage number: %04x
Stage (movement): %04x
Main area: %04x
Current area: %04x
%s
]], direction, cameraX, cameraY, vertical, partyTileOffset, memory.readword(STAGE_NUMBER), memory.readword(STAGE_NUMBER_MOVEMENT), util.table_to_string(game.getInputs()):gsub("[\\{\\},\n\"]", ""):gsub("-1", "X"):gsub("0", "."):gsub("1", "O"):gsub("(.............)", "%1\n"))
]], direction, cameraX, cameraY, vertical, partyTileOffset, memory.readword(mem.addr.mainAreaNumber), memory.readword(mem.addr.currentAreaNumber), util.table_to_string(game.getInputs()):gsub("[\\{\\},\n\"]", ""):gsub("-1", "X"):gsub("0", "."):gsub("1", "O"):gsub("(.............)", "%1\n"))
text(guiWidth - 125, guiHeight - 200, stats)
@ -283,7 +274,7 @@ Stage (movement): %04x
local sprites = {}
for idx = 0,22,1 do
local base_addr = idx * 94 + SPRITE_BASE
local base_addr = idx * mem.size.sprite + mem.addr.spriteBase
local sprite = get_sprite(base_addr)
@ -305,7 +296,7 @@ Stage (movement): %04x
text(sprite.screenX * 2, sprite.screenY * 2, string.format("%04x, %04x, %04x", sprite.control, sprite.animnum, sprite.attr), FG_COLOR, sprcolor)
local filename = os.getenv("HOME").."/neat-donk/catchem/"..sprite.animnum..","..sprite.attr..".png"
if pokemon and spriteScreenX > (guiWidth / 4) and spriteScreenX < (guiWidth / 4) * 3 and spriteScreenY > (guiHeight / 3) and spriteScreenY < guiHeight and not util.file_exists(filename) then
if pokemon and sprite.screenX > (guiWidth / 4) and sprite.screenY < (guiWidth / 4) * 3 and sprite.screenY > (guiHeight / 3) and sprite.screenY < guiHeight and not util.file_exists(filename) then
gui.screenshot(filename)
pokecount = pokecount + 1
end
@ -316,25 +307,25 @@ Stage (movement): %04x
local halfWidth = math.floor(guiWidth / 2)
local halfHeight = math.floor(guiHeight / 2)
local cameraTileX = math.floor(cameraX / TILE_SIZE)
local cameraTileX = math.floor(cameraX / mem.size.tile)
gui.line(0, halfHeight, guiWidth, halfHeight, BG_COLOR)
for i = cameraTileX, cameraTileX + guiWidth / TILE_SIZE / 2,1 do
text((i * TILE_SIZE - cameraX) * 2, halfHeight, tostring(i), FG_COLOR, BG_COLOR)
for i = cameraTileX, cameraTileX + guiWidth / mem.size.tile / 2,1 do
text((i * mem.size.tile - cameraX) * 2, halfHeight, tostring(i), FG_COLOR, BG_COLOR)
end
local cameraTileY = math.floor(cameraY / TILE_SIZE)
local cameraTileY = math.floor(cameraY / mem.size.tile)
gui.line(halfWidth, 0, halfWidth, guiHeight, BG_COLOR)
for i = cameraTileY, cameraTileY + guiHeight / TILE_SIZE / 2,1 do
text(halfWidth, (i * TILE_SIZE - cameraY) * 2, tostring(i), FG_COLOR, BG_COLOR)
for i = cameraTileY, cameraTileY + guiHeight / mem.size.tile / 2,1 do
text(halfWidth, (i * mem.size.tile - cameraY) * 2, tostring(i), FG_COLOR, BG_COLOR)
end
end
local tilePtr = memory.readhword(TILEDATA_POINTER)
local tilePtr = memory.readhword(mem.addr.tiledataPointer)
for x = -TILE_RADIUS, TILE_RADIUS, 1 do
for y = -TILE_RADIUS, TILE_RADIUS, 1 do
local tileX = math.floor((partyX + x * TILE_SIZE) / TILE_SIZE) * TILE_SIZE
local tileY = math.floor((partyY + y * TILE_SIZE) / TILE_SIZE) * TILE_SIZE
local tileX = math.floor((partyX + x * mem.size.tile) / mem.size.tile) * mem.size.tile
local tileY = math.floor((partyY + y * mem.size.tile) / mem.size.tile) * mem.size.tile
local offset = game.tileOffsetCalculation(tileX, tileY, vertical)
@ -369,7 +360,7 @@ Stage (movement): %04x
flags = oam[idx * 4 + 4],
}
if screenSprite.x < 0 or screenSprite.y > guiHeight / 2 or screenSprite.y < TILE_SIZE then
if screenSprite.x < 0 or screenSprite.y > guiHeight / 2 or screenSprite.y < mem.size.tile then
goto continue
end
@ -378,8 +369,8 @@ Stage (movement): %04x
if sprite.control == 0 then
goto nextsprite
end
if screenSprite.x > sprite.screenX - ENEMY_SIZE and screenSprite.x < sprite.screenX + ENEMY_SIZE / 2 and
screenSprite.y > sprite.screenY - ENEMY_SIZE and screenSprite.y < sprite.screenY then
if screenSprite.x > sprite.screenX - mem.size.enemy and screenSprite.x < sprite.screenX + mem.size.enemy / 2 and
screenSprite.y > sprite.screenY - mem.size.enemy and screenSprite.y < sprite.screenY then
goto continue
end
::nextsprite::

109
game.lua
View file

@ -1,10 +1,13 @@
--Notes here
local memory, bit, memory2, input = memory, bit, memory2, input
local base = string.gsub(@@LUA_SCRIPT_FILENAME@@, "(.*[/\\])(.*)", "%1")
local mathFunctions = dofile(base.."/mathFunctions.lua")
local config = dofile(base.."/config.lua")
local spritelist = dofile(base.."/spritelist.lua")
local util = dofile(base.."/util.lua")
local mem = dofile(base.."/mem.lua")
local _M = {
leader = 0,
tilePtr = 0,
@ -22,37 +25,15 @@ local _M = {
spritelist.InitSpriteList()
spritelist.InitExtSpriteList()
local KREMCOINS = 0x7e08cc
local TILE_SIZE = 32
local ENEMY_SIZE = 64
local TILE_COLLISION_MATH_POINTER = 0x7e17b2
local SPRITE_BASE = 0x7e0de2
local SPRITE_SIZE = 94
local SPRITE_DYING = 0x1000
local VERTICAL_POINTER = 0xc414
local TILEDATA_POINTER = 0x7e0098
local HAVE_BOTH = 0x7e08c2
local CAMERA_X = 0x7e17ba
local CAMERA_Y = 0x7e17c0
local LEAD_CHAR = 0x7e08a4
local PARTY_X = 0x7e0a2a
local PARTY_Y = 0x7e0a2c
local SOLID_LESS_THAN = 0x7e00a0
local KONG_LETTERS = 0x7e0902
local MATH_LIVES = 0x7e08be
local DISPLAY_LIVES = 0x7e0c0
local MAIN_AREA_NUMBER = 0x7e08a8
local CURRENT_AREA_NUMBER = 0x7e08c8
function _M.getPositions()
_M.leader = memory.readword(LEAD_CHAR)
_M.tilePtr = memory.readhword(TILEDATA_POINTER)
_M.vertical = memory.readword(TILE_COLLISION_MATH_POINTER) == VERTICAL_POINTER
_M.partyX = memory.readword(PARTY_X)
_M.partyY = memory.readword(PARTY_Y)
_M.leader = memory.readword(mem.addr.leadChar)
_M.tilePtr = memory.readhword(mem.addr.tiledataPointer)
_M.vertical = memory.readword(mem.addr.tileCollisionMathPointer) == mem.addr.verticalPointer
_M.partyX = memory.readword(mem.addr.partyX)
_M.partyY = memory.readword(mem.addr.partyY)
_M.cameraX = memory.readword(CAMERA_X)
_M.cameraY = memory.readword(CAMERA_Y)
_M.cameraX = memory.readword(mem.addr.cameraX)
_M.cameraY = memory.readword(mem.addr.cameraY)
_M.screenX = (_M.partyX-256-_M.cameraX)*2
_M.screenY = (_M.partyY-256-_M.cameraY)*2
@ -69,7 +50,7 @@ function _M.getCoins()
end
function _M.getKremCoins()
local krem = memory.readword(KREMCOINS)
local krem = memory.readword(mem.addr.kremcoins)
return krem
end
@ -91,7 +72,7 @@ function _M.getGoalHit()
end
function _M.getKong()
local kong = memory.readword(KONG_LETTERS)
local kong = memory.readword(mem.addr.kongLetters)
return bit.popcount(kong)
end
@ -107,7 +88,7 @@ end
function _M.getBoth()
-- FIXME consider invincibility barrels
local both = memory.readword(HAVE_BOTH)
local both = memory.readword(mem.addr.haveBoth)
return bit.band(both, 0x4000)
end
@ -132,13 +113,12 @@ function _M.writePowerup(powerup)
-- memory.writebyte(0x0019, powerup)
end
function _M.getHit(alreadyHit)
return not alreadyHit and memory.readword(MATH_LIVES) < memory.readword(DISPLAY_LIVES)
return not alreadyHit and memory.readword(mem.addr.mathLives) < memory.readword(mem.addr.displayLives)
end
function _M.getHitTimer(lastBoth)
return (memory.readsbyte(DISPLAY_LIVES) - memory.readsbyte(MATH_LIVES))
return (memory.readsbyte(mem.addr.displayLives) - memory.readsbyte(mem.addr.mathLives))
+ lastBoth - _M.getBoth()
end
@ -180,10 +160,6 @@ function _M.tileIsSolid(x, y, tileVal, tileOffset)
return false
end
if questionable_tiles then
return true
end
local a2 = bit.band(x, 0x1f)
if bit.band(tileVal, 0x4000) ~= 0 then
@ -192,7 +168,7 @@ function _M.tileIsSolid(x, y, tileVal, tileOffset)
tileVal = bit.band(tileVal, 0x3fff)
local solidLessThan = memory.readword(SOLID_LESS_THAN)
local solidLessThan = memory.readword(mem.addr.solidLessThan)
if tileVal >= solidLessThan then
return false
@ -228,8 +204,8 @@ function _M.tileIsSolid(x, y, tileVal, tileOffset)
end
function _M.getTile(dx, dy)
local tileX = math.floor((_M.partyX + dx * TILE_SIZE) / TILE_SIZE) * TILE_SIZE
local tileY = math.floor((_M.partyY + dy * TILE_SIZE) / TILE_SIZE) * TILE_SIZE
local tileX = math.floor((_M.partyX + dx * mem.size.tile) / mem.size.tile) * mem.size.tile
local tileY = math.floor((_M.partyY + dy * mem.size.tile) / mem.size.tile) * mem.size.tile
local offset = _M.tileOffsetCalculation(tileX, tileY, _M.vertical)
@ -243,7 +219,7 @@ function _M.getTile(dx, dy)
end
function _M.getCurrentArea()
return memory.readword(CURRENT_AREA_NUMBER)
return memory.readword(mem.addr.currentAreaNumber)
end
function _M.getJumpHeight()
@ -255,27 +231,28 @@ function _M.getJumpHeight()
end
function _M.getSprite(idx)
local base_addr = idx * SPRITE_SIZE + SPRITE_BASE
local base_addr = idx * mem.size.sprite + mem.addr.spriteBase
local control = memory.readword(base_addr)
local offsets = mem.offset.sprite
local control = memory.readword(base_addr + offsets.control)
if control == 0 then
return nil
end
local x = memory.readword(base_addr + 0x06)
local y = memory.readword(base_addr + 0x0a)
local x = memory.readword(base_addr + offsets.x)
local y = memory.readword(base_addr + offsets.y)
local sprite = {
control = control,
screenX = x - 256 - _M.cameraX - 256,
screenY = y - 256 - _M.cameraY - 256,
jumpHeight = memory.readword(base_addr + 0x0e),
jumpHeight = memory.readword(base_addr + offsets.jumpHeight),
-- style bits
-- 0x4000 0: Right facing 1: Flipped
-- 0x1000 0: Alive 1: Dying
style = memory.readword(base_addr + 0x12),
velocityX = memory.readsword(base_addr + 0x20),
velocityY = memory.readsword(base_addr + 0x24),
style = memory.readword(base_addr + offsets.style),
velocityX = memory.readsword(base_addr + offsets.velocityX),
velocityY = memory.readsword(base_addr + offsets.velocityY),
x = x,
y = y,
good = spritelist.Sprites[control]
@ -328,15 +305,15 @@ function _M.getExtendedSprites()
end
-- Hide the interface icons
if screenSprite.x < 0 or screenSprite.y < TILE_SIZE then
if screenSprite.x < 0 or screenSprite.y < mem.size.tile then
goto continue
end
-- Hide sprites near computed sprites
for s=1,#sprites,1 do
local sprite = sprites[s]
if screenSprite.x > sprite.screenX - ENEMY_SIZE and screenSprite.x < sprite.screenX + ENEMY_SIZE / 2 and
screenSprite.y > sprite.screenY - ENEMY_SIZE and screenSprite.y < sprite.screenY then
if screenSprite.x > sprite.screenX - mem.size.enemy and screenSprite.x < sprite.screenX + mem.size.enemy / 2 and
screenSprite.y > sprite.screenY - mem.size.enemy and screenSprite.y < sprite.screenY then
goto continue
end
::nextsprite::
@ -363,7 +340,7 @@ function _M.getInputs()
inputs[#inputs+1] = 0
inputDeltaDistance[#inputDeltaDistance+1] = 1
tile = _M.getTile(dx, dy)
local tile = _M.getTile(dx, dy)
if tile == 1 then
if _M.getTile(dx, dy-1) == 1 then
inputs[#inputs] = -1
@ -376,13 +353,13 @@ function _M.getInputs()
for i = 1,#sprites do
local sprite = sprites[i]
local distx = math.abs(sprite.x - (_M.partyX+dx*TILE_SIZE))
local disty = math.abs(sprite.y - (_M.partyY+dy*TILE_SIZE))
local distx = math.abs(sprite.x - (_M.partyX+dx*mem.size.tile))
local disty = math.abs(sprite.y - (_M.partyY+dy*mem.size.tile))
local dist = math.sqrt((distx * distx) + (disty * disty))
if dist <= TILE_SIZE * 1.25 then
if dist <= mem.size.tile * 1.25 then
inputs[#inputs] = sprite.good
if dist > TILE_SIZE then
if dist > mem.size.tile then
inputDeltaDistance[#inputDeltaDistance] = mathFunctions.squashDistance(dist)
end
end
@ -390,13 +367,13 @@ function _M.getInputs()
end
for i = 1,#extended do
local distx = math.abs(extended[i]["x"]+_M.cameraX - (_M.partyX+dx*TILE_SIZE))
local disty = math.abs(extended[i]["y"]+_M.cameraY - (_M.partyY+dy*TILE_SIZE))
if distx < TILE_SIZE / 2 and disty < TILE_SIZE / 2 then
local distx = math.abs(extended[i]["x"]+_M.cameraX - (_M.partyX+dx*mem.size.tile))
local disty = math.abs(extended[i]["y"]+_M.cameraY - (_M.partyY+dy*mem.size.tile))
if distx < mem.size.tile / 2 and disty < mem.size.tile / 2 then
inputs[#inputs] = extended[i]["good"]
local dist = math.sqrt((distx * distx) + (disty * disty))
if dist > TILE_SIZE / 2 then
if dist > mem.size.tile / 2 then
inputDeltaDistance[#inputDeltaDistance] = mathFunctions.squashDistance(dist)
end
end
@ -432,7 +409,7 @@ function _M.onEmptyHit(handler)
end
local function processEmptyHit(addr, val)
local idx = math.floor((bit.band(addr, 0xffff) - bit.band(SPRITE_BASE, 0xffff)) / SPRITE_SIZE)
local idx = math.floor((bit.band(addr, 0xffff) - bit.band(mem.addr.spriteBase, 0xffff)) / mem.size.sprite)
local pow = _M.getSprite(idx)
if pow == nil or
pow.control ~= 0x0238 then
@ -442,7 +419,7 @@ local function processEmptyHit(addr, val)
local sprites = _M.getSprites()
for i=1,#sprites,1 do
local sprite = sprites[i]
if bit.band(sprite.style, SPRITE_DYING) ~= 0 and
if bit.band(sprite.style, mem.flag.sprite.dying) ~= 0 and
sprite.good == -1 then
return
end
@ -487,7 +464,7 @@ function _M.registerHandlers()
registerHandler(memory2.BUS, 'registerwrite', 0xb517b2, processAreaLoad)
registerHandler(memory2.WRAM, 'registerread', 0x06b1, processMapLoad)
for i=2,22,1 do
registerHandler(memory2.WRAM, 'registerwrite', bit.band(SPRITE_BASE + SPRITE_SIZE * i, 0xffff), processEmptyHit)
registerHandler(memory2.WRAM, 'registerwrite', bit.band(mem.addr.spriteBase + mem.size.sprite * i, 0xffff), processEmptyHit)
end
end

47
mem.lua Normal file
View file

@ -0,0 +1,47 @@
local _M = {
addr = {
kremcoins = 0x7e08cc,
tileCollisionMathPointer = 0x7e17b2,
spriteBase = 0x7e0de2,
verticalPointer = 0xc414,
tiledataPointer = 0x7e0098,
haveBoth = 0x7e08c2,
cameraX = 0x7e17ba,
cameraY = 0x7e17c0,
leadChar = 0x7e08a4,
partyX = 0x7e0a2a,
partyY = 0x7e0a2c,
solidLessThan = 0x7e00a0,
kongLetters = 0x7e0902,
mathLives = 0x7e08be,
displayLives = 0x7e0c0,
mainAreaNumber = 0x7e08a8,
currentAreaNumber = 0x7e08c8,
},
flag = {
sprite = {
dying = 0x1000,
}
},
size = {
tile = 32,
enemy = 64,
sprite = 94,
},
offset = {
sprite = {
control = 0x00,
x = 0x06,
y = 0x0a,
jumpHeight = 0x0e,
style = 0x12,
velocityX = 0x20,
velocityY = 0x24,
}
}
}
return _M

View file

@ -1,4 +1,5 @@
--Update to Seth-Bling's MarI/O app
local gui = gui
local base = string.gsub(@@LUA_SCRIPT_FILENAME@@, "(.*[/\\])(.*)", "%1")

View file

@ -658,6 +658,9 @@ runner.onRenderForm(function(form)
processRenderForm(form)
end)
local playTop = nil
local topRequested = false
local loadRequested = false
local saveRequested = false
local function mainLoop(currentSpecies)
@ -724,8 +727,7 @@ local function mainLoop(currentSpecies)
)
end
local topRequested = false
local function playTop()
playTop = function()
local maxfitness = 0
local maxs, maxg
for s,species in pairs(pool.species) do

BIN
rom.srm Normal file

Binary file not shown.

View file

@ -1,3 +1,5 @@
local gui, utime = gui, utime
local base = string.gsub(@@LUA_SCRIPT_FILENAME@@, "(.*[/\\])(.*)", "%1")
local Promise = dofile(base.."/promise.lua")
@ -77,7 +79,7 @@ runner.onLoad(function(filename)
end)
local waiter = nil
if not isWin then
if not util.isWin then
waiter = util.startWaiting(inputFilePath)
end
@ -98,7 +100,7 @@ local function waitLoop()
print('Waiting for input from master process')
if not isWin then
if not util.isWin then
util.finishWaiting(waiter)
end
@ -154,7 +156,7 @@ local function waitLoop()
local inputFile = io.open(inputFilePath, "w")
inputFile:close()
if not isWin then
if not util.isWin then
waiter = util.startWaiting(inputFilePath)
end

View file

@ -1,3 +1,5 @@
local random = random
local base = string.gsub(@@LUA_SCRIPT_FILENAME@@, "(.*[/\\])(.*)", "%1")
local util = dofile(base.."/util.lua")

View file

@ -1,3 +1,5 @@
local gui, input, movie, settings, exec, callback, set_timer_timeout = gui, input, movie, settings, exec, callback, set_timer_timeout
local base = string.gsub(@@LUA_SCRIPT_FILENAME@@, "(.*[/\\])(.*)", "%1")
local config = dofile(base.."/config.lua")
@ -302,7 +304,7 @@ local function painting(_M)
displayForm(_M)
end
local function evaluateNetwork(network, inputs, inputDeltas)
local function evaluateNetwork(_M, network, inputs, inputDeltas)
table.insert(inputs, 1)
table.insert(inputDeltas,99)
if #inputs ~= Inputs then
@ -353,7 +355,7 @@ local function evaluateCurrent(_M)
local inputDeltas = {}
inputs, inputDeltas = game.getInputs()
controller = evaluateNetwork(genome.network, inputs, inputDeltas)
controller = evaluateNetwork(_M, genome.network, inputs, inputDeltas)
if controller[6] and controller[7] then
controller[6] = false
@ -720,6 +722,7 @@ local function keyhook (_M, key, state)
_M.helddown = key
config.Running = not config.Running
elseif key == "4" then
-- FIXME Should be handled similarly to other events
_M.helddown = key
pool.requestTop()
elseif key == "6" then
@ -729,6 +732,7 @@ local function keyhook (_M, key, state)
_M.helddown = key
load(_M)
elseif key == "9" then
-- FIXME Event inversion
_M.helddown = key
pool.run(true)
end

View file

@ -1,3 +1,5 @@
local utime = utime
local base = string.gsub(@@LUA_SCRIPT_FILENAME@@, "(.*[/\\])(.*)", "%1")
local _M = {}