|
General Altitude Discussion Discuss anything Altitude related that doesn't belong in another forum. |
|
Thread Tools | Display Modes |
#1
|
|||
|
|||
Altitude p# image files
After I began being annoyed by the zebra skin I wondered if it is possible to get rid of it while still being able to see my glorious checkered skins. So I took a look at the Altitudes image folders, and removed p4 files that corresponded to the zebra skin which made the client default to the standard no skin planes for the zebra users. However I was left wondering if its possible to view or even edit the p# files, and it turns out that I can.
So I'll be leaving this post here in case anyone else feels like browsing through the Altitudes image files. A lot of the p# files contain a header which I assume contains the mappings to each sprite within the file. If you find the index of the last mapping ( last ".png" representing byte sequence), and skip 32 bytes ahead, the next 8 bytes contain the image dimensions(4 for the height, and then 4 for the width). The rest of the file after that is just raw pixel data. 4 byte sequences of RGB + Alpha. Parse it and you can retrieve the images: I also managed to modify the images within these files and altitude seems to be rendering them just fine. |
#2
|
|||
|
|||
This is really cool. I'll try it out later today after APL. Been playing with skins off because camo is pretty OP, but I miss my santa hat
|
#3
|
|||
|
|||
I wrote a small tool to read and write these files a couple of months ago (not quite 'usable' enough that I'd release it, re-writing it for release has been on my to-do list for a while now.)
Here's my documentation of the format: Code:
Each `pack` file is a texture atlas containing a texture (sometimes multiple textures, but only for large images), and one or more sprites. The file starts with a list of sprites. First is a little endian (later referred to as 'LE') 32bit integer giving the number of sprites the pack contains. For each sprite, the following is then read: - It's file name + a UTF-8 string which starts with a 16bit LE integer giving the length of the string in bytes. - X-offset (The horizontal offset in pixels from the left of the image) + a 32bit LE integer. - Y-offset (The vertical offset in pixels from the bottom of the image) + a 32bit LE integer. - Width in pixels + a 32bit LE integer - Height in pixels + a 32bit LE integer After the list of sprites is the metadata for the textures: - A 32bit big endian (BE) integer: - If the value is less than 10000, the image is uncompressed, and this value gives the pixel format: - 0 => ALPHA8 - 1 => RGB5 - 2 => RGBA4 - 3 => RGBA8 - 4 => DXT1 - 5 => DXT1A - 6 => DXT3 - 7 => DXT5 - If the value is 10000 or higher, it gives the compression type, and _another_ 32bit integer is read for the pixel format. - 10000 => Uncompressed - 10001 => DXT - 10002 => JPEG - Altitude extends the JPEG format to add transparency, by way of an optional LZMA compressed bit-mask. - 10003 => LZMA - Another 32bit BE integer giving the repeat type: - 0 => Clamped - 1 => Repeat (a draw area larger than the texture will repeat the texture) - Another 32bit BE integer giving the filter type: - 0 => Nearest neighbour - 1 => Linear Finally, the textures: - A 32 bit BE integer giving the number of textures. - For each texture: - It's width (32bit BE) - It's height (32bit BE) - The RAW pixel data, with the compression and pixel format given above. The default maximum texture size is 256x256. For large images there can be multiple textures which are tiled together to make the full image. As far as I can tell, these packs only ever contain a single sprite (presumably whatever bin-packing algorithm they use starts with the largest, and ends when a single texture is full). Last edited by LewisH; 09-14-2016 at 05:40 PM. |
#4
|
|||
|
|||
so you're saying we can edit these to make whatever kind of skin we want?
|
#5
|
|||
|
|||
I thought you were only concernign yourself with server side exploration. What other stuff have you been looking into?
Also have you played around with messing with the texture sizes? Does altitude still recognises the file, and does it scale the textures down after reading them? Or for eample with planes, does it produce some odly shaped textures with regular hitboxes? edit: @Oyster, depends on what you mean by 'whatever kind of skin.' I edited the files without changing any of the dimensions of the textures and the altitude recognised them just fine. Not sure if alti would be happy with non-standard dimensions even assuming you properly define them using the format LewisH outlines for us here. Also.. will anyone really be bothered enough to edit 36 odd images? :/ Last edited by Moon; 09-12-2016 at 01:45 PM. |
#6
|
|||
|
|||
I am mostly concerned with server stuff -- In this case, Stam asked if it was possible to edit the files, so I spent a week or so looking into it. I'll clean up the code whenever solemnsky gets a proper map graphics format, for adding images in my altitude to solemnsky map converter ^^
As for what I've looked into: File formats (maps and resources), the packet/message format (including vapor), and the protocol (also including vapor). Along the way I've deobfuscated enough of the main game code to make small server modifications. I prefer to pretend client modification isn't possible, for reasons. My current work is on writing my own implementation of all of this, with the eventual goal of custom server software (altserv). I may also write a vapor master server, for whenever nimbly shut down their altitude servers, be it in 10 months or 10 years. I haven't played with the skins at all, so I'm not sure what's possible with that. > Also.. will anyone really be bothered enough to edit 36 odd images? :/ I wouldn't be particularly surprised :3 Last edited by LewisH; 09-12-2016 at 02:43 PM. |
#7
|
|||
|
|||
I'd gladly edit 36 images if it meant having a new skin
|
#8
|
|||
|
|||
Mind telling what the read/write tool will be able to do?
I'm asking since the mapping for each sprite seem to cut up the texture in rather awkward ways.. I think not even properly mapping to some in worst cases. Since the skin sprites are plastered over the image in different positions compared to the plane ones, thought that i could automatically rearrange them nicely to sit over them, but alas I could not... Last edited by Moon; 09-13-2016 at 10:00 PM. |
#9
|
|||
|
|||
Extract pack files to a directory, with one image per sprite (so an image for each animation frame of each skin, for example), and re-create pack files from a directory of sprites. I'll probably have some recursive mechanism to extract/pack all the game's resources in bulk.
At the start it will only support encoding to uncompressed RGBA8 (and perhaps lzma compressed), and extracting to PNGs. I'm pretty sure this covers all of the in-game sprites, but not the title screen, and not most map graphics. edit: I probably won't keep the existing sprite metadata around, and instead use the given file names, image sizes, and a simple bin-packing algorithm to re-create it in a way the client can still read. Last edited by LewisH; 09-13-2016 at 10:49 PM. |
#10
|
|||
|
|||
The relative positions of skins and planes are defined in `.poly`, e.g:
Code:
altitude/resources/dist/.poly/render/skins/loopy/checker.animatedpoly This also let's us create new directories for the skin textures, instead of overwriting the existing ones, and just change the path to the texture in the `.animatedpoly` file for the skin you want to replace -- then to switch back to the original skin you would only need to switch back to the old `.animatedpoly`file. A theoretical workflow for adding your own skin for loopy, by overwriting the `animatedpoly` file of the flame skin: - Backup your resources folder - Create a new directory for your skin: resources/dist/.image/render/skins/my_skin/ - Get the plane sprites to use as a base: pack_tool unpack <path-to-altitude>/resources/dist/.image/render/planes/loopy/p0 - Add all your skin files to that directory: loopy_0000.png, etc - Then, to create the pack files and overwrite a skin with your own: Code:
# Create pack files and an `image_lookup_map.txt` from the files in the given # directory $ cd <path-to-altitude>/resources/dist/.image/ $ pack_tool pack render/skins/my_skin # Overwrite the given `animatedpoly` file to use the specified images # The '{}' is replaced by the frame number for each frame. $ cd <path-to-altitude>/resources/dist/.poly/ $ pack_tool skin_poly --images "render/skins/my_skin/loopy_{}.png" \ render/skins/loopy/flame.animatedpoly |
#11
|
|||
|
|||
Well I may be stupid but I've spent a fair bit of time today trying to map the goal.poly to its sprite today but no matter what transform (specified in the poly) I applied to the poly or sprite positons I can't get them to align.
Of course immediately after I type this up something works... It still however relies on the sprite mapping within the p# file neatly mapping onto the sprite, which it doesn't. It required me to manually offset it by y+50. The translate and rotation within the poly file doesn't compensate for it by itself. Last edited by Moon; 09-14-2016 at 04:21 PM. |
#12
|
|||
|
|||
Quote:
https://gitlab.com/xalri/libalt/blob...ources/pack.rs https://gitlab.com/xalri/libalt/blob...l/pack_tool.rs Using this code to extract the goal sprite: Code:
*[message][~/code/libalt/util/pack_tool]$ cp /opt/altitude/resources/dist/.image/render/map/goal/p0 ./ *[message][~/code/libalt/util/pack_tool]$ cargo run Running `/data/Code/libalt/target/debug/pack_tool` [II] pack_tool sprites: [Sprite { name: "render/map/goal/0_128_5.png", off_x: 0, off_y: 0, width: 154, height: 76 }] *[message][~/code/libalt/util/pack_tool]$ identify render/map/goal/0_128_5.png render/map/goal/0_128_5.png PNG 154x76 154x76+0+0 8-bit sRGB 11.1KB 0.000u 0:00.000 The `.poly` file isn't particularly relevant here, it maps the image to the defined polygon, so the graphics align with the collision poly. edit: I'll work on this for a few hours now, cleaning up and adding lzma support to `pack.rs` and moving `pack_tool` out of the libalt repository. (edit2: bbcode's lack of inline code support is rather annoying ._.) Last edited by LewisH; 09-14-2016 at 04:41 PM. |
#13
|
|||
|
|||
Sigh.. It works now.. A lot of time could have been saved if I knew that the offsets are from the bottom-left corner not the top-left :/
|
#14
|
|||
|
|||
Oops, I had forgotten about that >_<
Oh well, at least it works now, I've fixed it in my post above. |
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Looking for some help in modifying some files. | Diablo | Tech Support | 1 | 04-13-2013 03:13 AM |
Altitude Promotional Image | lamster | News | 34 | 05-18-2010 08:15 PM |
Background Image | York | Map Making | 8 | 01-13-2010 09:20 PM |
Altitude Fansite/Press Image kit | Karl | General Altitude Discussion | 6 | 12-13-2009 07:12 PM |