Skip to content

Instantly share code, notes, and snippets.

@taotao54321
Created February 21, 2024 10:30
Show Gist options
  • Save taotao54321/8f39bc817579ee80955f971146594392 to your computer and use it in GitHub Desktop.
Save taotao54321/8f39bc817579ee80955f971146594392 to your computer and use it in GitHub Desktop.
NES Exciting Rally (a.k.a. Championship Rally): map parts generation script for FCEUX
--[[
エキサイティングラリー (FC) マップ生成スクリプト for FCEUX
T を押すとレースを開始する状態から起動する。
結果は本スクリプトからの相対パス output/map-{block_x}-{block_y}.png として出力される。
結合は別途行うこと。
--]]
local function mem_write_u8(addr, value)
memory.writebyte(addr, value)
end
local function run_frame(input)
joypad.set(1, input)
emu.frameadvance()
end
local function run_frames(n, input)
for _i = 1, n do
run_frame(input)
end
end
-- アドレス addr の実行を 1 回だけフックする。
local function hook_exec_once(addr, f)
memory.registerexec(addr, function ()
f()
memory.registerexec(addr, nil)
end)
end
-- ブロック (block_x, block_y) のマップ画像を出力する。
local function create_map_piece(block_x, block_y)
local OUTPUT_DIR = "output"
hook_exec_once(0xC89A, function ()
mem_write_u8(0x5A, block_x)
mem_write_u8(0x5B, block_y)
end)
run_frame({ start = true })
run_frames(300, {})
-- NOTE: スクリーンショットは 1F 後のものが保存されるので、フレームを進める必要がある。
local path = string.format("%s/map-%02d-%02d.png", OUTPUT_DIR, block_x, block_y)
gui.savescreenshotas(path)
run_frame({})
end
-- 全ブロックのマップ画像を出力する。
local function create_map()
local BLOCK_X_MIN = 0
local BLOCK_X_MAX = 15
local BLOCK_Y_MIN = 0
local BLOCK_Y_MAX = 63
-- 最初の emu.frameadvance() が実際にはフレームを進めない不具合の workaround。
run_frame({})
-- 路面状況は良いものとする。
mem_write_u8(0x9F, 0)
mem_write_u8(0xA0, 0)
-- 初期ステートをセーブ。
local state = savestate.object()
savestate.save(state)
for block_x = BLOCK_X_MIN, BLOCK_X_MAX do
for block_y = BLOCK_Y_MIN, BLOCK_Y_MAX do
create_map_piece(block_x, block_y)
savestate.load(state)
end
end
end
local function main()
emu.speedmode("maximum")
-- レンダリング設定: スプライトを非表示にする。
emu.setrenderplanes(false, true)
create_map()
-- レンダリング設定を元に戻す。
emu.setrenderplanes(true, true)
emu.speedmode("normal")
end
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment