Welcome, Guest!

Here are some links you may find helpful

Tennarit279

Member
Sep 27, 2020
5
2
3
Thank you for making this release possible, everyone.

This has been something of a holy grail for me, and it was super neat to try it out. It really made me wonder what it would have been like if they had a few more months, but who knows, maybe if we're lucky some later builds may surface. It'd be fun to see how the Tim Curry looking character handled!

That aside, I enjoy reverse engineering stuff, so I wrote a script to dump the assets. It's super fascinating to see what they put together. For those curious here's some initial observations:

A lot of the game appears scriptable in plain text, including AI. Entities are also composed in a component style model in plain text, and adding new ones seems easy enough. Levels are entirely described in plain text, including entity placement and lighting data. Level geometry is in binary, however, and is referenced in these level scripts. In fact, everything seems to be oriented around the concept of a 'level', very much like how a scene works in Unity and such. Overall, it's a super modern impression that I got from this well over 20 year old prototype! Some examples

Item definitions:
Code:
ITEM_DEF
UNK_ECandle_tallstand_candle
tallstand_candle
NULL
NULL
1
0 0 0 0
NULL

ITEM_DEF
ECandle_s2_01_Lght_item_glow01
tallstand_candle_glow
NULL
tallstand_candle_glow
1
1 0 0 0
s2_01_Lght_item_01

Animation sets:
Code:
ANIMSET_DEF
E06_GhostCardinalAnimSet
5
E06_GhstCardinal_Death
E06_GhstCardinal_Get_Hit
E06_GhstCardinal_Move
E06_GhstCardinal_Shield
E06_GhstCardinal_Strike

ANIMSET_DEF
E02_GhostAnimSet
2
E02_Ghost_Die_Blue
E02_Ghost_Float_Blue

Entity placements:
Code:
ENTITY_DEF
RigidModel
s2_01
0
2
0
-2174.27
-2167.98
3.0305
0
0
0

ENTITY_DEF
Actor
Sonia
0
3
0
-3094
-1445.29
68
0
0
90

ENTITY_DEF
Emitter
Ghost_Cardinal_Dist500_Max1
0
4
1
-1692.35
-2385.17
21.646
0
0
-135

Note that the entity placements reference level geometry with the RigidModel tag.

AI script:
Code:
AI_DEF
Attack_FarRangeCorkscrew
TurnTowardTarget    0.0
FlyForwardUpLeft    50.0
FlyLeft                50.0
FlyForwardDownLeft    50.0
FlyDown                50.0
FlyForwardDownRight    50.0
FlyRight            50.0
FlyForwardUpRight    50.0
FlyUp                50.0
TurnTowardTarget    0.0
FlyTowardTarget        0.0
FlyForward            75.0
FlyUp                50.0
AI_ENDDEF

AI_DEF
Attack_FarRangeSawtooth
TurnTowardTarget    0.0
FlyForward            75.0
FlyUp                75.0
FlyForward            75.0
FlyDown                75.0
FlyForward            75.0
FlyUp                75.0
FlyForward            75.0
FlyDown                75.0
FlyForward            75.0
AI_ENDDEF

AI_DEF
Spawn_MedusaHeadRise
FlyUp                75.0
TurnTowardTarget    0.0
Death2                0.0
TurnTowardTarget    0.0
TurnRight            22.5
TurnLeft            45.0
TurnRight            45.0
TurnLeft            45.0
TurnRight            45.0
TurnLeft            45.0
TurnRight            45.0
TurnLeft            45.0
TurnRight            45.0
TurnLeft            22.5
Taunt                0.0
FlyDown                25.0
AI_ENDDEF

AI_DEF
Dying_DefaultRotInHell
Death1                0.0
Wait                5.0
AI_ENDDEF

The AI script reminded me the original Quake, where AI routines were built up on small, generic atomic actions, but in form it reminded me more of Half Life, which regimented the Quake style into a more data-oriented style. See here for a comparison! It's not really surprising though, the game programmer world is pretty small. As an aside, if you've ever read DeLoura's book you've probably noticed the castlevania team really took it to heart!

Another fun curiosity is this script file for a font tool they were using, which was left on disk:

Code:
/* Font database. */
/* setdir: set the path for font textures for subsequent fonts */
    DIRSYS #basepath, (#subpath1, #subpath2, ... ) - set path from dirpaths.txt */
/*      DIRPATH #fullPath - set path directly; path must be a string (i.e. enclosed in double quotes, with '\' at end) */
/* type: 0 - fixed width, 1 - proportional */

fontname Heading_White
type 1
asciirange 32 126
texturesize 256
numtextures 1
celldimension 21 17
texturefiles heading_white.pvr
sp 8
. 5
0 12
1 10
2 12
3 12
4 13
5 13
6 12
7 12
8 12
9 12
A 16
B 15
C 15
D 15
E 13
F 12
G 16
H 14
I 5
J 12
K 15
L 13
M 17
N 14
O 16
P 13
Q 17
R 15
S 14
T 13
U 14
V 16
W 21
X 15
Y 14
Z 14
a 14
b 13
c 13
d 13
e 12
f 11
g 14
h 12
i 6
j 10
k 13
l 11
m 14
n 12
o 14
p 12
q 15
r 13
s 12
t 12
u 12
v 14
w 19
x 13
y 13
z 12
end

The actual file is quite a bit larger, but all follows this same format

It's likely that all these files would have been converted into some binary form for production, but imagine how cool it would have been if the game had shipped with this system intact? we could have a very modifiable castlevania!

Moving on, there are no major surprises on disk from what I can tell. The other character is not present in any form, and some of the creatures seen in other screenshots are not here either. No extra levels seem to be left on disk either. It's unfortunate, but then again, we're very fortunate to have just this release as is! There are some neat trivia about the assets though:

All textures are 16 bit, encoded in either ARGB1555, ARGB4444 or RGB565 format. Larger textures use the VQ encoding, while smaller ones are just morton coded. None use the bump map format, though there are two textures, 'b_brick_01_bump' and 'b_brick_01_bump' which appear to be meant to be, and may possibly be used, as bump maps. Sonia is a single 512x512 texture, as well as Medusa and the Evil Cleric characters. Lesser ones are 256x256. Environmental textures run the gamut. Animated effects like the candle flames have each frame of animation stored in separate images, which are then referenced in a binary file that appears to describe the animation. The script dumps these into png format, in case anyone is wondering, and I've attached a few for those interested in art appreciation.

Characters all use skeletal animation. The skeletal hierarchies are described in separate binary files from the meshes. I'm unsure of the exact number of vertex weights at the moment, but it's likely to be a limit of one per vertex. If I have time I'll get the script to dump the assets in gltf so people can play around with them in Unity or whatever. The script itself should be available soon for anyone else interested in diving into the guts of this.

That's about it for now. Thanks again to everyone involved in getting this released. It's been a lot of fun!
Thanks for the info! I was wondering if there might be some leftover data on the disc.
 
  • Like
Reactions: MKKhanzo

Sifting

Well-known member
Registered
Aug 23, 2019
63
168
33
Okay, I've cleaned up the script for any one else who wishes to use it. it may be found here. I hope it helps in some small way. It requires python3 and pypng to work; run it with -h to see the help text, but really you just need to pass the .bin files to the script and it should do The Right Thing, but your mileage may vary as always.

Over the next few days I intend to document the file formats, and if anyone's interested, I'll publish that stuff too.

For the astute, you may have noticed there are no audio files. I believe they are stored in the .MLT file, but has a different structure so there's no way to pull anything out at the moment, or at least as far as I know. There's not really a lot of audio in the prototype though, so it's kind of a low priority for me.

Here's hoping someone finds a secret or two lurking on disk
 

Sega Dreamcast Info

Well-known member
Registered
May 30, 2019
186
844
93
Okay, I've cleaned up the script for any one else who wishes to use it. it may be found here. I hope it helps in some small way. It requires python3 and pypng to work; run it with -h to see the help text, but really you just need to pass the .bin files to the script and it should do The Right Thing, but your mileage may vary as always.

Over the next few days I intend to document the file formats, and if anyone's interested, I'll publish that stuff too.

For the astute, you may have noticed there are no audio files. I believe they are stored in the .MLT file, but has a different structure so there's no way to pull anything out at the moment, or at least as far as I know. There's not really a lot of audio in the prototype though, so it's kind of a low priority for me.

Here's hoping someone finds a secret or two lurking on disk
nice work

It is possible to contact me privately, I cannot do it. I have other questions for you on other matters.
 

Sifting

Well-known member
Registered
Aug 23, 2019
63
168
33
I have the skeleton files part way figured out. these can be found in the ssk directory that the script generates. For the most part they're pretty straight forward, but I've hit a bit of a snag with them. While the hierarchy was easy to figure out, the exact way it stores the bone transform(s) is kind of bizarre. I've worked with stranger stuff before though, so we'll see how it goes. For the technically inclined people, the problem is this:

typically each bone in a skeleton has a transform matrix used to deform the vertices that are assigned to it. this usually takes the form of one of the following:

1. A 4x4 transform matrix (16 floats)
2. A 3x4 transform matrix (12 floats)
3. A versor and a vector (7 floats)
4. Euler angles and a vector (6 floats)

Sometimes there may be an extra value for scale (1-3 floats), but this is uncommon.

But here though, we have 21 floats worth of information, and none of it seems to fit any of the above patterns. It's quite a puzzle, so I decided to look at the .scf files, which is where character geometry is stored, and as far as I can tell, they are the same format as the .smf files used for static geometry, perhaps with some extra fields to weight vertices to their skeletons. This is good news, since it means once one format is known, then we know the other. More interesting, it appears that vectors may be stored as 4D, with an extra 1.0 padding the end, which makes them homogeneous. This is all subject to change though.

I've also loaded the code into ghidra to help get some more insight. I'd kill for IDA, but the free version does not support super H, unfortunately, but I digress. I poked around for some strings and found some fun things to share:


0008f374"%s.bin"
000a10c8"%s.scf"
000c7100"%s.smt"
000a10d0"%s.ssk"
000a10d8"%s.ssn"

This appears to confirm some of the file extensions, which are not encoded in the .bin files.


0007bc40"%s_actors.txt"
000af0c8"%s_AIDefs.txt"
0006cc70"%s_animsets.txt"
0008f37c"%s_e"
000dfdc8"%s_emitters.txt"
00078320"%s_entities.txt"
0007c3e4"%s_fountain.txt"
0007bc50"%s_items.txt"
0007c3f4"%s_lightning"
00087c28"%s_lightsets.txt"
00078330"%s_nibillboards."

The engine seems to organise around the concept of a 'level', this appears to be broadly similar to a 'scene' in Unity or UDK. A level is composed of multiple text files, and these strings appear to confirm the naming scheme for them. Upon loading a level, the engine will look for the above text files and load their contents to produce the level. the %s is a place holder for a level name. These files may be found in the ramdisk directory, where there are ones like s2_01_items.txt, s2_01_lightsets.txt and so on. It appears not all files have to be present, as many levels are lacking a _fountain.txt.


00074ba8".\\\\DC5\\\\SOURCE/filesys.c"
0007137c".\\\\DC5\\\\SOURCE/kc_file.c"
00074c08".\\\\DC5\\\\SOURCE/kc_kmtexturesys.c"
00071524".\\\\DC5\\\\SOURCE/kc_xfstk.ic"
0007155c".\\\\DC5\\\\SOURCE/smfrdr.c"
00067da4".\\\\DREAMCAST/dcinit.c"
00068dd8".\\\\SOURCE/ActorSys.c"
00070e70".\\\\SOURCE/AISys.c"
000689f4".\\\\SOURCE/Alarm.c"
00070724".\\\\SOURCE/AnimUtil.c"
00074c38".\\\\SOURCE/basetracksys.c"
00070158".\\\\SOURCE/BSpline.c"
00071a0c".\\\\SOURCE/canimsys.c"
00074c90".\\\\SOURCE/canimtrk.c"
00073f0c".\\\\SOURCE/cmesh.c"
00071618".\\\\SOURCE/cmodelsys.c"
0007274c".\\\\SOURCE/CollSrvr.c"
0007166c".\\\\SOURCE/cskelsys.c"
0007168c".\\\\SOURCE/cskinsys.c"
00071ba4".\\\\SOURCE/database.c"
00074ce4".\\\\SOURCE/dirsys.c"
00068a34".\\\\SOURCE/EmitSys.c"
00068960".\\\\SOURCE/Entity.c"
00071730".\\\\SOURCE/fontsys.c"
00069dd4".\\\\SOURCE/FountainSys.c"
00074140".\\\\SOURCE/gameloader.c"
00067f64".\\\\SOURCE/GMain.c"
00069d34".\\\\SOURCE/ItemSys.c"
00074c54".\\\\SOURCE/kc_cam.c"
00074c68".\\\\SOURCE/kc_light.c"
00071ee0".\\\\SOURCE/kc_pool.c"
000716c0".\\\\SOURCE/kc_vbuf.c"
00071700".\\\\SOURCE/kc_view.c"
00069f50".\\\\SOURCE/LightningSys.c"
0006a060".\\\\SOURCE/lightset.c"
000718e0".\\\\SOURCE/lightsys.c"
0007416c".\\\\SOURCE/msgsys.c"
000701c0".\\\\SOURCE/NIBillboardSys.c"
00074d54".\\\\SOURCE/nmempool.c"
00074414".\\\\SOURCE/partsrvr.c"
00072128".\\\\SOURCE/pdfsys.c"
000680dc".\\\\SOURCE/Scene.c"
00071fbc".\\\\SOURCE/set.c"
00074cac".\\\\SOURCE/smf.c"
00071b38".\\\\SOURCE/smfsys.c"
00071b68".\\\\SOURCE/smfuser.c"
00071b04".\\\\SOURCE/smt.c"
0006e330".\\\\SOURCE/sndutls.c"
00074cc0".\\\\SOURCE/ssk.c"
00074cd4".\\\\SOURCE/ssn.c"
0007502c".\\\\SOURCE/stacksys.c"
0006e9a8".\\\\SOURCE/stream.c"
00068140".\\\\SOURCE/StrReg.c"
00074da0".\\\\SOURCE/strutil.c"
00074228".\\\\SOURCE/sttmachn.c"
0007194c".\\\\SOURCE/texturesys.c"
00074e2c".\\\\SOURCE/tuningsys.c"
00073eb8".\\\\SOURCE/Zone.c"
00068d14".\\\\SOURCE\\OBJECTS/Actor.c"
000704c8".\\\\SOURCE\\OBJECTS/BookOfProtection.c"
000690c4".\\\\SOURCE\\OBJECTS/camera.c"
00070610".\\\\SOURCE\\OBJECTS/Clock.c"
0006c998".\\\\SOURCE\\OBJECTS/E00_Skeleton.c"
0006ca44".\\\\SOURCE\\OBJECTS/E02_BlueGhost.c"
0006cbf0".\\\\SOURCE\\OBJECTS/E05_BoneSkeleton.c"
0006cd0c".\\\\SOURCE\\OBJECTS/E06_GhostCardinal.c"
0006cf18".\\\\SOURCE\\OBJECTS/E07_EvilCleric.c"
0006d064".\\\\SOURCE\\OBJECTS/E07_EvilClericCrystal.c"
0006d158".\\\\SOURCE\\OBJECTS/E33_Bat.c"
0006d24c".\\\\SOURCE\\OBJECTS/E43_SkullPillar.c"
0006d2ac".\\\\SOURCE\\OBJECTS/E43S_Fireball.c"
0006d674".\\\\SOURCE\\OBJECTS/E70_Medusa.c"
0006da60".\\\\SOURCE\\OBJECTS/E70_MedusaHead.c"
0006dc18".\\\\SOURCE\\OBJECTS/E70_MedusaSpit.c"
000709c0".\\\\SOURCE\\OBJECTS/EmitterCandle.c"
00070814".\\\\SOURCE\\OBJECTS/HolyWater.c"
0006984c".\\\\SOURCE\\OBJECTS/RigidMdl.c"
0006f6c0".\\\\SOURCE\\OBJECTS/Scene2Section1.c"
0006e180".\\\\SOURCE\\OBJECTS/shield.c"
0006df10".\\\\SOURCE\\OBJECTS/SpecialAxe.c"
00070560".\\\\SOURCE\\OBJECTS/SpecialBookOfProtection.c"
0006e07c".\\\\SOURCE\\OBJECTS/SpecialBoomerang.c"
00070694".\\\\SOURCE\\OBJECTS/SpecialClock.c"
0006de20".\\\\SOURCE\\OBJECTS/SpecialDagger.c"
000708dc".\\\\SOURCE\\OBJECTS/SpecialHolyWater.c"
00069814".\\\\SOURCE\\OBJECTS/UsrObj.c"
00069760".\\\\SOURCE\\OBJECTS/Whip.c"

There is also a list of source files, which appears to be partial. It appears the game was written in C, which was fairly common up until the early 2000s or so.

000fcf5d"S37at motherfucker *****"

There was also this entry. No comment!


00081a00"0,4 Build:Jul 23 1999 11:28:48\n"
00063120"04 Build:Mar 01 1999 11:57:40\n"

There are a few build strings through out as well, which should help date it exactly.

There are also numerous references to other enemies:

Evil Cleric, Pirate Skeleton With Sword, Boomerang Skeleton, Blood Skeleton, Headless Zombie, Lantern Mummy, Axe Knight, Spear Knight, Zombie, Great Armour With Sword, Headless Knight, Ghost Musician, Aristocrat Ghost, Fishman, Hunchback, Succubus, Bat, Hell Hound, Raven, Flying Fish, Skull Pillar, Grasping Hand, Hydra, Gorgon, Medusa Head, Skeletal Dragon Head, Wyvern, Harpy, Spirit, Flying Furniture, Flying Book, Marionette, Lesser Demon, Beelzebub, Maggot, Werewolf, Frankenstein, Female Dracula, Death Horse, Death, and of course, Dracula.

You can't say they didn't have ambition!

There are references to 'Victor' as well, which I think was the second playable character?

For the technical people, there are lots of debug bits in the string list too. I've attached the string dump from ghidra to this post for others to look at. One interesting trivia bit is that the collision detection system appears to have at least two primitives: trimeshes and spheres. It's likely that they supported capsules as well.

More to come, hopefully!

EDIT: It appears the forum does not like csv files. I've uploaded it here:


The link will expire in a week.
 
Last edited:

MetalliC

Well-known member
Registered
Jun 28, 2019
75
71
18
AGName
MetalliC
AG Join Date
23.04.2014
I have the skeleton files part way figured out. these can be found in the ssk directory that the script generates. For the most part they're pretty straight forward, but I've hit a bit of a snag with them. While the hierarchy was easy to figure out, the exact way it stores the bone transform(s) is kind of bizarre. I've worked with stranger stuff before though, so we'll see how it goes. For the technically inclined people, the problem is this:
normally, earlier generations 3D console games have models etc in native hardware display list format, or at least as much as possible close to it. so it will be possible to only modify necessary fields (e.g. apply matrix transformation to vertices) and then DMA whole model data chunk as is to GPU.
many/mostof DC games uses NJA/Ninja models format, which is almost native PowerVR2's "Tile Accelerator" format, perhaps something similar used here as well ?
 

Sifting

Well-known member
Registered
Aug 23, 2019
63
168
33
Have you any information on the NJA format, or could point in a direction to look? I'll definitely give it a look. In the mean time I've made some more discoveries:

Vectors do seem to be written in the homogeneous 4D way, with the 1.0 appended at the end, at least for the bones. The first 4 floats of bone data are its position in local space, the next 4 floats are the position in model space. The remaining values are most certainly related to rotation.

Also the coordinate space for the game appears to be X+ for right, Y+ for forward, and Z- for up.
 

MetalliC

Well-known member
Registered
Jun 28, 2019
75
71
18
AGName
MetalliC
AG Join Date
23.04.2014
Have you any information on the NJA format, or could point in a direction to look? I'll definitely give it a look.
it's documented in Katana SDK. looking at it will be good starting point, since Dreamcast game developers had no any low level hardware etc docs, and was limited by SDK tools (converters) and higher level APIs.
 
  • Like
Reactions: Sifting

Sifting

Well-known member
Registered
Aug 23, 2019
63
168
33
Hey, great advice! I gave the NJA stuff a look over, and while the formats are different, there are definitely similarities in regard to how geometry is stored. It's unclear whether the castlevania files are derivative of or informed by the NJA format. The big question remaining is figuring out the framing that holds the data together, but once that's done I can start writing the static assets out into glTF or some other accessible format.

For the curiosity people:

The vertex data is decomposed and written out into banks, so in the file you have something that looks like:

Code:
point  point  point  ...
normal normal normal ...
uv     uv     uv     ...
...    ...    ...

The first vertex would then be described by the first point, the first normal, and the first uv. The second vertex described by the second point, normal and uv, and so on for the rest. i.e.: It's stored column major. The NJA format permits some extra attribute data as well, and it's safe to bet the castlevania SMF format stores it in a similar way.

Big thanks to MetalliC for pointing me in the right direction!
 

Sifting

Well-known member
Registered
Aug 23, 2019
63
168
33
Work on the model format is near completion now. All the static geometry exports fine, but the animated characters come out as a jumble. This is interesting, not because it means there's an error on my part, rather, it means the vertices are stored relative to their assigned bones, and without the skeleton, the character models will not render properly. The file formats for the characters and the static geometry are the exact same. It appears that the information binding the vertices to bones in the skeleton are stored in the files inside the ssn directory. I have already mapped these out, along with the ones in the tft directory.

All in all it's been a very productive day.

I need to finish up the export code. Right now the normals seem a bit weird, and there's no UV coordinates or texture references written, but I hope to publish the updates to the script soon.

EDIT:

Texture support is now functioning. Where things seem a bit off in the images below is because of Blender not doing The Right Thing. There's a separate problem where the texture coordinates rely on a mirror texture mode, which Blender doesn't support as far as I can tell, but these issues are outside the scope of this project.

I have discovered another interesting thing too, it appears there are multiple versions of some models written in the different .bin files, and at least some are different, varying in vertex count and such.

Now to get the skeleton and animation files figured out...
 

Attachments

  • axe.png
    axe.png
    731.2 KB · Views: 0
  • 1up.png
    1up.png
    702.3 KB · Views: 0
  • dagger.png
    dagger.png
    781.9 KB · Views: 0
  • sonia.png
    sonia.png
    1,001.9 KB · Views: 0
  • texturedchapel.png
    texturedchapel.png
    2.3 MB · Views: 0
  • texturedchapel2.png
    texturedchapel2.png
    2.3 MB · Views: 0
  • texturedbridge.png
    texturedbridge.png
    2.2 MB · Views: 0
  • texturedbridge2.png
    texturedbridge2.png
    2.2 MB · Views: 0
  • texturedvillage2.png
    texturedvillage2.png
    2.1 MB · Views: 0
  • texturedvillage.png
    texturedvillage.png
    1.8 MB · Views: 0
Last edited:

Sifting

Well-known member
Registered
Aug 23, 2019
63
168
33
Alright, I have the animation format figured out! All that remains is to finish up the skeleton definitions and I should be able to write out all the animated models into glTF or similar. As usual here are some technical bits for the interested:

The animation format used in Castlevania is pretty straight forward. It stores data key major, with data for every bone stored inside each frame; each frame is given a monotonic time code in seconds, which is stored as a uint! Conceptually the frame data is written column major, with rotations written first, then if a flag is set in the header, position data. Most animations do not have any position data written. Rotations are stored as versors, and positions as 4D vectors.

It appears that they may have wanted to do some sort of delta compression scheme judging by some flags in the header which are set, but don't actually do anything.

Aside from this, I realised there's a way that I can fake the mirrored texture mode by generating mirrored versions of the textures in the script, so I may do that time permitting.

Another day of progress!
 

Sifting

Well-known member
Registered
Aug 23, 2019
63
168
33
And we're just about done now! I'm sorry for hijacking this thread and turning it into a kind of running blog, but I should be done in a post or two more, I promise. I've attached some pictures to make up for the transgression.

So the skeletons were actually a lot simpler than I thought. It appears most of the data on the bones is redundant. No rotations appear to be stored at all, in fact. Only their positions relative to their parent. This is very common pattern for this era of games, and I feel a bit silly for not thinking of it sooner - I've even used it before in my own work!

By combining the relative position with a rotation provided by an animation a frame of may be reproduced, or, as I have done here, supplying a identity matrix reproduces the bind pose.

I also realised there is some extra data in Sonia's skeleton. It's impossible to tell what it's used for, but if I had to hazard a guess, then it appears to be describing small IK chains, which would have been used to dynamically place Sonia's feet on the ground. This is common now in games, but back then it was quite rare! Her skeleton is the only one to have this extra data.

Next up is to write out the animations and everything into glTF!
 

Attachments

  • cardinal.png
    cardinal.png
    1 MB · Views: 0
  • medusahead.png
    medusahead.png
    890.8 KB · Views: 0
  • skull.png
    skull.png
    879.5 KB · Views: 0
  • skeleton.png
    skeleton.png
    857 KB · Views: 0
  • sonia.png
    sonia.png
    888.4 KB · Views: 0

Weinflames

Active member
Registered
Mar 25, 2020
35
40
18
AGName
Weinflames
And we're just about done now! I'm sorry for hijacking this thread and turning it into a kind of running blog, but I should be done in a post or two more, I promise. I've attached some pictures to make up for the transgression.

So the skeletons were actually a lot simpler than I thought. It appears most of the data on the bones is redundant. No rotations appear to be stored at all, in fact. Only their positions relative to their parent. This is very common pattern for this era of games, and I feel a bit silly for not thinking of it sooner - I've even used it before in my own work!

By combining the relative position with a rotation provided by an animation a frame of may be reproduced, or, as I have done here, supplying a identity matrix reproduces the bind pose.

I also realised there is some extra data in Sonia's skeleton. It's impossible to tell what it's used for, but if I had to hazard a guess, then it appears to be describing small IK chains, which would have been used to dynamically place Sonia's feet on the ground. This is common now in games, but back then it was quite rare! Her skeleton is the only one to have this extra data.

Next up is to write out the animations and everything into glTF!
Don’t apologize! Fantastic progress!
 
  • Like
Reactions: MKKhanzo

Sifting

Well-known member
Registered
Aug 23, 2019
63
168
33
Thank you! It means a lot.

At this point I have all the asset formats figured out, and the script now saves them into the popular gltf format, which is supported by virtually every 3D package out there, and as an added bonus, the textures that required the mirrored repeat mode are now fixed. There are still some kinks to work out, but the animations are now viewable too. It appears there are a bunch of unused animations for Sonia - ones for jumping off edges, falling from great height, hard and soft landing animations, and most interesting, at least three super neat acrobatic jumps.

Judging by their file names, I speculate that the R trigger was originally a kind of dodge or evade button, and that standing R + analog stick would have played the acrobatic jumps. In support of this, in the prototype, if you hold down R and move the analog stick, then regardless of whether you crouch, you do a crouch roll. It looks a bit odd from the standing pose, but it looks fine from crouching with the L trigger.

@Sega Dreamcast Info has uploaded a video where you can see them:



They start about half way through it.

Progress will be slower going forward, since I return to work tomorrow, but I hope to have everything wrapped up and pushed to the repo before too long. Fortunately all of the hard work is more or less done.
 

Sifting

Well-known member
Registered
Aug 23, 2019
63
168
33
Okay, I managed to get some more work on the script. The models are now properly animated by their skeletons now. @Sega Dreamcast Info has some video on twitter:

I also searched around about the .mlt file, and it seems that it's a fairly common format with dreamcast games. as I understand it, it's used with the manatee sound driver. There are already tools out there for extracting them, which may be found here: http://snesmusic.org/hoot/kingshriek/ssf/

The sound and music files are most likely in yamaha adpcm, which may be converted to other formats with ffmpeg, but I've not yet had the chance to try it yet.

There's only small stuff remaining now, I think. Once I get the script cleaned up and released, I'll write up some more coherent document on the whole journey. Here's hoping some more builds come forward!
 

Sifting

Well-known member
Registered
Aug 23, 2019
63
168
33
Is it possible to enable the unused animations?

It should be! Sonia's animation set is defined in plaintext inside of common_animsets.txt, so you just have to edit a few lines to replace the crouch roll animations or similar with the unused ones. The 'hard' part is rebuilding the bin files afterward. The script only extracts them at present.

On that note, I will try to get an update pushed as soon as possible. Everything looks quite nice now, but there is a couple remaining things to do. e.g.: applying a global transform to the geometry so it's oriented in the proper direction and other similar silly things. It should be up on the github page by next sunday at the latest.
 

Sifting

Well-known member
Registered
Aug 23, 2019
63
168
33
Okay, as promised here it is: https://github.com/sifting/Castlevania-Resurrection-Tools

I tested the gltf output exclusively with Blender, so your mileage may vary. I wanted to spend more time cleaning it up, but my job saps all my free time and I didn't want to keep anyone waiting. I'll publish the binary templates too, but I want to do a post mortem about this, so it might be another week for those. Please excuse the cruft in the mean time haha
 

RogerDoom

New member
May 26, 2021
4
5
3
AGName
RogerDoom
Ok thx...
I already have the files but I don't know how to use them in the blender.
I would like to play this demo on the Unity engine, or another
 

Sifting

Well-known member
Registered
Aug 23, 2019
63
168
33
Run the script that I linked previously on the .BIN files in the disk image, and it will extract all the assets in GLTF/PNG where appropriate. You can then load those into blender or unity or anything that loads GLTF/PNG files.

There is no unity version of the game - it was made before unity even existed - but you could try to recreate it yourself with the assets!
 

Make a donation