Skip to content

Commit

Permalink
lua plugin support raw memory operation, and decodeall
Browse files Browse the repository at this point in the history
  • Loading branch information
devseed committed Dec 9, 2024
1 parent acf0ed1 commit 0ae5782
Show file tree
Hide file tree
Showing 6 changed files with 447 additions and 7 deletions.
4 changes: 3 additions & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

Also, it supports for droping file, save decoded image and show cursor moving in tiles. Futhermore, the window is flexible for changing size and support for zooming in and out with converting the client coordinate to logical coordinate.

The main purpose is for analyzing game font or textures. See [TileDB](https://github.com/YuriSizuku/TileViewer/wiki/Font-Database) and [TexDB](https://github.com/YuriSizuku/TileViewer/wiki/Texture-Database) in detail.
The main purpose is for analyzing game font or textures. See [FontDB](https://github.com/YuriSizuku/TileViewer/wiki/Font-Database) and [TexDB](https://github.com/YuriSizuku/TileViewer/wiki/Texture-Database) in detail.

![tile_test1](asset/picture/tile_test1.png)
(example of decoding a 2bpp tile font)
Expand Down Expand Up @@ -405,6 +405,8 @@ chmod +x script/*.sh
* [x] 16bpp(rgb565), 24bpp(rgb888), 32bpp(rgba8888)
* [x] plugincfg, endian, channel_first, bgr, flip ([v0.3.4.3](https://github.com/YuriSizuku/TileViewer/releases/tag/v0.3.3.7))
* [x] plugin lua decoder ([v0.2](https://github.com/YuriSizuku/TileViewer/releases/tag/v0.2))
* [x] set/get raw data, set/get tilecfg, tilenav
* [x] raw memory operations, memnew, memdel, memread, memwrite ([v0.3.5](https://github.com/YuriSizuku/TileViewer/releases/tag/v0.3.5))
* [x] plugin C decoder (dll, so) ([v0.3](https://github.com/YuriSizuku/TileViewer/releases/tag/v0.3))

* UI
Expand Down
185 changes: 185 additions & 0 deletions asset/plugin/9nine_fnt_switch.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
---@diagnostic disable : lowercase-global, missing-fields, undefined-global, duplicate-doc-field, undefined-field

io = require("io")

version = "v0.1"
description = "[lua_9nine_fnt::init] lua plugin to decode 9nine fnt lz77 format"

-- global declear
g_datap = nil --- @type lightuserdata
g_tilecfg = {} ---@type tilecfg_t
g_ntile = 0 ---@type integer
g_tilesp = nil ---@type lightuserdata

---@class fnt_t
---@field magic string
---@field version integer
---@field fsize integer
---@field distop integer -- distance between baseline and top/bottom
---@field disbottom integer

---@class fntglphy_t
---@field bearingx integer
---@field bearingy integer
---@field actualw integer
---@field actualh integer
---@field advancew integer
---@field reserve1 integer
---@field texturew integer
---@field textureh integer
---@field zsize integer
---@field ref_glphyaddr integer

g_fnt = {}
g_fntglphys = {} -- start from 1
g_glphylist = {} -- list for render tiles, remove duplicate

---@param indata lightuserdata
---@param outdata lightuserdata
---@param inoffset? integer
---@param outoffset? integer
---@param offsetbits? integer
---@return integer
function lz77_decode(indata, outdata, insize, inoffset, outoffset, offsetbits)
--[[
MSB XXXXXXXX YYYYYYYY LSB
val len backOffset
size (16-OFFSET_BITS) OFFSET_BITS
index8, 8 * [val16 | val8]
--]]

if insize == nil then insize = memsize(indata) - inoffset end
if inoffset == nil then inoffset = 0 end
if outoffset == nil then outoffset = 0 end
if offsetbits == nil then offsetbits = 10 end

local incur, outcur = inoffset, outoffset
local outsize = memsize(outdata) - outoffset
while incur - inoffset < insize do
local index8 = memreadi(indata, 1, incur)
incur = incur + 1
for j = 0, 8 - 1 do
local flag = (index8 >> j) & 1
if flag == 0 then -- direct byte output
if(incur - inoffset >= insize) then break end -- sometimes no other bytes in the end
local d = memreadi(indata, 1, incur)
memwrite(outdata, d, 1, outcur)
incur = incur + 1
outcur = outcur + 1
else -- seek from output
local backseekval = memreadi(indata, 2, incur)
backseekval = ((backseekval & 0xff) << 8) + ((backseekval >> 8) & 0xff) -- big endian
local backoffsetmask = (1<<offsetbits) - 1
local backlength = (backseekval >> offsetbits) + 3 -- length must larger than 3
local backoffset = (backseekval & backoffsetmask) + 1
for _ = 1, backlength do -- push char to output one by one
memwrite(outdata, outdata, 1, outcur, outcur - backoffset)
outcur = outcur + 1
end
incur = incur + 2
end
end
end
return outcur - outoffset
end

---@param p lightuserdata
---@return fnt_t, table<fntglphy_t>
function parse_fnt(p)
FNT_FMT, FNTGLPHY_FMT = "<c4I4I4HH", "<bbBBBBBBH"
FNT_FMT_SIZE = string.packsize(FNT_FMT)
FNTGLPHY_FMT_SIZE = string.packsize(FNTGLPHY_FMT)
local data = memreads(p, FNT_FMT_SIZE + 0x10000 * 4)
local magic, version, fsize, distop, disbottom = string.unpack(FNT_FMT, data)
local fnt = {magic=magic, version=version, fsize=fsize, distop=distop, disbottom=disbottom}
local fntglphys = {}
for i = 1, 0x10000 do
local offset = string.unpack("<I4", data, FNT_FMT_SIZE + (i - 1) * 4 + 1)
local data2 = memreads(p, FNTGLPHY_FMT_SIZE, offset)
-- print(string.format("%d %x %x", i, offset, data2:len()))
local bearingx, bearingy, actualw, actualh, advancew, reserve1,
texturew, textureh, zsize = string.unpack(FNTGLPHY_FMT, data2)
fntglphys[i] = {bearingx=bearingx, bearingy=bearingy, actualw=actualw,
actualh=actualh, advancew=advancew, reserve1=reserve1, texturew=texturew,
textureh=textureh, reserve2=reserve2, zsize=zsize, ref_glphyaddr=offset + FNTGLPHY_FMT_SIZE}
-- print(string.format("%d %d %d %x", i, texturew, textureh, zsize))
end
return fnt, fntglphys
end

function decode_pre()
-- get neccessory data for decoding
g_datap = get_rawdatap()

-- get tile information from font_00.fnt
g_fnt, g_fntglphys = parse_fnt(g_datap)
if(g_fnt.magic ~= "FNT4") then return false end
local count = 0
local tmpmap = {}
for i, t in pairs(g_fntglphys) do -- paris index start from 1
if tmpmap[t.ref_glphyaddr] == nil then
tmpmap[t.ref_glphyaddr] = i
count = count + 1
table.insert(g_glphylist, i)
end
end

g_ntile = count

-- set the information for decoding
g_tilecfg = {w=80, h=80, bpp=8, nbytes=1, nrow=64, size=g_ntile}
set_tilecfg(g_tilecfg)

log(string.format("[lua_9nine_fnt::pre] datasize=%d, w=%d h=%d bpp=%d nbytes=%d ntiles=%d",
memsize(g_datap), g_tilecfg.w, g_tilecfg.h, g_tilecfg.bpp, g_tilecfg.nbytes, g_ntile))

return true
end

function decode_pixels()
local tilesize = g_tilecfg.w * g_tilecfg.h * 4
g_tilesp = memnew(g_ntile * tilesize)
local i = 0
local outdatap = memnew(128 * 128 * 4)
for _, glphyi in ipairs(g_glphylist) do -- iparis index start from 1
local insize = g_fntglphys[glphyi].zsize
local inoffset = g_fntglphys[glphyi].ref_glphyaddr
local outoffset = i * tilesize
local outsize = lz77_decode(g_datap, outdatap, insize, inoffset)
print(string.format("i=%d glphyi=%d inoffset=%x insize=%x outsize=%x %dx%d",
i, glphyi, inoffset, insize, outsize,
g_fntglphys[glphyi].textureh, g_fntglphys[glphyi].texturew))

-- blit pixels
for y = 0, g_fntglphys[glphyi].textureh -1 do
for x = 0, g_fntglphys[glphyi].texturew - 1 do
if x >= g_tilecfg.w then goto continue end
if y >= g_tilecfg.h then goto continue end
local offset1 = 4 * (y * g_tilecfg.w + x)
local offset2 = y * g_fntglphys[glphyi].texturew + x
local d = memreadi(outdatap, 1, offset2)
local pixel = d + (d << 8) + (d << 16) + (255 << 24)
memwrite(g_tilesp, pixel, 4, outoffset + offset1)
::continue::
end
end

i = i + 1
-- if i > 10 then break end
end
memdel(outdatap)
return g_tilesp, g_ntile * g_tilecfg.w * g_tilecfg.h, 0
end

function decode_post()
log("[lua_9nine_fnt::post] decode finished")
set_tilenav({index=0, offset=-1})
set_tilestyle({scale=1.0})
if g_tilesp ~= nil then
memdel(g_tilesp)
end
return true
end

log(" ", description, version)
45 changes: 44 additions & 1 deletion asset/plugin/lualib/util_declear.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,41 @@
-- use log(...) to redirect to log window
function log(...) end

-- memory manipulate with c

---@param size integer
---@return lightuserdata ...
function memnew(size) end --c api

---@param p lightuserdata
---@return boolean ...
function memdel(p) end --c api

---@param p lightuserdata
---@return integer ...
function memsize(p) end --c api

---@param p lightuserdata
---@param size? integer
---@param offset? integer
---@return integer ...
function memreadi(p, size, offset) end --c api

---@param p lightuserdata
---@param size? integer
---@param offset? integer
---@return string ...
function memreads(p, size, offset) end --c api

---@param p lightuserdata
---@param data integer|string|lightuserdata
---@param size? integer
---@param offset1 ? integer p offset
---@param offset2 ? integer data offset
---@return integer ...
function memwrite(p, data, size, offset1, offset2) end --c api

-- set or get tile informations
---@return tilecfg_t ...
function get_tilecfg() end -- c api

Expand All @@ -50,9 +85,12 @@ function get_rawsize() end -- c api
---@param offset? integer
---@param size? integer
---@return string ...
---@option
function get_rawdata(offset, size) end --c api

-- get the lightuserdata pointer for userptr
---@return lightuserdata ...
function get_rawdatap() end --c api

---@return boolean ...
function decode_pre() end -- c callback

Expand All @@ -62,6 +100,11 @@ function decode_pre() end -- c callback
---@return integer ... pixel value packed in rgba
function decode_pixel(i, x, y) end -- c callback

---@return lightuserdata | string ... pixels memory
---@return integer ... npixels
---@return integer ... offset
function decode_pixels() end -- c callback

---@return boolean ...
function decode_post() end -- c callback

Expand Down
1 change: 0 additions & 1 deletion asset/plugin/narcissus_lbg_psp.lua
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ function decode_pre()
if(g_tilecfg.size > 0) then g_datasize = math.min(g_datasize, g_tilecfg.size) end
g_data = get_rawdata(0x20, 0);


--- prepare decoding data
w, h = 512, 272
for i=0, w*h do
Expand Down
5 changes: 4 additions & 1 deletion src/plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,14 @@ extern "C" {
#define OPTIONAL
#define REQUIRED
#undef STDCALL
#define STDCALL
#if 0
#if defined(_MSC_VER) || defined(__TINYC__)
#define STDCALL __stdcall
#else
#else // warning: ‘stdcall’ attribute ignored [-Wattributes]
#define STDCALL __attribute__((stdcall))
#endif
#endif

struct pixel_t
{
Expand Down
Loading

0 comments on commit 0ae5782

Please sign in to comment.