diff --git a/config.lua b/config.lua index 941c3d2..1799023 100644 --- a/config.lua +++ b/config.lua @@ -43,6 +43,9 @@ local common_cfg = { timer_loser = 1/2, decrement_reward = false, -- bad idea, encourages mario to run into goombas. score_multiplier = 1, -- how much the ingame score influences our rewards. + + starting_world = 1, -- set to 0 for random! + starting_level = 1, -- set to 0 for random! } local cfg = { diff --git a/main.lua b/main.lua index 1d13a77..10fc005 100644 --- a/main.lua +++ b/main.lua @@ -26,6 +26,7 @@ local force_start = false local force_start_old = false local startsave = savestate.create(1) +local any_random = cfg.starting_world == 0 or cfg.starting_level == 0 local poketime = false local max_time @@ -41,7 +42,7 @@ local status_old local coins_old local score_old -local once = false +local state_saved = false local reset = true local state_old = '' @@ -457,6 +458,25 @@ local function joypad_mash(button) joypad.write(1, jp_mash) end +local function loadlevel(world, level) + if world == 0 then world = random(1, 8) end + if level == 0 then level = random(1, 4) end + emu.poweron() + while emu.framecount() < 60 do + if emu.framecount() == 32 then + local area = game.area_lut[world * 10 + level] + game.W(0x75F, world - 1) + game.W(0x75C, level - 1) + game.W(0x760, area) + end + if emu.framecount() == 42 then + game.W(0x7A0, 0) -- world screen timer (reduces startup time) + end + joypad_mash('start') + emu.frameadvance() + end +end + local function do_reset() local state = game.get_state() -- be a little more descriptive. @@ -495,6 +515,10 @@ local function do_reset() if epoch_i > 0 then learn_from_epoch() end if not cfg.playback_mode then epoch_i = epoch_i + 1 end prepare_epoch() + if any_random then + loadlevel(cfg.starting_world, cfg.starting_level) + state_saved = false + end end if game.get_state() == 'loading' then game.advance() end -- kind of a hack. @@ -516,12 +540,12 @@ local function do_reset() max_time = min(6 * sqrt(480 / cfg.epoch_trials * (epoch_i - 1)) + 60, cfg.cap_time) max_time = ceil(max_time) - if once then + if state_saved then savestate.load(startsave) else savestate.save(startsave) end - once = true + state_saved = true jp = nil screen_scroll_delta = 0 @@ -549,11 +573,9 @@ local function init() emu.unpause() if not cfg.playable_mode then emu.speedmode("turbo") end - while emu.framecount() < 195 do -- FIXME: don't hardcode this. - joypad_mash('start') - emu.frameadvance() + if not any_random then + loadlevel(cfg.starting_world, cfg.starting_level) end - --print(emu.framecount()) local res, err = pcall(network.load, network, cfg.params_fn) if res == false then print(err) end diff --git a/smb.lua b/smb.lua index e11bd99..0cf85f4 100644 --- a/smb.lua +++ b/smb.lua @@ -27,6 +27,20 @@ for i, v in ipairs(valid_tiles) do tile_lut[v] = i - 1 end +local area_lut = { + -- first digit: world number. + -- second digit: level number. + -- note: excludes pipe intros. + [11] = 0, [12] = 2, [13] = 3, [14] = 4, + [21] = 0, [22] = 2, [23] = 3, [24] = 4, + [31] = 0, [32] = 1, [33] = 2, [34] = 3, + [41] = 0, [42] = 2, [43] = 3, [44] = 4, + [51] = 0, [52] = 1, [53] = 2, [54] = 3, + [61] = 0, [62] = 1, [63] = 2, [64] = 3, + [71] = 0, [72] = 2, [73] = 3, [74] = 4, + [81] = 0, [82] = 1, [83] = 2, [84] = 3, +} + local rotation_offsets = { -- FIXME: not all of these are pixel-perfect. 0, -40, -- 0x00 6, -38, @@ -295,6 +309,7 @@ S=S, overlay=overlay, valid_tiles=valid_tiles, +area_lut=area_lut, sprite_input=sprite_input, tile_input=tile_input,