hex007 / freej2me

A free J2ME emulator with libretro, awt and sdl2 frontends.
Other
484 stars 74 forks source link

MascotCapsule V3? #27

Open minexew opened 6 years ago

minexew commented 6 years ago

Hi, I didn't attempt to compile freej2me yet, but I'd like to ask if there is any support for the M3D API (used for example by Fishlab's Abyss engine -- Galaxy on Fire 1/2, Deep etc.)

If not, would you be interested in adding support? The docs and tools seem to have been recently pulled from the web, but I have most if not all backed up.

hex007 commented 6 years ago

Is this the same as M3G API for 3d graphics?

minexew commented 6 years ago

I have no clue about M3G, but MC3D is a proprietary API that resides in the com.mascotcapsule.micro3d.v3 package

recompileorg commented 6 years ago

Both mascotcapsule's micro3d (m3d) and m3g are stubbed out so that games that use either api will run. The problem, of course, is that you won't actually see any of the images those api's were intended to produce. A good example would be X-Men Origins: Wolverine, where the "loading" 3d claws that tear out of the display aren't visible, but the the game remains completely playable. On the opposite side, one of the Asphalt games (3?) leaves you racing in an invisible car, in a mostly invisible world, against invisible racers.

If you're interested, they're both pretty self-contained, so it you can do (almost) the complete implementation without worrying about the rest of the code base. It can also be worked-on over time, as you won't risk 'breaking' anything without a complete implementation.

If I had to make a recommendation, I'd say m3d is the one to implement. It's much smaller and simpler overall, even though most of the documentation has vanished. As you still have some of those old resources, you're in a great position. I have no doubt that your implementation would essentially become the standard reference for m3d going forward. That's to say nothing of the joy that you'll bring to those finally able to play some of their favorite old games.

Edit to add: As both API's are already stubbed-out, it's essentially a fill-in-the-blank implementation.

minexew commented 6 years ago

You're making it sound much simpler than it actually is :))

I agree that the API is mostly-self contained. While it does use some proprietary formats, due to all the resources available it shouldn't be too hard to read them.

For me the main issue is: how to implement the actual rendering? Writing a software renderer would be a lot of fun, but is probably undesirable. That leaves us with a choice among several Java GL libraries. I'm not really familiar with the ecosystem enough to determine the most suitable one.

Secondly, 3D rendering will need to be integrated with 2D drawing in the same Canvas. In the worst case, this will involve some blitting from 3D framebuffer to 2D memory. Probably not that big of an issue due to low resolutions used.

recompileorg commented 6 years ago

Writing a software renderer would be a lot of fun

If it's fun, I don't see why you shouldn't write one. It'll certainly be more interesting than trying to wrangle a Java GL library. Resolutions are low, after all, and modern hardware should be more than adequate for the task.

Secondly, 3D rendering will need to be integrated with 2D drawing in the same Canvas

The com.mascotcapsule.micro3d.v3.Graphics3D.bind gives m3d a Graphics object (javax.microedition.lcdui.Graphics) to use for drawing. Let the games worry about compositing as you can't, really, worry about it yourself.

You're making it sound much simpler than it actually is :))

But is pretty straight-forward! I've found that in, 3D graphics, people tend to stress over the math, which is almost a copy/paste job in this particular case. For the actual rendering, you'll find more than enough help in older graphics programming resources, with various techniques to draw filled/textured polygons with high-efficiency.

Really, the hard-part looks to be the model formats themselves, but you've go the resources you need to puzzle them out, so there's no reason to think it's going to be a difficult project. It looks like it'll be a lot of fun.

minexew commented 6 years ago

Fun indeed... as it turns out, there is zero documentation for the actual MBAC format. And the emulator JARs don't have it either, it's all done in native code.

IDA.png

jan-kleks commented 6 years ago

Well, I guess @nikita36078 's J2ME-Loader would benefit from the MascotCapsule support too. People kept asking him about MascotCapsule, so he had to put a notice that MascotCapsule support won't be available. :P

recompileorg commented 6 years ago

That certainly doesn't make it impossible. File formats have been reverse-engineered with little to no documentation before. I've even done a few myself. It's usually just a matter of time and patience. You already know what kind of data it needs to include, so it's just a matter of finding out how it's stored.

I'll take a look at it, see if I can get you started.

minexew commented 6 years ago

Don't bother. It would take you ages to figure out all the different bit packing modes they have.

But if you have IDA, I can send you the project and you can continue where I left off. I'm decompiling one of the SDK tools, which is in the screenshot above. I'm making progress, though it obviously takes time.

recompileorg commented 6 years ago

You can't really know until you try. I have no idea how long it would take, or if I can puzzle it out at all. I've worked out proprietary 3d formats before in a few hours, yet spent weeks failing to work out seemingly simple image formats. Stay positive!

As for IDA, I simply don't have the interest. I don't really like Java. I just wanted to play a few old games.

minexew commented 6 years ago

This has nothing to do with Java actually. It's just disassembly/decompilation of (native) MascotCapsule SDK tools that produce this obscure format, from a slightly-less-obscure text format.

The only other implementation of MBAC parsing/processing, that I know of, is in Sony Ericsson's version of WTK2. And guess what, that's also a native DLL.

In other words, there's likely no publicly available Java code for this thing. If there were any, I would've understood the format by now.

minexew commented 6 years ago

For anyone interested: https://github.com/minexew/MascotCapsule_Archaeology

minexew commented 6 years ago

Now we're talking.

recompileorg commented 6 years ago

Nice!

I'm guessing this means you've got a good bit of the format worked out? If so, can you share those details?

minexew commented 6 years ago

@recompileorg https://github.com/minexew/MascotCapsule_Archaeology/blob/master/Format_Descriptions/MBAC.md

recompileorg commented 6 years ago

Phenomenal.

vadosnaprimer commented 6 years ago

This is fantastic!!! Please keep up the unique work!

minexew commented 6 years ago

I have also contacted HI Corporation, who developed the API (apparently 15 years ago!). It is a long shot, but as they seem to have no more commercial interest in the MascotCapsule franchise, it would be great if they are able to provide us any old documentation, tools or even code.

Meanwhile I've updated the MBAC doc based on further RE work. It is fairly understood now, so I'll probably try to tackle MTRA next.

jan-kleks commented 6 years ago

@minexew You can also try to look for MascotCapsule programmers using LinkedIn, Facebook, Twitter, etc., and send them messages.

nikita36078 commented 6 years ago

@minexew So, did Hi Corp answer? Or maybe it's worth to contact them again :)

minexew commented 6 years ago

They did not.

And I haven't yet returned to the reverse engineering, either.

minexew commented 5 years ago

It's been a year, about time to look into this again. I believe my previous progress can be found in https://github.com/minexew/freej2me/tree/micro3d. It's not much, it lets GoF boot to menu, but doesn't render any 3D.

Update: I've started writing about the RE stuff here. I don't want to spam this issue too much.

minexew commented 5 years ago

@hex007 Did you write the Micro3D API stubs that are currently in freej2me master?

They all have a GPL3 license header, but I'd like to share my work under a more permissive license. Would it be OK to relicense them (probably as MIT), or do I have to throw them away?

hex007 commented 5 years ago

@recompileorg Would be better to guide you on this.

recompileorg commented 5 years ago

@minexew Sorry for the delay. It looks like I'm the only contributor there so far. I don't mind licensing those parts under a more permissive license, though it would be nice if your efforts also found there way back to the GPL licensed version as well.

The reason I opted for the GPL is to better serve the interests of the end user. Licenses like MIT and Apache are great for developers, but don't afford end users the same rights and guarantees.

minexew commented 5 years ago

I'm fine with dual licensing all of my work.

I definitely like the mission of GPL, but in practice, it has only brought me headache. Gotta admit, I probably do care more about the developers than about the end users.

hex007 commented 5 years ago

I am mostly busy with work and a game engine I am writing for Pico8. Apologies for not replying sooner.

recompileorg commented 4 years ago

Possibly helpful. The version of Super Real Tennis Kremlin Cup I have is not obfuscated and uses mascotcapsule v3.

minexew commented 4 years ago

Since my efforts haven't progressed since last year, and nobody else seems to have picked up on it either, it might be appropriate to at least document the tools I have built along the way.

Command Log Renderer

For a 3D rendering API, MascotCapsule v3 has a quite small API surface. This is great -- it lets us stub all the classes fairly quickly and make games at least execute. Much of the complexity that is not immediately obvious hides in Graphics3D's command list capability, and in the data formats.

To avoid having to start with writing a rasterizer from scratch, my first steps of implementing MC3D in freej2me were to record all draw calls and save them in a command log file, along with any necessary resources. The idea, greatly inspired by Dolphin's FIFO logs, was to create self-contained test cases that can be more easily analyzed (and rendered) using a stand-alone tool; in this case one written in Python and using opengl.

You can see a snippet from such command log below:

(Figure "44e2f324"
    (data "4d420500020203019600c00000000100000000000100010000...")
)
(Texture "2f06e8e7"
    (data "424d7824000000000000760000002800000060000000600000...")
)
(drawFigure
    (figure "44e2f324"
        (texture "2f06e8e7")
        (pattern 0)
        (actionTable "null")
        (postureAction 0)
        (postureFrame 0)
    )
    (x 0)
    (y 0)
    (layout
        (affineTrans 4086 -187 96 0 190 4082 -160 0 -88 165 4091 0)
        (projection "PERSPECTIVE_FOV")
        (center 120 160)
        (perspective 100 31767 800)
    )
    (effect
        (light "null")
        (shadingType "NORMAL_SHADING")
        (texture "null")
        (toonHigh 0)
        (toonLow 0)
        (toonThreshold 0)
        (transparency 0)
    )
)

Unfortunately, in practice it is not so straightforward to guarantee that the command list is correct in the first place. The MC3D API contains not only rendering functions, but also classes for math, vectors, matrices... If a wrong result is produced in one of those, the game might end up taking a wrong decision somewhere, and produce a nonsensical sequence of commands. In addition, some of the values in the command log, such as affine transforms, are results of calculations done by the games through the MC3D API, so any mistakes in our implementation can also propagate through there.

Ultimately, this led to the creation of a second tool.

Fuzzer / Black-box identification tool

Although we have full documentation of the Micro3D API, it doesn't bother to go into much detail about things like rounding rules and depth resolution. However, games do make assumptions about these, and if you violate them, things will break -- we are speaking about things like ensuring that sin^2(x) + cos^2(x) == 1.0 in the API's fixed-point format. Since we are fortunate enough to have the Sony Ericsson J2ME emulator which implements Micro3D (e.g. our black-box), we can compare behavior between the emulator and our re-implementation.

To this end, I made a J2ME program which takes a list of expressions, and evaluates them against the Micro3D API. Do not expect anything fancy, the input looks like this:

Util3D.sin 1234
Util3D.sin 2345
Util3D.cos 1234
...

and the output is another file including the results:

Util3D.sin 1234 9876
Util3D.sin 2345 8765
Util3D.cos 1234 5432
...

The point is: since it is a standard J2ME application, you can also run it in freej2me and compare the outputs.

The fuzzer can be found here.


I can't say if/when I will do more work on Micro3D emulation. I have some ideas that I would still like to explore, but the part where one has to actually write Java code has not been particularly entertaining. For the time, my latest freej2me code can be found here. I hope somebody finds this short write-up useful, or at least interesting. Of course the best outcome would be to inspire someone to the point of picking up on my work :)

nikita36078 commented 4 years ago

Well, I got it to work on J2ME Loader. The pre-made animations (ActionTable) are still unimplemented, and I still don't know how to properly implement the render queue with the z-sorting, but some games are playable right now. I'm not ready to publish the source code yet (mainly because of Google Play clones), but if someone wants to help, I can send it directly to them.

recompileorg commented 4 years ago

Thanks to Minexew's fuzzer and , I was able to correct a bunch of things.

@minexew I've also solved the mystery of Util3D.sqrt. You can probably also snag a lot from AffineTrans as I ported a good bit of that from known working code from some of my other projects. LookAt, for example, is probably an important one to have implemented. Thanks for all the work you've put in to this. I wouldn't doubt if we had this working before the month was out.

@nikita36078 Wow! You're well ahead of us here already! I'll try to catch up to you in the next week or two.

3dcinetv commented 1 month ago

Hi, I didn't attempt to compile freej2me yet, but I'd like to ask if there is any support for the M3D API (used for example by Fishlab's Abyss engine -- Galaxy on Fire 1/2, Deep etc.)

If not, would you be interested in adding support? The docs and tools seem to have been recently pulled from the web, but I have most if not all backed up.

I am interested in reading those documents. I've been trying to get information about the SonyEricsson Developer guidelines for Monster Capsule 3D in regards of importing .m3g models from Blender. I wrote an article, with my findings>>

Is it possible to download the Monster Capsule 3D game engine itself (or reading their PDF user manual) somewhere?