|
Post by spideyseth on Jun 14, 2015 22:32:00 GMT -5
Yeah i know dude its really awesome!
|
|
|
Post by cruzifixio on Jul 23, 2015 23:05:58 GMT -5
I did it! I got textures to work with this game! WOW! Thanks for trying to help though i'll send some screenshots! I can't wait to see what you came up with, and what this can (possibly) lead to~ last I knew the biggest breakthrough was getting Teisel's face to go over the water texture Are you still at it, can you share how did you make the textures to work with it? I have an old project to make this, you can check on this boards I already retextured Megaman, and many other things for the Nintendo 64 version of the game.
|
|
|
Post by spideyseth on Oct 23, 2017 1:13:37 GMT -5
Don't wanna necro a dead thread but i still know how to do this and will send the screenshots. I'll also maybe make a video for those who are interested in learning this thing. But i am making my own game so maybe after that i might do some kind of retexture thing for Legends 1.
|
|
|
Post by spideyseth on Nov 8, 2017 23:04:39 GMT -5
I just have to get a disc drive for my new gaming rig!
|
|
|
Post by Rockman Striker on Nov 10, 2017 14:54:39 GMT -5
I've always wondered if it's possible to make an HD mod for Legends, do you think it is? swapping high polygon models and hi-res textures would be awesome.
Edit: Didn't meant to quote, Tapatalk app seems to be changed a little, I tapped the wrong button.
|
|
|
Post by spideyseth on Apr 15, 2018 11:47:10 GMT -5
Gonna post the answer in maybe 2 weeks.
|
|
|
Post by murdertrain7848 on Sept 3, 2018 8:24:05 GMT -5
So, how is the answer coming along?
|
|
kion
Arukoitan
@kion_dgl
Posts: 193
|
Post by kion on Apr 17, 2019 2:15:22 GMT -5
I was debating on whether to start a thread or not, but I guess I'll post this here. So even though my attention is focused on taking things out of games, most of the attention and interest seems to be centered around modding what exists. So while I don't specifically plan on making any modding tools, what I can do is to help document some of the file types and resources I used when breaking down the game as a resource for anyone interested in modding. ChallengesThe first section is specifically challenges around modding and specifically the format. Using the PC game would make things a lot easier for swapping out data. But the PC version is hard to come by and doesn't seem to run very well. Not to mention that most people's experience with the game seems to be with the PSX version (also the PC version seems to be using most of the same mechanics and files as the PSX version anyway), so focusing on that version seems to be the most widely available version to work with. But working with PSX games comes with its own challenges. ROM Editing - Maybe someone can write a guide on this. While it's pretty easy to get files out of a PSX disk, I was never able to re-pack the extracted data back into an ISO that could be used. So being able to extract files, change them and then pack them back up again might make making changes a lot more viable, than having to dig around and edit the .ISO or .BIN file directly (not fun). Another option that would be a lot easier would be to be able to run the PSX's .EXE file directly. I've tried doing this on PCSX-R, but the emulator then tries to read from the disk, so I don't know if there is a way to get the emulator to read from the extracted files directly, to make the PSX environment work similar to the PC version. RAM Editing - Outside of editing the ROM, editing the RAM seems like the next best bet for making and testing changes. The Playstation has 2MB of system RAM and 1MB of graphical memory (along with other data needed for registers). In most emulators they dump all of this data to a single file and then use gzip to compress it for save states making it difficult to work with the save state data. I was able to edit PCSX-R to dump save states to non-compressed individual files for each memory type which made editing memory a lot easier.
Pallet EditingThis is probably the "low hanging fruit" of modding. Pallets are stored in a 16bit R5G5B5A1 format. Generally the difficult part about this is tracking back images to which scene they are referenced in, but editing shouldn't be terribly difficult. Though I think that also dpends on the degree to which the tools are made, easiest option is to open a hex editor and mess with the values. Not sure what the UI would look like for a 16 bit pallet selector, or how you'd pair it ad update files. Maybe if there are similar tools, someone can post about about it. Video reference for MML2: www.youtube.com/watch?v=dxft4nFsyP4 TIM viewer: mml.dashgl.com/tools/mml1_psx_tex/Texture EditingTexture editing is going to be somewhat more difficult than pallet editing. There are two obvious limitations, first is the 256 x 256 size limit, and second is that pallets are 4 but indexed, so you're limited to 16 colors. But that's only for one draw call, so you can get around this limit by using different pallets for different parts of the section and changing the draw call depending on the part of the mesh. Though this is a lot more sophisticated than is really needed for proof of concept considerations. The main issue with editting textures is the encoding, the game "mixes up" the order of the textures and splits different parts into blocks. So for a texture to render correctly you have to use this function: (credit xDaniel) for (y = 0; y < tim.height; y += block_height) { for (x = 0; x < tim.width; x += block_width) { for (by = 0; by < block_height; by++) { for (bx = 0; bx < block_width; bx += inc) {
byte = fp.readUInt8(ofs++);
switch (tim.nb_colors) { case 16:
pos = ((y + by) * tim.width) + (x + bx); image_body[pos] = pallet[byte & 0xf]; pos = ((y + by) * tim.width) + (x + bx + 1); image_body[pos] = pallet[byte >> 4];
break; case 256:
pos = ((y + by) * tim.width) + (x + bx); image_body[pos] = pallet[byte];
break; }
} } } }
Otherwise if you try to read the data normally, you end up with this result: for (y = 0; y < tim.height; y++) { for (x = 0; x < tim.width; x++) { byte = fp.readUInt8(ofs++);
switch (tim.nb_colors) { case 16:
image_body[pos++] = pallet[byte & 0xf]; image_body[pos++] = pallet[byte >> 4];
break; case 256:
image_body[pos++] = pallet[byte];
break; }
} }
That doesn't mean that this barrier is inpassable, it mostly means that someone less lazy than me will need to go though the trouble of writing and testing an encoder. Since it's possible to edit the UV values of stage tiles, you could edit a wall and set it to view an entire tile to test to see if the game is reading the data correctly. Barring that, assuming you wrote a save state and could separate out which 1MB is the graphical memory, then you could render and edit the game's graphical memory and then load it back. Though it's alot easier to edit textures than it is to edit pallets that way, so the approach will likely depend on the delivery system for the mods. Being able to edit and replace files pc-style would be easiest. Being able to unpack and repack iso's could be another possibility. Replacing textures in memory seems like more of a brute force proof of concept approach. But in general what works is what matters. Character Mesh EditingThe game has two 'kinds' of mesh formats. PBD for megaman, and EBD for the other characters, but in general they're the same format when it comes to the vertex and face definition. The PBD files that make up Megaman's parts are pretty a pretty simple file type, and are pretty easy to locate in memory. But I can't really say anything about editing or changing these meshes due to a general lack of effort in this area. I tried replacing Megaman's head with a trashcan one time, it was a really half-ass attempt, and it didn't accomplish anything noteworthy at all, so that's my extend of experience for PBD files. EBD files I'm a little more familiar with. And the general issue here is that while the vertex and face format for these models is pretty straightforward, they're contained in an archive, where each mesh has three LOD's, high, medium and low placed one right after the other, and each character immediately follows another character. So in general replacing data for one charatcer generally means you will need to repack all of the other data. But there are likely two ways around this. One is to force the game to use the high LOD pointer all of the time, and that way you can use the space for the medium and low LOD models, and not have to repack the model. And another option is the game is good at handling commented out models, so you could comment out everything after a certain item, and then focus on one object to manipulate and change. The challenge around editing models mostly revolves around the vertex format. The PSX doesn't use normal 32 bit floats, it uses 16 bit signed short values. Floats are generally used from the Dreamcast and onwards. What that basically means is that the PSX doesn't use the same format of data that you would normally use in a 3d editor. So taking a model and converting it into something that the PSX can render would take a lot of trial and error. Being able to edit textures ahead of time would also be a possitive. Stage Terrain EditingThe stage terrain is stored in a stack of quads. It's possible to read the quads, and edit them to change the terrain if you're realy meticulous and start small. Because the game manages geometry as a list of stacked quads one right after each other, you would need to take your time and try to figure out from where you can edit, add more quads if you need to, and also manage the LOD and collisions. Stage Tile EditingSomething I'm really not familiar enough with to provide much detail on at all. The game uses a 2d tile system to arrange the floor, but which tile id's have which properties, and how that interacts with the terrain is not something I have a extensive experience with. Each tile has a tile id and height, so it's possible to change the layout of a stage pretty easily. But as far as doing anything else meaningful, like changing spawn locations or things like that isn't somethng I've looked into at all.
|
|
|
Post by ShadyRounds on Apr 21, 2019 6:44:31 GMT -5
You can most certainly edit the PSX ISO. Well, specifically, the IMG format. Usually you have to take ram values, find the source where they write from, and compare that value to a hex-search to the img-file. I've changed many a thing, which I think I recorded in another thread. The PC version would be most accessible file-wise, but is also the least stable and enjoyable imo. Someone already made a Hi-Def version of PC assets though iirc, check YouTube. EDIT: And to be specific, someone in 2006 proved you can patch the PSX Legends, at this romhacking page entry. This is what inspired me, alongside Tau and Trege and Furry's ram editing and my own basic background in ram tracing among other scarce psx debug documentation. Ambyra's 2006 psx romhack: www.romhacking.net/hacks/40/my youtube videos showing (some) psx trace and romhacking: www.youtube.com/watch?v=MvOS1qcS5Zc&list=PLycE38kjLqQX7EsygZ4OQDlNuGrgTekYeALSO EDIT: Note that these values edited aren't texture, model, tile, palette, ect. These are general script-values that give items, busterpart strength, door destinations, and gameplay based things. In my experience, these seem simpler than the 3d world and cosmetic parts of the game so far, since they're writ and/or calculated very simply. I most certainly envy Kion and xDaniel as the graphical engine gurus so far, I am not even good at basic modern 3d program or file types.
|
|
kion
Arukoitan
@kion_dgl
Posts: 193
|
Post by kion on Apr 27, 2019 14:32:18 GMT -5
I updated the model viewer to include a pallet editor on the right side. You can use the sliders and it will update the model preview. On top of the sliders are two hex values "Source Binary" and "Updated Binary". You can copy these values into replace.js, and then run the replace script by running: node replace.js MegaManLegendsRom.bin
The script will create a copy of the rom with replaced values: MegaManLegendsRom_out.bin. If things work out your pallet edits will appear in game.
|
|
|
Post by ShadyRounds on Apr 30, 2019 8:14:20 GMT -5
Well. No s#!+. I really wish I could make a comprehensive script to generate new bins with changes from old bins. I have to rely on standard NUPS patchers common among romhacking.net projects, but they provide a concrete patch and not anything randomly or custom generated like this.
...and you say this works in PSX version?
|
|
kion
Arukoitan
@kion_dgl
Posts: 193
|
Post by kion on Apr 30, 2019 18:42:37 GMT -5
1. Custom TexturesFirst development is I finally tried writing an encoder for textures. After writing the palette editor and having the ability to re-create the 16 bit color texture, the next step was to index an image and then put the bytes in the order that the game wants. This encoding turned out to be easier than I expected as it's the reverse of the parser. So rather than reading the bytes in order and determining the color of the x, y pixel coordinate, the approach is to write bytes in a fixed order for a given x, y coordinate. I first started out with the 256 color encoded title opening. But I wasn't able to write the image to the ROM. One issue is that the title opening has a lot of transparent pixels, so finding where it is in ROM is difficult. And the other issue is that because it's a larger image, data itself could be cut by the ISO's boundaries. So I might try again with a smaller image tonight and then test the 16 bit coded textures as well. 2. Discord SummaryTalked with Shady about how the game handles chest last night. And to save the information from discord oblivion I will do what I can to summarize what I was able to gather last night. The game stores the id for the item inside the "You got XXXX" dialog. The hexidecimal for "You got" is 2E 3F 45 4F 36 3F 44 13 86 89 03. Meaning you can search for this value in ROM to find where the game stores items in chests. Following the "you got" hexadecimal is a four byte value for what kind of item is in the chest (ie. zenny or buster part). An example scan can be found here: pastebin.com/ACfXmBmNA few examples of Item handler codes are: 13 86 89 03 - buster parts? 4f 30 4f 43 - unknown 4f 38 44 86 - unknown 13 86 89 02 - zenny? So these handler codes can be used as magic numbers to filter out which chests are the target of interest. Following the item handler magic number is four bytes for which item, or zenny amount is in the chest. So if we have a list of item handlers, and then the format that the game stores each item would theoretically allow for custom item placements in ROM. Example code for searching for buster parts and printing the value can be found below. "use strict";
const fs = require("fs"); const haystack = fs.readFileSync("mml1.bin");
const needle = Buffer.from("2E3F454F363F4413868903", "hex"); //const needle = Buffer.from("2E3F454F363F4413868903D00D89009A0D050D9F", "hex");
let index = 0; while( (index = haystack.indexOf(needle, index)) !== -1) { let ofs = index.toString(16); index += needle.length; let bytes = [ haystack.readUInt8(index + 0).toString(16), haystack.readUInt8(index + 1).toString(16), haystack.readUInt8(index + 2).toString(16), haystack.readUInt8(index + 3).toString(16) ];
for(let i = 0; i < bytes.length; i++) { if(bytes[i].length < 2) { bytes[i] = "0" + bytes[i]; } }
//haystack.writeUInt8(0x11, index + 1);
console.log("Chest found at offset: 0x%s with %s %s %s %s", ofs, bytes[0], bytes[1], bytes[2], bytes[3] );
}
fs.writeFileSync("mml_cheat.bin", haystack); 3. ROM Editing ApproachesI spent most of my time on Linux, so I don't have easy access to a lot of the robust ISO tools that windows offers. So my approach has been to write short scripts with Nodejs to search through a ROM file, write the changes in memory and then write result to a new file. Though this could just as well be accomplished with python or even C depending on preference. The advantage of using a short program is you can add in some logic, debug, write and retest for any edits that you might want to apply (you also have the option of distributing the program and not the ROM). Though in general if you open up the ROM in a hex editor, change a value, save and rum the game you have a ROM hack. In windows I mostly use HxD and in Linux i use Bless or Hx which are are "basic bitch" hex-editors so it kind of depends on what kind of functionality you're looking for. Another option would be to unpack the files from the game, edit and replace what you need and then put a new ROM back together. On Linux I tried psximager but didn't have any luck in unpacking an image. On windows there is magic ISO, so if anyone is able to unpack and repack an ISO and have it run in emulator, it definitely seems like a good idea to write a guide. One of the best (but least plausible) options would be able to run ROCK_NEO.EXE from the emulator directly. But every time I try this it says, "please insert disk". So I don't know how the game is controlling reads. If the game is specifying file names, or offsets in the disk. I don't know how difficult it would be to implement a lookup table to tell the emulator to read a given file for a specific offset. 4. Tools to create ISOgenisoimagemkpsxisopsximager
|
|
kion
Arukoitan
@kion_dgl
Posts: 193
|
Post by kion on May 1, 2019 20:48:39 GMT -5
1. Chest EditingEdited the first chest in the ocean tower to contain a 'Buster Max' part. The script for the edit looks something like this: Download and install nodejs. Make sure you enable the option to add it to the path. In the folder you have your megaman legends cue/bin files. Create a file called "patch.js" with the following code. Make a copy of track1.bin and call it "mml1.bin" const fs = require("fs"); const haystack = fs.readFileSync("mml1.bin"); const needle = Buffer.from("2E3F454F363F4413868903", "hex"); const index = haystack.indexOf(needle); haystack.writeUInt8(0x10, index + needle.length + 0x01); haystack.writeUInt8(0x10, index + needle.length + 0x05);
fs.writeFileSync("mml_cheat.bin", haystack);
Open up a terminal in that folder and run: node patch.js It will create a new patched version of the bin called "mml_cheat.bin". Edit the cue file to reference the cheat bin file as follows: FILE "mml_cheat.bin" BINARY TRACK 01 MODE2/2352 INDEX 01 00:00:00 FILE "Mega Man Legends (USA) (Track 2).bin" BINARY TRACK 02 AUDIO INDEX 00 00:00:00 INDEX 01 00:02:00
Once you do that, start up an emulator, select the cue file. Start a new game and make your way to the first chest. It should have the Max Buster instead of the power raiser. How this works is we read the original ROM file. We create a needle which is a combination of "you got" + the buster part identifier. We get the first index, and then we overwrite the byte for the dialog and the item id of the power raiser to the max buster. So the next question is really what kind of rules to search for, and what to replace. 2. 16 Bit PaletteTested encoding 16 bit images yesterday, and got the image written back to the DEMO_DAT.BIN to be read by my TIM reader tools. So theoretically textures can be replaced in ROM, but in practice I haven't had any luck in getting the textures to display in game. 3. ROM EditingLast night I tried two approaches. First I tried running the game directly from ROCK_NEO.EXE, which I edited the source of PCSX-R to try and debug why nothing runs. I found emulator loads the file fine, but it's when it runs the code to start execution that the emulator gets stuck in a loop. So not sure what's going on there. Next I tried to edit the .BIN file, which didn't work likely because of the boundary breaks in the .BIN file. Which means there are two options. The first is to open a hex editor and try replacing the texture by hand to see if there is a pattern for what works and what doesn't. The second approach would be to try and extract the files from the disk, edit them and then regenerate a file from there. Create image from disk: dd if=/dev/cdrom of=/directory/example.iso Create .cue, .bin
|
|
kion
Arukoitan
@kion_dgl
Posts: 193
|
Post by kion on May 2, 2019 10:40:39 GMT -5
Okay, I guess I'll go ahead and triple post.
After coming home from work, and looking at the pathetic excuse of code I wrote at 4am last night was missing and end position for the copy point. I fixed that and textures worked. I also fixed another issue that was causing pallets to reference the wrong color index on export. Fixed that too. And the result can be seen above, custom textures injected into the ROM. Next step will be to work on a tool for customizing roms.
The code for replacing looks something like this: "use strict";
const fs = require("fs"); const source = fs.readFileSync("mml1.bin");
const LENGTH = 0x800; const STRIDE = 0x130;
let pal, palOfs, img, imgOfs, ofs;
/* Replace Servbot Texture */
palOfs = 0x0230818; imgOfs = 0x0231048;
pal = fs.readFileSync("palette_16.bin"); img = fs.readFileSync("image_16.bin");
pal.copy(source, palOfs);
ofs = imgOfs; for(let i = 0; i < img.length / LENGTH; i++) { img.copy(source, ofs, i*LENGTH, (i+1)*LENGTH); ofs += (LENGTH + STRIDE); }
/* Title Logo Texture */
palOfs = 0x0261e38; imgOfs = 0x0262668;
pal = fs.readFileSync("palette_256.bin"); img = fs.readFileSync("image_256.bin");
pal.copy(source, palOfs);
ofs = imgOfs; for(let i = 0; i < img.length / LENGTH; i++) { img.copy(source, ofs, i*LENGTH, (i+1)*LENGTH); ofs += (LENGTH + STRIDE); }
/* Write to new ROM */
fs.writeFileSync("america.bin", source); Assuming we have and encoded palette and image, then we need to find the respect offsets of the data we're replacing in the ROM. Palettes are short enough that they can be copied in as-is. Images are longer and have to be copied in-between the 0x800 sections of disk. So we cut the image up, copy 0x800 bytes of the image, skip over 0x130 for the .cue/bin boundary data, and then copy another 0x800 bytes. Rinse and repeat.
|
|
|
Post by Rockman Striker on May 12, 2019 22:13:10 GMT -5
You always manage to amaze me! Changing pallette colors and injecting custom textures? If you keep going with this excellent work, will you be able to modify or replace even the 3D models? Imagine the possibilities of modifying the game at your own liking! I know I usually don't have anything relevant to comment but that's because you literally left me speechless... All I can say is "keep up the good work!"
|
|