-
Posts
425 -
Joined
-
Last visited
-
Days Won
1
Content Type
Profiles
Pokédex
Portal
Technical Documentation
Pages
Tutorials
Forums
Events
Downloads
Gallery
Blogs
Everything posted by psy_commando
-
Actually, now that you mention it, you'll probably want to look up more infos on how the Lua VM works. And what the ASM for exposed functions/methods looks like. Also all lua numbers and constants are stored as doubles. So now that I think of it, that might be why you were having issues finding the values you wanted in the exefs maybe? The 3ds runs ARMv6, with VFPv2. Just for reference. The VFP is a floating point number co processor. Basically, it adds some op-codes and registers for floating points numbers to take into account. It works very similarly to how the NDS ARM9 worked. Except that now there's executable and non-executable memory pages and services and etc..
-
Ohh, I understand now ^^; Well, maybe a good lead would be investigating the scripts ? I found this while looking around: local textId = FUNC_COMMON:GetItemExplainTextId(parent.curItem.obj.obj:GetIndex()) Then with the IDA demo, and some messing around to get an elf to feed it: .text:0011C8A0 ; --------------------------------------------------------------------------- .text:0011C8A0 .text:0011C8A0 loc_11C8A0 ; CODE XREF: sub_112FAC+9510j .text:0011C8A0 BL sub_1D8BE0 ; Branch with Link .text:0011C8A4 LDR R2, =sub_16CA38 ; Load from Memory .text:0011C8A8 ADR R1, aGetitemexpla_0 ; "GetItemExplainTextId" .text:0011C8AC MOV R0, R4 ; Rd = Op2 So the subroutine that runs this is at 0x16CA38 in the elf, and you just have to subtract 0x10000 from it to get the offset in the exefs.bin file. Though, its bound to have all the Lua parameter processing stuff and etc in there to make things more complicated..
-
The new palemoon update seems to have completely broken the forums for me.. It seems the forum's software is really abusing user agent sniffing.. Well the thing is, there's probably a reason why message_us doesn't have its own directory. In GTI, the text used to be stored like that, in a subdirectory. But in PSMD, its all packed into an archive, and accessed via filename like before. The best example of that is the function in the script for loading the string file for shops that is used the same way as it was in GTI.. Also, its been reported that the european language files, which message_en is part of, are incomplete. Names of things for one. Apparently that only the dialog was translated. But that's mainly just from hearing randomn player accounts that tried the language hack on the US psmd rom. MENU:LoadMenuTextPool("message/shop.bin", false) MENU:LoadMenuTextPool("message/top.bin", true) SCREEN_B:LoadWallpaper("WALLPAPER_SUB_SKILL01") Also, I'm not sure what you mean about the strings tables being weird. They have a table with offsets from the start of the header to a string, and each entry has a 32bits UUID used to refer to it in the scripts. Its been like this since GTI. https://dl.dropboxusercontent.com/u/13343993/my_pmd_research_files/PMD_GTI/FileFormats/string_database.txt As for the pokemon data file, silverhawke and andibad found a lot about them a few pages back. There are still some things we're not too sure about though.
-
Hey TruePikachu! Yeah its unclear how string ids are assigned to stuff. Except pokemon have their String UUID for their names I think. Also, you probably don't want to look at message_en, its not used in the US version. You want to look at message_us. I modified the text in there, and I figured that its what the game uses to display the text in the US version. I also noticed that, the text in there is loaded based on context, and not directly in the script like GTI used to do. I suspect the "script_flow_data" files to contain some hints. That, or its hard-coded. Since, most lua functions in the scripts appear to be callbacks called from the original C++ code. Also, like evan mentioned, there is something odd with starters.. I made a little script edit I posted earlier to be able to pick whatever pokemon as starter, but the thing is, if they're not one of the 20 official starters, their ability, and their starting moves will be the ones from one of the official starter pokemon.. And sometimes, for some pokemon, they won't always get the same starter's moveset/ability. Like I had on eevee both oshawott and pipplup's moveset on different occasions. Poochyena seems to always get piplup's moveset and ability.. And looking for some of the move ids in the binaries didn't yield anything. Not to mention that, while the fancy starter select screen is hard-coded, only the starter's model ids are in the binary, they match the pokemons' ids. I edited then, and found out only their model changed, not the actual pokemon tied to it.. And after the select screen you'd get the actual correct pokemon model assigned with the starter you picked.. So something tells me there is some data in the game files with details on starters and their moveset and ability.
-
The script editor is made by Nerketur, he has a thread for it on pokecommunity. I doubt he checks this thread. Cutscenes and boss battles are handled by script too. Statsutil can't edit this kind of stuff right now. I need more feedback on things too, since nobody seem to say anything about it. Its hard to make modding tools if nobody says anything about them.. Nitro explorer isn't really great for modding. Get ndstool or dsbuff, or one of the other programs that can unpack roms. A lot of new ones popped up.
-
If you'd give some more details I could probably say something helpful. ^^; I haven't tried it. I've been mostly looking up the very few strings I needed to look up by UUID with an hex editor. Besides, I don't want to have any excuses keeping me from finishing my 90% finished string parser I've been putting off finishing constantly for dumb reasons.. ^^; (Its funny however, because literally everyone in this thread made their own string parser And I began mine when I was working on GTI, even before making this thread ^^; ) Did you try to run this with python 2.7 or the latest? Python development is in a weird spot.. There's a split between 2.7 and higher. So if something doesn't work with anything higher than 2.7, try it with 2.7. I'm not a python expert though. I barely even skimmed the surface.
-
I'm probably also the only person that tried it then, because its really easy. ^^; And a lot of the code chunsoft made is modifying the global state of some objects. Its pretty dirty and confusing, because those objects needs to be in a particular state to work as expected. Well, some menus will refuse to work when using the same method though. I'm still not 100% sure what might be the problem. And some make heavy use of the "flow system". The "flow system" is probably the most annoying thing in the scripts.. Its basically some kind of bastardized and overcomplicated state machine. Also, a lot of things were moved from the script right into the game code after GTI. So, we don't have all that much control on the game this far. Scripts are only, for the most part, filled with callback functions called by the game code. Its also possible that those callbacks are defined in some of the bin files laying around the script folder and etc.. I'm still not sure. We'll need more research into the plb, and script data files. Interestingly, a lot of the flowsys bin files have strings containing numbers and constants, and even some strange repeating patterns of bytes that look like opcodes almost. Which might imply they're used by the game code to work/interface with the scripts. You mean the encoded pointer list ? Because that's just used to translate pointer offsets in the file to offsets in memory when the file's content is loaded. Also, the notes I have up are for GTI. In PSMD, they put all the string db files into a big FARC archive. And you're welcome.
-
Well, you're saying you're new to this, but you seemed really specific about wanting that hero/partner select code, while there's the entire game script as example already. So, I assumed you might have been looking at something specific, or some pointers ? Because, its probably best to not reinvent the wheel and go through researching everything on your own. Its alright. Its just that I'm pretty sure I could help you get started more than that crappy code snippet ^^; Not to mention that at the same time I'd have an excuse to make an info dump in here.
-
You know, it might be much easier to help you if you'd mention what you're trying to do/are looking for, and ask some question. What you've said so far is very vague. And, I didn't do anything very special besides changing the content of the lua callback functions with stuff I stumbled on in other lua files and put together. The menu is the same as the one used for gold ingots, and I used the function to set the hero and partner pokemon id from the value entered in the menu. repeat WINDOW:CloseMessage() WINDOW:SysMsg("Select _ Pokemons ?(Menu#2)") WINDOW:SelectStart() WINDOW:SelectChain("Done", 0) WINDOW:SelectChain("Set Hero pkid", 1) WINDOW:SelectChain("Set Partner pkid", 2) WINDOW:DefaultCursor(0) local id = WINDOW:SelectEnd(MENU_SELECT_MODE.DISABLE_CANCEL) if id == 1 then WINDOW:SysMsg( "--- Changing _ Hero _ pokemon _ id ---" ) local oldpokemonid = SymAct("HERO"):GetIndex() local menu = MENU:CreateNumericMenuWindow(ScreenType.A) menu:SetLayoutRect(Rectangle(96, 80, 132, 84)) menu:SetPlace(3) menu:SetDigit(3) menu:SetStartNum(initval) menu:SetType(NUM_MENU_TYPE.TYPE_DIGIT_ON) menu:SetTextOffset(24, 40) function menu:decideAction() charname = self:GetSettingData() GROUND:SetHero(charname, 0) CHARA:ReloadHeroPartner() self:Close() end function menu:cancelAction() charname = oldpokemonid GROUND:SetHero(charname, 0) CHARA:ReloadHeroPartner() self:Close() end menu:Open() menu:SetCaption("Pokemon ID") MENU:SetFocus(menu) MENU:WaitClose(menu) elseif id == 2 then WINDOW:SysMsg( "--- Changing _ Partner _ pokemon _ id ---" ) local oldpokemonid = SymAct("HERO"):GetIndex() local menu = MENU:CreateNumericMenuWindow(ScreenType.A) menu:SetLayoutRect(Rectangle(96, 80, 132, 84)) menu:SetPlace(3) menu:SetDigit(3) menu:SetStartNum(initval) menu:SetType(NUM_MENU_TYPE.TYPE_DIGIT_ON) menu:SetTextOffset(24, 40) function menu:decideAction() pertnername = self:GetSettingData() GROUND:SetPartner(pertnername, 0) CHARA:ReloadHeroPartner() self:Close() end function menu:cancelAction() pertnername = oldpokemonid GROUND:SetPartner(pertnername, 0) CHARA:ReloadHeroPartner() self:Close() end menu:Open() menu:SetCaption("Pokemon ID") MENU:SetFocus(menu) MENU:WaitClose(menu) end until id == 0 Its really quick and dirty. I also re-used the original script-local variable names, so don't be surprised if there are horrible typos or if the names makes no sense, that's chunsoft's own weirdness. Also all functions that write text strip white spaces from string literals. Still not too sure why because strings returned by the API's functions, or string UUIDs seems to work fine. Also, I was holding back on releasing that, because there is most likely a better way to do this. And I think using the setpartner and sethero functions do some extra junk in the background which causes issues.. Feel free to ask questions. That's pretty much what research threads are for.
-
Its not really ready to be used in a playthrough at all. There are some pretty big problems right now.. Detailed in the post you just quoted.. And modifying the message.bin has nothing to do with this. I'm not sure why you insist on text? For what ? Select chain is just for adding a choice to the basic default choice dialog.
-
Well, I guess crypto key was not the right term on second thought.. ^^; ( I really don't know that much about crypto.. ^^; ) Maybe, its really a checksum/hash, or some kind of validity seal ? There seems to be some similarities between those two examples. It would be nice if you had more of them though. And, I wish some of the more wondermail savy people would show up ^^;
-
Why would they need another checksum though ? Doesn't QR codes use redundancy to deal with error checking ? Maybe its some kind of crypto key ? Anyways, I know someone in the first few pages posted a list of codes, but I'm not sure if that's what you're looking for: http://projectpokemon.org/forums/showthread.php?46904-Pokemon-Super-Mystery-Dungeon-And-PMD-GTI-Research-And-Utilities&p=210769&viewfull=1#post210769
-
Not really. Its been pretty much free for all this far. Though if anyone wants to help figure out the .plb file format, or the script_flow_data.bin file that could be useful. I'm guessing we still haven't reversed character animations either ? Unless that's covered by ohana already.. There's also disassembling the code.bin that would really help. Well, a lot of things written using .Net languages can be run in wine. Regular executable built for windows can also be. Personally I write everything in C++, using portable libraries, just to make things more portable between platforms. I still haven't figured out how to make hassle-free makefiles though, since my mingw and clang setup keeps killing themselves.. That's exactly what its supposed to do. Its explained when you use it. Awakening is a catch-all term. Basically, pokemon that can mega-evolve do mega-evolve, but others just get some buffs. And I noticed that having a pokemon that can mega-evolve in your party seems to increase the likelihood of stumbling on one.
-
No problems. But, performance for something you load once per launch, ever, and that can be parsed and processed in maybe ~a millisecond with tinyxml is not really much of a concern. High performances are only really important in time critical aspects of the software, like rendering for instance. Performance always comes at a cost too, in readability, maintainability, memory usage, etc.. I mean, the pros vastly outweigh the cons in this case. Sorry if I sound patronizing/nosy, I don't mean any disrespect, I just wanted to spare you having to find out the hard way why its not such a good idea, and why its almost universally frowned upon.. ^^; I wrote a lot of generic code, and some games too, and I used to do things like you're doing right now, aka putting data in the code, and using performance as an excuse. And I can tell you in most cases, it was a huge waste of time in the end, even though it seemed like it was quicker and simpler to do that.. I ended up scrapping projects over that, because it had become too much of a bother to "do things right" at that point, and rewriting from scratch was the better way out. But, motivation is a funny thing, and when something like that happens, you're a bit less inclined to go through rewriting everything unless you're getting paid for it.. ^^; And since you're coding this entirely in C, you'll probably have better things to spend time on than rewriting the stats data loader half-way through IMO. If you're not too into XML/JSON, you can also do almost the same thing by binding Lua to your C code. It has a nice C API, and you can expose functions and types to the script engine. And Lua has been used a lot to store data directly into tables(Which isn't very clean, but is still better than storing data into your binaries ), as well as scripting game logic, UI, etc.. So if you want to keep things relatively simple, and kill two birds with one stone, you can always just go that way. Script language makes repetitive things like narrative, logic, UI, and etc a breeze as opposed to writing it in native code. Plus Lua is pretty much the fastest script language around(Maybe except python compiled to native C..) especially with JIT compilation. Its also really simple. But yeah, its a nice project you have, and I hope it'll work out! I just wanted to share some things I learned from big projects like that in the past. But really, just do whatever you want with that advice ^^ I'm really not sure what you mean. You can't just awaken them using the awakening emera ? I works on non-mega capable pokes, and mega-capable pokes. So it seems like a catch-all emera for temporary evolutions and power buffs. But, honestly, beyond that I don't really care much about legendaries, so I never used one in PSMD. ^^;
-
I don't mean to tell you how to do your job, but you probably really don't want to store data in your code like that ^^; You should put that in some config/data files outside your executable. It will make maintenance and improvements a thousand time easier, not to mention it allows for easier modding too. And you won't need to recompile each times you change something. XML/JSON are really good and well supported by a ton of libraries around, and they're great at storing data, you can zip them too if they get too big. And XML is great for mass search and replace operations, thanks to its predictable tag layout. It might be worth it looking into those? Just some thoughts ^^;
-
PMD never worked like main series game for stats. That's pretty much a big part of what makes it interesting I can't imagine dealing with dungeons as a starter with base 300 stats or something against an army of high level fully evolved pokes D: And, just scroll back up a few post until you reach Andibad's post. They're stored in act_data_info.bin apparently. I'm guessing someone on gamefaq might have made a list with those values. But otherwise, you'll probably have to make a list yourself. Unless you use PMD2 stats. There are already excel sheets and etc filled with this kind of stuff floating around the web.
-
Happy holidays ! I've been working on a thing I finally got the UI to work without freezing the game, and actually displaying properly! The initial movesets and abilities being wrong, and the crashing on some cutscenes (When forcing the game to use the HERO/PARTNER actors in cutscenes) hasn't been addressed yet though. But once its done, this should work pretty well I noticed that not all pokemon that aren't the official starters had their initial moveset set to piplup's. And it seems like, official starters picked through my modification still get assigned the correct moveset. So it might mean that we might be able to affect what moveset and abilities are assigned somehow. For example: - Poochyena gets piplup's moveset + ability. - Mightyena gets piplup's moveset + ability. - Squirtle gets its own moveset + ability. - Eevee gets Oshawott's moveset + ability.
-
answered Red Rescue Team: Adding Portraits?
psy_commando replied to BlueLeafeon's topic in ROM - GBA Discussion & Help
Red Rescue Team is on the GBA though, so there's no filesystem like in Blue Rescue Team. I haven't messed around much with those, but modding RRT would be much more complicated than modding BRT IMO. I know that its possible to add pokemon portrait in PMD2, but in BRT or RRT it seems like only pokemon that needs them have portraits "slots".. If you look at the monster.sbin file, there's a long table of content at the beginning. The files beginning with "kao" and ending with a pokemon number are all the faces for a given pokemon. But you'll notice there are a lot missing. It all depends on whether the game code and game script looks for a kao file that matches a pokemon's id or not. Otherwise, the format for the portraits is nearly identical to how it was in EoS. Its just that each pokemon has a SIR0 container with a table of content pointing to each of its portraits. And each portrait has its palette right before, just like in EoS. My suggestion would be to try to add a kao file for a pokemon manually into the sbin, maybe just copy one of the existing pokemon's, and name it after another pokemon's id. Then find a way to talk to that pokemon. You'll see if it works. As far as hacking notes go, there's this thing: http://fileformats.archiveteam.org/wiki/Pok%C3%A9mon_Mystery_Dungeon You need to use a hex editor with a 30 days trial on it though, or you can also just read the XML yourself and use another hex editor. But, a lot of things are very similar to how they are in PMD2. Besides that, I think I remember that antylamon and a few others have posted some interesting RRT/BRT notes in the PMD2 thread. It might be worth digging into it. -
Honestly, I hope the game doesn't assume hardcoded offsets in those files.. It would make things much more difficult ^^; And its really not much, but I've been going through files and trying to decipher as much as possible then moved to other files, and I got this: [font=Fixedsys] ==================================== pokemon_evolution.bin ==================================== Offset Name Size Type Description ---------- ---- ---- ---- ----------- 0x00 Sir0Header 16 - The standard SIR0 header. [] 0x10 EvoDataTbl vary - [ PkmnEvoData 12 - [ ] ... ] PtrEvoInfoTbl vary - [ Entry 12 - [ PtrEvoData 4 uint32 A pointer to a structure containing detail on the evolution of the pokemon stored in the EvoDataTbl. unk1 4 uint32 unk2 4 uint16 unk3 4 uint16 ] ... ] Subheader 16 Contain a pointer to the data, and the nb of entries. [ PtrEvoInfoTbl 4 uint32 A pointer to the PtrEvoInfoTbl. NbEntriesEvoInfTbl 4 uint32 The nb of entries in the PtrEvoInfoTbl table. ZeroPadding 8 - Null bytes. ] SIR0EncodedPtrOffsetTbl [] [/font] I noticed a lot of other little things, but I didn't write those down yet because I still got to validate stuff. That's what we're saying. Its just that it got decompiled as a large signed integer instead of an hex string for some reasons. Its been like that since GTI.
-
So, I've been digging in the executable for a while now, but I just can't find the pokemon IDs used in the starter selection screen.. I have no ideas why there are 7 of the 20 starters that have their model ID as literal in the bin, but none of the others do.. It also seems the game refers to a lot of data loaded at runtime at static memory addresses. There are a lot of fairly big 32bits pointers stored in the literal pools, and they don't point to sensible locations in the code bin most of the time.. So they have to point to places in memory.. But the only way to figure that would be with an emulator or debugger... At least AFAIK. Unless someone has some suggestion ? ^^; If the faces are grouped by pokemons in the face_graphic.bin file, its probably structured like the kaomado.kao files in EoS. Basically, the ID of the actor would the index in the face_graphic.bin file, if we consider that each entry is 16 to 32 portraits long. I don't know if the amount of portraits for each pokes is specified in the table of content though. I didn't really investigate that file much yet. But in EoS, the table of content was just a table made of entries containing 40 pointers, null pointers indicating missing portraits. Yeah, the decompiler interprets the string UUID as signed 32 bits integers. But originally they were probably just an hexadecimal literal. Or maybe even some kind of macro that got replaced by their buildscript. The decompiler doesn't seem to have an option to set how to interpret literals, but it might be possible to write a simple script to convert large decimal signed value to an hexadecimal string, and just mass replace them. But, I'm thinking that the devs didn't just place those hex strings by themselves, Some kind of automated reference handling system probably did the work for them. Btw, have you noticed that in all files ending in "_info.bin" there is a short 64 bytes table after the last entry ? I really wonder what its for, and how the game figures out its not just another entry.. Also, have you looked at pokemon_evolution.bin ? It seems to contain a lot of extra data on pokemmon evolutions and megas.
-
On my end, I can confirm that the starter menu is hard-coded. And the starter moves are most likely too. I can't find the literals for all starters for some reasons however, I changed the 7 I could find, and it only changed the 3d model of 7 of the starters, their stats and even the actual pokemon you get to play after the character select screen stays the same.. Here's what you see: [ATTACH=CONFIG]12804[/ATTACH] And what's displayed on the bottom screen: [ATTACH=CONFIG]12805[/ATTACH] Afterward it gave me the starter I was supposed to get, and not poochyena. For those interested, the 7 starters IDs I found and changed are located at 0x004F 1618 in the code.bin. There seems to be some ldr opcodes that refers to those literals a bit above. I was able to find them using radare2. But I really wonder where the rest of them are ? They're probably not stored as 4 bytes integers if they're in there.. Also, here are the starter pokemon IDs for those interested. (Its one of those big ugly if/else if statement in the scripts): if pokemonIndexHero == 30 then CH("PIKACHUU_H"):ResetFacialMotion() elseif pokemonIndexHero == 595 then CH("POKABU_H"):ResetFacialMotion() elseif pokemonIndexHero == 598 then CH("MIJUMARU_H"):ResetFacialMotion() elseif pokemonIndexHero == 592 then CH("TSUTAAJA_H"):ResetFacialMotion() elseif pokemonIndexHero == 1 then CH("FUSHIGIDANE_H"):ResetFacialMotion() elseif pokemonIndexHero == 5 then CH("HITOKAGE_H"):ResetFacialMotion() elseif pokemonIndexHero == 10 then CH("ZENIGAME_H"):ResetFacialMotion() elseif pokemonIndexHero == 197 then CH("CHIKORIITA_H"):ResetFacialMotion() elseif pokemonIndexHero == 200 then CH("HINOARASHI_H"):ResetFacialMotion() elseif pokemonIndexHero == 203 then CH("WANINOKO_H"):ResetFacialMotion() elseif pokemonIndexHero == 322 then CH("KIMORI_H"):ResetFacialMotion() elseif pokemonIndexHero == 325 then CH("ACHAMO_H"):ResetFacialMotion() elseif pokemonIndexHero == 329 then CH("MIZUGOROU_H"):ResetFacialMotion() elseif pokemonIndexHero == 479 then CH("NAETORU_H"):ResetFacialMotion() elseif pokemonIndexHero == 482 then CH("HIKOZARU_H"):ResetFacialMotion() elseif pokemonIndexHero == 485 then CH("POTCHAMA_H"):ResetFacialMotion() elseif pokemonIndexHero == 537 then CH("RIORU_H"):ResetFacialMotion() elseif pokemonIndexHero == 766 then CH("HARIMARON_H"):ResetFacialMotion() elseif pokemonIndexHero == 769 then CH("FOKKO_H"):ResetFacialMotion() elseif pokemonIndexHero == 772 then CH("KEROMATSU_H"):ResetFacialMotion() end 332 is poochyena btw for those wondering