News: 11 March 2016 - Forum Rules
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia, Danke

Author Topic: Shining Tears UNDUB attempt  (Read 8882 times)

Sizzin

  • Jr. Member
  • **
  • Posts: 3
  • Tsunagatte yuke todoke ~
    • View Profile
Shining Tears UNDUB attempt
« on: June 18, 2013, 01:03:58 pm »
First, hello. I'm a newcomer here, and a newbie in romhacking, but I'm hungry for knowledge and I'll try to absorb as much as possible. ::)
So, I opened the Shining Tears (for those who don't know, the japanese version of the game is fully voiced while the english version is only voiced in the battles, yay  :banghead:) USA version image with the PSound program, just for curiosity and to learn more about the file contents. Then I randomly played one sound file and it was a japanese voice acting...! Although I don't know the exactly location of the files inside the iso, it's surely inside it. Just what the heck is this?
Someone can tell me if I have to move the files to certain location or change some config or something like that, to have the dub to play in-game?
Well, and if possible, suggest a programm to extract these contents.
Thanks in advance.

StorMyu

  • Jr. Member
  • **
  • Posts: 65
    • View Profile
Re: Shining Tears UNDUB attempt
« Reply #1 on: June 20, 2013, 09:25:11 am »
Even if you do extract and put it where it was, you have no idea if it would work if they've removed not only the audio file but the code that generates it.

Which means, good luck, it can be easy or a real pain.

Auryn

  • Hero Member
  • *****
  • Posts: 650
    • View Profile
Re: Shining Tears UNDUB attempt
« Reply #2 on: June 20, 2013, 04:25:46 pm »
Well, make at least a file list of what you saw when you opened it so that we get an idea as well.
Even if we are romhackers, we didn't open and memorized all file structures of all games around.
Remember this next time when you ask questions.

Sizzin

  • Jr. Member
  • **
  • Posts: 3
  • Tsunagatte yuke todoke ~
    • View Profile
Re: Shining Tears UNDUB attempt
« Reply #3 on: June 22, 2013, 10:35:35 am »
Even if you do extract and put it where it was, you have no idea if it would work if they've removed not only the audio file but the code that generates it.

Which means, good luck, it can be easy or a real pain.

So that means that its easier if I try the normal process, swap the USA files with the JPN, than trying change the place of the files or find a solution to the USA rom alone?

Well, make at least a file list of what you saw when you opened it so that we get an idea as well.
Even if we are romhackers, we didn't open and memorized all file structures of all games around.
Remember this next time when you ask questions.

Yeah, I know. If was that's what it seemed than I'm sorry.
It's just, what I asked was something general, not a specific thing. Like "the USA rom has the JPN audio files, what does this mean?".
And, like I said, I opened the rom with the PSound, I'll screenshot it, but it doesn't really help with anything.

This keep going until "Shining Tears (USA) | 01582".
« Last Edit: June 22, 2013, 03:30:59 pm by Sizzin »

Auryn

  • Hero Member
  • *****
  • Posts: 650
    • View Profile
Re: Shining Tears UNDUB attempt
« Reply #4 on: June 22, 2013, 06:54:34 pm »
OMG, i posted an answer but it got lost O.o

Well, here again.


If you open the japanese version of the game, do you have the same 1582 sounds??
Do they look in the same sequence??

Post a pic or a write down the folder/file tree of the iso or dvd for both versions of the game like this please:


Do you want to the english version of the game (without full dub) with japanese voices....right??
Not the japanese version of the game (with full dub) with english text....right??
If you want the first, you still have a chance, if you want the second, you will probably need to "untext" the japanese version of the game (insert the english text/images in the japanese version).

Sizzin

  • Jr. Member
  • **
  • Posts: 3
  • Tsunagatte yuke todoke ~
    • View Profile
Re: Shining Tears UNDUB attempt
« Reply #5 on: July 03, 2013, 09:43:27 pm »
Yes, I want the english version (without full dub) with japanese voice.
Sorry, I lost the japanese version, maybe I deleted it by mistake. I'll download it again and list the contents of both.

@EDIT

The English Version has 1582 sound files, the Japanese version has 1584.

The contents are:
obs.: The files in bold are the only changes.

Shining Tears (JAP).iso (1.641.280 KB  / 1,56 GB)
 --- Modules (Folder)
              --- CVS (Folder)
                    ENTRIES (1 KB)
                    REPOSI~1 (1 KB)
                    ROOT (1 KB)

              CRI_ADXI.IRX (111 KB)
              CW_DBG.IRX (18 KB)
              IOPRP280.IMG (264 KB)
              LIBSD.IRX (28 KB)
              MCMAN.IRX (94 KB)
              MCSERV.IRX (8 KB)
              PADMAN.IRX (43kb)
              SDHD.IRX (15 KB)
              SIO2MAN.IRX (7 KB)
  NOW01.TXR (4 KB)
  SLPM_657.73 (3,749 KB)
  ST.CVM (1,636,324 KB  /  1,55 GB)

  SYSTEM (1 KB)


Shining Tears (USA).iso (1,536,288 KB  /  1,46 GB)
 --- Modules (Folder)
              CRI_ADXI.IRX (111KB)
              CW_DBG.IRX (18 KB)
              IOPRP280.IMG (264 KB)
              LIBSD.IRX (28 KB)
              MCMAN.IRX (94 KB)
              MCSERV.IRX (8 KB)
              PADMAN.IRX (43kb)
              SDHD.IRX (15 KB)
              SIO2MAN.IRX (7 KB)
  NOW01.TXR (4 KB)
  SLUS_210.63 (3,761 KB)
  ST.CVM (1,510,868 KB  /  1,44 GB)

  SYSTEM (1 KB)

July 04, 2013, 06:00:19 pm - (Auto Merged - Double Posts are not allowed before 7 days.)
UPDATE

Sorry for the double post, if needed, please delete this.
« Last Edit: July 04, 2013, 06:00:19 pm by Sizzin »

Nanashi3

  • Newbie
  • *
  • Posts: 1
    • View Profile
Re: Shining Tears UNDUB attempt
« Reply #6 on: January 06, 2014, 04:52:44 pm »
Hey @Sizzin,

You may want to have a look at roxfan's cvm tool (mirror) to convert back and forth between .CVM and .ISO
Quote
cvm_tool.exe
ROFS tool v0.02 by roxfan (c) 2010.
Usage: cvm_tool [options] <command> <file1>...
    available commands:
    info  [-p <password>] <file.cvm>                          Show information about a ROFS volume
    split [-p <password>] <file.cvm> <file.iso> [<file.hdr>]  Extract ISO file from a ROFS volume
    mkcvm [-p <password>] <file.cvm> <file.iso>  <file.hdr>   Make a ROFS volume from an ISO file and header file
Do not mind the password option, since we are not dealing with encrypted (obfuscated) volumes.

Here is the tool output:
Quote
cvm_tool split H:\ST.CVM ST.CVM.iso ST.CVM.hdr
Input file: H:\ST.CVM
00000000: chunk 'CVMH', length 0x000007F4 (0x00000800)
CVMH chunk:
  file size: 0x5C375000
  date: 2004-12-27 19:45:12, GMT offset: 540 minutes
  verinfo1: 1.1.0.0
  flags_30: 0x00000000
  FS id: ROFS
  maker id: 'ROFSBLD Ver.1.52 2003-06-09'
  verinfo2: 1.31.0.0
  flag_7C: 3
  flag_7D: 0
  zone table (1 entries): [ 1 ]
  zone TOC sector: 1 (index 0)
  ISO start sector: 3
00000800: chunk 'ZONE', length 0x5C3747F4 (0x5C374800)
ZONE chunk:
  zone0C: 3
  zone10: 0
  zone11: 0
  zone12: 4
  zone13: 16
  zone14: 0
  sector len 1: 2048
  sector len 2: 2048
  dataloc1: sector 2, len 0x00000800
  dataloc ISO: sector 3, len 0x5C373800
Output file: ST.CVM.iso
Header file: ST.CVM.hdr

cvm_tool mkcvm ST-gen.CVM ST.CVM.iso ST.CVM.hdr
Input file: ST.CVM.iso
Header file: ST.CVM.hdr
Writing unencrypted volume
Output file: ST-gen.CVM
Patching ISO zone length to 0x5C373800
Patching file size to 0x5C375000
Setting encryption flag to 0

sha1sum H:\ST.CVM ST-gen.CVM
5624073167a074bbcd596b47f88a5a99eb4e2021  H:\ST.CVM
5624073167a074bbcd596b47f88a5a99eb4e2021  ST-gen.CVM


The CVM (ISO9660) for the USA version has the following structure: https://snipt.net/raw/0631ca7d35f144c9487a17f5f74d226f/?nice (listing mirror)


Here are a few observations on the matter:

- There are noticeably fewer .AHX + .ADX files than actually spoken in-game; where are they buried? [in both USA and JPN editions]. I also saw a few structures resembling ADPCM-like sounds
- TXR looks like a bitmap format that has several flavors, 5bpp, 8bpp indexed RGBa, flat 32bpp RGBa, and there are occasionally several images in a single TXR.
- RAX is an archive format containing several of the following filetypes: txr, ban, trs, efp, etc. It employs a clearly marked LZSS compression variant which I have not completely reversed. The window is 0x2000 bytes long, i.e. 13-bit long backreference index. It is kinda weird because the command word is also used as a source, meaning you read 5 bits from the control word and 8 bits from the curret byte to compute the backreference offset.
If you want to have a look, go to sub_14A340 in SLUS-21063, sub_14A310 in SLPM-65773, sub_221FF0 in SLPM-66671

- some files entries in PACK***.RAX match other files in the CVM hierarchy, e.g. AHX/*
- Shining Wind is the other title in the series using the same engine.

Appendices

NON-WORKING TXR converter:
Code: [Select]
# Extractor for SEGA/Nextech *.TXR (script 0.1.0)
# = used in shining tears & shining wind
# script for QuickBMS http://quickbms.aluigi.org

endian little
get myext EXTENSION
if myext != "TXR"
    print "Please run this script on a .TXR file"
    cleanexit
endif

get DAT_SIZE asize

# A .txr file typically contains a single bitmap, but there are some edge cases
math i = 0

for OFFSET = 0 < DAT_SIZE
    idstring "TXR\x00"

    math i += 1
   
    get query->bm_type long
    get query->bm_widt short
    get query->bm_heig short
    get RESERVED_ long # always zero?

    callfunction query2tga
    cleanexit

    savepos OFFSET
next

###############################################
# struct TGAHeader
# {
#   uint8   idLength,           // Length of optional identification sequence.
#           paletteType,        // Is a palette present? (1=yes)
#           imageType;          // Image data type (0=none, 1=indexed, 2=rgb,
#                               // 3=grey, +8=rle packed).
#   uint16  firstPaletteEntry,  // First palette index, if present.
#           numPaletteEntries;  // Number of palette entries, if present.
#   uint8   paletteBits;        // Number of bits per palette entry.
#   uint16  x,                  // Horiz. pixel coord. of lower left of image.
#           y,                  // Vert. pixel coord. of lower left of image.
#           width,              // Image width in pixels.
#           height;             // Image height in pixels.
#   uint8   depth,              // Image color depth (bits per pixel).
#           descriptor;         // Image attribute flags.
# };
startfunction query2tga

    savepos DATOFFSET

    if query->bm_type == 0
        # 32bpp RGBa
        math query->bm_bpp = 32
        math query->bm_pal = 0
        set MEMORY_FILE binary "\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\xAA\xAA\xBB\xBB\x20\x28"
    elif query->bm_type == 0x13
        # indexed 8bpp RGBa with 256-entry RGBa palette (0x400 bytes)
        math query->bm_bpp = 8
        math query->bm_pal = 0x400
        set MEMORY_FILE binary "\x00\x01\x01\x00\x00\x00\x01\x20\x00\x00\x00\x00\xAA\xAA\xBB\xBB\x08\x28"
#    elif query->bm_type == 0x14
        # 5bpp
    else
        print "unknown bitmap type in TXR file %query->bm_type% starting @ offset %OFFSET%"
        cleanexit
    endif

    goto 0x0C MEMORY_FILE   # x,y
    put query->bm_widt short MEMORY_FILE
    put query->bm_heig short MEMORY_FILE
    get TGAHDSIZE asize MEMORY_FILE

    math PXBITMAP = query->bm_widt
    math PXBITMAP *= query->bm_heig
    math BYT = query->bm_bpp
    math BYT u/= 8
    math PXBITMAP *= BYT

    get NAME basename
    string NAME p= "%s_%03d.tga" NAME i
append
    log MEMORY_FILE2 0 TGAHDSIZE MEMORY_FILE
    if query->bm_pal > 0
        math PALOFFSET = DATOFFSET
        math PALOFFSET += PXBITMAP  # TXR puts image data first, then colormap
        log MEMORY_FILE2 PALOFFSET query->bm_pal
    endif

    log MEMORY_FILE2 DATOFFSET PXBITMAP
append
    get TGATOTSIZE asize MEMORY_FILE2
    log NAME 0 TGATOTSIZE MEMORY_FILE2

endfunction

Blue-ish Elwyn
 


Some LZSS sample (extracted out of a .RAX file):



001.BAN.slz = 0x3AE4 bytes
001.BAN = 0xFA90 bytes


EDIT1

The initial scene where Elwyn finds a boy washed ashore = event/TOWN02.bss from PACKTOWN02.RAX
A .bss file is a compiled script made of 4 sections:
- TNVE "EVeNT" seems to be a bunch of offsets
- CNUF "FUNCtions", a bunch of ASCII symbols
- DCMV "VM CoDe"
- TDMV "VM DaTa" = \x00 separated list of strings
- DEMV (end of file marker)

You shall find this file in-memory when snapping a savestate.

The DCMV and TDMV are of particular interest to us:
- DCMV contains opcodes referring to TDMV strings by offset, after removing the 12-byte long header
- TDMV contains game strings (ASCII strings in the case of the USA version)

e.g.:
  • offset 678B: Looks like he's hurt pretty bad...
  • offset 67AF: Boy (speaker name)
  • offset 67B3: U... Ugh...
  • offset 67C0: I better get him to (...)

contrast with JPN version:


  • offset 59E3: *S4*ひどい傷……
  • offset 59F9: 少年 (speaker name)
  • offset 59FE: *S5*う…… (...)
  • offset 5A28: *S4*一刻も早く^ (...)

Undoubtedly some of those opcodes in the JPN version correspond to voiceovers.
If you compare USA vs. JPN, there are outstanding instructions on the right column:
USA                           

27: FFFFFFFF (-1)             
29: 08000000 (8)             





2A: 8B670000 (ofs 678B) msgbox                       
29: 13000000 (19)             
29: 09000000 (9)             
02: 01000000 (1)
02: 02000000 (2)
02: 18000000 (24)
27: FDFFFFFF (-3)
29: 0A000000 (10)
02: 02000000 (2)             
03: AF670000 (ofs 67AF) msgspk
27: FEFFFFFF (-2)             
29: 0F000000 (15)             
02: FFFFFFFF (-1)             
27: FFFFFFFF (-1)             
29: 08000000 (8)             
                             
                             
                             
                             
                             
2A: B3670000 (ofs 67B3) msgbox
29: 13000000 (19)             
29: 09000000 (9)             
02: 01000000 (1)             
02: 02000000 (2)             
02: 19000000 (31)             
27: FDFFFFFF (-3)             
29: 0A000000 (10)             
02: 01000000 (1)             
27: FFFFFFFF (-1)             
29: 08000000 (8)             
                             
                             
                             
                             
                             
2A: C0670000 (ofs 67C0) msgbox
JPN

                 27: FFFFFFFF (-1)
                 29: 08000000 (8)
02: 2C000000 (44)
02: 03000000 (3)
02: 00000000 (0)
27: FDFFFFFF (-3)
29: 39000000 (57)

                 2A: E3590000 (ofs 59E3) msgbox
                 29: 10000000 (16)
                 29: 09000000 (9)





                 02: 02000000 (2)
                 03: F9590000 (ofs 59F9) msgspk
                 27: FEFFFFFF (-2)
                 29: 0C000000 (12)
                 02: FFFFFFFF (-1)
                 27: FFFFFFFF (-1)
                 29: 08000000 (8)
02: 2D000000 (45)
02: 03000000 (3)
02: 00000000 (0)
27: FDFFFFFF (-3)
29: 39000000 (57)

                 2A: FE590000 (ofs 59FE) msgbox
                 29: 10000000 (16)
                 29: 09000000 (9)
                 02: 01000000 (1)
                 02: 02000000 (2)
                 02: 19000000 (31)
                 27: FDFFFFFF (-3)
                 29: 0A000000 (10)
                 02: 01000000 (1)
                 27: FFFFFFFF (-1)
                 29: 08000000 (8)
02: 2E000000 (46)
02: 03000000 (3)
02: 00000000 (0)
27: FDFFFFFF (-3)
29: 39000000 (57)

                 2A: 285A0000 (ofs 5A28) msgbox


EDIT2:
OK, I have confirmed by loading a save state, that the incrementing value refers to a voice file.
The 27 opcode seems to indicate how many values need to be "unstacked" by the following function call (-1, -2, -3, etc.)
The 29 opcode, subcode 39 seems to be the code for playing a voice file, taking 3 parameters.

Now what's left:
1/ somehow recompile a valid bss image, fixing pointers
2/ repack a RAX archive. Thoroughly figuring the LZSS compression is a plus, but not necessary, as a dummy compression always reading literals (0xFF control word) should be enough.
2a/ which copy takes precedence in the CVM? The one in the ISO9660 or in the RAX?
3/ recreate ST.CVM
4/ repack complete ISO, test


Appendix

RAX archive dumper:
Code: [Select]
# Dumper for SEGA/Nextech *.RAX (script 0.1.0)
# = used in shining tears & shining wind
# script for QuickBMS http://quickbms.aluigi.org

# This version only dumps LZSS segments as-is

endian little
get myname FILENAME
get myext EXTENSION
if myext != "RAX"
    print "Please run this script on a .RAX file"
    cleanexit
endif

get DAT_SIZE asize
idstring "RAX\x00"
get rax->RESERVED1_ long
get rax->RESERVED2_ long
get rax->entcount long

math i = 0

for OFFSET = 0x10 < DAT_SIZE
    getdstring query->sig 4
    get        query->blksize long
    get        query->fnamelen long
    get        query->usize long

    math i += 1

    if query->fnamelen > 0x100
        print "(%myname% at OFFSET=%OFFSET%) entry filename overly long, maybe bad value [query->fnamelen=%query->fnamelen%]"
        cleanexit
    endif
    if query->fnamelen > 0
        getdstring query->fname query->fnamelen
    else
        string query->fname p= "--%03d--.bin" i
    endif

    set        query->zsize query->blksize
    math query->zsize -= 0x10
    math query->zsize -= query->fnamelen

    savepos tmpOFFSET
    get magic long
    goto tmpOFFSET
   
    string dumpext = ".slz"
    if magic u!= 0x53535A4C # LZSS
        string dumpext = ".raw"
    endif

    set fname query->fname
    string fname R= "/" "!"
    string fname R= "\\" "!"

    get NAME basename
    string NAME p= "%s# [%s]%s" NAME fname dumpext
   
    if magic u== 0x53535A4C # LZSS
        log NAME tmpOFFSET query->zsize
    else
        log NAME tmpOFFSET query->usize
    endif

    goto query->zsize 0 SEEK_CUR

    savepos OFFSET
next

if i != rax->entcount
    print "(%myname%) Expected %rax->entcount% entries, found %i%"
endif

_ext_rax.cmd helper batch (copy cvm contents into work/ and duplicate its tree structure in extr/) :
Code: [Select]
@echo off & setlocal ENABLEEXTENSIONS

goto :main

:do_one
SET ZPATH=%~dp1
SET ZPATH=%ZPATH:work=extr%
quickbms -o sega-nextech-shining_wind-rax-010.bms %1 %ZPATH%
goto :eof

:main
for /R %%i in (*.rax) DO call :do_one %%i



:end
pause
EDIT3:
I've been leading a few interesting experiments on the NTSC-J version.

(...put in a separate entry b/c this post exceeds the board limit...)
main conclusions are:
- can mod RAX files
- CVMFS takes over if entry missing from RAX
« Last Edit: January 08, 2014, 03:48:24 am by Nanashi3 »