Jump to content


  • Posts

  • Joined

  • Last visited


13 Good

1 Follower

About Tabun_ne

  • Birthday 01/01/1991

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Tabun_ne


    banner.bin and banner_s.bin are both found in the /FONT/ folder. They contain data for the dungeon title font. File Structure The file uses SIR0 headers to store its pointers. General SIR0 details can be found in the main SIR0 documentation. The sections below will cover only banner.bin-specific blocks of data. Name Offset Size (Per Element) # of Elements Description SIR0 Header 0x00 16 Bytes 1 Details in the SIR0 documentation Glyph Textures Pointed by Glyph Metadata Varies Specified by Content Header Each element is read nibble-by-nibble to assemble the glyph. Glyph Metadata Pointed by Content Header 8 Bytes Specified by Content Header Each element contains a pointer to the glyph texture, the letter it represents, and how many pixels wide the letter is. Content Header Pointed by SIR0 Header 12 Bytes 1 Contains the pointer to Glyph Metadata, and the number of elements in that data block. Pointer Offsets List Pointed by SIR0 Header 1 Byte Varies Details in the SIR0 documentation SIR0 Padding After Pointer Offsets List Varies --- Details in the SIR0 documentation Content Header 3 Sections containing 4 bytes each: AA AA AA AA BB BB BB BB CC CC CC CC A. Pointer to the start of the Glyph Metadata block. Little-Endian. B. Pointer to the number of elements in the Glyph Metadata block. Little-Endian. C. Unknown. Glyph Metadata This is an array of elements, each 8 bytes. Contains 3 sections: AA AA AA AA BB BB CC CC A. Pointer to this element's texture data in the Glyph Textures block. Little-Endian. B. The letter that the glyph represents. Little-Endian. The encoding varies by language, which is covered in the strings documentation. C. The number of pixels to move the cursor to the right, when drawing the text in-game. Little-Endian. Appears to be signed. Glyph Textures Individual elements in the Glyph Textures block have a variable length. Data is read nibble-by-nibble: First, the high bit of the nibble is checked. If it is 1, then the game will read the next nibble as pixel data and draw it N times. N is the other 3 bits of the first nibble. If it is 0, then the game will read the next N nibbles as pixel data and draw them in that order. N is the other 3 bits of the first nibble. The game draws pixels in order of left to right, top to bottom. It moves on to the next row when 24 pixels have been drawn, and ends the parsing when 24 rows have been drawn. Parsing For convenience, the following python code is provided below to parse these files: import sys import os import re import shutil import math import struct import glob from PIL import Image GLYPH_SIZE_D = 24 PALETTE_MAP = [0,8,24,41,57,74,90,107,123,140,156,173,189,206,214,231] def ReadNextNib(reader, next_nibbles): if len(next_nibbles) > 0: return next_nibbles.pop() byte = int.from_bytes(reader.read(1), 'little') next_nibbles.append(byte & 15) return byte >> 4 def ExportDChar(reader, char_val): pixels = [] next_nibbles = [] while len(pixels) < GLYPH_SIZE_D * GLYPH_SIZE_D: control_nib = ReadNextNib(reader, next_nibbles) draw_repeat = control_nib >> 3 draw_amount = control_nib & 7 if draw_repeat == 1: pixel_nib = ReadNextNib(reader, next_nibbles) pixel_val = PALETTE_MAP[pixel_nib] for ii in range(draw_amount): pixels.append(pixel_val) else: for ii in range(draw_amount): pixel_nib = ReadNextNib(reader, next_nibbles) pixel_val = PALETTE_MAP[pixel_nib] pixels.append(pixel_val) return_img = Image.new('RGBA', (GLYPH_SIZE_D, GLYPH_SIZE_D), (0, 0, 0, 0)) datas = [(0, 0, 0, 0)] * (GLYPH_SIZE_D * GLYPH_SIZE_D) for yy in range(GLYPH_SIZE_D): for xx in range(GLYPH_SIZE_D): pixel_idx = yy * GLYPH_SIZE_D + xx if pixels[pixel_idx] > 0: datas[pixel_idx] = (255,255,255,pixels[pixel_idx]) return_img.putdata(datas) return return_img def ReadChars(reader, amt): return_imgs = [] for ii in range(amt): glyph_ptr = int.from_bytes(reader.read(4), 'little') glyph_val = int.from_bytes(reader.read(2), 'little') advance = int.from_bytes(reader.read(2), 'little') cur_ptr = reader.tell() reader.seek(glyph_ptr) return_img = ExportDChar(reader, glyph_val) return_imgs.append((return_img, glyph_val, advance)) reader.seek(cur_ptr) return return_imgs def ReadFont(input_file): output_parent, basename = os.path.split(input_file) dir, _ = os.path.splitext(basename) output_dir = os.path.join(output_parent, dir) if not os.path.exists(output_dir): os.mkdir(output_dir) with open(input_file, "rb") as reader: ##Read SIR0 Header: ptr to font header reader.seek(4) font_ptr = int.from_bytes(reader.read(4),'little') ##Read font header: ptr to charmap, amount of chars reader.seek(font_ptr) list_ptr = int.from_bytes(reader.read(4),'little') char_amt = int.from_bytes(reader.read(4),'little') _ = int.from_bytes(reader.read(4), 'little')#don't know what this is reader.seek(list_ptr) imgs = ReadChars(reader, char_amt, mode) for idx, img_pair in enumerate(imgs): img = img_pair[0] code = img_pair[1] advance = img_pair[2] if advance > 0: img = img.crop((0,0,advance,GLYPH_SIZE_D)) img.save(os.path.join(output_dir, str(code) + '.png'))
  2. Finally got back to this place. Thought I'd have to reset my password because of the security issue so I kept putting it off... But I picked up on the effect bin again. And now it is finished. https://www.spriters-resource.com/ds_dsi/pokemonmysterydungeonexplorersofsky/sheet/85692/ A few closing notes for posterity, as an addendum to the info I posted up there in Section 2 is definitely responsible for some form of Draw-behind shenanigans. I went through the whole list of effects and all of the components that don't use a "0" for that value tend to appear behind the player. Also, the metaframes all use X and Y offset values in the same format as with WAN sprites. For Colors... as far as the custom palettes for each effect goes, a series of transformations is applied to the color value as it appears in ROM in order to get the value that appears in game: First, the color value is rounded down to the nearest multiple of 8, and that becomes the color that appears in the palette viewer. That palette viewer color is then multiplied by 32, and divided by 31. That is then the true color as it appears in-game. Really strange, considering no other graphics files do this to my knowledge... Anyways, it feels good to finally have resources like this out there... 8 years after release... Now I can go back to my fangame. lol
  3. I'm taking a break from VFX ripping... I got pretty far, but the last step demands more free time than I have at the moment... I'm more curious about dungeon data now. Has there been any headway made in the past regarding the stats for the dungeons? According to the notes I was able to find on the subject, that data seems to be found in /BALANCE/. But which files would they be?
  4. After playing around with the ROM a bunch, it looks like this is how the meta-frames work: Example Metaframe: FF FF 00 00 ED A1 E9 04 00 7CSections: 00 00 11 22 33 44 55 66 77 89 Section 0: ALL FFFF Section 1: ALL 00. Section 2: 00 or FB. Maybe determines draw-behind? Section 3: Y Offset Section 4: Dimensions in Binary Flags: 0123 4567 01: 00 in Sharpen and Barrage, 10 in Embargo 2: Unknown (ALL 1) 3: Mosaic Mode (ALL 0) 45: Unknown (ALL 00) 67: Upper Bits for Y offset Section 5: X OFfset? Section 6: Dimensions in Binary Flags: 0123 4567 01: Size; 00=8x8, 01=16x16, 10=32x32, 11=64x64 2: Flip Vertical 3: Flip Horizontal 4: Is Last Meta Frame in Group (1 in Sharpen and Barrage, SOMETIMES in Embargo) 56: Unknown (ALL 10) 7: Upper Bits for X Offset (SOMETIMES 1 in Embargo) Section 7: Image Offset by blocks. 1 LSB = 2 8x8 textures. Examples: +1 for 8x8 Sharpen (will skip 1 block; the game appears to add 1 block space to 1-block textures) +1 for 8x16 Embargo (8x16 = 2 blocks) +2 for 16x16 Barrage (16x16 = 4 blocks) +2 for 16x16 Sharpen (16x16 = 4 blocks) +8 for 32x32 Sharpen (32x32 = 16 blocks) Section 8: Palette Index. Values of 0 to C all appear to exist outside the file. They reference a palette that, on runtime, remains static. Values at D and E seem to use custom palettes that may or may not exist in the current file. Section 9: ALL C Section 4 and Section 6 are not completely confirmed, but the flags for size, flip, and horizontal/vertical dimensions are the same. It's pretty much following the same pattern as WAN sprites, except it's LITTLE-endian. Even though there's no variable for image index, it looks like ti can still be figured out be reading Section 7, which deals with memory offsets. Also, it appears that colors in the Palette viewer (And presumably in the memory itself) need to be multiplied by 32, then divided by 31 in order to achieve the correct colors displayed in-game. There's just one issue remaining... and that is regarding the palette data of these effects. None of the palette data that actually shows up as colors used in the game appears to be stored in these files. There are some exceptions, such as with Aura Sphere- but it appears that the file has only one of several palettes needed to display that move properly. And even then, the one palette that appears to be stored in the file is not 1:1 with the colors used in the game, or even the palette data that shows up on runtime. So now we have palette data in the file, palette data in memory, and palette data in the actual game/tile map, all of which are different... So the questions left unanswered are: -Where are the correct colors for these effect sprites, for the files that do not have them? -What operation needs to be done in order to transform existing colors in the files to the colors actually used on runtime? EDIT: Ok so I edited effect_0178_0x194630.sir0 (Dragon Pulse) to use the following info as its palette data: 00 00 00 80 FF 00 00 80 FF 20 00 80 FF 40 00 80 FF 60 00 80 FF 80 00 80 FF A0 00 80 FF C0 00 80 FF E0 00 80 FF FF 00 80 E0 FF 00 80 C0 FF 00 80 A0 FF 00 80 80 FF 00 80 60 FF 00 80 40 FF 00 80 20 FF 00 80 00 FF 00 80 00 FF 20 80 00 FF 40 80 00 FF 60 80 00 FF 80 80 00 FF A0 80 00 FF C0 80 00 FF E0 80 00 FF FF 80 00 E0 FF 80 00 C0 FF 80 00 A0 FF 80 00 80 FF 80 00 60 FF 80 00 40 FF 80 00 20 FF 80 00 00 FF 80 20 00 FF 80 40 00 FF 80 60 00 FF 80 80 00 FF 80 A0 00 FF 80 C0 00 FF 80 E0 00 FF 80 FF 00 FF 80 FF 00 E0 80 FF 00 C0 80 FF 00 A0 80 FF 00 80 80 FF 00 60 80 FF 00 40 80 It's basically a cycle of all the rainbow colors. The result was pretty interesting: http://i.imgur.com/NqsbvOr.png The rainbow-cycle apparently goes out to palettes 13, 14, and 15. And it also appears to prove that, with Dragon Pulse's live sprite changing, that all of the palette info is indeed coming from the effect file itself. Somehow. At least for Dragon Pulse and other files that use palettes 13-15. EDIT 2: To be comprehensive, I also blanked out the entire palette for Sharpen and observed the results. Nothing happened, so it looks like every move using palettes 12 and below are actually getting them from somewhere else.
  5. Given how both the screenshots are at "Main Spr Ext PAL 7" I can't think of any way the palettes aren't set to the correct slot... I just needed some sanity check to make sure I wasn't making some silly mistake with my emulation. I guess if all else fails I'll skip right to editing the image datas to reference every palette index possible and see what the colors are that way...
  6. It's odd... for some reason, the colors in the palette view don't match up with the tile view. For instance in that earlier image with Embargo: http://i.imgur.com/VtxmdYn.png The shades of purple found on the embargo diamonds don't match any of the purple in Main Spr Ext PAL. It's messing with my attempts to investigate palette. Might this be an emulator problem? (I'm using DesMuMe) Have you or anyone else run into this issue?
  7. http://i.imgur.com/H4koduf.png There's the meta frame data, palette data, and data for both textures of Embargo there. Looking at the palette data, I couldn't find any colors that the actual in-game sprite used. However, I remembered something about the way palettes worked with moves in the past: there's always this list of about 8 to 10 palettes that gets loaded in "Main spr EXTPAL", and (nearly) all of the moves in the game use this as a sort of "master" palette. There's still a small amount of exceptions that use their own palette instead of the "master" palette- something I noticed with Aura Sphere, in fact, which would explain why it came out without any color issues! Following on this hunch, I checked out the sir0 files for Sharpen and Barrage- specifically their Metaframe files. I think I can draw some conclusions: Example Metaframe: FF FF 00 00 ED A1 E9 04 00 7CSections: 00 00 11 22 33 33 44 44 55 67 Section 0: This value has been FFFF for every metaframe I could find. I don't know what that means but it seems to definitely NOT be frame index as it was for the character WAN sprites. Section 1: This section has always been 00. It remains unknown, like the character sprites. Section 2: This section has been 00, and FB in all the values I've checked so far. The only times it's been FB so far is in certain parts of Embargo's animation. My wild (COMPLETELY UNBACKED) guess is that it determines whether something is drawn behind the target or in front. Section 3: This section has changed with what appears to be a change in offset. I don't know if, like the character offset, there's some additional flag data embedded in its bytes... Section 4: Behaves the same as section 3. Probably for the other axis. Section 5: I am almost sure that this block is related to which image gets drawn. But it's not a simple "Frame 0, Frame 1, Frame 2, etc." relation. There's values that would go way beyond the maximum image count. Maybe it's related to the size of the images? Section 6: Almost sure that this refers to which palette this sprite is using, when it is loaded into memory. Embargo's correct palette was "Main spr EXTPAL," on palette 7 on runtime. Sharpen's correct palette was 3, which is also its value for this region. Section 7: This is always C. I don't know why. With the palette data, I'm thinking that if we can find where that "master palette" data is stored, it can be used to extract all these sprites in the correct color! There's still a lingering uncertainty on how to get dimension data for the images, though... assuming that the effect meta-frames have them like the sprite meta-frames... When I get the time, I think I'll make changes to the sprites and repack the ROM to do some more experiments...
  8. Yeah, it looks like the last files aren't WAN and happen to be some other format... I actually ran a script to first rewrite that one byte all the sir0 files since the gfxcruncher didn't work with my current version of c++ (and I'm wary of getting the new Visual studio currently...) http://pastebin.com/z6rwsX9q These are my notes for the garbage texture data- I wasn't really aiming for completeness so much as trying to find points of interest to deduce from. There were in fact a number of effects that showed up with the same palette as in the game! For everything else, though, it looks like the palette data may have some different rules to it when it comes to effects... I need to reread the palette and image notes again for WAN to see what it's supposed to be read as to begin with, though... those parts of the interpretation still confuse me. In preparation of that, though, I got a look at Embargo. I picked it as the easiest thing to tackle since I recognized the graphics as effect_0156_0x153310, that it was such a small graphical file, and the only thing wrong with it seems to be the wonky palette. http://pastebin.com/yqpxjM07 Also, the correct palette for Embargo as it's live in-game: http://i.imgur.com/VtxmdYn.png Aura Sphere was also notable, because I remember that move's correct palette appearing on a very high palette index when the graphics were loaded into the emulator's tile viewer. I haven't looked at that in depth though...
  9. I had some time today and ran through a list of all the sir0 files found in the effect.bin, and what WAN-like filetypes they are, assuming they're WAN at all. http://pastebin.com/UrAGG3TU I also force-converted the files with the image type of 2 through the gfxcruncher, just curious of the results https://www.dropbox.com/s/yi904m0da78m4s3/forceChar.zip?dl=0 Even though the palette and image sizes are garbage, the converted product actually survived the process! There's definitely some familiar effects in there that have the same silhouettes as what I manually ripped before... I'm considering comparing them for palette data. Perhaps there's a correlation there...
  10. http://pastebin.com/JtUTvrR3 These are the results I got when I opened up effect_0117_0x100610.sir0, extracted from the effect.bin and followed the WAN reference of pointers. It was the smallest file on the list, so I went through the whole thing manually. All of the pointer data appears to be consistent and the format seems to fit perfectly, with a few things to note: ln174: The sprite type reads out as 2. According to your notes, you've never found files with that number before... ln13 and 27: Meta-frames read out for some wonky results. -1 frames the only meta-frames in the list. Resolution flags of all 1's, and demanding both HFlip and VFlip. It's odd... perhaps the format here is different? ln139: There is no particle offsets table. It might be because this particular sprite is so tiny, but I could see this being the case for all effects. I tried viewing the pixel strips in tilesGGD, but couldn't get anything sensible to show (although again, it may be because it's a tiny file that may not hold meaningful information): http://i.imgur.com/r8RB1xz.png I wonder if decoding it like a WAN file would just solve 90% of this format's mysteries. I did attempt to just run the gfx cruncher on the little file, as both a .sir0 and a .wan extension, but apparently it doesn't recognize the parameters.
  11. I ran effects.bin through the ppmd_packfileutil this time, and now things start making much more sense. I'm not very well-versed with rom hacking (I've only just now downloaded HxD and tilesGDD to work with), but I think I'll try to research on this effects.bin format as well, probably cross-referencing with the existing WAN format due to how much sense it makes that they would be similar. I don't have much else to do in the immediate future...
  12. As a needed step towards finishing my standalone game, I've come to the challenge of having to obtain the graphical effects used in Pokemon moves. Traditionally I've done this by ripping them through emulator tile view, but that involves going through every single move manually. Does there exist the means to extract these graphics from an unpacked rom? I tried running the gfx cruncher on /EFFECT/effect.bin, but the resultant files seem to be in an unspecified format. And on the topic of ripping sprites from a live game... Regarding dungeon tiles, would it help your research if I provided a guide of which texture mapped to which type of dungeon tile, in for instance Beach Cave? With the tasks in my own project, it's something I could do along the way. Ex: There are 8 tiles adjacent to any given tile, giving us 2^8=256 possibilities of adjacent-tile configurations. http://i.imgur.com/laKdF4F.png However, (at least for walls) diagonally adjacent tiles are not counted when their cardinally adjacent tiles are missing, leaving us with 47 different possibilities that are visually distinct. http://i.imgur.com/l00XuHK.png Each of these possibilities has at least one dungeon tile mapped to it (Note, image does not have every combination filled). http://i.imgur.com/DSrSbz1.png
  13. I tested the monster and m_attack animations after porting them directly into my standalone application. I suspect there may be a few bugs, but just testing out charmander, charmeleon, and charizard revealed a few things. monster 0- walk 5- sleep 6- hurt 7- idle m_attack 1- regular attack 2- kick? (charmander kicks, charmeleon and charizard scratch) 3- shooting (flamethrower) 4- attack with arm/shooting? (charmander scratches, charmeleon/charizard shoots) 8- spin around attack (fling, feint attack) 9- double team/agility 10- jump a little, while in shooting animation (maybe digging?) 11- also a charging animation? 12- single twirl (item throwing, orb usage, etc) -the order of the animations starts from downwards-oriented animation, and then goes counterclockwise. -some pokemon have the same animation to do multiple things; e.g. the animations for charmander's "shoot" and "charge" are visually identical, but the animations for charizard have them different. You can see this in action by giving them both pokemon the moves Flamethrower(shoot) and Blast Burn(charge), and seeing how they execute them. -animation 4 puzzles me. I'll have to check how it looks for more pokemon, because it appears ambiguous. -when a pokemon (such as charmander) does its normal attack in PMD, it lunges forward and then springs back to its original position. However, the animation playback from the xml consists of its lunging forward, a long pause (514 units of pause!), an odd twitch (offset of movement), another long pause (258 units) and then the spring back. EDIT: These long pauses only appear in attack-related animations, and seem to signify a critical point in the animation, such as then the attack is supposed to land, or hit. Now I just need to find a way to upload screencapped animations... EDIT2: Perhaps the duration of a frame consists of one byte, and the other byte is for some special flag value?
  14. Alright, these last few days I've been writing some conversion scripts to check things out. Firstly, I wanted some more confirmation on the reverse-drawing method, so I assembled every FrameGroup that had overlaps, and drew them all out in reverse order: https://www.dropbox.com/s/pkgvs9g7u5bod1r/MONSTER_overlap.zip?dl=0 Just having them all on preview in that one folder seems to confirm it as a consistent rule- at least enough to convince me. The images that start with an underscore denote that they have -1 frames and aren't completely reliable, which led to another question... One thing didn't sit right with me: given that -1 frames used existing memory, it would mean that they would be drawn after the original sprite piece. However, there's many places where -1 frames are at the END of a FrameGroup list, and never at the beginning. If frame pieces were truly drawn in reverse order, that would mean that the -1 frames are paradoxically pulling memory from a future state. Perhaps the draw order isn't in reverse, and the game just constantly draws behind (however strange that may be)? I was going to try and edit the position of Giratina's -1 Frame to overlap with the frame it copied, in an experiment of which frame would draw first, but I got sidetracked by a more general issue... I wanted a better understanding of -1 Frames, and trawled through all the FrameGroups with -1 frames in hopes of finding some pattern. I initially tried checking if all -1 frames referred to another frame that was a constant X frames earlier. It didn't work that way, nor did it give me any insight on possible patterns. So then what I tried next was using the Resolution variable of the -1 Frames. The fact that, out of runtime, the game seems to know what the dimensions are of the piece it is copying makes me highly suspect that the copied frame could be deduced from existing data. I then attempted to run a script that would draw out all FrameGroups with -1 Frames, and then attempt to find any preceding frames that matched the dimensions of the -1 frame. All possibilities would then be tried, and laid out in such a way that it would be easy for a human to manually identify the correct assembly: https://www.dropbox.com/s/i1ipz5pslp7lr09/MONSTER_minus_one_monster.zip?dl=0 A large number of sprites, when pushed through this algorithm, had only one possible solution, which meant that they were solved (the folder is preceded with the underscore). For the purposes of using the sprites for my standalone project, I considered applying this approach to all sprites out there to shrink the workload, and simply manually identify the correct assemblage from the remainder. Save for that Dugtrio (which has a lot of particle bits), it seemed like a straight shot... However, when I ran this algorithm on the m_ground sprites, python nastily ran out of memory. I did a sweep check on just how many combinations the sprites had in there, and confirmed that some sprites had too much possibility depth to feasibly deduce even when the human eye and script automation were put together: http://pastebin.com/9CGLahLK (each number getting multiplied is a -1 frame, and its value is how many frames match up with its dimensions) ...It's all those darn story-releated animations, due to m_ground being the story-related sprites directory. I guess my last hunch that may be worth pursuing is to count the amount of graphics (maybe by the number of 8x8 textures?) that get listed in a framegroup to see if there's any correlation between that, and the -1 Frame's copy target. I dunno. If worst comes to worst and I can't squeeze anything else out of this frame data, I'll probably just ignore those complex story-related frames and settle for the m_monster and m_attack frames. All of the frames in those subdirectories have much tamer probability spaces, and I didn't really need that animation of Dusknoir charging a giant shadow ball, after all... That said, I hope some portion of the info that came out of this hunt can help your searches, now or in the future.
  • Create New...