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!"
I didn't expect to be writing a post like this, but here it is:
I've finished up on the UI side, so now it's time to start working on the export and replacement aspects. The user interface is general the aspect that takes the longest, as you have to figure out what the best way to interact with the data is. What I ended up doing is requiring the files to be included into the page. If you click on an image, you can preview it, and swap out the internal palettes. I was trying to think of how to implement a simple texture editor, but I ended skipping on that entirely. Textures can replaced by uploading an image file, and then the colors can be fine tuned by changing the sliders for the palettes.
I think there's a downside to approaching the texture editing this way. As there are some pretty obvious pit falls, as it makes editing for multi-call images quite difficult. And it doesn't really allow for images that use a "side loaded" palette from another file. That being said, I wanted to keep the scope of this editor to a "proof of concept" and not carried away with fringe cases from the start. So i think I at least made a tool that can be used for basic editing, and potentially more if you have the patience to manage it.
I have two aspects to approach next. The first is exports. Originally my plan was to have the ROM file included into the page, and have the page manage the edits and export the modded ROM. But in reality, it looks like the size made that approach more difficult than it needs to be. So right now my plan is to export a list of "dirty" textures, with the adjusted palette and image data in a list of base64 strings. And then the second aspect is the search and replace program. My plan is to try and replace the specific files edited in the UI, and since the game often re-uses the same file several times, I'm hoping that I can either find the offset in the table of contents for the disk, or come up with a way to filter out which file is where by trying to match a list of strings.
For 3d models, I think we might be reaching the point where modding the PSX rom could become obsolete. Uradamus has done some amazing work with the stage tiles and has a working version of the Ocean Tower and the Apple Market.
Working on models would be fun, but my general prediction for how long a model editor would take to make is somewhere between three to five weeks (full time days, not sure how long it would take spare time-wise) to come up with a basic editor. If you were able to replace models like you would in a pc game by editing a single model for a single file, then I think it would be a lot easier. But you have other things to keep in mind, like packing and unpacking all of the assets in the EBD, memory limits for how many vertices you can fit in memory, matching bone counts, and you'd have to match it with updated textures as well. In general I think that's time that could be better spent getting more assets out of Megaman Legends to be able to pop into Godot or similar engine. So my plan right now is to work on replacing textures in ROM to allow for people to play around and have fun with modding the game, and then start looking into save states to see if there is a way to cut corners for stuff and things.
Okay, so custom textures is now a thing that actually exists.
The Ui looks like this:
Source here: gitlab.com/megamanlegends/dash-tex The page for it can be found here: megamanlegends.gitlab.io/dash-tex/ The short version is you select the game files to include in the page. When you click on a tim image, it will render the texture. You can click "set image" to upload a new texture. The texture will need to be the same size as what its replacing. The texture will need to be an indexed png with the correct number of colors. After replacing files, you can click export. The page will produce a json file. You can run that json file into a script to write to rom. I'll post a video once I've made it.
Looking good, that should come in handy. If your new viewer if displaying correct names, then it is offering a great insight. All those textureless files that have C at the end of their name are those variant palette sets I've been banging on about for a while now. I was just looking at the ones in Apple Market and it's definitely the case there. For instance in ST04_00.BIN, INAC201.TIM is the main exterior texture for Jetlag Bakery and Akbar Toy Store. While INAC202c.TIM, INAC203c.TIM, INAC204c.TIM, and INAC205c.TIM are the variant color palettes using the texture in INAC201.TIM.
Based on my past few days working on porting Apple Market, the names always start with a 2-4 letter prefix (if they have 4 the first 2 are usually IN, probably meant to indicate interior, while the other 2 are probably a code for specific stages/uses) followed by 3-4 numbers and ending with an optional letter suffix, usually N or C. N I suspect might have been meant for Night stuff at some point and now that I'm seeing those C endings, I feel confident they are all alternate color palettes.
I have yet to see more than 7 palette variants in use, so I would imagine they put a hard cap of 8 on the variants, much like they put a limit of 8 on the palettes within a variant. So the last number in the name is usually the variant number. The other numbers should be in reference to which texture is to be used. This is just speculation of course, but it jives well with my experience with Apple Market so far.
So if you could find a way to make those additional palette variants selectable with their root texture, like maybe an additional drop down like the one you already have for palettes within the root textures, that would make it so we can get all the textures out through that new tool. Or instead of cluttering things up, just do a basic name matching method to find TIM files where only the last number is changed and C/c is added in at the end, and give them their root texture to display. It would also be really nice to see a download image option added to the tool, to make this a nice replacement for the old texture viewer.
EDIT: BTW, I love that you are including the paths with the file names, I really want to organize my rips to follow the original dir structure, as that often gives some subtle hints to what they were thinking when creating and organizing assets, I'd love to see that feature extended to your other tools as well.
Last Edit: May 15, 2019 19:59:18 GMT -5 by uradamus
Looking good, that should come in handy. If your new viewer if displaying correct names, then it is offering a great insight. All those textureless files that have C at the end of their name are those variant palette sets I've been banging on about for a while now. I was just looking at the ones in Apple Market and it's definitely the case there. For instance in ST04_00.BIN, INAC201.TIM is the main exterior texture for Jetlag Bakery and Akbar Toy Store. While INAC202c.TIM, INAC203c.TIM, INAC204c.TIM, and INAC205c.TIM are the variant color palettes using the texture in INAC201.TIM.
I wonder if I can cover current laziness with previous laziness. In one of my really earlier programs I made a texture debugger when first working with models.
It's a debug program, so it's not very intuitive. Like all of the other applications, start by importing all of the files. Once that has happened you can click on the BIN files, and they will be loaded into the "memory", which is the second tray. After that when you click a TIM file in the tray, a popup will appear, which will allow you to use the palette from any other TIM file for that given image. You can click on the palette previews below the image to apply a given palette and then right click and save the TIM preview canvas once you've found what you need.
I wasn't planning on posting in here for a while, but I couldn't pass up a perfectly good shitpost. I made a script that mods the ROM to force the lowest LOD model possible.
Okay, time to start looking into another mod, which is being able to change the font for Megaman Legends 1. Which means we first need to be able to display the font from Megaman Legends 1, something that I haven't looked into since it didn't have much to do with exporting assets. So as a start we can try to use what's available in xDaniel's Dash Viewer as a start to see if we can build on it from there.
So starting with stating the obvious. The game seems to have two font files. FONT.BIN and KAIFONT.BIN. I'm not sure what the difference is, but if they're the same format, then it shouldn't really matter too much. And in each bin, they seem to only have one file defined each which is "..\bg\char\font.dat" and "..\bg\char\kaifont.dat". As for xDaniel's Dash Viewer, it's not hosted on Github/Gitlab (which seems like a shame), but instead on dropox. So specifically here is the file for reading the font: www.dropbox.com/s/9j0b6aduj4f1dic/MMLPSX.rar?dl=0
Since working with Dropbox is stupid, let's create a working copy on pastebin to be able to reference. It also looks like there's a class for handling messages, which we might as well make a note of. FontHanlder : pastebin.com/XB0S6P91 Message Handler: pastebin.com/tn9TkwNj
Font
In general it looks like the font is stored similar to a TIM image, which means we can break the image into two aspects. The first being reading the palette and the second being reading the image data. So first let's take a look at the palette.
Data = new byte[filelen]; Buffer.BlockCopy(arc.Data, ofs, Data, 0, Data.Length);
So first part is it looks like it's only grabbing the file length from the header which is 0x8000 bytes. Looks like there is other stuff in the header, which is probably things like palette and image location of the framebuffer, as I assume the font needs to be stored in the framebuffer to actually be used for rendering in text boxes. Well probably not "need" as much as that's how the programmers approached it.
A second note is that it looks like the program makes a copy of the data to keep the offset relative to the start of the data and not relative to the start of the archive. So we need to double check that we're using the right offsets.
int rofs = 0x8700; for (int i = 1; i < Palettes.GetLength(0); i++) { if (lcd != null) lcd(string.Format("{0}: Loading palettes...", System.IO.Path.GetFileName(Path)));
Okay as for reading the palette, the syntax threw me off for a bit, but I think i get what's going on here. The program makes 5 palettes. The first palette has a fixed set of colors, and then the other four palettes need to be read from the file. Each palette has 4 colors.
So in terms of the data it looks like this. There are four palettes, and it looks like each palette defines 4 colors, and the rest of the colors are just repeats of the first, so we can skip over them. Though one nice thing about changing text is i don't need to care too much about palettes and can leave these numbers alone, the next step will be looking into how the font bitmap is encoded.
Image
int imgw = 256; int imgh = 512; int blockw = 128; int blockh = 32;
Images = new Bitmap[Palettes.GetLength(0)]; for (int i = 0; i < Images.Length; i++) { if (lcd != null) lcd(string.Format("{0}: Creating image for palette {1}...", System.IO.Path.GetFileName(Path), i));
rofs = 0x800; Images[i] = new Bitmap(imgw, imgh); for (int y = 0; y < imgh; y += blockh) for (int x = 0; x < imgw; x += blockw) for (int by = 0; by < blockh; by++) for (int bx = 0; bx < blockw; bx += 2) { byte r = Data[rofs]; int idx1 = (r & 0x3); int idx2 = ((r & 0x30) >> 4); if (y + by > 256) { idx1 = ((r >> 2) & 0x3); idx2 = (((r >> 2) & 0x30) >> 4); } ((Bitmap) Images[i]).SetPixel(x + bx, y + by, Palettes[i][idx1]); ((Bitmap) Images[i]).SetPixel(x + bx + 1, y + by, Palettes[i][idx2]); rofs++; if (rofs == 0x8800) rofs -= 0x8000; }
Okay this code is pretty much what i expected. In general the game uses palettes to encode images. The images can have 8 bits per pixel (0 - 255) for 256 color images in the tiles screen, or 4 bits per pixel (0 - 15) used for the 16 color textures in the game. This is an extension of that of using 2 bits (0 - 3) of selecting from 4 colors. Which I almost expected 1 bit, black or white, but 2 bits isn't all that surprising. So each pixel in the font image is going to be a number 0 -3, and I think i could take that a step further of defining 4 colors specifically and using that to encode and decode the images for the font. After that is getting the right number of images, so next step is going to be a test page to see if I can display the fonts.
As a separation of concerns, I might as well make this its own post. I uh, did the thing.
FONT.BIN
KAIFONT.BIN
I guess I should comment one out or the other to see which file is actually being used in game, but it shouldn't be too hard to write an encoder and it works on the same principle as the texture files. And I managed to simplify the code a little bit, the result looks like this:
let ofs = 0; for (let y = 0; y < imgh; y += blockh) { for (let x = 0; x < imgw; x += blockw) { for (let by = 0; by < blockh; by++) { for(let bx = 0; bx < blockw; bx += 2) {
let byte = view.getUint8(ofs++); let a = byte & 0x03; let b = ((byte & 0x30) >> 4); let c = ((byte >> 2) & 0x3); let d = (((byte >> 2) & 0x30) >> 4);
ctx.fillStyle = palette[c]; ctx.fillRect(x + bx, y + by + 256, 1, 1);
ctx.fillStyle = palette[d]; ctx.fillRect(x + bx + 1, y + by + 256, 1, 1);
} } } }
}
Instructions
Okay, I'm able to encode font files. Instructions for how to do it as as follows. 1. Use KAIFONT.BIN as a base for adding in the alphabet you want 2. Open megamanlegends.gitlab.io/mml1-psx/font/ 3. Select you're updated font image 4. The page will spit out a "patch.js" file 5. Run patch.js with : node patch.js <rom> <out>
ex: node patch.js mml1.bin mml_text.bin And then run the game to confirm the changes. So as a proof of concept we can edit and change the font file to add letters or alphabets. Next step is looking into how to change text.
Most post spam. Take some quick notes while I have a chance.
Here's a screenshot of the header. So the way it works is offsets to strings. The start to each message is a short value. So the first offset is 0x1e, which means that each short up to that point is a pointer as well. So it goes in the order of 0x1e,0x113, 0x1db, 0x203... The start of the first message is 0x1e, and the start of the text is at 0x2e. Which means we need to fill in the parts inbetween.
[a1][8c](Z)0T0?3[93]08[8f] 0000Wait a second![a4]J0[9f][87]00[8f] 1000There should be a[86]Reaverbot around[86]there somewhere...[a4]J0[9f][87]00[8f] 2000Can you see it?[a4]J0[9f][87]00[8f] 3000It looks like a[86]small one--[a4]J0[9f][87]00[8f] 4000you should be able[86]to take it down with[86]your Buster Gun.[a4]J0[9f][87]00[99]01[a9][84] 0000[a2]
I've worked with this a little bit. I added some instructions for kerning/leading spacing in the gitlab wiki. That way, you can change I to Ж and the letters not bleed together at edges.
If you read it and add it to your editing abilities, you can explain more about it here. I'm bad at explaining, but it's a simple table of size values that add to the next letter's x-pos.
Last Edit: Jun 3, 2019 0:48:00 GMT -5 by ShadyRounds
As for the tool, I have the general approach to editing text down, but it's only one character at a time. So I need to add a few bare minimum functions to make editing easier:
1. [ x ] Restore button to reset message
2. [ x ] "Dirty" css rule to show which files have been changed.
3. [ x ] Multi-letter delete support
4. [ x ] Multi-letter paste support
For the rom edit script, I might force using an img file, the 0x800 boundaries on .cue/bin combined with the fact that the length of the msg file will probably be changed makes it annoying to write rules for the difference in length.
And then for the letters for the message, I'll go ahead make a copy and hardcode the letters in, which will be available here: megamanlegends.gitlab.io/mml1-psx/msg/rus/
So the idea for this came from MegaRockEXE who made a dab patch for Megaman Battle Network 6 Twitter Link Here. Which got me thinking that why not have a dab patch in Megaman Legends. We could replace the kick animation, and have Megaman dab on the reaverbots.
Except when expectations meet reality, the results can be brutal. And after trying to throw something together, this is what I managed to get.
That being said, I dropped my edits into a simple script. So if you want to try your hand at editing the kick animation. You can find the code here: gitlab.com/megamanlegends/mml1-psx/snippets/1885292/raw The way you use it, is drop it into your save state folder, save a state in slot 1, edit the FRAMES in the script, run script with Nodejs, load slot 1, rinse and repeat.
New resource. This is from Ombra who has been working on tools for translation for the font and MSG files. The github repository is here: github.com/OmbraRD/DashEditor and it looks like he's been making pretty good progress on parsing a lot of the code the game uses for wait and speech.
I was the one that PMd and tweeted you. Sorry about that.
I did the upload the bin files in the dat folder like so below and I gave it 20 minutes but nothing shows up. I also did the same thing on Chrome and got the same results. Should I try a different browser or is there a version of the game I should be using?