ROM Hack [Help Needed] Format Difficulties Ripping Models From Tongari Boushi/Magician's Quest

nebulousquid

Member
OP
Newcomer
Joined
Jul 13, 2019
Messages
9
Trophies
0
Age
25
XP
80
Country
United States
I've been attempting to rip player and NPC models from the game Tongari Boushi for the Nintendo DS.
I managed to make a little progress on my own, but hit a bit of a wall when it came to how certain files were encrypted.

t6p6v4.jpg


I believe the models I'm looking for are stored in the npc.dat and pc.dat files, considering A) the container folder being named "Model" and B) When viewed, certain parts of the translated hexadecimal indicate that they contain .BMD0 model files.

10eorxu.jpg


While certain files are encrypted in LZ77 (such as the one highlighted in blue in the first image,) Console Tool does not recognize these files as being encrypted, and attempting to decompress them via BatchLZ77 yielded the message "Not a compressed file!"
Under 1 MB seems awfully small to contain every single model for the game without compression, even for a DS title. Is this another type of encryption you know of, or possibly something unknown used in-house? Am I missing something? Here is a link to the NPC.dat if you'd like to take a look at it yourself, and below is an image of the first lines of the file in case that helps with identifying it.

2mq9owi.jpg

Thank you in advance for any help!
 

Attachments

  • ripping1.PNG
    ripping1.PNG
    43.2 KB · Views: 236

alfador

New Member
Newbie
Joined
Dec 24, 2018
Messages
4
Trophies
0
Age
43
XP
1,552
Country
United Kingdom
You can use something like this to extract entries (each entry is LZSS compressed):


Code:
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>

#define MIN(a, b) ((a) < (b) ? (a) : (b))

int read_int32(FILE *f)
{
    int32_t buf;
    if (fread(&buf, sizeof(buf), 1, f) != 1) {
        fprintf(stderr, "file too short\n");
        exit(1);
    }
    return buf;
}

void save_entry(FILE *fi, int n, int offset, int size)
{
    FILE *fo;
    char tmp[32];
    char buf[4096];

    sprintf(tmp, "%03i.bin", n);
    fo = fopen(tmp, "w");

    long pos = ftell(fi);
    fseek(fi, offset, SEEK_SET);

    while (size > 0) {
        size_t readed = fread(buf, 1, MIN(size, sizeof(buf)), fi);
        if (size > 0 && readed == 0) {
            fprintf(stderr, "file too short\n");
            exit(1);
        }
        fwrite(buf, 1, readed, fo);
        size -= readed;
    }

    fseek(fi, pos, SEEK_SET);
    fclose(fo);
}

int main(void)
{
    FILE *f = fopen("npc.dat", "r");

    int count = read_int32(f);

    for (int i = 0; i < count; i++) {
        int offset = read_int32(f);
        int size = read_int32(f);
        if (offset == 0 || size == 0) {
            continue;
        }
        save_entry(f, i, offset, size);
    }

    fclose(f);
}
 

Hammer_Jr

New Member
Newbie
Joined
Jul 13, 2019
Messages
3
Trophies
0
Age
44
XP
55
Country
United States
I had a similar issue as well with ripping a rom called fossil fighters.
Hopefully you can share your successes with us. :)
 

nebulousquid

Member
OP
Newcomer
Joined
Jul 13, 2019
Messages
9
Trophies
0
Age
25
XP
80
Country
United States
You can use something like this to extract entries (each entry is LZSS compressed):


Code:
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>

#define MIN(a, b) ((a) < (b) ? (a) : (b))

int read_int32(FILE *f)
{
    int32_t buf;
    if (fread(&buf, sizeof(buf), 1, f) != 1) {
        fprintf(stderr, "file too short\n");
        exit(1);
    }
    return buf;
}

void save_entry(FILE *fi, int n, int offset, int size)
{
    FILE *fo;
    char tmp[32];
    char buf[4096];

    sprintf(tmp, "%03i.bin", n);
    fo = fopen(tmp, "w");

    long pos = ftell(fi);
    fseek(fi, offset, SEEK_SET);

    while (size > 0) {
        size_t readed = fread(buf, 1, MIN(size, sizeof(buf)), fi);
        if (size > 0 && readed == 0) {
            fprintf(stderr, "file too short\n");
            exit(1);
        }
        fwrite(buf, 1, readed, fo);
        size -= readed;
    }

    fseek(fi, pos, SEEK_SET);
    fclose(fo);
}

int main(void)
{
    FILE *f = fopen("npc.dat", "r");

    int count = read_int32(f);

    for (int i = 0; i < count; i++) {
        int offset = read_int32(f);
        int size = read_int32(f);
        if (offset == 0 || size == 0) {
            continue;
        }
        save_entry(f, i, offset, size);
    }

    fclose(f);
}

Thank you very much for the help! I installed MinGW (runtime environment for the GCC compiler,) and created an executable from the source code you gave me, but unfortunately the .BIN file generated was only 1KB and wouldn't successfully mount, even after i made a .CUE for it. Not sure what the issue is. I've done too much work on this to give up, though, so I'll keep looking into it.
 

alfador

New Member
Newbie
Joined
Dec 24, 2018
Messages
4
Trophies
0
Age
43
XP
1,552
Country
United Kingdom
In source code replace .bin string with .nsbmd :)

PS: You can try to use The Console Tool (if you can find it) or you can uncompress that files (use some LZ77 decompressor tool) and try COLLADA converter (Google "model + animation => COLLADA converter").
 
Last edited by alfador,

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    S @ salazarcosplay: @BigOnYa If he does not take them by mouth then how does he take them?