New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to load EXFONT from file or RPG_RT.exe resource #605

Open
fdelapena opened this Issue Sep 28, 2015 · 20 comments

Comments

Projects
None yet
5 participants
@fdelapena
Copy link
Contributor

fdelapena commented Sep 28, 2015

EXFONT is an embedded bitmap resource containing symbols displayed with $a-$z and $A-$Z. Some games have this asset customized by patching the RPG_RT.exe file.

Because EasyRPG Player executable does not contain a windows resource based asset easy to change and needs to rebuild the source, several users asked for an alternate way to customize these icons.

@carstene1ns

This comment has been minimized.

Copy link
Member

carstene1ns commented Sep 29, 2015

In a forum thread it was suggested to read the RPG_RT.exe to check for applied patches. This is a major task, but it would make exfont detection and use simple, as we could strip the exfont from Player and just use whatever is present in RPG_RT.exe.
What I really do not like about this approach is that we need to rely on that binary too much, so it would be great to allow enabling everything the "exereader" does without having the RPG_RT.exe at all.
This comes to mind: bundling a rpg2k game with free assets together with the Player executable.
Some compatible patches could be enabled in RPG_RT.ini, for example the simple ones like disabling/skipping Title scene…

That said, reading the EXFONT.bmp from file if present is a good thing!

I am going to add an extractor script to Tools repository soon.

@Ghabry

This comment has been minimized.

Copy link
Member

Ghabry commented Sep 29, 2015

For patches (for old games at least) I was thinking about some type of database that was distributed with the Player and installed into the program directory. Which contains patches for all games and is regularly updated. To make this configuration-free for the user.

@carstene1ns

This comment has been minimized.

Copy link
Member

carstene1ns commented Sep 29, 2015

This would need some way to differentiate between different versions of games, i.e. compare the checksum of the RPG_RT.exe.
This would have the additional benefit that all games using the same patches and no custom resources would work ootb.
However, if we would like the Player to be a drop-in replacement for RPG_RT, adding them to ini is still an option, as you do not need to distribute anything in some shared directory.

@Ghabry

This comment has been minimized.

Copy link
Member

Ghabry commented Sep 29, 2015

Yeah the database and the local (in game directory) option format should be the same (and game config wins over db config).
But old games are unmaintained and we can't expect that there devs declare a config for us.

I would use a super simple heuristic for now: Take the game name from the RPG_RT.ini file. And then wait until people complain about strange bugs :P

@carstene1ns

This comment has been minimized.

Copy link
Member

carstene1ns commented Sep 29, 2015

Heh, good thing is we support a lot of patches without modifying anything yet. (MP3 and other music support?)
And there are some patches that have the same effect, but are implemented differently.
We can support them in one go. 😀.

@fdelapena

This comment has been minimized.

Copy link
Contributor Author

fdelapena commented Sep 29, 2015

(MP3 and other music support?)

MP3 is a built-in feature (no patches at all) in RPG Maker 2000 since 1.50 and 2003 since 1.05.
The MOD Music (Audieremony patch) is accidentally supported by SDL_mixer if built with libmodplug.

@carstene1ns

This comment has been minimized.

Copy link
Member

carstene1ns commented Sep 29, 2015

There was some mp3 patch at least for older versions.

@carstene1ns

This comment has been minimized.

Copy link
Member

carstene1ns commented Feb 6, 2016

FYI: As reported by mail today, Wadanohara uses a modified EXFONT, the skull glyph has been changed to a note.
exfonts

@Ghabry

This comment has been minimized.

Copy link
Member

Ghabry commented Feb 6, 2016

Just for convenience :D

⚔⛨✡☉🌙☿♀♁♂♃♄♅♆
♇♈♉♊♋♌♍♎♏♐♑♒♓
☺😐☹💧💦♤♡♢♧♠♥♦♣
☠♰☀☽●⇑⇒⇓⇐⇗⇘⇙⇖

unbenannt

@Ghabry

This comment has been minimized.

Copy link
Member

Ghabry commented Feb 6, 2016

So instead of using the embedded font, when using freetype it's also possible to simply fall back to an emoji font ^^

@carstene1ns

This comment has been minimized.

Copy link
Member

carstene1ns commented Feb 6, 2016

Yes, but this is totally not supporting custom exfonts whatsoever.

@Ghabry

This comment has been minimized.

Copy link
Member

Ghabry commented Feb 6, 2016

hmm, right :P. Sorry for being off-topic

@Ghabry

This comment has been minimized.

Copy link
Member

Ghabry commented Apr 1, 2017

Parser candidate: https://github.com/trailofbits/pe-parse

MIT, 5 files, 2500 LoC.

@Ghabry Ghabry changed the title Allow to load EXFONT from file Allow to load EXFONT from file or RPG_RT.exe resource Apr 1, 2017

@carstene1ns

This comment has been minimized.

Copy link
Member

carstene1ns commented Apr 1, 2017

Oh cool, they did drop boost already!
Have modified their dump prog some months ago. Still needs file saving, but worked quite well:

#include <iostream>
#include <sstream>
#include "parse.h"

using namespace std;
using namespace boost;
using namespace peparse;

int printRsrc(void *N, resource r)
{
  //somehow this does not work:
  //if ((r.name_str.compare("LOGO1") == 0) || (r.name_str.compare("EXFONT") == 0)) {
  if ((r.name == 0x80000d68) || (r.name == 0x80000e5a)) {
    if (r.type_str.length())
      cout << "Type (string): " << r.type_str << endl;
    else
      cout << "Type: 0x" << to_string<uint32_t>(r.type, hex) << endl;
    if (r.name_str.length())
      cout << "Name (string): " << r.name_str << endl;
    else
      cout << "Name: 0x" << to_string<uint32_t>(r.name, hex) << endl;
    cout << "Size: " << to_string<uint32_t>(r.size, dec) << endl << endl;

    // content is in `r.buf->buf` and can be saved to file directly...
  }

  return 0;
}

int main(int argc, char *argv[]) {
  if(argc == 2) {
    parsed_pe *p = ParsePEFromFile(argv[1]);

    if(p != NULL) {
      cout << "Resources: " << endl;
      IterRsrc(p, printRsrc, NULL);
      DestructParsedPE(p);
    } else {
      cout << "Error: " << GetPEErr() << " (" << GetPEErrString() << ")" << endl;
      cout << "Location: " << GetPEErrLoc() << endl;
    }
  }
  return 0;
}
@Ghabry

This comment has been minimized.

Copy link
Member

Ghabry commented Apr 1, 2017

I wasted 2 hours today to figure this out so maybe useful :D: For the bitmaps (EXFONT) you have to write a BITMAPFILEINFO header before writing because it's a packed DIB (device independent bitmap). Is like a normal bitmap but lacks the 14 byte header m( :

char type[14] = {0};
// Header magic BM
type[0] = 'B';
type[1] = 'M';
// Filesize
*(int*)(type+2) = r.buf->bufLen + 14;
// Offset to the pixel data by reading biSizeImage
*(int*)(type+10) = r.buf->bufLen - *(int*)(r.buf->buf+20) + 14;

// write these 14 bytes to a file, then the buffer

And about the String compare: The strings are actually utf-16 strings which means every 2nd char is a 0-byte because it's ASCII. So you can e.g. memcmp them against a UTF-16 string:

r.name_str.length() == 12 && !memcmp(u"EXFONT", r.name_str.c_str(), 12)
@DieKatzchen

This comment has been minimized.

Copy link

DieKatzchen commented Oct 2, 2017

Is there any progress on this? I really want too play Dragon Destiny on my Vita. Or if someone could point me to how to custom compile a version with the right glyphs, I've never cross compiled before.

@carstene1ns

This comment has been minimized.

Copy link
Member

carstene1ns commented May 5, 2018

@DieKatzchen: We have implemented part of this now: ExFont will be loaded from a dedicated file (exfont.bmp/png) from the game directory for now. This means you need to extract it yourself (which you already did, looking at your repository clone).
This change will be in the continuous build found on our download page for now (even for PSVita of course): https://easyrpg.org/player/downloads/

@DieKatzchen

This comment has been minimized.

Copy link

DieKatzchen commented May 18, 2018

Can confirm this works as intended on Vita.

@20kdc

This comment has been minimized.

Copy link
Contributor

20kdc commented Jun 23, 2018

Regarding theoreticals, which is better: Saving exfont.bmp if not already present, or just loading from RPG_RT.exe directly?
One of these is more awkward on read-only filesystems, but is still possible.

@Ghabry

This comment has been minimized.

Copy link
Member

Ghabry commented Jun 24, 2018

loading from RPG_RT.exe, creating exfont.bmp would be goal of another dumper tool, maybe you could add it to your editor :D.

Though we agreed on that parsing RPG_RT from Player is awkward in general, so we won't do it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment