Created
April 22, 2016 22:31
Star
You must be signed in to star a gist
This file contains 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
local startCrystalActivityAddr = 0x6B4 | |
local levelObjAddrs = { | |
0x167D5, | |
0x18815, | |
0x173F6, --FFCount=1 | |
0x14B7A, --FFCount=1 | |
0x1550E, --FFCount=1 | |
0x194D3, | |
0x128D6, | |
0x13642, --show 1 fake crystal | |
0x17E04, | |
0x10912, | |
} | |
local levelFFCount = {0,0,1,1,1,0,0,0,0,0} --hack used to correct determinate objects count per level | |
local mowgliAddrX = 0x572 | |
local mowgliAddrY = 0x571 | |
local mowgliAtScrAddrX = 0x662 | |
local mowgliAtScrAddrY = 0x674 | |
local levelNoAddr = 0x35D | |
local crystals = nil --store info about current level crystals states (position and index to monitor state (if player already got it) | |
--I don't want to find real items count variable, so I just calc objects while meet 0xFF, | |
--sometimes object list contain 0xFF, so I must use hack FFCount for manual skip it for some levels | |
function calcItems(addr, maxFFCount) | |
local count = -1 | |
local FFCount = 0 | |
repeat | |
local val = rom.readbyte(addr) | |
count = count + 1 | |
addr = addr + 1 | |
if val == 0xFF then | |
FFCount = FFCount + 1 | |
end | |
until FFCount > maxFFCount -->1 for level 3/4/5, 0 for other levels | |
return count + 1 | |
end | |
function getCrystals(addr, objectsCount) | |
local crystals = {} | |
for i = 0, objectsCount do | |
local v = rom.readbyte(addr + objectsCount*0 + i); | |
local d = rom.readbyte(addr + objectsCount*1 + i); | |
--if v == 0x40 and d == 0x0F then | |
if d == 0x0F then | |
local x = rom.readbyte(addr - objectsCount*2 + i); | |
local y = rom.readbyte(addr - objectsCount*1 + i); | |
table.insert(crystals, {x,y,i}) | |
--print("crystal coord", x, y, "index", i) | |
end | |
end | |
return crystals | |
end | |
function updateCompass(crystals) | |
if crystals == nil then | |
return | |
end | |
local posX = memory.readbyte(mowgliAddrX) | |
local posY = memory.readbyte(mowgliAddrY) - 2 | |
gui.text(1, 12, string.format("PosX:%2d",posX)) | |
gui.text(1, 20, string.format("PosY:%2d",posY)) | |
--find min dist | |
local MAXVAL = 10e6 | |
local minDist = 10e6 | |
local minDx, minDy = MAXVAL, MAXVAL | |
for i,c in ipairs(crystals) do | |
local x,y,i = c[1], c[2], c[3] | |
--check activity | |
local isActiveByte = memory.readbyte(startCrystalActivityAddr + i) | |
local isActive = bit.band(isActiveByte, 0x40) ~= 0x40 | |
if isActive then | |
local dx, dy = posX-x, posY-y | |
local distSq = dx*dx + dy*dy | |
if distSq < minDist then | |
minDist = distSq | |
minDx, minDy = dx, dy | |
end | |
end | |
end | |
local dist = math.sqrt(minDist) | |
gui.text(1, 28, string.format("Min distantion:%d",dist)) | |
if minDist == MAXVAL then | |
return | |
end | |
--draw line | |
local sx = memory.readbyte(mowgliAtScrAddrX) + 20 | |
local sy = memory.readbyte(mowgliAtScrAddrY) | |
local scale = 4 | |
local endx = sx - minDx*4 | |
local endy = sy - minDy*4 | |
gui.line(sx, sy, endx, endy, "#FFFFFF") | |
local ends = 2 | |
gui.box(endx - ends, endy - ends, endx + ends, endy + ends, "#00FF00") | |
end | |
function changeLevelNo() | |
local levelNo = memory.readbyte(levelNoAddr) | |
print("Change level no", levelNo) | |
local levelObjAddr = levelObjAddrs[levelNo+1] | |
if levelObjAddr == nil then | |
crystals = nil | |
return | |
end | |
local maxFFCount = levelFFCount[levelNo+1] | |
if maxFFCount == nil then | |
crystals = nil | |
return | |
end | |
local objectsCount = calcItems(levelObjAddr, maxFFCount) | |
print("Objects count", objectsCount) | |
crystals = getCrystals(levelObjAddr, objectsCount) | |
print("Crystals count", #crystals) | |
for k,v in ipairs(crystals) do | |
local x,y,i = v[1], v[2], v[3] | |
print("crystal coord", x, y, "index", i) | |
end | |
end | |
memory.registerwrite(levelNoAddr, changeLevelNo) | |
while(true) do | |
updateCompass(crystals) | |
FCEU.frameadvance() | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment