Basic save/load system (#23)

Save/load system. Not golfed.

Saves the music flag, the last level the player played, and the furthest level reached. Loads music flag on launch. Title screen starts on most recent level played; when in "release configuration" the title screen will only let the player pick levels up to the maximum reached through gameplay, but right now this is replaced with the 31.

Save file can be wiped by holding the down arrow at the title screen.

block writes while reading

Disabling writes during "wipe" and "first load" is not quite semantically what we want, it's writes during read we want to block. This happens because turning the music on or off tries to save the state, and it's easier to just ignore that persistence request than to rework the music code so it doesn't. "wipe" and "first load" are when we're actually reading (and enacting) state, but it's the act of reading rather than those two acts that should block writes.

It is also unwilling to write until it's done its first read, which I think is a feature; it makes it harder to accidentally blank out the player's data.

Reviewed-on: #23
Co-authored-by: Kistaro Windrider <kistaro@gmail.com>
Co-committed-by: Kistaro Windrider <kistaro@gmail.com>
This commit is contained in:
Kistaro Windrider 2023-01-02 23:08:03 +00:00 committed by Pyrex
parent 7c209f1125
commit b6d1a21b7e

View File

@ -8,8 +8,9 @@ real_modules={}
frame=0 frame=0
function _init() function _init()
-- printh("restarting") -- printh("restarting")
music_on() _doall("init")
_doall("init") end end
function _update() function _update()
frame+=1 frame+=1
if (frame%1==0) _doall("update") end if (frame%1==0) _doall("update") end
@ -17,12 +18,16 @@ function _draw()
_doall("draw") end _doall("draw") end
function music_on() function music_on()
music(0) if (stat(54) ~= 0) music(0)
persist.music=true
persist:write()
menuitem(3, "music: on", music_off) menuitem(3, "music: on", music_off)
end end
function music_off() function music_off()
music(-1) music(-1)
persist.music=false
persist:write()
menuitem(3, "music: off", music_on) menuitem(3, "music: off", music_on)
end end
@ -261,7 +266,7 @@ end
title={} title={}
add(modules,title) add(modules,title)
blinkcol=10 lvlshimmer = {4,9,10,10,9}
function title:draw() function title:draw()
cls(0) cls(0)
-- this is right for 72x32 -- this is right for 72x32
@ -270,22 +275,33 @@ function title:draw()
print("[nyeogmi]",62,73,7) print("[nyeogmi]",62,73,7)
print("kistaro",32,79,7) print("kistaro",32,79,7)
local lvlstr = "⬅️ "..start_level.." ➡️" local lvlstr = "⬅️ "..start_level.." ➡️"
print(lvlstr,50,91,1) local lx, ly = 51+wrongbleep:vibrate(), 90+wrongbleep:vibrate()
print(lvlstr,51,90,blinkcol) print(lvlstr,lx-1,ly+1,1)
print(lvlstr,lx,ly,cycle(lvlshimmer))
end end
start_level=0 function title:init()
max_level=31 start_level=persist.recent_level
-- max_level=persist.max_level
max_level = 31 --debugging/coding
wiped = false
end
function title:update() function title:update()
blinkcol=9
if (time()*4\1%2==0) blinkcol=10
if (btnp"0") start_level-=1 if (btnp"0") start_level-=1
if (btnp"1") start_level+=1 if (btnp"1") start_level+=1
start_level%=max_level start_level%=(max_level+1)
if btn"3" and not wiped then
if (btnp"4" or btnp"5") modules=real_modules _init() music(0) wrongbleep:bleep()
if (wrongbleep:adequately_warned()) then
persist:wipe()
max_level = 0
start_level = 0
wiped=true
-- todo: sfx(kaboom!)
end
end
if (btnp"4" or btnp"5") modules=real_modules _init()
end end
-->8 -->8
@ -308,6 +324,8 @@ function level:reinit(n)
self:load_dynobjs() self:load_dynobjs()
self:recollide_reanchor() self:recollide_reanchor()
self:spawn_exit() self:spawn_exit()
persist:lvlstart()
end end
function level:restart() function level:restart()
@ -1715,6 +1733,7 @@ end
-->8 -->8
--wrongbleeps --wrongbleeps
wrongbleep={} wrongbleep={}
add(modules,wrongbleep)
add(real_modules,wrongbleep) add(real_modules,wrongbleep)
function wrongbleep:init() function wrongbleep:init()
self.duration=0 self.duration=0
@ -1722,8 +1741,12 @@ function wrongbleep:init()
end end
function wrongbleep:update() function wrongbleep:update()
if (self.duration>5) self.duration=5 if (self.duration>5) self.duration=5
if self.duration>0 then sfx(63,3) self.continuous+=1 if self.duration>0 then
else self.continuous=0 end sfx(63,3)
self.continuous+=1
else
self.continuous=0
end
self.duration=max(self.duration-1,-4) self.duration=max(self.duration-1,-4)
end end
function wrongbleep:bleep(duration) function wrongbleep:bleep(duration)
@ -1881,6 +1904,48 @@ function debugmouse:draw3()
pal() pal()
end end
-->8
-- save/load
persist={}
add(modules, persist)
add(real_modules, persist)
function persist:init0()
cartdata("ulimate_lizard_total_destruction_0_1")
self.init0 = self.read
self:read()
end
function persist:read()
self.ready=false
local m = dget(0) == 0
self.music = m
if m then music_on() else music_off() end
self.max_level = dget(1)
self.recent_level = dget(2)
self.ready=true
end
function persist:wipe()
for i=0,64 do
dset(i,0)
end
self:read()
end
function persist:lvlstart()
self.recent_level = level.ix
self.max_level = max(self.max_level, level.ix)
self:write()
end
function persist:write()
if (not self.ready) return
dset(0, self.music and 0 or -1)
dset(1, self.max_level)
dset(2, self.recent_level)
end
__gfx__ __gfx__
000030000000002200003000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeff1ff1ff1fffffff1ffffff1fffffff1dddddddd111111110000000033300333 000030000000002200003000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeff1ff1ff1fffffff1ffffff1fffffff1dddddddd111111110000000033300333
003333300000332200333330eeffffffffffffffffffffeee5e555e55e555e5eff1ff1ffffffffffffffffffffffffffdddddddd111111110cc00cc033300333 003333300000332200333330eeffffffffffffffffffffeee5e555e55e555e5eff1ff1ffffffffffffffffffffffffffdddddddd111111110cc00cc033300333