local ObjectPosYList = {} local ObjectTypeList = {} --敵のロード処理 function LoadEnemies() --オブジェクト種類保存配列初期化 ObjectTypeList = {} ObjectPosYList = {} --ボス出現中フラグ local BossCurrentStrategy = memory.readbyte(0x3E) --移動中フラグ local ScreenMovedFlag = memory.readbyte(0x8D) --ボス戦中か if(BossCurrentStrategy ~= 0x00)then return end --移動していないか if(AND(ScreenMovedFlag,0x01) == 0x00)then return end --右向きに移動中か if(AND(ScreenMovedFlag,0x01) == 0x00)then return end if(AND(ScreenMovedFlag,0xFE) == 0x00)then LoadEnemies_Backward() else LoadEnemies_Forward() end end function LoadEnemies_Forward() local ScrollPosX = memory.readbyte(0x1A) --画面右端の座標 local CurrentScreenXMinusOne = AND(0xFF,ScrollPosX + 0xFF) --スクロールする画面番号 local ScrollPosScreen = memory.readbyte(0x1B) if(ScrollPosX ~= 0x00)then ScrollPosScreen = AND(0xFF,ScrollPosScreen + 0x01) end --敵インデックスロード local CurrentEnemyIndex = memory.readbyte(0x8C) --オブジェクトのX座標 local ObjectPosX = memory.readbyte(0x00) --現在の部屋ポインタ local CurrentRoomPointer = LoadEnemyNumber(CurrentEnemyIndex,ObjectPosX) --ポインタ local RegisterY = 0x00 while(true)do --オブジェクトの画面番号 local ObjectScreenNumber = memory.readbyte(CurrentRoomPointer+RegisterY) --画面端の判定 if(ObjectScreenNumber < ScrollPosScreen)then --何もしない elseif(ObjectScreenNumber - ScrollPosScreen ~= 0x00)then return; else --オブジェクトのX座標 ObjectPosX = memory.readbyte(CurrentRoomPointer+RegisterY+0x01) if(ObjectPosX - CurrentScreenXMinusOne == 0x00)then --何もしない elseif(ObjectPosX - CurrentScreenXMinusOne > 0x00)then return end end --オブジェクトのX座標 ObjectPosX = memory.readbyte(CurrentRoomPointer+RegisterY+0x01) --オブジェクトのY座標 local ObjectPosY = memory.readbyte(CurrentRoomPointer+RegisterY+0x02) --オブジェクトの種類 local ObjectType = memory.readbyte(CurrentRoomPointer+RegisterY+0x03) --オブジェクト出現処理へ SpawnObject(ObjectType,CurrentEnemyIndex,ObjectPosX,ObjectPosY) --ポインタインクリメント CurrentEnemyIndex = AND(0xFF,CurrentEnemyIndex + 1) RegisterY = AND(0xFF,RegisterY + 4) if(CurrentEnemyIndex == 0x00)then return end end end function LoadEnemies_Backward() --左端のスクロール座標 local ScrollPosX = memory.readbyte(0x1A) --スクロールする部屋番号 local ScrollPosScreen = memory.readbyte(0x1B) --前側の敵インデックス local PreviousEnemyIndex = memory.readbyte(0x8B) --オブジェクトのX座標 local ObjectPosX = memory.readbyte(0x00) --現在の部屋ポインタ local CurrentRoomPointer = LoadEnemyNumber(PreviousEnemyIndex,ObjectPosX) --ポインタ local RegisterY = 0x00 while(true)do --オブジェクトの画面番号 local ObjectScreenNumber = memory.readbyte(CurrentRoomPointer+RegisterY) if(PreviousEnemyIndex == 0xFF)then return end --画面端の判定 if(ObjectScreenNumber < ScrollPosScreen)then return elseif(ObjectScreenNumber ~= ScrollPosScreen)then --何もしない else --オブジェクトのX座標 ObjectPosX = memory.readbyte(CurrentRoomPointer+RegisterY+0x01) if(ObjectPosX < ScrollPosX)then return end end --オブジェクトのX座標 ObjectPosX = memory.readbyte(CurrentRoomPointer+RegisterY+0x01) --オブジェクトのY座標 local ObjectPosY = memory.readbyte(CurrentRoomPointer+RegisterY+0x02) --オブジェクトの種類 local ObjectType = memory.readbyte(CurrentRoomPointer+RegisterY+0x03) --オブジェクト出現処理へ SpawnObject(ObjectType,PreviousEnemyIndex,ObjectPosX,ObjectPosY) --ポインタデクリメント RegisterY = AND(0xFF,RegisterY + 4) PreviousEnemyIndex = AND(0xFF,PreviousEnemyIndex - 1) CurrentRoomPointer = LoadEnemyNumber(PreviousEnemyIndex,ObjectPosX) end end function SpawnObject(ObjectType,EnemyIndex,ObjectPosX,ObjectPosY) --オブジェクトの種類がFFのときは再描画的処理へ if(ObjectType == 0xFF)then return --オブジェクトのY座標がFEのときは特殊処理へ elseif(ObjectPosY == 0xFE)then return end local temp for temp = 0x0F, 0x00, -1 do if(EnemyIndex - memory.readbyte(0x7B + temp) == 0)then return end end --オブジェクトを入れる場所があるか探す local FreeObjectPointer = FindFreeObject(0x10) --あった場合はオブジェクト出現! if(FreeObjectPointer >= 0)then --出力テーブルに保存 ObjectSpriteNum = 0x6E0 + FreeObjectPointer ObjectTypeList[ObjectSpriteNum] = ObjectType --FindFreeObjectのためにObjectPosYを保存 ObjectPosYNum = 0x600 + FreeObjectPointer ObjectPosYList[ObjectPosYNum] = ObjectPosY end end --オブジェクトを-いれる場所があるか探す function FindFreeObject(ObjectPtr) while(true)do --0x600:ObjectPosY --ObjectPosYが0xF8に一致した場合 if(memory.readbyte(0x600+ObjectPtr) == 0xF8)then if(ObjectPosYList[0x600+ObjectPtr] == nil)then --オブジェクトを入れる場所を返す return ObjectPtr end end ObjectPtr = ObjectPtr + 1 --全オブジェクトが埋まっていた場合はオブジェクトを入れる場所がない local TotalObjects = memory.readbyte(0x54); if(ObjectPtr == TotalObjects)then return -1 end end end --敵番号ロード処理 function LoadEnemyNumber(CurrentEnemyIndex,ObjectPosX) local CurrentRoomPointerH = AND(0xFF,bit.lshift(ObjectPosX,2)) local CurrentRoomPointerL = AND(0xFF,bit.lshift(CurrentEnemyIndex,2)) local CurrentStagePtr = AND(0xFF,bit.lshift(memory.readbyte(0x31),1)) --CurrentRoomPointer算出。ここの処理がバンク5のとき誤りの値となる CurrentRoomPointerL = memory.readbyte(0xA452 + CurrentStagePtr) + CurrentRoomPointerL CurrentRoomPointerH = AND(CurrentRoomPointerH,0x03) + memory.readbyte(0xA453 + CurrentStagePtr); local CurrentRoomPointer = CurrentRoomPointerH * 0x100 + CurrentRoomPointerL --CurrentRoomPointerを返す return CurrentRoomPointer; end function printf(param1,param2,param3) local xadj, yadj = 0, 5 -- 行数表示 gui.text(5+xadj,5+yadj,"Param1->:"..string.format("[%X]",param1) ) gui.text(5+xadj,15+yadj,"Param2->:"..string.format("[%X]",param2) ) gui.text(5+xadj,25+yadj,"Param3->:"..string.format("[%X]",param3) ) end memory.registerexec(0xd8a0, 0x03, function(address) local pc = memory.getregister("pc") local b1 = memory.readbyte(pc) if (pc == 0xd8a0 and b1 == 0x85) then --セーブ local state = savestate.create() savestate.save(state) --いったんバンク5に切り替え memory.writebyte(0xC006,0x05) --敵呼び出し LoadEnemies() --ロード savestate.load(state) end end ) gui.register( function() --出力 local xadj, yadj = 0, 5 i=1 for j,k in pairs(ObjectTypeList) do local outputstr = string.format("[%X]->%X",j,k) local objectnum = string.format("%X",k) gui.text(5+xadj,(35+(i*10))+yadj,outputstr) i=i+1 end end ) while true do emu.frameadvance() end