Spoiler tag

Tuesday, August 27, 2019

JSRF ModTool 2.5 - Model importer improvements + High resolution texture importing

Hey, here's an update for the tool, I have improved the model importing, fixed some bugs, and added support for a model type(player character head models) that are different from the common model setup.

Also it is now possible to import scaled up textures, meaning you can for instance edit a 512x512 texture, scale it up to 1024x1024 in the image editor, save, and then import with "Save changes" in the JSRF ModTool Texture Viewer tab, the tool will import with the texture with the new resolution.
This will be useful for some of you out there who want to re-create some of the UI textures which are quite pixelated and low resolution and could use an HD remake, looking forward to those mods.

The tool maximum texture resolution import is limited to 2048x2048, I haven't tested higher resolutions and really for JSRF you should stick to 1024 as the maximum anyways.

Looking forward to seeing some of your mods ;)

JSRF now playable in HD on PC with the cxbx-reloaded emulator

You can now play JSRF in high resolution with the emulator cxbx-reloaded




The emulator runs JSRF flawlessly, you might need a fairly powerful CPU and/or GPU to run it at a good frame-rate depending on the resolution you chose in the options "Settings > Config Video".

To run at higher resolutions set the "Display resolution" and "Render Resolution" to something higher than the default.


You can download the latest version of cxbx-reloaded by clicking on "Latest Development Build" in this page.

I of course own a DVD copy of the original JSRF game (and an original xbox) and so should you if you're going to play on the emulator, as I don't advocate piracy, you'll have to figure out on your own how to get the files of the game to run it on cxbx-reloaded.


You can support the development on cxbx-reloaded here on Patreon as while it may very well run JSRF, there's still lots of work to be done to get other xbox games running and the amazing developers could use our support.


We might not have gotten an official JSRF port, but we have this amazing emulator now, have fun!

Thursday, July 18, 2019

JSRF ModTool 2.4 - And character model importing

Hey there, here's the new version of the tool that can import models of the type named "MDLB" (characters and objects).




For learning the basics on how to use the tool, see this post and also this post

While its now possible to import models, keep in mind if you want to do so you will need to have some 3D modelling, uv mapping and rigging skills if you want to make a brand new character and import it.

Therefore this is not going to be a tutorial on how to do 3D modelling as that's a separate gigantic topic, you can find various 3D modelling apps and tutorials online, you might however be able to try doing simple edits on models like changing proportions of the body if you follow this example.



Three new buttons have been added to the top right of the model viewer to import/export models.
The JSRF ModTool will export and import models as .SMD model file format.


The "Collapse vertices" button will move all the model's points to the origin position (0 0 0) making the model invisible, this can be useful to hide parts of the original model such as the different facial expressions the game switches through as the character is animated.
If you don't want to bother making separate models for each facial expression, you can have the body and head model all contained in the first imported MDLB and then you could just make all the other original head models invisible by using the "Collapse vertices" button.


As for the tiny buttons "Expt." and "Impt." they let you export or import the selected item(block of data) as a binary file if you want to take a look with a hexadecimal editor to mod some particular data manually.



Anatomy of a JSRF character .dat file

Here's how playable character models are organized in the .dat file






                          Exporting a model

Just select an MDLB item and click "Extract MDL", it will let you select a folder where you want the model to be exported as .smd files, give it a name and click Save.

The tool also exports the lower level parts of the model which have to have the same naming as the main model so when importing the tool can find the lower parts of the model to import as well to rebuild the model properly.






Using Blender (2.79) to edit a model

Since the JSRF ModTool exports the models in .smd file format, for Blender you will need the Source Tools here  to import the model(s).
Installation instructions for the plugin are on this page

Once the plugin is installed and enabled you should be able to import .smd files by going into the menu File > Import > Source Engine



In this example I am going to make a small edit to the body of Beat, which I exported as "beat_body.smd"

First thing you'll notice is you need to rotate the model 90 degrees on the X axis.
Also note that the models comes inverted on the X axis, unfortunately I don't have the math/trigonometry etc knowledge and skills to code something so the JSRF Tool would sort these issues,luckily you won't need to turn it front 90 degrees again as the SMD exoprting tool can manage that for you.







Unfortunately with the SMD file format I haven't searched a way to have the models export with its texture(s), so you'll need to export them, select a texture and click "Edit texture", the texture will be extracted in the JSRF ModTool folder "resources\tmp"
Then assign the texture(s) manually in blender.


Made some edits to the model here:



Since I am barely familiar with blender, I just make some simple edits for demonstration, making his skates tubes ridiculously long and his shoulder spikes longer.

Once you are done with your edits, go to the top right panel where you see the list of the objects in the scene, right click on "beat_body_skeleton" and "Selected Hierarchy"







Blender and SMD export settings


Now before exporting we need to setup a few things in the Source Engine export panel.

Click on the  third button highlighted by the red circle, to display the
Source Engine export panel with which we can export the model back to SMD format.


Under "Source Engine Export" there's a few things to setup.

1-Set the export path, to the folder where you extracted the models (same folder where you extracted with the JSRF Tool)

2-Set the export format to SMD

3-Set the Target Up axis to Y


4-Now click the "Export" button, that's it!


Importing a model on the JSRF ModTool

Go back to the JSRf ModTool and with the original MDLB selected click  "Import MDL"
Select the first model on the list, in my case "beat_body.smd" and click Open.

This window should show up if there are no errors with the model files.
The lower level models (p_0 p_1 p_2) should be also loaded automatically if the naming is as on this example.



There are many settings here that you'll most likely never will need to modify but I am going to explain them anyways:

-Vertex definition size: size of the block of data defining a vertex(point) and other properties depending on the size, such as UV, Normals, sekeleton/bone ID,
bone deformation factor etc

-Global draw distance
: distance at which the model disappears (for performance optimization)




Materials

A JSRF player model usually has multiple materials/shaders that define the shading style.

Your model's materials groups should be named "mat_" and the corresponding number you want the material to be.

You can change the color and transparency of the material with the RGBA values, though this might depend on the type of "Material ID", this seems to be mostly used on models for the menus where they used a flat/solid color, and so the RGBA seems to work mainly on materials types dedicated to menu/UI models.


Material ID: this defines the type of shading for this material group (mat_0), there are many many more material IDs in other models that will show up as a number since I haven't researched them all to give them a name.

Float: this is an unknown parameter, it rarely changes, if you figure out what it does, don't hesitate to post in the comments.

You can remove materials by clicking the [x] box on the top right, and add materials from the button on the top right.



Importing

Now that all is setup click "Import", if everything about the model is properly setup it should import without giving any error messages.

Please note that JSRF models are limited to 2 deformers(bones) per vertex


There's the modified model imported, recompiled and ready for the game. 

And there it is ingame.


Some info and tips for full custom character mods

 You must keep the original bone hierarchy, modifying it or replacing it might cause animations to get messed up or even cause a crash.

If you're going to rig a different model, a new model, or ported mesh from some other game, note that you can move the bones around quite a bit(if the proportions differ from the JSRF's original character model) and the game engine will tolerate and will compensate for it anyways, so you can make a character shorter or taller moving bones around.

As you might notice, the exported character model's bones do not have a rotation, they are set to 0 0 0, it seems the rotation is completely dependent and applied by the animation data(which I haven't reverse engineered), some animations seem to be shared between characters and they all share the same or very similar rig(bone hierarchy and placement).



Well, I think that's more or less all there is to it, if you have any questions don't hesitate to ask in the comments.

Cheers

Tuesday, June 4, 2019

JSRF : model importing, custom character models now possible

Hey everyone, so I reverse engineered more of the model format and managed to code a model importer for JSRF (for characters and objects).

Here's some examples of custom player model imports:

 


I still have more work to do on the Mod Tool for model importing, I will post the tool as soon as its ready.

That's all for now, see ya!

Monday, November 12, 2018

JSRF Tool 2.3b and mods

Hello everyone, here's a new version of the JSRF tool which allows you to copy/past add/remove data blocks within a JSRF file, you can copy and paste model parts from one file to another, that is what I did for the player model swaps I showed earlier.

Note that this version of the tool isn't finished so many models in model viewer are displayed without textures, if you need to preview models you're better off with previous versions of the tool.






For how to use the tool, see this post and also this post

Regarding the new features, its mainly the ability to, add/remove copy/paste, insert, delete blocks of data within the JSRF file container structure.

For example you can select a model or texture from and click "copy", open a different file, select a texture and click "paste" to overwrite by whatever you copied earlier.


Also, here's some mods:

 That's all for now ;)
-neodos


Thursday, May 17, 2018

Tuesday, March 20, 2018

JSRF emulated at good framerate (minus sound) by Cxbx-Reloaded

This time its another app and its emulating the game at a good framerate and even high resolutions, though sound doesn't still work, it seems to run fairly well overall, aside from some visual glitches here and there and some rare crashes.

You can find the emulator (download under "Automated Builds") and the repo here

Support the developer on Patreon 

PS:don't bug the developers just about JSRF, they get enough of that already, their focus is on emulating as many games as possible first, so keep that in mind ;)


Monday, February 19, 2018

Character model swaps - rebuilding main file structure



So I have re-coded a core part of the JSRF Mod Tool, so it loads files differently and can now entirely re-build the base container structure of the files, allowing for adding, removing or resizing of blocks of data contained within the main structure.
And of course the first thing in mind to try was copying non-playable character models onto the player files annnnnd it works! (in most cases).

I still have to finish re-coding parts of the tool before release so it can handle different types of files.



The pedestrians models, unfortunately use a different bone structure than the player models, so the bones of the model won’t match with the original animation
…but we could say this is totally fine…
look at him go!
he’s got quite the moves!
like a smooth gentleman!


As if skating on the sidewalk in JSRF didn’t scare the pederastrians enough already, we’re getting on the levels of crazy taxi here:
 

Monday, March 20, 2017

How I reverse engineered JSRF file formats [Part 1]

Time for a retrospect on this adventure!

This is a long time coming, some people have asked over time how I went about reverse engineering the game Jet Set Radio Future file formats.
Well here it is and is it going to be lonnnnng, trying to keep it short but there is much to explain.

Note: the stuff in this post is probably very basic for experienced programmers, sorry might not be so interesting for you fellow devs ;)
I'll be skipping some details as its more aimed at the general public and the curious, for technical keywords I have embedded a link to articles more details on the subject if you want to know more.


Something around seven years ago I set out to reverse engineer some of the JSRF file formats, simply because I love the game and wanted to get a closer look at the game's artwork and its unique artstyle.





Videogames load things such as the 3D models and textures (images) from files.

While many file formats are standard and well documented, JSRF as most videogames, has its own custom game engine and its own custom set of file formats, which means we don't have any documentation on how to read/write those file formats, hence why we resort to reverse engineering them to read and extract the data we want, in this case we're looking for 3D models and textures(images).

Accessorily for me, this was also a good excuse to learn and practice programming, as for the life of me at the time I could hardly pickup a book on such a technical subject and do meaningless exercises to study this subject.
Instead, here was some real incentive, to learn and practice programming while having a real goal, real obstacles and a real reward if I get through the brick walls: reverse engineer the JSRF file format to get to extract and view the 3D models and textures.

I already had some beginner experience in reverse engineering game file formats from modding Halo: CE and Halo 2, writing some plugins, mapping "tag" (object type) file structures.
Modding Halo 2 taught me some basics about game engines, 'data types' and 'binary files', what a byte, an integer,  a float are, what an offset is, how data can be arranged in blocks and nested blocks within a file etc

What's the point of all this?

The main goal of this project was being able to get a closer look at the 3D models of the game, for instance character models, vehicles etc
In order to do that we'd need to figure out what model format the game uses, how data is structured within the different files and once we know that, code a program to do the file reading and extracting/converting data for us into standard readable formats.

In this first part, we'll focus on getting straight to the model data, without knowing the file structure at all, that's how I started with JSRF.

So for instance we would eventually be able to extract the models and textures to get a closer look at the game's character models as follows:

 

So how did I start reverse engineering JSRF?

-I didn't really have much of a clue where to start
-I was going to do it the dumb brute force way
-The only compiled programming language I roughly knew at the time was VB.net

Before I explain how I went about it, lets explain why I chose to do it the "dumb brute force way".

A computer program is created by using a programming language, in that form its human-readable and understandable, when the code is "compiled" it is converted to CPU language, so to speak, and the compiled code is written into a binary file (zeroes and ones) as an executable file (.exe) that the operative system will be able to open and load as a program.

Usually most file format or software reverse engineering is done by decompiling the program executable file and reading the program's CPU commands to figure out what the program is doing.


That would have been a much "easier" and better way to reverse engineer the file formats in the long run, and I mean in the long run because in my case I would have first needed to learn Assembly Machine Code(ASM), in order to be able to read and understand CPU code/commands.
Disassembling/Decompiling the Xbox executable (.xbe) file and by analyzing the program's long and twisted list of CPU commands/operations, we could figure out how the program reads the files and loads the data, easier said than done though.

For instance this is what ASM instructions (from a de-sasssembled executable file) look like:



What may be a line of code before compiling the program can turn into multiple or several dozens of lines of CPU instructions once compiled into an executable file.
The cherry on the cake, the Xbox CPU (a modified x86 Intel Pentium 3) has its very own set of custom CPU commands unique to the xbox which makes things a bit more complicated.


I knew reverse engineering the game's file format was going to take time, but learning ASM and being able to read and understanding xbox CPU commands was going to take me at least a year or two before I was even able to get remotely anything out of it.

Given the steep learning curve time required and me having no programming experience then, ASM was too daunting and unreasonable path for me to pick at the time, besides this was more of a hobby and my main study/work was focused on art and 3D modelling/animation/painting.

I have nothing but the utmost respect for people who know ASM, can read/write it and reverse engineer that way.
Maybe today I could learn it but its not something I would personally make use of often enough to justify learning and mastering such a complex skill.


And so, instead... I chose to reverse engineer things by brute-force, figuring out file structures by reading files manually, hex editor in one hand, notepad in the other, an eye for seeing patterns and puzzling things together!
Oh and patience for trial and error, a whole lot of that.... really.


What is binary data, hexadecimal etc?

Before we go into what and how I was reverse engineering, lets explain some basics of how computer files work.

Computers files are stored as a list of zeroes and ones, because that's how hard disk drives or flash memory, transistors etc work, they store and transfer zeroes and ones.

To get an idea how data is stored here is a visual representation of how the text word "Hello" is stored into a file (as binary) translates in different forms, from binary to hexadecimal to integers values to ASCII characters.

 

In green, the binary data, this is really how computer files are stored, a list of zeroes and ones, and that's how many 0s and 1s it takes to store the word Hello as ASCII text.

In this example we show that reading  0100 1000  which is 1 Byte (8 bits) of data, translates to   48  as Hexadecimal, which translates to   72   as an Integer number, which translates to the character H, given that in the ASCII character table the number   72   corresponds to the the capital letter "H".

So for instance a classic text editor as notepad, will open a file and try to read the binary data as list of integer numbers and then display the corresponding characters based on the ASCII character table.

At its core the data is always stored as binary but it can be translated into Hexadecimal, especially for debugging or reverse engineering, hex is easier to read than a long list of seemingly random zeroes and ones.

This Hello example is pretty basic and there are many other forms to encode and read the data (integers, decimals, boolean, text etc) and any programmer can come up with their very own format and way to store any type of data.

Now that you have an idea of what a computer file is like, lets get to reading the data! :)


What/Where to start looking for?

I decided to start by looking for 3D model (polygon mesh) data, and try to visualize it, or at least part of it as 3D points.

When starting I of course had strictly no clue how the JSRF files are structured nor what type of data exactly they contain, so I wasn't even sure what files might contain model data or even if they did, if the model data would be interpret-able as well known standard formats, most games have their own formats.

Doesn't matter though! 
I just wanted to first make sure that the files contained readable 3D models and confirm that "I was onto something" for starters. So I chose a few files which I thought might contain models, based on how they were named.

THE Hex Editor
In order to read the data of a (binary) file, I used a program/tool known as a Hex Editor.
This tool reads and displays the binary file data as hexadecimal code, as well as text, it also lets us modify the files.
The hex editor also serves to "translate" how the data can read, we can select part of the data and it displays how it would read as different types of values (i.e: integer, decimal, text/string etc), in the "Data Inspector" panel on the right.



So what kind of data type are we looking for 3D models?

We're first going to look for 3D points data, because its easy to recognize as generally most 3D models are stored as lists of 3D points and triangles definitions(how the points are connected to form edges/triangles).

Luckily, JSRF files don't have any form of data compression nor encryption as some more modern games can have, so the data is "raw" and quite accessible, otherwise I would have first needed to reverse engineer the executable file and reading CPU instructions.

Anyways, generally a 3D point is stored as a '3D Vector', that means 3 floats: X, Y, Z, that is as three values of the type "float", one for each axis (X,Y,Z) to define the position of a point in a 3D space.

So I opened up JSRF files in a hex editor where I thought (based on the file name) models would be stored, looking for data patterns that looked like lists of floats.

This is what scrolling through the start of a JSRF file binary file looks like in a hex editor:



This is what the different columns represent:



The left column represents the "offsets" a list of positions/address in the file for each line start, in this case we have 16 bytes (0 to 15) of data displayed per line, so the offsets on the left are incremented by +16 for each line.

The central column displays the binary file data, Binary (ones and zeros) read as Hexadecimal.
We usually count and work with "Base 10" (0123456789) but for computers, we translate binary "Base 2": zeros and ones into in "Base 16" aka hexadecimal (From 0 to 16: 0123456789 ABCDEF).

The right column represents the binary data read as text, it can be useful to find actual text data, but also helps noticing patterns of the binary data, for the most part it doesn't make any sense because its binary data (not text).


In the central column, we can change the amount of bytes we want to display per line, by doing this, in some cases, we can more easily spot structured data and its patterns, illustrated as follows:

So I went through files looking for patterns and lists of floats and found this section.
We can expect structures, because in programming we tend to organize data in structures or lists that have items of a fixed size.

You'll notice there clearly is a pattern when I set the number of collumns to 23:


Its actually 24 bytes being displayed per row, the way computer memory is defined and with most programming languages, for lists of objects/data the first object's identifier or starting position is defined as starting from 0 rather than 1.


How to read the data and what does it mean?

Notice the selection in black in the previous image, I have selected 4 bytes of data, a float is encoded with 4 bytes of data.

Once selected the Hex Editor has another panel where it reads the selection as various types of data of the selected length or less.

On the left, we have the list of "types" of data, on the right what the data reads as.


int8 type is a signed integer, its stored as 1 byte of data, it can store an integer number that can go from -128 to 127.

int16 type is a signed integer, its stored as 2 byte of data it can store an integer number that can go from -32 768 to 32 767.

uint For the other "int" starting by "u", it means unsigned, has no sign, which means it can only be a positive number, this allows to have a larger range.

uint8 is stored as 1 byte but can have a value from 0 to 255, in other words its always positive.

 
float type can store a decimal number, it is stored in 4 bytes and its value can range from -3.4E+38 to +3.4E+38 (E for exponent, its quite long).

Note: the E stands for Exponent notation, for instance 6E-06 would equal to 0.000006, the exponent notation is just a shorter way to represent the float.

You can find more information about data types here.
 
You get the idea, this is how different types of values can be stored in computer file formats, in memory and programming in general.

So the 4 bytes I have selected (40 BE 5B 41) read as -13.73395 as a float, this seems like quite a plausible float number.
If I read the next 4 bytes (70 F8 9B C1) it also gives a plausible float: -19.49631 and so on more floats for the next 4 bytes etc

I didn't select these 4 Bytes for no reason in particular, notice the pattern changes before the black selection:

Well, in red its mostly empty data, but there is clearly a pattern and structure.

Here for every line, we have 24 bytes displayed for which we find a similar pattern that starts with 4 bytes being 00 00 00 00, then 00 00 80 BF, and the 16 other bytes are for the most part different for each line.

If we read every 4 bytes of the first line as floats, this is what the data looks like:


This does look like it could be float data, as the numbers aren't too high nor too low, generally if we tried to read data that was an Int as a float we could get a very large or small number for a float such as 1.1204101e-038, generally we would expect float numbers to only have a few decimals after the comma, not 38 decimals after the comma, that's one way to determine that the data at that position most likely isn't a float.


So at this point we've established there is a pattern and this is a list of floats, we're looking for 3D point positions, so XYZ floats.

 
Lets take the first 15 lines of hex code and read them as floats, as seen in black text.
Note for the sake of readability I arranged the hex bytes in groups of 4 bytes. 



Ok so now that we have a block of data that looks more or less like a list of floats that could be 3D points , we want to visualize these floats as 3D points to see if it looks like anything coherent and that is seen in the game.

As I said earlier a 3D point is described by 3 floats:
X Y Z, but here we have a pattern of 24 bytes per line, or 24/4 = 6, so that's 6 floats per line, where as a 3D point is described by 3 floats.

So which part of that is the actual point data? is it a sequence of
XYZ XYZ in a single line?

Lets find out!  by importing the list of floats as 3D points into a 3D application which can display these points in 3D in space.

You might have noticed I colored
XYZ, that's because its the color codes used for each axis in geometry and most 3D applications use this color scheme too.



So for starters, let's try to import the floats list as a linear sequence of floats XYZ
XYZ ... etc
We read the entire listas follows, though I only listed the first three lines of data to keep it short:

So we're going to import the points in this order:
Point 0: (0, 0, 13.73395)
Point 1: (-19.49631, 0.203655, -1E-06)
Point 2:(0, -1, 13.88524)
Point 3:(-19.4553, 0.203655, -1E-06)
Point 4:(0, -1, 13.62626)
Point 5:(-19.60399, 0.203655, -1E-06) 
... (and +44  other points)

And this is what we get:

Hmmm.. so it doesn't look like much, definitely nothing coherent as most of the points align either in the X or Z axis, this doesn't make any sense :(

What now? 
Well, remember we figured there's a structure and a pattern of 24 bytes repeating, what if those 24 bytes (6 floats) have only one 3D point and the rest of the floats are another type of data?

I figured that would make more sense, as the first 2 floats are always 0 or -1, that didn't make much sense for the points to have different positions you would expect at least 2 or 3 of the floats to have quite different or at least opposite values as the third and fourth do.

So lets then try to only read one 3D point from a single line as follows:

We already tried reading XYZ starting from position 0 (and it looked like nothing) so instead we try reading starting from the second float (so from the byte position = 4)

We get this:


Hey! now that looks like, something, lets get a closer look:


Now we definitely seem to finally be onto something.


The file from which I got this float data is under the path and file name Media\Disp\map\Stg00.dat 
I guessed Disp probably stands for "display" and might be related to the game's UI.

I wasn't quite sure what this could be at first, so I searched more float lists in the same file and imported more 3D points.

And sure enough! those are the icon models from one of the game's menu as seen in the youtube video screenshot of the game's menu below:



Pssshhht! little secret, actually the proper position to read XYZ is this:

Starting at offset 8 and not 4, the model is no longer flipped and we get the correct Z value too.

Now you might be wondering, so what's the rest of the data ??? 
At the time I guessed probably more 3D model data, but lets not over complicate things, for now we don't need it.

Getting the triangle data

So far we have the 3D points aka vertices, but as you can see from the menu:

These icons have more details to them, they have colors and separate shapes, so what are we still missing?

Triangles! that's how 3D polygonal meshes work in computer graphics, points connect to one another to form edges, that form triangles - the facets we'll be able to see.

At the time I had to learn about 3D models, how are the triangle faces stored and defined?
Most game engines use triangles to represent 3D models as that is how graphics cards work, with triangles, which are composed of, points(vertices) and edges.

The triangles are defined by a list of indices(number of the vertices) for how the points are connected to form edges that compose one or multiple triangles.

Vertex indices are just integer numbers, so the first point (0, 013.73395) will be referenced as "0" in the triangle list, second point as "1" etc

Back to the hex editor

So let's get back to the hex editor and look for something that looks like a list of integers, the most logical place to look for that would be before or right after the float list we initially found.
But to keep this short, I'll skip ahead, I know the triangle data is after the floats list.

Here we have the end of the floats list, so the 3D points (encapsulated in the green outline)

And after it, you might notice this pattern 

Not that it means anything in ASCII text, but it helps us notice and differentiate a change in pattern or type of data.

so lets try to read the hex data of this section:

At first we see a bunch of 000000 zeroes, but then, 01... 02...02..01...03..03..01..04...01...05...06...06
So first thing that comes in mind is, incrementing numbers, but there's a bunch of zeroes between them, so lets try to read this as intergers with the hex editor.

So we try reading as Int16, that is a integer encoded in 2 bytes of data:


0000 (hex) = 0   (Int16)
0100 (hex) = 1   (Int16)
0200 (hex) = 2   (Int16)
0300 (hex) = 3   (Int16)
0900 (hex) = 3   (Int16)
0A00 (hex) = 10 (Int16)
0B00 (hex) = 11 (Int16)
0C00 (hex) = 12 (Int16)
...

So, pretty sure these are indeed Int16, if we read the data as Int16

So what does that look like if I select a few bytes and read it as integers?
It looks like a list of: 0 1 2 2 1 3 3 1 4 4 1 5 5 1 6 6...

Here's the whole block, I chose to start and stop at these specific locations because you can clearly see it starts and ends with a lot of zeroes, this is usually called "padding" in file structures and in many cases it helps us recognize when a section of data starts and ends.



Once again for the sake of ease of readability  I have here paired the hex code as groups of 2 bytes (the size of an Int16).

So as you can see, the numbers increase but it goes back to lower numbers sometimes.
It starts by 0 1 2, then follows by 2 1 3, these are most likely triangle definitions, because we cannot find the same number for every 3 int16.

A triangle definition of a polygon mesh references to the vertex(Point) number and defines in what order to connect vertices, to form the triangles.

Clearly though, the start being several zeroes, that's not exactly the start of the triangle list, it starts at the fifth 0, which the 8th byte, right before 1.

The highest number we get is 50, this would mean that the model has 51 vertices(points), enumerated 0 to 50.

Remember the floats list? 


We figured there's 24 bytes per line, a line has a definition for a vertex aka 3D point (XYZ) floats.

How many lines are there?
Notice I have highlighted the position in yellow: 00043512  to 00044712
So 44712 - 43512 = 1200 bytes

1200 / 24 = 50 lines, that is 50 vertices.

So we have 50 vertices, and the data we think is the triangle definitions has values up to 50, actually 51 if we count the one starting at 0, seems it is what we think it is.
It all comes together now :)

So now that we have the full lists of 3D points aka vertices and the list of triangle definitions, we import the vertices list and the triangle definitions into a 3D program, I was using good old Softimage at the time.

I won't go into details of how this works, basically I just coded a little script that would read the JSRF binary file, then created an empty mesh in the 3d program, then feed it the vertices list (floats for the points positions) and also the triangle definitions, the list of integers for each triangle.
And the 3D program would then display the 3D mesh object.


And this is what we get tadaaaaaaaa:



I manually added the colors so its more readable and as ingame:

The mesh with the vertices (red) and the edges/triangles in yellow:



An animation showing the order in which triangles are built:



Okay, the animation is just for the kicks, the modelling software can import and display the model in milliseconds of course :)

There's the other vertices/triangles list I manually extracted and imported:

Perfectly extracted as on the game's menu :D



I picked these menu meshes as an example because they are fairly simple and smaller models in terms of amounts of data, its easier to present/explain, but it really was one of the first meshes I stumbled upon and used to test reading/importing because of its simplicity.

Of course, this lead to extracting much more interesting 3D meshes such as characters, vehicles etc






But those models are somewhat different and more complex and I extracted later after figuring out more of the file structures, which we'll see in Part 2.



This concludes Part 1, that was the easy part, we were just trying to get raw polygon mesh data and importing it into a 3D software to view it to see if it really existed in the JSRF files and was readable as common 3D meshes.

The game has hundreds of files, and within each file there can be dozens or hundreds of 3D meshes, so searching for lists of floats and triangles definitions as explained in this post is not a solution, this was simply a means to getting started and making sure there was readable 3D polygon mesh data.

In Part 2, we'll get to the real puzzle, the next step is being able to understand the general file structure, to know where a block of data starts and ends within the file, how many models the file contains etc
Then to understand the model's file structure to be sure where the vertices list starts and ends, same for triangles etc


Anyways, that's it for now!
If you've gotten this far, bravo! I tried to keep it short, but its not my strongest suit... and I guess this techy stuff is not the most interesting to some so I tired to have some images to make it more bearable.

Feel free to ask questions and/or leave feedback, not sure if I over-explained things or missed on some things, let me know! :)