Created
February 21, 2024 10:30
-
-
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
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
--[[ | |
エキサイティングラリー (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