Move a ton of constants into a separate file.
This commit is contained in:
parent
5c03d02c0e
commit
4158876854
13 changed files with 186 additions and 146 deletions
|
@ -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
10
bsnes-launch.lua
Normal 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..'"')
|
|
@ -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",
|
||||
|
|
137
donkutil.lua
137
donkutil.lua
|
@ -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
109
game.lua
|
@ -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
47
mem.lua
Normal 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
|
|
@ -1,4 +1,5 @@
|
|||
--Update to Seth-Bling's MarI/O app
|
||||
local gui = gui
|
||||
|
||||
local base = string.gsub(@@LUA_SCRIPT_FILENAME@@, "(.*[/\\])(.*)", "%1")
|
||||
|
||||
|
|
6
pool.lua
6
pool.lua
|
@ -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
BIN
rom.srm
Normal file
Binary file not shown.
|
@ -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
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
local random = random
|
||||
|
||||
local base = string.gsub(@@LUA_SCRIPT_FILENAME@@, "(.*[/\\])(.*)", "%1")
|
||||
|
||||
local util = dofile(base.."/util.lua")
|
||||
|
|
|
@ -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
|
||||
|
|
2
util.lua
2
util.lua
|
@ -1,3 +1,5 @@
|
|||
local utime = utime
|
||||
|
||||
local base = string.gsub(@@LUA_SCRIPT_FILENAME@@, "(.*[/\\])(.*)", "%1")
|
||||
|
||||
local _M = {}
|
||||
|
|
Loading…
Add table
Reference in a new issue