mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-10-06 01:04:05 -04:00
Store Gen 3 cache pixel data deflated and write compressed PNGs
Same decoded pixels, about 60 percent smaller caches. Bumps the FireRed/LeafGreen, Emerald and Ruby/Sapphire cache versions.
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
local Pack = require("src.import.gba.native_pack")
|
||||
local Palette = require("src.core.game3.palette")
|
||||
local OwExtract = require("src.import.gba.ow_extract")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
local D = {}
|
||||
|
||||
function D.imageData(rgba, w, h)
|
||||
@@ -111,12 +112,13 @@ function D.cache(spec, cancelSignal)
|
||||
if spec.directory then
|
||||
local f = io.open(spec.directory .. "/" .. path(rel), "rb")
|
||||
if not f then return nil end
|
||||
local bytes = f:read("*a"); f:close(); return bytes
|
||||
local bytes = f:read("*a"); f:close(); return CacheBlob.decode(rel, bytes)
|
||||
end
|
||||
return love.filesystem.read(path(rel))
|
||||
return CacheBlob.readFs(path(rel))
|
||||
end
|
||||
function cache:write(rel, bytes)
|
||||
checkCancel()
|
||||
bytes = CacheBlob.encode(rel, bytes)
|
||||
-- No directory creation or mounting in a worker; derived caches are optional.
|
||||
if spec.directory then
|
||||
local f = io.open(spec.directory .. "/" .. path(rel), "wb")
|
||||
|
||||
@@ -5,10 +5,11 @@ local Versions = require("src.import.gba.versions")
|
||||
local Extract = require("src.import.gba.extract_island1")
|
||||
local MapIds = require("src.core.game3.map_ids")
|
||||
local Profile = require("src.core.game3.profile")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local Dataset = {}
|
||||
|
||||
local function diskFallback(rel)
|
||||
local function diskFallbackRaw(rel)
|
||||
local override = Dataset.cacheRootOverride
|
||||
if override then
|
||||
local f = io.open(override .. "/" .. rel:gsub("^data/generated/gba/", ""), "rb")
|
||||
@@ -63,6 +64,10 @@ local function diskFallback(rel)
|
||||
return nil
|
||||
end
|
||||
|
||||
local function diskFallback(rel)
|
||||
return CacheBlob.decode(rel, diskFallbackRaw(rel))
|
||||
end
|
||||
|
||||
local function loveCache()
|
||||
return {
|
||||
assetWorkerSpec = function(_, root, kind, key)
|
||||
@@ -82,7 +87,7 @@ local function loveCache()
|
||||
if type(bytes) == "string" then return bytes end
|
||||
end
|
||||
if love and love.filesystem then
|
||||
local bytes = love.filesystem.read(rel)
|
||||
local bytes = CacheBlob.readFs(rel)
|
||||
if type(bytes) == "string" then return bytes end
|
||||
end
|
||||
return diskFallback(rel)
|
||||
@@ -93,7 +98,7 @@ local function loveCache()
|
||||
return CacheFs.write(rel, bytes)
|
||||
end
|
||||
if not love or not love.filesystem then return false end
|
||||
return love.filesystem.write(rel, bytes)
|
||||
return love.filesystem.write(rel, CacheBlob.encode(rel, bytes))
|
||||
end,
|
||||
exists = function(_, rel)
|
||||
local ok, CacheFs = pcall(require, "src.import.CacheFs")
|
||||
@@ -108,7 +113,7 @@ local function loveCache()
|
||||
and love.filesystem.getInfo(rel, "file") then
|
||||
return true
|
||||
end
|
||||
return diskFallback(rel) ~= nil
|
||||
return diskFallbackRaw(rel) ~= nil
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
local SE = require("src.core.game3.se_ids")
|
||||
|
||||
local MB = require("src.core.game3.mb")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local Doors = {}
|
||||
|
||||
@@ -619,13 +620,13 @@ local function loadSheet(tileName, sheetFile)
|
||||
end
|
||||
|
||||
if not bytes and love and love.filesystem and love.filesystem.read then
|
||||
bytes = love.filesystem.read(relPath) or love.filesystem.read("doors/" .. file)
|
||||
bytes = CacheBlob.readFs(relPath) or CacheBlob.readFs("doors/" .. file)
|
||||
end
|
||||
|
||||
if not bytes then
|
||||
local f = io.open(relPath, "rb")
|
||||
if f then
|
||||
bytes = f:read("*a")
|
||||
bytes = CacheBlob.decode(relPath, f:read("*a"))
|
||||
f:close()
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,6 +5,7 @@ local Extract = require("src.import.gba.extract_island1")
|
||||
local Dex = require("src.core.game3.dex")
|
||||
local Pokemon = require("src.core.game3.pokemon")
|
||||
local RomText = require("src.core.game3.rom_text")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local PokedexData = {}
|
||||
|
||||
@@ -40,7 +41,7 @@ local function read_bytes(rel)
|
||||
for _, p in ipairs(candidates) do
|
||||
local f = io.open(p, "rb")
|
||||
if f then
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(p, f:read("*a"))
|
||||
f:close()
|
||||
if d and #d > 0 then return d end
|
||||
end
|
||||
|
||||
@@ -3,6 +3,7 @@ local CachePaths = require("src.core.game3.cache_paths")
|
||||
local PokemonExtract = require("src.import.gba.pokemon_extract")
|
||||
local Versions = require("src.import.gba.versions")
|
||||
local ModRuntime = require("src.mods.Runtime")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local Pokemon = {}
|
||||
|
||||
@@ -56,7 +57,7 @@ local function resolve_cache(cache)
|
||||
end
|
||||
local f = io.open(rel, "rb") or io.open("data/generated/gba/" .. rel, "rb")
|
||||
if f then
|
||||
local data = f:read("*a")
|
||||
local data = CacheBlob.decode(rel, f:read("*a"))
|
||||
f:close()
|
||||
return data
|
||||
end
|
||||
|
||||
@@ -4,6 +4,7 @@ local band, rshift = bit.band, bit.rshift
|
||||
local Tasks = require("src.core.game3.gba_tasks")
|
||||
|
||||
local RsPolicy = require("src.core.game3.rs.berry_blender_policy")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
local Blender = {}
|
||||
Blender.__index = Blender
|
||||
|
||||
@@ -71,7 +72,7 @@ local function readCache(path)
|
||||
if okR and s then return s end
|
||||
end
|
||||
if love and love.filesystem and love.filesystem.getInfo and love.filesystem.getInfo(path) then
|
||||
return love.filesystem.read(path)
|
||||
return CacheBlob.readFs(path)
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
local Tower = {}
|
||||
|
||||
-- pokefirered/include/constants/trainer_tower.h:30
|
||||
@@ -152,12 +153,12 @@ local function read_bytes(rel)
|
||||
if okR and type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
if type(love) == "table" and love.filesystem and love.filesystem.read then
|
||||
local okR, d = pcall(love.filesystem.read, rel)
|
||||
local okR, d = pcall(CacheBlob.readFs, rel)
|
||||
if okR and type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
local f = io.open(rel, "rb")
|
||||
if f then
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(rel, f:read("*a"))
|
||||
f:close()
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
local CacheBlob = {}
|
||||
|
||||
CacheBlob.LEVEL = 6
|
||||
CacheBlob.DERIVED_LEVEL = 1
|
||||
|
||||
local PACKED = { rgba = true, idx = true }
|
||||
|
||||
local function extension(rel)
|
||||
return type(rel) == "string" and rel:match("%.([^./\\]+)$") or nil
|
||||
end
|
||||
|
||||
function CacheBlob.packs(rel)
|
||||
local ext = extension(rel)
|
||||
return ext ~= nil and PACKED[ext] == true
|
||||
end
|
||||
|
||||
local loveData
|
||||
local function loveBackend()
|
||||
if loveData ~= nil then return loveData end
|
||||
loveData = false
|
||||
local L = rawget(_G, "love")
|
||||
if L and not (L.data and L.data.compress) then pcall(require, "love.data") end
|
||||
if L and L.data and L.data.compress and L.data.decompress then loveData = L.data end
|
||||
return loveData
|
||||
end
|
||||
|
||||
local zlib
|
||||
local function ffiBackend()
|
||||
if zlib ~= nil then return zlib end
|
||||
zlib = false
|
||||
local okF, ffi = pcall(require, "ffi")
|
||||
if not okF then return zlib end
|
||||
pcall(ffi.cdef, [[
|
||||
unsigned long compressBound(unsigned long sourceLen);
|
||||
int compress2(uint8_t *dest, unsigned long *destLen, const uint8_t *source, unsigned long sourceLen, int level);
|
||||
int uncompress(uint8_t *dest, unsigned long *destLen, const uint8_t *source, unsigned long sourceLen);
|
||||
]])
|
||||
for _, name in ipairs(ffi.os == "Windows" and { "zlib1", "z" } or { "z", "libz.so.1" }) do
|
||||
local okL, lib = pcall(ffi.load, name)
|
||||
if okL and lib and pcall(function() return lib.uncompress end) then
|
||||
zlib = { ffi = ffi, lib = lib }
|
||||
break
|
||||
end
|
||||
end
|
||||
return zlib
|
||||
end
|
||||
|
||||
function CacheBlob.deflate(raw, level)
|
||||
level = level or CacheBlob.LEVEL
|
||||
local L = loveBackend()
|
||||
if L then return L.compress("string", "zlib", raw, level) end
|
||||
local Z = assert(ffiBackend(), "CacheBlob: no zlib backend (love.data or libz)")
|
||||
local ffi = Z.ffi
|
||||
local cap = tonumber(Z.lib.compressBound(#raw))
|
||||
local out = ffi.new("uint8_t[?]", cap)
|
||||
local len = ffi.new("unsigned long[1]", cap)
|
||||
local rc = Z.lib.compress2(out, len, raw, #raw, level)
|
||||
assert(rc == 0, "CacheBlob: compress2 failed (" .. tostring(rc) .. ")")
|
||||
return ffi.string(out, tonumber(len[0]))
|
||||
end
|
||||
|
||||
function CacheBlob.inflate(z)
|
||||
local L = loveBackend()
|
||||
if L then return L.decompress("string", "zlib", z) end
|
||||
local Z = assert(ffiBackend(), "CacheBlob: no zlib backend (love.data or libz)")
|
||||
local ffi = Z.ffi
|
||||
local cap = math.max(4096, #z * 16)
|
||||
while true do
|
||||
local out = ffi.new("uint8_t[?]", cap)
|
||||
local len = ffi.new("unsigned long[1]", cap)
|
||||
local rc = Z.lib.uncompress(out, len, z, #z)
|
||||
if rc == 0 then return ffi.string(out, tonumber(len[0])) end
|
||||
assert(rc == -5, "CacheBlob: uncompress failed (" .. tostring(rc) .. ")")
|
||||
cap = cap * 4
|
||||
end
|
||||
end
|
||||
|
||||
function CacheBlob.encode(rel, bytes)
|
||||
if type(bytes) ~= "string" or not CacheBlob.packs(rel) then return bytes end
|
||||
return CacheBlob.deflate(bytes, rel:find("/atlas_", 1, true) and CacheBlob.DERIVED_LEVEL or CacheBlob.LEVEL)
|
||||
end
|
||||
|
||||
function CacheBlob.decode(rel, bytes)
|
||||
if type(bytes) ~= "string" or not CacheBlob.packs(rel) then return bytes end
|
||||
local ok, raw = pcall(CacheBlob.inflate, bytes)
|
||||
if not ok then error("cache blob " .. tostring(rel) .. " is not deflated (stale cache, reimport): " .. tostring(raw), 2) end
|
||||
return raw
|
||||
end
|
||||
|
||||
function CacheBlob.readFs(rel)
|
||||
if not (love and love.filesystem and love.filesystem.read) then return nil end
|
||||
local bytes = love.filesystem.read(rel)
|
||||
return CacheBlob.decode(rel, bytes)
|
||||
end
|
||||
|
||||
return CacheBlob
|
||||
@@ -22,12 +22,12 @@ CacheContract.VERSION_FORMAT = {
|
||||
-- data/pikachu/pikachu_pic_animation.asm:340
|
||||
yellow = "rom-cache-v12-yellow2:",
|
||||
-- v8: M4A tracks retain reachable patterns and explicit entry offsets.
|
||||
firered = "rom-cache-v24-firered:",
|
||||
leafgreen = "rom-cache-v9-leafgreen:",
|
||||
emerald = "rom-cache-v4-emerald:",
|
||||
firered = "rom-cache-v25-firered:",
|
||||
leafgreen = "rom-cache-v10-leafgreen:",
|
||||
emerald = "rom-cache-v5-emerald:",
|
||||
-- pokeruby/src/string_util.c:408
|
||||
ruby = "rom-cache-v6-ruby:",
|
||||
sapphire = "rom-cache-v6-sapphire:",
|
||||
ruby = "rom-cache-v7-ruby:",
|
||||
sapphire = "rom-cache-v7-sapphire:",
|
||||
}
|
||||
CacheContract.MARKER_PATH = "rom-cache.complete"
|
||||
|
||||
@@ -1009,7 +1009,7 @@ function CacheContract.sourceTreeHasData(version)
|
||||
local exact = {
|
||||
read = function(path)
|
||||
local full = prefix .. path
|
||||
if love.filesystem.getRealDirectory(full) == source then return love.filesystem.read(full) end
|
||||
if love.filesystem.getRealDirectory(full) == source then return require("src.import.CacheBlob").readFs(full) end
|
||||
end,
|
||||
exists = function(path)
|
||||
local full = prefix .. path
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
local CacheFs = {}
|
||||
local Platform = require("src.core.Platform")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
local SaveData = setmetatable({}, {
|
||||
__index = function(_, k) return require("src.core.SaveData")[k] end,
|
||||
})
|
||||
@@ -324,6 +325,7 @@ end
|
||||
function CacheFs.write(rel, data)
|
||||
rel = withPrefix(rel)
|
||||
if unsafe_rel(rel) then return false, "unsafe cache path" end
|
||||
data = CacheBlob.encode(rel, data)
|
||||
local root, rootErr = resolveWriteRoot()
|
||||
if not root and rootErr then return false, rootErr end
|
||||
if root then
|
||||
@@ -389,12 +391,12 @@ function CacheFs.readAt(rel)
|
||||
if not f then return nil end
|
||||
local data = f:read("*a")
|
||||
f:close()
|
||||
return data
|
||||
return CacheBlob.decode(rel, data)
|
||||
end
|
||||
-- headless (plain luajit, e.g. the modkit validate/pack driver): there is
|
||||
-- no save directory to read from, so a cache miss is nil, not a crash
|
||||
if not (love and love.filesystem and love.filesystem.read) then return nil end
|
||||
return love.filesystem.read(rel)
|
||||
return (CacheBlob.readFs(rel))
|
||||
end
|
||||
|
||||
-- read cache-relative `rel`; returns the bytes or nil
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
local Versions = require("src.import.gba.versions")
|
||||
local Lz77 = require("src.import.gba.lz77")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local BattleAnimExtract = {}
|
||||
|
||||
@@ -504,16 +505,6 @@ local function crc32(str)
|
||||
return bxor(c, 0xFFFFFFFF)
|
||||
end
|
||||
|
||||
local function adler32(str)
|
||||
local s1 = 1
|
||||
local s2 = 0
|
||||
for i = 1, #str do
|
||||
s1 = (s1 + str:byte(i)) % 65521
|
||||
s2 = (s2 + s1) % 65521
|
||||
end
|
||||
return s2 * 65536 + s1
|
||||
end
|
||||
|
||||
local function u32be(n)
|
||||
n = band(n, 0xFFFFFFFF)
|
||||
return string.char(
|
||||
@@ -524,10 +515,6 @@ local function u32be(n)
|
||||
)
|
||||
end
|
||||
|
||||
local function u16le(n)
|
||||
return string.char(band(n, 0xFF), band(rshift(n, 8), 0xFF))
|
||||
end
|
||||
|
||||
local function make_chunk(type_str, data)
|
||||
local crc = crc32(type_str .. data)
|
||||
return u32be(#data) .. type_str .. data .. u32be(crc)
|
||||
@@ -607,31 +594,7 @@ local function encode_png(pixels, w, h)
|
||||
raw_data = table.concat(raw_lines)
|
||||
end
|
||||
|
||||
local idat_data
|
||||
if love and love.data and love.data.compress then
|
||||
local ok, comp = pcall(love.data.compress, "string", "zlib", raw_data)
|
||||
if ok and comp then
|
||||
idat_data = comp
|
||||
end
|
||||
end
|
||||
|
||||
if not idat_data then
|
||||
-- Deflate uncompressed blocks (max 65535 per block)
|
||||
local zlib_blocks = { string.char(0x78, 0x01) } -- ZLIB header
|
||||
local pos = 1
|
||||
local total_len = #raw_data
|
||||
while pos <= total_len do
|
||||
local chunk_len = math.min(total_len - pos + 1, 65535)
|
||||
local is_final = (pos + chunk_len > total_len) and 1 or 0
|
||||
zlib_blocks[#zlib_blocks + 1] = string.char(is_final)
|
||||
zlib_blocks[#zlib_blocks + 1] = u16le(chunk_len)
|
||||
zlib_blocks[#zlib_blocks + 1] = u16le(bxor(chunk_len, 0xFFFF))
|
||||
zlib_blocks[#zlib_blocks + 1] = raw_data:sub(pos, pos + chunk_len - 1)
|
||||
pos = pos + chunk_len
|
||||
end
|
||||
zlib_blocks[#zlib_blocks + 1] = u32be(adler32(raw_data))
|
||||
idat_data = table.concat(zlib_blocks)
|
||||
end
|
||||
local idat_data = CacheBlob.deflate(raw_data, 9)
|
||||
|
||||
-- PNG Signature + IHDR + IDAT + IEND
|
||||
local sig = "\137PNG\r\n\026\n"
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
local Versions = require("src.import.gba.versions")
|
||||
local Lz77 = require("src.import.gba.lz77")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local BattleChromeExtract = {}
|
||||
|
||||
@@ -725,11 +726,11 @@ function BattleChromeExtract.ready(cache, cacheRoot)
|
||||
local CacheFs = require("src.import.CacheFs")
|
||||
local bytes = CacheFs.readActive and CacheFs.readActive(rel)
|
||||
if bytes then return bytes end
|
||||
if love and love.filesystem then bytes = love.filesystem.read(rel) end
|
||||
if love and love.filesystem then bytes = CacheBlob.readFs(rel) end
|
||||
if bytes then return bytes end
|
||||
local file = io.open(rel, "rb")
|
||||
if not file then return nil end
|
||||
bytes = file:read("*a"); file:close(); return bytes
|
||||
bytes = CacheBlob.decode(rel, file:read("*a")); file:close(); return bytes
|
||||
end
|
||||
local body = read_file(root .. "/manifest.lua")
|
||||
local chunk = type(body) == "string" and load(body, "@battle/manifest.lua", "t", {})
|
||||
@@ -767,7 +768,7 @@ function BattleChromeExtract.ready(cache, cacheRoot)
|
||||
if data and #data >= minSize then return true end
|
||||
end
|
||||
if love and love.filesystem and love.filesystem.read then
|
||||
local ok, data = pcall(love.filesystem.read, rel)
|
||||
local ok, data = pcall(CacheBlob.readFs, rel)
|
||||
if ok and data and #data >= minSize then return true end
|
||||
end
|
||||
local f = io.open(rel, "rb")
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
-- File-backed mod.imports / mod.cache shim for offline extract (dev CLI).
|
||||
|
||||
local FileIO = {}
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
function FileIO.makeImports(path, md5, id)
|
||||
id = id or "firered"
|
||||
@@ -45,7 +46,7 @@ function FileIO.makeCache(root)
|
||||
local parent = path:match("^(.*)/[^/]+$")
|
||||
if parent then mkdir_p(parent) end
|
||||
local f = assert(io.open(path, "wb"))
|
||||
f:write(bytes)
|
||||
f:write(CacheBlob.encode(rel, bytes))
|
||||
f:close()
|
||||
return true
|
||||
end
|
||||
@@ -54,7 +55,7 @@ function FileIO.makeCache(root)
|
||||
if not f then return nil end
|
||||
local d = f:read("*a")
|
||||
f:close()
|
||||
return d
|
||||
return CacheBlob.decode(rel, d)
|
||||
end
|
||||
function cache:exists(rel)
|
||||
local f = io.open(root .. "/" .. rel, "rb")
|
||||
|
||||
@@ -3,7 +3,7 @@ local VersionsRse = require("src.import.gba.versions_rse")
|
||||
local V = VersionsRse.new("emerald")
|
||||
local sym, count = V.sym, V.count
|
||||
|
||||
V.CACHE_VERSION = 14
|
||||
V.CACHE_VERSION = 15
|
||||
V.NATIVE_VERSION = 2
|
||||
V.OW_VERSION = 1
|
||||
V.ANIM_VERSION = 1
|
||||
|
||||
@@ -6,7 +6,7 @@ local Rs = {}
|
||||
local function tables(game, revision)
|
||||
local V = VersionsRse.new(game, revision.build)
|
||||
local sym, count = V.sym, V.count
|
||||
V.CACHE_VERSION = 2
|
||||
V.CACHE_VERSION = 3
|
||||
V.NATIVE_VERSION = 2
|
||||
V.OW_VERSION = 1
|
||||
V.ANIM_VERSION = 1
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
local Versions = require("src.import.gba.versions")
|
||||
local Lz77 = require("src.import.gba.lz77")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local PartyChromeExtract = {}
|
||||
|
||||
@@ -488,12 +489,12 @@ function PartyChromeExtract.ready(cache, cacheRoot)
|
||||
if d and #d >= 80 * 56 * 4 then return true end
|
||||
end
|
||||
if love and love.filesystem and love.filesystem.read then
|
||||
local d = love.filesystem.read(need)
|
||||
local d = CacheBlob.readFs(need)
|
||||
if d and #d >= 80 * 56 * 4 then return true end
|
||||
end
|
||||
local f = io.open(need, "rb") or io.open("data/generated/gba/" .. PartyChromeExtract.CACHE_SUB .. "/slot_main.rgba", "rb")
|
||||
if f then
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(need, f:read("*a"))
|
||||
f:close()
|
||||
if d and #d >= 80 * 56 * 4 then return true end
|
||||
end
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
local Versions = require("src.import.gba.versions")
|
||||
local TextIR = require("src.core.game3.scripting.text_ir")
|
||||
local Lz77 = require("src.import.gba.lz77")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local PokedexChromeExtract = {}
|
||||
|
||||
@@ -873,7 +874,7 @@ function PokedexChromeExtract.ready(cache, cacheRoot)
|
||||
if data and #data >= minSize then return true end
|
||||
end
|
||||
if love and love.filesystem and love.filesystem.read then
|
||||
local ok, data = pcall(love.filesystem.read, rel)
|
||||
local ok, data = pcall(CacheBlob.readFs, rel)
|
||||
if ok and data and #data >= minSize then return true end
|
||||
end
|
||||
local f = io.open(rel, "rb")
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
-- src/region_map.c:393-427
|
||||
|
||||
local RegionMapExtract = {}
|
||||
@@ -553,12 +555,12 @@ local function baked(cache, rel)
|
||||
if d and #d > 8 then return true end
|
||||
end
|
||||
if love and love.filesystem and love.filesystem.read then
|
||||
local d = love.filesystem.read(rel)
|
||||
local d = CacheBlob.readFs(rel)
|
||||
if d and #d > 8 then return true end
|
||||
end
|
||||
local f = io.open(rel, "rb")
|
||||
if f then
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(rel, f:read("*a"))
|
||||
f:close()
|
||||
if d and #d > 8 then return true end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
local Lz77 = require("src.import.gba.lz77")
|
||||
local LuaWriter = require("src.import.LuaWriter")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local bit = rawget(_G, "bit") or require("bit")
|
||||
local band, bxor, rshift = bit.band, bit.bxor, bit.rshift
|
||||
@@ -51,40 +52,9 @@ local function chunk(kind, data)
|
||||
return be32(#data) .. kind .. data .. be32(crc32(kind .. data))
|
||||
end
|
||||
|
||||
local function adler32(s)
|
||||
local a, b = 1, 0
|
||||
for i = 1, #s do
|
||||
a = (a + s:byte(i)) % 65521
|
||||
b = (b + a) % 65521
|
||||
end
|
||||
return b * 65536 + a
|
||||
end
|
||||
|
||||
local function zlibStored(raw)
|
||||
local parts = { "\120\1" }
|
||||
local n = #raw
|
||||
local pos = 1
|
||||
repeat
|
||||
local len = math.min(65535, n - pos + 1)
|
||||
local final = (pos + len > n) and 1 or 0
|
||||
parts[#parts + 1] = string.char(final, len % 256, math.floor(len / 256),
|
||||
(65535 - len) % 256, math.floor((65535 - len) / 256))
|
||||
parts[#parts + 1] = raw:sub(pos, pos + len - 1)
|
||||
pos = pos + len
|
||||
until pos > n
|
||||
parts[#parts + 1] = be32(adler32(raw))
|
||||
return table.concat(parts)
|
||||
end
|
||||
|
||||
local function zlib(raw)
|
||||
local love = rawget(_G, "love")
|
||||
if love and love.data and love.data.compress then
|
||||
local ok, out = pcall(love.data.compress, "string", "zlib", raw)
|
||||
if ok and type(out) == "string" then return out end
|
||||
end
|
||||
return zlibStored(raw)
|
||||
return CacheBlob.deflate(raw, 9)
|
||||
end
|
||||
K.zlibStored = zlibStored
|
||||
|
||||
local function scanlines(w, h, idx)
|
||||
local rows = {}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
local Versions = require("src.import.gba.versions")
|
||||
local Lz77 = require("src.import.gba.lz77")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local SummaryChromeExtract = {}
|
||||
|
||||
@@ -82,12 +83,12 @@ local function read_bin(candidates)
|
||||
if d and #d > 0 then return d end
|
||||
end
|
||||
if love and love.filesystem and love.filesystem.read then
|
||||
local ok, d = pcall(love.filesystem.read, p)
|
||||
local ok, d = pcall(CacheBlob.readFs, p)
|
||||
if ok and d and #d > 0 then return d end
|
||||
end
|
||||
local f = io.open(p, "rb")
|
||||
if f then
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(p, f:read("*a"))
|
||||
f:close()
|
||||
if d and #d > 0 then return d end
|
||||
end
|
||||
@@ -709,12 +710,12 @@ function SummaryChromeExtract.ready(cache, cacheRoot)
|
||||
if d and #d >= 240 * 160 * 4 then return true end
|
||||
end
|
||||
if love and love.filesystem and love.filesystem.read then
|
||||
local d = love.filesystem.read(need)
|
||||
local d = CacheBlob.readFs(need)
|
||||
if d and #d >= 240 * 160 * 4 then return true end
|
||||
end
|
||||
local f = io.open(need, "rb") or io.open("data/generated/gba/" .. SummaryChromeExtract.CACHE_SUB .. "/page_info.rgba", "rb")
|
||||
if f then
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(need, f:read("*a"))
|
||||
f:close()
|
||||
if d and #d >= 240 * 160 * 4 then return true end
|
||||
end
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
local Versions = require("src.import.gba.versions")
|
||||
local Lz77 = require("src.import.gba.lz77")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local TrainerCardExtract = {}
|
||||
|
||||
@@ -406,12 +407,12 @@ function TrainerCardExtract.ready(cache, cacheRoot)
|
||||
if d and #d >= 240 * 160 * 4 then return true end
|
||||
end
|
||||
if love and love.filesystem and love.filesystem.read then
|
||||
local d = love.filesystem.read(need)
|
||||
local d = CacheBlob.readFs(need)
|
||||
if d and #d >= 240 * 160 * 4 then return true end
|
||||
end
|
||||
local f = io.open(need, "rb") or io.open("data/generated/gba/" .. TrainerCardExtract.CACHE_SUB .. "/bg.rgba", "rb")
|
||||
if f then
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(need, f:read("*a"))
|
||||
f:close()
|
||||
if d and #d >= 240 * 160 * 4 then return true end
|
||||
end
|
||||
|
||||
@@ -43,7 +43,7 @@ Versions.ROM_SIZE = 16777216
|
||||
-- v115: LeafGreen profiles, edition-specific title assets and Deoxys stats.
|
||||
-- v121: chrome/fonts/japanese_{normal,small}_* and japanese_widths.lua, the
|
||||
-- cart's Japanese fonts, for text a Japanese translation mod prints.
|
||||
Versions.CACHE_VERSION = 129
|
||||
Versions.CACHE_VERSION = 130
|
||||
Versions.NATIVE_VERSION = 6
|
||||
Versions.OW_VERSION = 3
|
||||
Versions.ANIM_VERSION = 1
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
local Extract = require("src.import.gba.extract_island1")
|
||||
local BagChromeExtract = require("src.import.gba.bag_chrome_extract")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local BagChrome = {}
|
||||
|
||||
@@ -48,10 +49,10 @@ local function read_bytes(rel)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
if love and love.filesystem and love.filesystem.read then
|
||||
local d = love.filesystem.read(rel)
|
||||
local d = CacheBlob.readFs(rel)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
local alt = "data/generated/gba/" .. (rel:gsub("^data/generated/gba/", ""))
|
||||
d = love.filesystem.read(alt)
|
||||
d = CacheBlob.readFs(alt)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
local candidates = {
|
||||
@@ -61,7 +62,7 @@ local function read_bytes(rel)
|
||||
for _, p in ipairs(candidates) do
|
||||
local f = io.open(p, "rb")
|
||||
if f then
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(p, f:read("*a"))
|
||||
f:close()
|
||||
if d and #d > 0 then return d end
|
||||
end
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
local Extract = require("src.import.gba.extract_island1")
|
||||
local BattleChromeExtract = require("src.import.gba.battle_chrome_extract")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local BattleChrome = {}
|
||||
|
||||
@@ -68,10 +69,10 @@ local function read_bytes(rel)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
if love and love.filesystem and love.filesystem.read then
|
||||
local d = love.filesystem.read(rel)
|
||||
local d = CacheBlob.readFs(rel)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
local alt = "data/generated/gba/" .. (rel:gsub("^data/generated/gba/", ""))
|
||||
d = love.filesystem.read(alt)
|
||||
d = CacheBlob.readFs(alt)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
local candidates = {
|
||||
@@ -81,7 +82,7 @@ local function read_bytes(rel)
|
||||
for _, p in ipairs(candidates) do
|
||||
local f = io.open(p, "rb")
|
||||
if f then
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(p, f:read("*a"))
|
||||
f:close()
|
||||
if d and #d > 0 then return d end
|
||||
end
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
local Extract = require("src.import.gba.extract_island1")
|
||||
local BerryPouchExtract = require("src.import.gba.berry_pouch_extract")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local BerryPouchChrome = {}
|
||||
|
||||
@@ -37,10 +38,10 @@ local function read_bytes(rel)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
if love and love.filesystem and love.filesystem.read then
|
||||
local d = love.filesystem.read(rel)
|
||||
local d = CacheBlob.readFs(rel)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
local alt = "data/generated/gba/" .. (rel:gsub("^data/generated/gba/", ""))
|
||||
d = love.filesystem.read(alt)
|
||||
d = CacheBlob.readFs(alt)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
local candidates = {
|
||||
@@ -50,7 +51,7 @@ local function read_bytes(rel)
|
||||
for _, p in ipairs(candidates) do
|
||||
local f = io.open(p, "rb")
|
||||
if f then
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(p, f:read("*a"))
|
||||
f:close()
|
||||
if d and #d > 0 then return d end
|
||||
end
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
local FrlgFont = require("src.ui.game3.frlg_font")
|
||||
local TextIR = require("src.core.game3.scripting.text_ir")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local Braille = {}
|
||||
|
||||
@@ -109,17 +110,17 @@ local function read_bytes(rel)
|
||||
if okR and type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
if love and love.filesystem and love.filesystem.read then
|
||||
local okR, d = pcall(love.filesystem.read, rel)
|
||||
local okR, d = pcall(CacheBlob.readFs, rel)
|
||||
if okR and type(d) == "string" and #d > 0 then return d end
|
||||
local alt = "data/generated/gba/" .. (rel:gsub("^data/generated/gba/", ""))
|
||||
okR, d = pcall(love.filesystem.read, alt)
|
||||
okR, d = pcall(CacheBlob.readFs, alt)
|
||||
if okR and type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
local candidates = { rel, "data/generated/gba/" .. (rel:gsub("^data/generated/gba/", "")) }
|
||||
for _, path in ipairs(candidates) do
|
||||
local f = io.open(path, "rb")
|
||||
if f then
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(path, f:read("*a"))
|
||||
f:close()
|
||||
if d and #d > 0 then return d end
|
||||
end
|
||||
|
||||
@@ -9,6 +9,7 @@ local Oam = require("src.core.game3.oam")
|
||||
local SE = require("src.core.game3.se_ids")
|
||||
local RomText = require("src.core.game3.rom_text")
|
||||
local BattleChrome = require("src.ui.game3.battle_chrome")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local EggHatch = {}
|
||||
|
||||
@@ -70,13 +71,13 @@ local function read_bytes(path)
|
||||
if love and love.filesystem and love.filesystem.getInfo then
|
||||
local info = love.filesystem.getInfo(path)
|
||||
if info then
|
||||
local data = love.filesystem.read(path)
|
||||
local data = CacheBlob.readFs(path)
|
||||
if data and #data > 0 then return data end
|
||||
end
|
||||
end
|
||||
local f = io.open(path, "rb")
|
||||
if f then
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(path, f:read("*a"))
|
||||
f:close()
|
||||
if d and #d > 0 then return d end
|
||||
end
|
||||
|
||||
@@ -6,6 +6,7 @@ local FrlgFont = require("src.ui.game3.frlg_font")
|
||||
local FameChecker = require("src.core.game3.fame_checker")
|
||||
local TextIR = require("src.core.game3.scripting.text_ir")
|
||||
local RomText = require("src.core.game3.rom_text")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local FameCheckerUi = { isMenu = true }
|
||||
|
||||
@@ -105,12 +106,12 @@ local function read_bytes(rel)
|
||||
if ok and type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
if love and love.filesystem and love.filesystem.read then
|
||||
local ok, d = pcall(love.filesystem.read, rel)
|
||||
local ok, d = pcall(CacheBlob.readFs, rel)
|
||||
if ok and type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
local f = io.open(rel, "rb")
|
||||
if f then
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(rel, f:read("*a"))
|
||||
f:close()
|
||||
if d and #d > 0 then return d end
|
||||
end
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
-- Field dialogue must use this — Gen2 Font.lua is fixed 8px and overflows the 208px box.
|
||||
|
||||
local TextIR = require("src.core.game3.scripting.text_ir")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local FrlgFont = {}
|
||||
|
||||
@@ -246,15 +247,15 @@ local function loadImage(candidates)
|
||||
end
|
||||
end
|
||||
if not data and love and love.filesystem and love.filesystem.read then
|
||||
data = love.filesystem.read(path)
|
||||
data = CacheBlob.readFs(path)
|
||||
if not data then
|
||||
data = love.filesystem.read("data/generated/gba/" .. (path:gsub("^data/generated/gba/", "")))
|
||||
data = CacheBlob.readFs("data/generated/gba/" .. (path:gsub("^data/generated/gba/", "")))
|
||||
end
|
||||
end
|
||||
if not data then
|
||||
local f = io.open(path, "rb") or io.open("data/generated/gba/" .. (path:gsub("^data/generated/gba/", "")), "rb")
|
||||
if f then
|
||||
data = f:read("*a")
|
||||
data = CacheBlob.decode(path, f:read("*a"))
|
||||
f:close()
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,6 +2,7 @@ local Stack = require("src.ui.game3.stack")
|
||||
local Window = require("src.ui.game3.window")
|
||||
local FrlgFont = require("src.ui.game3.frlg_font")
|
||||
local Status = require("src.core.game3.link.status")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local LinkMenu = {}
|
||||
|
||||
@@ -53,12 +54,12 @@ local function read_bytes(rel)
|
||||
if okR and type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
if love and love.filesystem and love.filesystem.read then
|
||||
local okR, d = pcall(love.filesystem.read, "data/generated/gba/" .. rel)
|
||||
local okR, d = pcall(CacheBlob.readFs, "data/generated/gba/" .. rel)
|
||||
if okR and type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
local f = io.open("data/generated/gba/" .. rel, "rb")
|
||||
if f then
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode("data/generated/gba/" .. rel, f:read("*a"))
|
||||
f:close()
|
||||
if d and #d > 0 then return d end
|
||||
end
|
||||
|
||||
@@ -5,6 +5,7 @@ local CaveTransition = require("src.ui.game3.cave_transition")
|
||||
local Extract = require("src.import.gba.extract_island1")
|
||||
local MapPreviewExtract = require("src.import.gba.map_preview_extract")
|
||||
local Strings = require("src.core.Strings")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local MapPreviewScreen = {}
|
||||
|
||||
@@ -87,10 +88,10 @@ local function read_bytes(rel)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
if love and love.filesystem and love.filesystem.read then
|
||||
local d = love.filesystem.read(rel)
|
||||
local d = CacheBlob.readFs(rel)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
local alt = "data/generated/gba/" .. (rel:gsub("^data/generated/gba/", ""))
|
||||
d = love.filesystem.read(alt)
|
||||
d = CacheBlob.readFs(alt)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
local candidates = {
|
||||
@@ -100,7 +101,7 @@ local function read_bytes(rel)
|
||||
for _, p in ipairs(candidates) do
|
||||
local f = io.open(p, "rb")
|
||||
if f then
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(p, f:read("*a"))
|
||||
f:close()
|
||||
if d and #d > 0 then return d end
|
||||
end
|
||||
|
||||
@@ -37,6 +37,7 @@ local WIN_PROMPT = Window.template(2, 15, 26, 4)
|
||||
-- pokefirered/src/learn_move.c:329 sMoveRelearnerYesNoMenuTemplate
|
||||
local WIN_YESNO = Window.template(21, 8, 6, 4)
|
||||
local SE = require("src.core.game3.se_ids")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local function se(id)
|
||||
pcall(function()
|
||||
@@ -57,12 +58,12 @@ local function read_bytes(rel)
|
||||
if ok and type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
if love and love.filesystem and love.filesystem.read then
|
||||
local ok, d = pcall(love.filesystem.read, rel)
|
||||
local ok, d = pcall(CacheBlob.readFs, rel)
|
||||
if ok and type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
local f = io.open(rel, "rb")
|
||||
if f then
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(rel, f:read("*a"))
|
||||
f:close()
|
||||
if d and #d > 0 then return d end
|
||||
end
|
||||
|
||||
@@ -5,6 +5,7 @@ local Extract = require("src.import.gba.extract_island1")
|
||||
local PartyChromeExtract = require("src.import.gba.party_chrome_extract")
|
||||
local FrlgFont = require("src.ui.game3.frlg_font")
|
||||
local RomText = require("src.core.game3.rom_text")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local PartyChrome = {}
|
||||
|
||||
@@ -54,10 +55,10 @@ local function read_bytes(rel)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
if love and love.filesystem and love.filesystem.read then
|
||||
local d = love.filesystem.read(rel)
|
||||
local d = CacheBlob.readFs(rel)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
local alt = "data/generated/gba/" .. (rel:gsub("^data/generated/gba/", ""))
|
||||
d = love.filesystem.read(alt)
|
||||
d = CacheBlob.readFs(alt)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
local candidates = {
|
||||
@@ -67,7 +68,7 @@ local function read_bytes(rel)
|
||||
for _, p in ipairs(candidates) do
|
||||
local f = io.open(p, "rb")
|
||||
if f then
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(p, f:read("*a"))
|
||||
f:close()
|
||||
if d and #d > 0 then return d end
|
||||
end
|
||||
|
||||
@@ -7,6 +7,7 @@ local Pokemon = require("src.core.game3.pokemon")
|
||||
local ItemsData = require("src.core.game3.items_data")
|
||||
local Strings = require("src.core.Strings")
|
||||
local Presentation = require("src.ui.game3.storage_presentation")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local PcChrome = {}
|
||||
|
||||
@@ -62,12 +63,12 @@ local function read_bytes(rel)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
if love and love.filesystem and love.filesystem.read then
|
||||
local ok, d = pcall(love.filesystem.read, rel)
|
||||
local ok, d = pcall(CacheBlob.readFs, rel)
|
||||
if ok and type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
local f = io.open(rel, "rb")
|
||||
if f then
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(rel, f:read("*a"))
|
||||
f:close()
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
local Display = require("src.core.game3.display")
|
||||
local Extract = require("src.import.gba.extract_island1")
|
||||
local PokedexData = require("src.core.game3.pokedex_data")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local PokedexChrome = {}
|
||||
|
||||
@@ -38,10 +39,10 @@ local function read_bytes(rel)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
if love and love.filesystem and love.filesystem.read then
|
||||
local d = love.filesystem.read(rel)
|
||||
local d = CacheBlob.readFs(rel)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
local alt = "data/generated/gba/" .. (rel:gsub("^data/generated/gba/", ""))
|
||||
d = love.filesystem.read(alt)
|
||||
d = CacheBlob.readFs(alt)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
local candidates = {
|
||||
@@ -51,7 +52,7 @@ local function read_bytes(rel)
|
||||
for _, p in ipairs(candidates) do
|
||||
local f = io.open(p, "rb")
|
||||
if f then
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(p, f:read("*a"))
|
||||
f:close()
|
||||
if d and #d > 0 then return d end
|
||||
end
|
||||
|
||||
@@ -7,6 +7,7 @@ local SummaryData = require("src.core.game3.summary_data")
|
||||
local Policy = require("src.ui.game3.rs.summary_policy")
|
||||
local Pal = require("src.core.game3.pal_fade")
|
||||
local Audio = require("src.core.game3.audio")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
local S = {isMenu = true, open = false, PAGE = Policy.PAGE, MODE = Policy.MODE, policy = Policy}
|
||||
local layers, tiles, quads = {}, {}, {}
|
||||
local function rawMon() return S._party and S._party[S._cursor] end
|
||||
@@ -275,7 +276,7 @@ local function frame(entry, index, x, y)
|
||||
if not quads[key] then quads[key] = love.graphics.newQuad(0, index * entry.h, entry.w, entry.h, image:getDimensions()) end
|
||||
love.graphics.setColor(1, 1, 1, 1); love.graphics.draw(image, quads[key], x, y)
|
||||
end
|
||||
local function read(path) return assert(love.filesystem.read(path), path) end
|
||||
local function read(path) return assert(CacheBlob.readFs(path), path) end
|
||||
local function shiny() return not Pokemon.isEgg(mon()) and Pokemon.isShiny(mon()) end
|
||||
local function nativeImage(key, tile, bank, sourceOverride)
|
||||
local palette = S._man.palettes.bg
|
||||
|
||||
@@ -7,6 +7,7 @@ local Sprites = require("src.core.game3.gba_sprites")
|
||||
local Machine = require("src.ui.game3.rse.gba_machine")
|
||||
local Affine = require("src.core.game3.bg_affine")
|
||||
local B = require("src.core.game3.rse.berry_blender")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local UI = {}
|
||||
UI.__index = UI
|
||||
@@ -102,7 +103,7 @@ function UI:readCache(path)
|
||||
if ok and Dataset and Dataset.cache then data = Dataset.cache():read(path) end
|
||||
end
|
||||
if not data and love and love.filesystem and love.filesystem.getInfo and love.filesystem.getInfo(path) then
|
||||
data = love.filesystem.read(path)
|
||||
data = CacheBlob.readFs(path)
|
||||
end
|
||||
return assert(data, "berry_blender: missing " .. tostring(path))
|
||||
end
|
||||
|
||||
@@ -5,6 +5,7 @@ local Palette = require("src.core.game3.gba_palette")
|
||||
local Sprites = require("src.core.game3.gba_sprites")
|
||||
local TileLayer = require("src.ui.game3.rse.tile_layer")
|
||||
local OwSheet = require("src.ui.game3.rse.ow_sheet")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local band = bit.band
|
||||
|
||||
@@ -406,7 +407,7 @@ function CableCar:loadCb()
|
||||
ppu.sprites:freeAllPalettes()
|
||||
ppu.palette:resetFade()
|
||||
self:startWeather()
|
||||
local tiles = assert(love.filesystem.read(self.man.bgTiles), "cable_car: bg tiles missing from cache")
|
||||
local tiles = assert(CacheBlob.readFs(self.man.bgTiles), "cable_car: bg tiles missing from cache")
|
||||
self.bg = {}
|
||||
for i = 0, 3 do self.bg[i] = TileLayer.new(tiles) end
|
||||
-- pokeemerald/src/cable_car.c:95
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
local Kit = require("src.ui.game3.rse.scene_kit")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local Gfx = {}
|
||||
Gfx.__index = Gfx
|
||||
@@ -16,7 +17,7 @@ local function readCache(path)
|
||||
end
|
||||
end
|
||||
if not data and love and love.filesystem and love.filesystem.getInfo(path) then
|
||||
data = love.filesystem.read(path)
|
||||
data = CacheBlob.readFs(path)
|
||||
end
|
||||
return data
|
||||
end
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
local Kit = require("src.ui.game3.rse.scene_kit")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local Gfx = {}
|
||||
|
||||
@@ -11,7 +12,7 @@ local function readCache(path)
|
||||
local okC, CacheFs = pcall(require, "src.import.CacheFs")
|
||||
local data = okC and CacheFs and CacheFs.read and CacheFs.read(path) or nil
|
||||
if not data and love and love.filesystem and love.filesystem.getInfo(path) then
|
||||
data = love.filesystem.read(path)
|
||||
data = CacheBlob.readFs(path)
|
||||
end
|
||||
return data
|
||||
end
|
||||
|
||||
@@ -4,6 +4,7 @@ local RomText = require("src.core.game3.rom_text")
|
||||
local FrlgFont = require("src.ui.game3.frlg_font")
|
||||
local Chrome = require("src.ui.game3.chrome")
|
||||
local Pal = require("src.core.game3.pal_fade")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local Kit = {}
|
||||
|
||||
@@ -60,7 +61,7 @@ function Kit.rgbaImage(path, w, h)
|
||||
local okC, CacheFs = pcall(require, "src.import.CacheFs")
|
||||
if okC and CacheFs and CacheFs.read then data = CacheFs.read(path) end
|
||||
if (not data) and love and love.filesystem and love.filesystem.getInfo(path) then
|
||||
data = love.filesystem.read(path)
|
||||
data = CacheBlob.readFs(path)
|
||||
end
|
||||
if type(data) == "string" and #data == w * h * 4 and love and love.image then
|
||||
local ok, id = pcall(love.image.newImageData, w, h, "rgba8", data)
|
||||
|
||||
@@ -7,6 +7,7 @@ local Seagallop = {}
|
||||
|
||||
local W, H = 240, 160
|
||||
local SE = require("src.core.game3.se_ids") -- pokefirered/include/constants/songs.h:23
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
local CROSSING_FRAMES = 140
|
||||
local MUSIC_FADE_FRAMES = 64
|
||||
|
||||
@@ -54,10 +55,10 @@ local function read_bytes(rel)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
if love and love.filesystem and love.filesystem.read then
|
||||
local d = love.filesystem.read(rel)
|
||||
local d = CacheBlob.readFs(rel)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
local alt = "data/generated/gba/" .. (rel:gsub("^data/generated/gba/", ""))
|
||||
d = love.filesystem.read(alt)
|
||||
d = CacheBlob.readFs(alt)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
local home = os.getenv("HOME") or ""
|
||||
@@ -71,7 +72,7 @@ local function read_bytes(rel)
|
||||
for _, p in ipairs(candidates) do
|
||||
local f = io.open(p, "rb")
|
||||
if f then
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(p, f:read("*a"))
|
||||
f:close()
|
||||
if d and #d > 0 then return d end
|
||||
end
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
local Extract = require("src.import.gba.extract_island1")
|
||||
local ShopChromeExtract = require("src.import.gba.shop_chrome_extract")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local ShopChrome = {}
|
||||
|
||||
@@ -59,10 +60,10 @@ local function read_bytes(rel)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
if love and love.filesystem and love.filesystem.read then
|
||||
local d = love.filesystem.read(rel)
|
||||
local d = CacheBlob.readFs(rel)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
local alt = "data/generated/gba/" .. (rel:gsub("^data/generated/gba/", ""))
|
||||
d = love.filesystem.read(alt)
|
||||
d = CacheBlob.readFs(alt)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
local candidates = {
|
||||
@@ -72,7 +73,7 @@ local function read_bytes(rel)
|
||||
for _, p in ipairs(candidates) do
|
||||
local f = io.open(p, "rb")
|
||||
if f then
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(p, f:read("*a"))
|
||||
f:close()
|
||||
if d and #d > 0 then return d end
|
||||
end
|
||||
|
||||
@@ -6,6 +6,7 @@ local FrlgFont = require("src.ui.game3.frlg_font")
|
||||
local Strings = require("src.core.Strings")
|
||||
local RomText = require("src.core.game3.rom_text")
|
||||
local Model = require("src.core.game3.slot_machine")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local SlotMachineUi = {}
|
||||
|
||||
@@ -119,12 +120,12 @@ local function read_bytes(rel)
|
||||
if okR and type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
if love and love.filesystem and love.filesystem.read then
|
||||
local okR, d = pcall(love.filesystem.read, rel)
|
||||
local okR, d = pcall(CacheBlob.readFs, rel)
|
||||
if okR and type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
local f = io.open(rel, "rb")
|
||||
if f then
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(rel, f:read("*a"))
|
||||
f:close()
|
||||
if d and #d > 0 then return d end
|
||||
end
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
local Display = require("src.core.game3.display")
|
||||
local Extract = require("src.import.gba.extract_island1")
|
||||
local SummaryChromeExtract = require("src.import.gba.summary_chrome_extract")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local SummaryChrome = {}
|
||||
|
||||
@@ -56,10 +57,10 @@ local function read_bytes(rel)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
if love and love.filesystem and love.filesystem.read then
|
||||
local d = love.filesystem.read(rel)
|
||||
local d = CacheBlob.readFs(rel)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
local alt = "data/generated/gba/" .. (rel:gsub("^data/generated/gba/", ""))
|
||||
d = love.filesystem.read(alt)
|
||||
d = CacheBlob.readFs(alt)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
local candidates = {
|
||||
@@ -69,7 +70,7 @@ local function read_bytes(rel)
|
||||
for _, p in ipairs(candidates) do
|
||||
local f = io.open(p, "rb")
|
||||
if f then
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(p, f:read("*a"))
|
||||
f:close()
|
||||
if d and #d > 0 then return d end
|
||||
end
|
||||
|
||||
@@ -6,6 +6,7 @@ local Chrome = require("src.ui.game3.chrome")
|
||||
local FrlgFont = require("src.ui.game3.frlg_font")
|
||||
local TeachyTv = require("src.core.game3.teachy_tv")
|
||||
local SeIds = require("src.core.game3.se_ids")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local Ui = {}
|
||||
|
||||
@@ -129,12 +130,12 @@ local function read_bytes(rel)
|
||||
if ok and type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
if love and love.filesystem and love.filesystem.read then
|
||||
local ok, d = pcall(love.filesystem.read, rel)
|
||||
local ok, d = pcall(CacheBlob.readFs, rel)
|
||||
if ok and type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
local f = io.open(rel, "rb")
|
||||
if f then
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(rel, f:read("*a"))
|
||||
f:close()
|
||||
if d and #d > 0 then return d end
|
||||
end
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
local Extract = require("src.import.gba.extract_island1")
|
||||
local TmCaseExtract = require("src.import.gba.tm_case_extract")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local TmCaseChrome = {}
|
||||
|
||||
@@ -41,10 +42,10 @@ local function read_bytes(rel)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
if love and love.filesystem and love.filesystem.read then
|
||||
local d = love.filesystem.read(rel)
|
||||
local d = CacheBlob.readFs(rel)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
local alt = "data/generated/gba/" .. (rel:gsub("^data/generated/gba/", ""))
|
||||
d = love.filesystem.read(alt)
|
||||
d = CacheBlob.readFs(alt)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
local candidates = {
|
||||
@@ -54,7 +55,7 @@ local function read_bytes(rel)
|
||||
for _, p in ipairs(candidates) do
|
||||
local f = io.open(p, "rb")
|
||||
if f then
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(p, f:read("*a"))
|
||||
f:close()
|
||||
if d and #d > 0 then return d end
|
||||
end
|
||||
|
||||
@@ -6,6 +6,7 @@ local Pokemon = require("src.core.game3.pokemon")
|
||||
local Extract = require("src.import.gba.extract_island1")
|
||||
local Profile = require("src.core.game3.profile")
|
||||
local RsTrade = require("src.ui.game3.rs.trade_policy")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local TradeSceneUi = {}
|
||||
|
||||
@@ -45,16 +46,16 @@ local function read_bytes(rel)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
if love and love.filesystem and love.filesystem.read then
|
||||
local d = love.filesystem.read(rel)
|
||||
local d = CacheBlob.readFs(rel)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
local alt = "data/generated/gba/" .. (rel:gsub("^data/generated/gba/", ""))
|
||||
d = love.filesystem.read(alt)
|
||||
d = CacheBlob.readFs(alt)
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
for _, p in ipairs({ rel, "data/generated/gba/" .. (rel:gsub("^data/generated/gba/", "")) }) do
|
||||
local f = io.open(p, "rb")
|
||||
if f then
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(p, f:read("*a"))
|
||||
f:close()
|
||||
if d and #d > 0 then return d end
|
||||
end
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
local Stack = require("src.ui.game3.stack")
|
||||
local FrlgFont = require("src.ui.game3.frlg_font")
|
||||
local RomText = require("src.core.game3.rom_text")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local TrainerCard = { isMenu = true }
|
||||
|
||||
@@ -47,15 +48,15 @@ local function read_cache_file(path)
|
||||
end
|
||||
end
|
||||
if love and love.filesystem and love.filesystem.read then
|
||||
local d = love.filesystem.read(path)
|
||||
local d = CacheBlob.readFs(path)
|
||||
if d and #d > 0 then return d end
|
||||
local alt = "data/generated/gba/" .. (path:gsub("^data/generated/gba/", ""))
|
||||
d = love.filesystem.read(alt)
|
||||
d = CacheBlob.readFs(alt)
|
||||
if d and #d > 0 then return d end
|
||||
end
|
||||
local f = io.open(path, "rb")
|
||||
if f then
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(path, f:read("*a"))
|
||||
f:close()
|
||||
if d and #d > 0 then return d end
|
||||
end
|
||||
|
||||
@@ -22,6 +22,7 @@ Records.BOARD_WINDOW_ID = 1
|
||||
Records.LINK_ROWS = 5
|
||||
-- pokefirered/include/constants/songs.h:9
|
||||
local SE = require("src.core.game3.se_ids")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
Records.CACHE_BG = "data/generated/gba/trainer_tower/records_bg.rgba"
|
||||
Records.CACHE_MANIFEST = "data/generated/gba/trainer_tower/manifest.lua"
|
||||
@@ -78,12 +79,12 @@ local function read_bytes(rel)
|
||||
if okR and type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
if type(love) == "table" and love.filesystem and love.filesystem.read then
|
||||
local okR, d = pcall(love.filesystem.read, rel)
|
||||
local okR, d = pcall(CacheBlob.readFs, rel)
|
||||
if okR and type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
local f = io.open(rel, "rb")
|
||||
if f then
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(rel, f:read("*a"))
|
||||
f:close()
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
end
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
package.path = "./?.lua;./?/init.lua;" .. package.path
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local T = require("tests.harness")
|
||||
local check, eq = T.check, T.eq
|
||||
@@ -62,7 +63,7 @@ local function readFile(path)
|
||||
if not IDROOT then return nil end
|
||||
local h = io.open(IDROOT .. path, "rb")
|
||||
if not h then return nil end
|
||||
local s = h:read("*a")
|
||||
local s = CacheBlob.decode(IDROOT .. path, h:read("*a"))
|
||||
h:close()
|
||||
return s
|
||||
end
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
package.path = "./?.lua;./?/init.lua;" .. package.path
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local T = require("tests.harness")
|
||||
local check, eq = T.check, T.eq
|
||||
@@ -29,7 +30,7 @@ end
|
||||
local function read(rel)
|
||||
local f = io.open(ROOT .. "/" .. rel, "rb")
|
||||
if not f then return nil end
|
||||
local s = f:read("*a")
|
||||
local s = CacheBlob.decode(ROOT .. "/" .. rel, f:read("*a"))
|
||||
f:close()
|
||||
return s
|
||||
end
|
||||
|
||||
@@ -16,8 +16,8 @@ local function digest(list)
|
||||
return h
|
||||
end
|
||||
|
||||
eq(CacheContract.markerFor("emerald", SHA), "rom-cache-v4-emerald:" .. SHA, "emerald marker")
|
||||
check(CacheContract.markerMatches("emerald", "rom-cache-v4-emerald:" .. SHA), "emerald marker matches")
|
||||
eq(CacheContract.markerFor("emerald", SHA), "rom-cache-v5-emerald:" .. SHA, "emerald marker")
|
||||
check(CacheContract.markerMatches("emerald", "rom-cache-v5-emerald:" .. SHA), "emerald marker matches")
|
||||
check(not CacheContract.markerMatches("emerald", "rom-cache-v17-firered:" .. SHA), "a FireRed marker does not")
|
||||
|
||||
eq(#CacheContract.requiredFiles("firered"), 456, "FireRed required list size")
|
||||
@@ -83,7 +83,7 @@ check(not CacheContract.cacheVersionCurrent("emerald", stale), "an emerald meta
|
||||
|
||||
local complete = {}
|
||||
for _, p in ipairs(em) do complete["emerald/" .. p] = "x" end
|
||||
complete["emerald/" .. CacheContract.MARKER_PATH] = "rom-cache-v4-emerald:" .. SHA
|
||||
complete["emerald/" .. CacheContract.MARKER_PATH] = "rom-cache-v5-emerald:" .. SHA
|
||||
complete["emerald/data/generated/gba/meta.json"] = emMeta
|
||||
check(CacheContract.isReady("emerald", memfs(complete)), "a complete emerald cache is ready")
|
||||
|
||||
|
||||
@@ -59,9 +59,11 @@ check(png:find("tRNS", 1, true) ~= nil, "transparent png has tRNS")
|
||||
check(K.encodeIndexed(1, 1, { 0 }, { [0] = 0 }, false):find("tRNS", 1, true) == nil, "opaque png has no tRNS")
|
||||
eq(select(1, K.pngSize(K.encodeGray(4, 5, K.blank(4, 5)))), 4, "gray png width")
|
||||
|
||||
local stored = K.zlibStored(string.rep("a", 70000))
|
||||
eq(stored:byte(1), 0x78, "zlib header")
|
||||
eq(#stored, 2 + 70000 + 5 * 2 + 4, "two stored blocks plus adler")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
local deflated = CacheBlob.deflate(string.rep("a", 70000), 9)
|
||||
eq(deflated:byte(1), 0x78, "zlib header")
|
||||
check(#deflated < 1000, "png idat is deflated")
|
||||
eq(CacheBlob.inflate(deflated), string.rep("a", 70000), "deflate round trip")
|
||||
|
||||
local mods = {
|
||||
"extract_intro_emerald", "intro_credits_gfx_extract", "extract_title_rse",
|
||||
|
||||
@@ -167,7 +167,7 @@ local GameVersion = require("src.core.GameVersion")
|
||||
for _, profile in ipairs(profiles) do
|
||||
local version = GameVersion.forSha1(profile[2])
|
||||
Versions.select(profile[2])
|
||||
T.eq(Versions.CACHE_VERSION, 129, profile[1] .. " active edition retains shared129 cache stamp")
|
||||
T.eq(Versions.CACHE_VERSION, 130, profile[1] .. " active edition retains shared130 cache stamp")
|
||||
local files, set = {}, {}
|
||||
for _, path in ipairs(Contract.requiredFiles(version)) do
|
||||
files[version .. "/" .. path] = "fixture"
|
||||
@@ -178,10 +178,10 @@ for _, profile in ipairs(profiles) do
|
||||
local profileFs = { prefix = "" }
|
||||
profileFs.exists = function(path) return files[profileFs.prefix .. path] ~= nil end
|
||||
profileFs.read = function(path) return files[profileFs.prefix .. path] end
|
||||
files[meta] = '{"cache_version":128}'
|
||||
T.eq(Contract.isReady(version, profileFs), false, profile[1] .. " old128 stamp requires reimport")
|
||||
files[meta] = '{"cache_version":129}'
|
||||
T.eq(Contract.isReady(version, profileFs), true, profile[1] .. " complete129 cache is ready")
|
||||
T.eq(Contract.isReady(version, profileFs), false, profile[1] .. " old129 stamp requires reimport")
|
||||
files[meta] = '{"cache_version":130}'
|
||||
T.eq(Contract.isReady(version, profileFs), true, profile[1] .. " complete130 cache is ready")
|
||||
local count = 0
|
||||
for key, info in pairs(frlgManifests[profile[1]].terrains) do
|
||||
count = count + 1
|
||||
@@ -202,6 +202,6 @@ for _, profile in ipairs(profiles) do
|
||||
end
|
||||
end
|
||||
Versions.select("firered")
|
||||
T.eq(V.CACHE_VERSION, 14, "Emerald cache version advanced once to14")
|
||||
T.eq(require("src.import.gba.versions_frlg").CACHE_VERSION, 129, "FRLG cache version advanced once to129")
|
||||
T.eq(V.CACHE_VERSION, 15, "Emerald cache version advanced once to15")
|
||||
T.eq(require("src.import.gba.versions_frlg").CACHE_VERSION, 130, "FRLG cache version advanced once to130")
|
||||
T.finish("game3_post_dex_background_2637")
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env luajit
|
||||
package.path = "./?.lua;./?/init.lua;" .. package.path
|
||||
local GameCache = require("tests.game3_cache")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
local root = GameCache.mountOrSkip("game3_ball_sheets_test")
|
||||
require("tests.fixture_data.game3_items").install()
|
||||
|
||||
@@ -17,7 +18,7 @@ end
|
||||
local function slurp(path)
|
||||
local f = io.open(path, "rb")
|
||||
if not f then return nil end
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(path, f:read("*a"))
|
||||
f:close()
|
||||
return d
|
||||
end
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
local M = {}
|
||||
|
||||
local function readable(path)
|
||||
@@ -40,7 +41,7 @@ end
|
||||
local function metaVersions(root)
|
||||
local f = io.open(root .. "/meta.json", "rb")
|
||||
if not f then return nil end
|
||||
local src = f:read("*a") or ""
|
||||
local src = CacheBlob.decode(root .. "/meta.json", f:read("*a")) or ""
|
||||
f:close()
|
||||
return tonumber(src:match('"cache_version"%s*:%s*(%d+)')) or 0,
|
||||
tonumber(src:match('"native_version"%s*:%s*(%d+)')) or 0
|
||||
@@ -104,7 +105,7 @@ function M.cache()
|
||||
read = function(_, rel)
|
||||
local f = io.open(rel, "rb")
|
||||
if not f then return nil end
|
||||
local data = f:read("*a")
|
||||
local data = CacheBlob.decode(rel, f:read("*a"))
|
||||
f:close()
|
||||
if type(data) == "string" and #data > 0 then return data end
|
||||
return nil
|
||||
|
||||
@@ -28,6 +28,7 @@ print("[info] FireRed cache at " .. cacheRoot)
|
||||
local FameChecker = require("src.core.game3.fame_checker")
|
||||
local Ui = require("src.ui.game3.fame_checker")
|
||||
local Stack = require("src.ui.game3.stack")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local PERSON = FameChecker.PERSON
|
||||
local PICK = FameChecker.PICKSTATE
|
||||
@@ -131,7 +132,7 @@ do
|
||||
local f = io.open(path, "rb")
|
||||
check(f ~= nil, "the trainer pic is in the cache today")
|
||||
if f then
|
||||
local bytes = f:read("*a")
|
||||
local bytes = CacheBlob.decode(path, f:read("*a"))
|
||||
f:close()
|
||||
eq(#bytes, 64 * 64 * 4, "it is a 64x64 RGBA sprite")
|
||||
end
|
||||
|
||||
@@ -31,6 +31,7 @@ local Versions = require("src.import.gba.versions")
|
||||
local Slot = require("src.import.gba.slot_machine_extract")
|
||||
local Trade = require("src.import.gba.trade_extract")
|
||||
local LinkArt = require("src.import.gba.link_art_extract")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local SHEETS = {
|
||||
{ "slot_machine/reel_icons.rgba", 32, 224 },
|
||||
@@ -139,7 +140,7 @@ print("[info] FireRed cache at " .. root)
|
||||
local function readFile(rel)
|
||||
local f = io.open(root .. "/" .. rel, "rb")
|
||||
if not f then return nil end
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(root .. "/" .. rel, f:read("*a"))
|
||||
f:close()
|
||||
return d
|
||||
end
|
||||
|
||||
@@ -35,6 +35,7 @@ local TrainerTowerExtract = require("src.import.gba.trainer_tower_extract")
|
||||
local TrainerCardExtract = require("src.import.gba.trainer_card_extract")
|
||||
local RegionMapExtract = require("src.import.gba.region_map_extract")
|
||||
local EggExtract = require("src.import.gba.egg_extract")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
print("[test] 1. the ROM offsets follow pret's declaration order")
|
||||
-- src/script_menu.c:647 aerodactyl tiles, palette, then kabutops tiles, palette
|
||||
@@ -188,7 +189,7 @@ print("[info] FireRed cache at " .. root)
|
||||
local function readFile(rel)
|
||||
local f = io.open(root .. "/" .. rel, "rb")
|
||||
if not f then return nil end
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(root .. "/" .. rel, f:read("*a"))
|
||||
f:close()
|
||||
return d
|
||||
end
|
||||
|
||||
@@ -35,6 +35,7 @@ local MysteryGiftExtract = require("src.import.gba.mystery_gift_extract")
|
||||
local TrainerTowerExtract = require("src.import.gba.trainer_tower_extract")
|
||||
local TutorExtract = require("src.import.gba.tutor_extract")
|
||||
local AltLayouts = require("src.import.gba.alt_layouts")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local SHEETS = {
|
||||
{ "fame_checker/bg.rgba", 240, 160 },
|
||||
@@ -160,7 +161,7 @@ print("[info] FireRed cache at " .. root)
|
||||
local function readFile(rel)
|
||||
local f = io.open(root .. "/" .. rel, "rb")
|
||||
if not f then return nil end
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(root .. "/" .. rel, f:read("*a"))
|
||||
f:close()
|
||||
return d
|
||||
end
|
||||
|
||||
@@ -27,6 +27,7 @@ local Seagallop = require("src.import.gba.seagallop_extract")
|
||||
local BattleChrome = require("src.import.gba.battle_chrome_extract")
|
||||
local CacheContract = require("src.import.CacheContract")
|
||||
local Versions = require("src.import.gba.versions")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local function fakeRom(str)
|
||||
return {
|
||||
@@ -256,7 +257,7 @@ print("[info] FireRed cache at " .. root)
|
||||
local function readFile(rel)
|
||||
local f = io.open(root .. "/" .. rel, "rb")
|
||||
if not f then return nil end
|
||||
local data = f:read("*a")
|
||||
local data = CacheBlob.decode(root .. "/" .. rel, f:read("*a"))
|
||||
f:close()
|
||||
return data
|
||||
end
|
||||
|
||||
@@ -14,6 +14,7 @@ end
|
||||
|
||||
local BattleChromeExtract = require("src.import.gba.battle_chrome_extract")
|
||||
local Versions = require("src.import.gba.versions")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
-- include/constants/battle.h:287
|
||||
local PRET_KEYS = {
|
||||
@@ -108,7 +109,7 @@ print("[info] FireRed cache at " .. root)
|
||||
local function readFile(rel)
|
||||
local f = io.open(root .. "/pokemon/battle/" .. rel, "rb")
|
||||
if not f then return nil end
|
||||
local data = f:read("*a")
|
||||
local data = CacheBlob.decode(root .. "/pokemon/battle/" .. rel, f:read("*a"))
|
||||
f:close()
|
||||
return data
|
||||
end
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
-- src/data/party_menu.h:111
|
||||
|
||||
package.path = "./?.lua;./?/init.lua;" .. package.path
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local failed = 0
|
||||
local function check(cond, msg)
|
||||
@@ -25,7 +26,7 @@ end
|
||||
local function slurp(path)
|
||||
local f = io.open(path, "rb")
|
||||
if not f then return nil end
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(path, f:read("*a"))
|
||||
f:close()
|
||||
return d
|
||||
end
|
||||
|
||||
@@ -24,6 +24,7 @@ end
|
||||
local Extract = require("src.import.gba.pokedex_chrome_extract")
|
||||
local Versions = require("src.import.gba.versions")
|
||||
local CacheContract = require("src.import.CacheContract")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local PAPER_BYTES = 240 * 160 * 4
|
||||
local FOOT_BYTES = 16 * 16 * 4
|
||||
@@ -179,7 +180,7 @@ print("[info] FireRed cache at " .. root)
|
||||
local function readFile(rel)
|
||||
local f = io.open(root .. "/pokemon/pokedex/" .. rel, "rb")
|
||||
if not f then return nil end
|
||||
local data = f:read("*a")
|
||||
local data = CacheBlob.decode(root .. "/pokemon/pokedex/" .. rel, f:read("*a"))
|
||||
f:close()
|
||||
return data
|
||||
end
|
||||
|
||||
@@ -33,6 +33,7 @@ print("[info] FireRed cache at " .. cacheRoot)
|
||||
local ExtractScripts = require("src.import.gba.extract_scripts")
|
||||
local Objects = require("src.core.game3.objects")
|
||||
local Field = require("src.core.game3.field")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
Space.bundle = ExtractScripts.loadBundle(Cache.cache(), cacheRoot, { allowIncomplete = true })
|
||||
check(Space.bundle ~= nil, "script bundle loads")
|
||||
@@ -163,7 +164,7 @@ if gym then
|
||||
local f = io.open(cacheRoot .. "/native/" .. pairName .. "/mids.idx", "rb")
|
||||
local packed = {}
|
||||
if f then
|
||||
local idx = NativePack.decodeIdx(f:read("*a"))
|
||||
local idx = NativePack.decodeIdx(CacheBlob.decode(cacheRoot .. "/native/" .. pairName .. "/mids.idx", f:read("*a")))
|
||||
f:close()
|
||||
for _, mid in ipairs(idx and idx.midIds or {}) do packed[mid] = true end
|
||||
end
|
||||
@@ -192,7 +193,7 @@ if gym then
|
||||
local f = io.open(cacheRoot .. "/native/" .. pairName .. "/mids.idx", "rb")
|
||||
local packed = {}
|
||||
if f then
|
||||
local idx = NativePack.decodeIdx(f:read("*a"))
|
||||
local idx = NativePack.decodeIdx(CacheBlob.decode(cacheRoot .. "/native/" .. pairName .. "/mids.idx", f:read("*a")))
|
||||
f:close()
|
||||
for _, mid in ipairs(idx and idx.midIds or {}) do packed[mid] = true end
|
||||
end
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
-- src/data/party_menu.h:664, src/party_menu.c:2743, :2785
|
||||
|
||||
package.path = "./?.lua;./?/init.lua;" .. package.path
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local failed = 0
|
||||
local function check(cond, msg)
|
||||
@@ -29,7 +30,7 @@ end
|
||||
local function slurp(path)
|
||||
local f = io.open(path, "rb")
|
||||
if not f then return nil end
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(path, f:read("*a"))
|
||||
f:close()
|
||||
return d
|
||||
end
|
||||
|
||||
@@ -30,6 +30,7 @@ local Versions = require("src.import.gba.versions")
|
||||
local Extract = require("src.import.gba.pokedex_chrome_extract")
|
||||
local PokedexChrome = require("src.ui.game3.pokedex_chrome")
|
||||
local Pokedex = require("src.ui.game3.pokedex")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
print("[test] 1. versions.lua carries the area-page / size-page ROM offsets")
|
||||
check(Versions.CACHE_VERSION >= 103, "CACHE_VERSION at or past the dex chrome import ("
|
||||
@@ -233,7 +234,7 @@ else
|
||||
local function slurp(rel)
|
||||
local f = io.open(dexRoot .. "/" .. rel, "rb")
|
||||
if not f then return nil end
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(dexRoot .. "/" .. rel, f:read("*a"))
|
||||
f:close()
|
||||
return d
|
||||
end
|
||||
|
||||
@@ -50,6 +50,7 @@ check(MultichoiceExtract.ready({
|
||||
|
||||
print("[test] 2. baked assets in an imported cache")
|
||||
local Cache = require("tests.game3_cache")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
local root = Cache.root("region_map/extract_status.json")
|
||||
if not root then
|
||||
print("[skip] region map assets: " .. tostring(Cache.reason))
|
||||
@@ -65,7 +66,7 @@ print("[info] FireRed cache at " .. root)
|
||||
local function readFile(rel)
|
||||
local f = io.open(root .. "/" .. rel, "rb")
|
||||
if not f then return nil end
|
||||
local data = f:read("*a")
|
||||
local data = CacheBlob.decode(root .. "/" .. rel, f:read("*a"))
|
||||
f:close()
|
||||
return data
|
||||
end
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
-- * bag: listPocket rows are reused until the pocket changes.
|
||||
|
||||
package.path = package.path .. ";./?.lua"
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local passed, failed = 0, 0
|
||||
local function test(name, fn)
|
||||
@@ -89,7 +90,7 @@ love = {
|
||||
filesystem = {
|
||||
read = function(path)
|
||||
counts.fsRead = counts.fsRead + 1
|
||||
if path:find("trainers/front/", 1, true) then return string.rep("\0", 64 * 64 * 4) end
|
||||
if path:find("trainers/front/", 1, true) then return CacheBlob.deflate(string.rep("\0", 64 * 64 * 4)) end
|
||||
return nil
|
||||
end,
|
||||
},
|
||||
|
||||
@@ -28,6 +28,7 @@ end
|
||||
local Versions = require("src.import.gba.versions")
|
||||
local MapCatalog = require("src.import.gba.map_catalog")
|
||||
local NativePack = require("src.import.gba.native_pack")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
MapCatalog.rebuildIndex()
|
||||
|
||||
-- pokefirered/include/constants/layouts.h:253,267,268,308
|
||||
@@ -169,7 +170,7 @@ else
|
||||
local function readFile(rel)
|
||||
local f = io.open(root .. "/" .. rel, "rb")
|
||||
if not f then return nil end
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(root .. "/" .. rel, f:read("*a"))
|
||||
f:close()
|
||||
return d
|
||||
end
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
-- pokefirered/src/region_map.c:425
|
||||
|
||||
package.path = "./?.lua;./?/init.lua;" .. package.path
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local failed = 0
|
||||
local function check(cond, msg)
|
||||
@@ -21,7 +22,7 @@ end
|
||||
local function slurp(path)
|
||||
local f = io.open(path, "rb")
|
||||
if not f then return nil end
|
||||
local s = f:read("*a")
|
||||
local s = CacheBlob.decode(path, f:read("*a"))
|
||||
f:close()
|
||||
return s
|
||||
end
|
||||
|
||||
@@ -39,11 +39,12 @@ Pokemon.install(nil)
|
||||
|
||||
local DIR = root .. "/pokemon/pokedex/footprints"
|
||||
local NUM_SPECIES = require("src.import.gba.versions").NUM_SPECIES or 412
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local function file_bytes(rel)
|
||||
local f = io.open(DIR .. "/" .. rel, "rb")
|
||||
if not f then return nil end
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(DIR .. "/" .. rel, f:read("*a"))
|
||||
f:close()
|
||||
if type(d) == "string" and #d > 0 then return d end
|
||||
return nil
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package.path = "./?.lua;./?/init.lua;" .. package.path
|
||||
|
||||
local T = require("tests.harness")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
local check, eq = T.check, T.eq
|
||||
|
||||
local PRET = "../pokefirered"
|
||||
@@ -13,7 +14,7 @@ local ROM_SHA1 = "41cb23d8dccc8ebd7c649cd8fbb58eeace6e2fdc"
|
||||
local function slurp(p)
|
||||
local f = io.open(p, "rb")
|
||||
if not f then return nil end
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(p, f:read("*a"))
|
||||
f:close()
|
||||
return d
|
||||
end
|
||||
|
||||
@@ -28,6 +28,7 @@ end
|
||||
|
||||
local Versions = require("src.import.gba.versions")
|
||||
local Trade = require("src.import.gba.trade_extract")
|
||||
local CacheBlob = require("src.import.CacheBlob")
|
||||
|
||||
local MENU_SHEETS = {
|
||||
{ "menu_bg1", 240, 160 },
|
||||
@@ -136,7 +137,7 @@ print("[test] 3. the offsets hit pret's graphics/trade bins in a matching build"
|
||||
local function slurp(path)
|
||||
local f = io.open(path, "rb")
|
||||
if not f then return nil end
|
||||
local d = f:read("*a")
|
||||
local d = CacheBlob.decode(path, f:read("*a"))
|
||||
f:close()
|
||||
return d
|
||||
end
|
||||
|
||||
@@ -92,7 +92,9 @@ end
|
||||
|
||||
local fs = { prefix = "" }
|
||||
function fs.exists(rel) return isFile(saveDir .. "/" .. fs.prefix .. rel) end
|
||||
function fs.read(rel) return readFile(saveDir .. "/" .. fs.prefix .. rel) end
|
||||
function fs.read(rel)
|
||||
return require("src.import.CacheBlob").decode(rel, readFile(saveDir .. "/" .. fs.prefix .. rel))
|
||||
end
|
||||
|
||||
if not identityOnly and sourceTreeHasData() then
|
||||
print("READY source tree")
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import zlib
|
||||
|
||||
from PIL import Image, ImageOps
|
||||
|
||||
@@ -29,7 +30,7 @@ def invert(source: Path, destination: Path) -> None:
|
||||
|
||||
|
||||
def invert_rgba(source: Path, destination: Path) -> None:
|
||||
raw = source.read_bytes()
|
||||
raw = zlib.decompress(source.read_bytes())
|
||||
size = GBA_PIC * GBA_PIC * 4
|
||||
if len(raw) < size:
|
||||
raise SystemExit(f"{source}: expected {size} bytes of 64x64 RGBA, got {len(raw)}")
|
||||
|
||||
Reference in New Issue
Block a user