This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| mozaic [2025/03/15 19:13] – created Yuki | mozaic [2025/03/20 01:28] (current) – Yuki | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| ====== Mozaïc ====== | ====== Mozaïc ====== | ||
| - | [[https:// | + | Some game distributed with lottery tickets from Loto-Québec |
| + | |||
| + | Download: [[https:// | ||
| + | |||
| + | See also: [[https:// | ||
| + | |||
| + | ===== Install on Wine ===== | ||
| + | |||
| + | This game makes heavy use of Indeo 5 and other DirectShow codecs so make sure to install it. Use a 32-bit prefix, and ideally pretend you're Windows XP and enable windowed mode. | ||
| + | |||
| + | <code bash> | ||
| + | # mount the ISO | ||
| + | # the game won't run without it | ||
| + | sudo mount MOZAIC.iso / | ||
| + | |||
| + | # create a new 32-bit prefix | ||
| + | # it currently won't work in a 64-bit prefix due to the codecs | ||
| + | # also make sure the CD-ROM is detected as such | ||
| + | export WINEARCH=win32 | ||
| + | export WINEPREFIX=~/ | ||
| + | winecfg | ||
| + | |||
| + | # install the codecs | ||
| + | winetricks -q allcodecs | ||
| + | |||
| + | # install and run the game (also make sure $WINEPREFIX is set) | ||
| + | wine / | ||
| + | </ | ||
| + | |||
| + | The installation may fail because you have an '' | ||
| ===== PAK file format ===== | ===== PAK file format ===== | ||
| Line 10: | Line 39: | ||
| |magic|string|0|4 bytes|" | |magic|string|0|4 bytes|" | ||
| |size|u32|4|4 bytes|Number of entries| | |size|u32|4|4 bytes|Number of entries| | ||
| - | |???| |8|32 bytes|Unknown| | + | |???| |8|32 bytes|Seems unused, can be used as a comment field| |
| |filelist|File|40|size * (12 + name)| | | |filelist|File|40|size * (12 + name)| | | ||
| Line 17: | Line 46: | ||
| ^Nom^Type^Offset^Size^Notes^ | ^Nom^Type^Offset^Size^Notes^ | ||
| |filesize|u32|0|4 bytes| | | |filesize|u32|0|4 bytes| | | ||
| - | |offset|u32|4|4 bytes|Offset within | + | |offset|u32|4|4 bytes|Byte offset from the beginning of the file| |
| - | |??? | + | |??? |
| - | |name|string|12| |Null-terminated string| | + | |name|Null-terminated |
| ==== ImHex pattern ==== | ==== ImHex pattern ==== | ||
| Line 25: | Line 54: | ||
| <code c> | <code c> | ||
| import std.string; | import std.string; | ||
| - | |||
| - | char magic[4] @ 0; | ||
| - | u32 size @ 4; | ||
| struct File { | struct File { | ||
| u32 filesize; | u32 filesize; | ||
| u32 offset; | u32 offset; | ||
| - | u32 type; | + | u32 unknown; |
| std:: | std:: | ||
| char data[filesize] @ offset; | char data[filesize] @ offset; | ||
| }; | }; | ||
| - | File filelist[size] @ 0x28; | + | char magic[4] @ 0; |
| + | u32 size @ 4; | ||
| + | char unknown[32] @ 8; | ||
| + | File filelist[size] @ 40; | ||
| </ | </ | ||
| + | |||
| + | ===== Tools ===== | ||
| + | |||
| + | < | ||
| + | <code javascript extractpak.js> | ||
| + | const fs = require(' | ||
| + | const path = require(' | ||
| + | |||
| + | if(process.argv.length < 3) | ||
| + | { | ||
| + | console.log(" | ||
| + | process.exit(1); | ||
| + | } | ||
| + | |||
| + | var f = fs.readFileSync(process.argv[2]); | ||
| + | |||
| + | var magic = f.toString(' | ||
| + | if(magic != " | ||
| + | { | ||
| + | console.log(" | ||
| + | process.exit(1); | ||
| + | } | ||
| + | |||
| + | var size = f.readUInt32LE(4); | ||
| + | var offset = 40; | ||
| + | |||
| + | for(var i = 0; i < size; i++) | ||
| + | { | ||
| + | var filesize = f.readUint32LE(offset); | ||
| + | var fileoffset = f.readUint32LE(offset); | ||
| + | var mystery = f.readUint32LE(offset); | ||
| + | var next = f.indexOf(0, | ||
| + | var name = f.toString(' | ||
| + | offset = next+1; | ||
| + | console.log(" | ||
| + | |||
| + | fs.mkdirSync(path.dirname(name), | ||
| + | var data = fs.createWriteStream(name, | ||
| + | data.end(f.slice(fileoffset, | ||
| + | } | ||
| + | </ | ||
| + | < | ||
| + | |||
| + | [[https:// | ||