ROM Hack [Release] Shin Megami Tensei IV Undub

Status
Not open for further replies.

Gadorach

Electronics Engineering Technologist
Member
Joined
Jan 22, 2014
Messages
970
Trophies
0
Location
Canada
XP
956
Country
Canada
it answers your question.

Thanks, glad that's all cleared up. Now we don't have to worry about if we're right or wrong in posting these patches, and the limitations there-in. We can still announce the releases here though, I'm sure, just with reference to "You can find them at the usual places." instead of direct links to files or websites hosting them.
 

Askedforthis

Well-Known Member
Member
Joined
Oct 15, 2013
Messages
117
Trophies
0
Age
32
XP
170
Country
Norway
Video subs coming soon™. Probably tomorrow.

Also I seem to have mistakenly removed two ctpk files in the archive while half asleep, which means the previous CSV was not complete and were missing two files that could potentially make it crash (tutorial45 and tutorial46). I dunno if they are required, but I'd recommend recompiling the ROM just in case.

I've updated the CSV + RSF zip with the new CSV that corrects the error completely. It has now the exact same amount of files as the original like intended. I'm sorry about that.
 

flatscreen

New Member
Newbie
Joined
Nov 17, 2014
Messages
2
Trophies
0
Age
43
XP
52
Country
Serbia, Republic of
This place exists between dream and reality, mind and matter.

Now repack it as usual. I have included my custom RSF. I also injected the original exheader.


Hi!

Can anyone tell me how to repack? I spent 10 hours writing my script, and I don't know what command line tools should I use to repack my cpk file to romfs.bin or *.3ds file (<-- is that even possible ) ??? I modified the sound files, made a new cpk with cpkmakec, and now what? I don't find the right command and / or the right parameters. I had no problem with the decryption / encryption, but I don't know the tools very well.

here is what I am working on. I have already completed the first 8 steps, I create an automated script.

1. download and the extract archive, a personaq folder should be there now
* now it's time to copy your slot0x25KeyX.bin to this directory
2. hold shift in the personaq folder and right click and choose open command prompt here
3. use "dir" command and press ENTER, personaq_1016_1313.exe file should be in the directory
4. copy your *.3ds files (Persona_Q_Shandow_of_the_Labyrinth_JPN_3DS-Caravan, Persona_Q_Shadow_of_the_Labyrinth_3DS-VENOM) to the personaq folder
* rename the US rom to US.3ds
* rename the JP rom to JP.3ds
5. type "personaq_1016_1313.exe --US3ds=US.3ds --JP3ds=JP.3ds" and press ENTER, verify the md5 checksums (don't close the window)
* US ROM checksum 25189a7dc2f726f65a521b1372097cb3 (2,147,483,648)
JP ROM checksum 20c6261b7de8ded232f05c44891dd453 (2,147,483,648)
6. Copy Launcher.dat, slot0x25KeyX.bin and ncchinfo.bin onto the 3ds internal sd card. (not the gateway micro sd card)
* insert card and go gateway mode
* wait until
Opening sd:/ncchinfo.bin ...
Opened! Reading info...
Number of entries: 10
Finished! You can turn off your 3DS now :P
7. copy the *.xorpad files from the internal sd card to your computer's personaq folder
8. return to the command line window (I said you shouldn't close it) and type "personaq_1016_1313.exe --bake" and press ENTER
* wait 90 minutes
9. done. copy the new personaq_undub.3ds file to the gateway micro sd card
+. report

And here is the full description

Similar to the 3DS CTR Decryptor helper script, but this one is tailored for the PersonaQ undub configuration files made by Askedforthis

cd personaq
copy <path-to-jp-rom> JP.3ds
copy <path-to-us-rom> US.3ds
personaq_1016_1313.exe --US3ds=US.3ds --JP3ds=JP.3ds
-- you should copy manually the Launcher.dat, slot0x25KeyX.bin and ncchinfo.bin onto the 3ds internal sd card (FAT32)---
-- go into gateway mode and come back with the *.xorpad files --
copy <path-to-internalsdcard>\*.xorpad .
personaq_1016_1313.exe --bake
copy personaq_undub.3ds <path-to-microsdcard>

non TL;DR

It's only for end-users. Mighty *.py(thon) files are already there for the pros, this package only contains a bunch of executable files:
* you should know command line and how to copy paste two lines from your browser window
* how to rename files
* how to copy files to your sd and micro sd card
* how to use the gateway exploit and run commercial games on it
* how to download 3ds roms, because you won't get those from here
* 4GB internal SD card for xorfiles (or use a microsd-sd adapter if you only have the microsd for the GW Red card)
* 16GB free space on the hard drive of PC
* 200MB RAM + 1GB for ctrtool :/
* fully charged 3DS to run ncch decryptor by VOiD, cause the console runs decryptor for 30 minutes
* if trimmedsize for one rom is 1GB then it will take 15min, if 2GB then 30 min etc.

Tested on Win 8.0 (64 bit, Japanese locale), contains files only from open-source projects.
Batteries included (excluding the 0 key file).

You should already have:
* the slot0x25KeyX.bin file ( 16 bytes ); use google to find the file on chinese forums
* Gateway Red card and a Nintendo 3ds (< 4.5FW) with gateway exploit
* the US and the JP release of the same game; currently only PersonaQ is supported

1. download and the extract archive, a personaq folder should be there now
* now it's time to copy your slot0x25KeyX.bin to this directory
2. hold shift in the personaq folder and right click and choose open command prompt here
3. use "dir" command and press ENTER, personaq_1016_1313.exe file should be in the directory
4. copy your *.3ds files (Persona_Q_Shandow_of_the_Labyrinth_JPN_3DS-Caravan, Persona_Q_Shadow_of_the_Labyrinth_3DS-VENOM) to the personaq folder
* rename the US rom to US.3ds
* rename the JP rom to JP.3ds
5. type "personaq_1016_1313.exe --US3ds=US.3ds --JP3ds=JP.3ds" and press ENTER, verify the md5 checksums (don't close the window)
* US ROM checksum 25189a7dc2f726f65a521b1372097cb3 (2,147,483,648)
JP ROM checksum 20c6261b7de8ded232f05c44891dd453 (2,147,483,648)
6. Copy Launcher.dat, slot0x25KeyX.bin and ncchinfo.bin onto the 3ds internal sd card. (not the gateway micro sd card)
* insert card and go gateway mode
* wait until
Opening sd:/ncchinfo.bin ...
Opened! Reading info...
Number of entries: 10
Finished! You can turn off your 3DS now :P
7. copy the *.xorpad files from the internal sd card to your computer's personaq folder
8. return to the command line window (I said you shouldn't close it) and type "personaq_1016_1313.exe --bake" and press ENTER
* wait 90 minutes
9. done. copy the new personaq_undub.3ds file to the gateway micro sd card
+. report

Credits
http://esrg.sourceforge.net/utils_win_up/md5sum/
https://github.com/Relys/3DS_NCCH_Decryptor

I rewrote the xor and the bin extract modules for speed improvement.

I realized that my progress maybe will be good for the homebrew development. Even if the 9th step will remain unpublished. Here is my working directory

PersonaQ - Undub [US]>dir /B
00040000000C3600.Main.exefs_norm.xorpad
00040000000C3600.Main.exheader.xorpad
00040000000C3600.Main.romfs.xorpad
00040000000C3600.Manual.romfs.xorpad
00040000000C3600.UpdateData.romfs.xorpad
0004000000123400.Main.exefs_norm.xorpad
0004000000123400.Main.exheader.xorpad
0004000000123400.Main.romfs.xorpad
0004000000123400.Manual.romfs.xorpad
0004000000123400.UpdateData.romfs.xorpad
cpkmakec.exe
CpkMaker.DLL
cpk_unpack.exe
ctrtool.exe
JP.ds
Launcher.dat
makerom.exe
md5.exe
Persona Q Filelist.csv
Persona.rsf
personaq.py
slot0x25KeyX.bin
US.ds

As you can see I extracted and decrypted at the same time the romfs.bin from the rom file. Modified ctrkeygen source code

Code:
#USAGE:
#python personaq.py --US3ds "US.3ds" --JP3ds "JP.3ds"
# --USsize 1856598016 --USoffset 0x2f5000

import sys, getopt, os
import struct #nhcc

ncch_title  = ''
ncch_offset = 0
romfs_offset= 0
romfs_size  = 0
s_rom__byte = []

def main(argv):
  global s_rom__byte
  s_param, s_arg = getopt.getopt( argv ,  '', [\
    'US3ds=', 'USsize=', 'USoffset=',\
    'JP3ds=', 'JPsize=', 'JPoffset=', 'skip-md5', 'xorpad', 'bake' ] )
  #s_param long and short keys
  #s_arg   values without keys
  #xorpad for xoring and wait for modification
  #bake is re-encrypting the 3ds file
  if filter( lambda x: x[ 0 ] == '--bake', s_param ):
    xorpad( s_param )

    print "ROM stats for dev"
    for i in range(0,2):
      print s_rom__byte[ i * 4 ]
      print hex( s_rom__byte[ i * 4 + 1 ] + s_rom__byte[ i * 4 + 2 ] )
      print str( s_rom__byte[ i * 4 + 3 ] )

    print ''
    the_offset   = 0
    for the_region in ["US", "JP"]:
      print "Decrypting " + the_region + " rom"
      xorbin = open( s_rom__byte[ the_offset * 4 + 0 ] + ".Main.romfs.xorpad", 'rb' )
      romfs( the_region, s_param,\
        s_rom__byte[ the_offset * 4 + 3 ],\
        s_rom__byte[ the_offset * 4 + 1 ] + s_rom__byte[ the_offset * 4 + 2 ],\
        xorbin )    
      xorbin.close()
      os.system( "ctrtool -x EncryptedRomFS.bin" );
      os.system( "ctrtool -t =romfs --romfsdir=" + the_region +"ROM EncryptedRomFS.bin" );
      os.system( "move " + the_region + "ROM\\data.cpk " + the_region + "data.cpk" );
      os.system( "cpk_unpack " + the_region + "data.cpk" );
      the_offset += 1

    print ''
    print 'Copy sound files from JP ROM'
    os.system( "xcopy USdata.cpk_unpacked UDdata.cpk_unpacked\\ /S /E")
    os.system( "xcopy JPdata.cpk_unpacked\\sound\\*.awb UDdata.cpk_unpacked\\sound\\ /Y")
    os.system( "move \"Persona Q Filelist.csv\" UDdata.cpk_unpacked\\")
    os.system( "cpkmakec \"Persona Q Filelist.csv\" dudata.cpk -align=2048 -mode=FILENAME -dir=UDdata.cpk_unpacked")
    os.system( "move UDdata.cpk_unpacked\\dudata.cpk ." )
    print 'This is the point where I refused to use any ddl or exe from the SDK tool.'
    print 'Now we have a useless cpk file. Enjoy :# ... these steps took 150 minutes on an average computer'

  else:
    if filter( lambda x: x[ 0 ] == '--skip-md5', s_param ):
      pass  
    else:
      print "US ROM checksum"
      os.system( 'md5 \"' +\
        filter( lambda x: x[ 0 ] == '--US3ds' , s_param )[ 0 ][ 1 ] +\
        '\"')
      print "JP ROM checksum"
      os.system( 'md5 \"' +\
        filter( lambda x: x[ 0 ] == '--JP3ds' , s_param )[ 0 ][ 1 ] +\
        '\"')

    xorpad( s_param )

def inline_xor_nocopy(aa, bb):
    real_size = len(aa)
    a = numpy.frombuffer(aa, dtype=numpy.uint64)
    b = numpy.frombuffer(bb, dtype=numpy.uint64)
    return weave.inline(code2, ["a", "b", "real_size"], 
                        headers = ['"emmintrin.h"'], 
                        support_code = support)
  
def xor(data, key):
    index = len(data) % 4
    size = (4, 1, 2, 1)[index]
    type = ('L', 'B', 'H', 'B')[index]
    key_len = len(key)/size
    data_len = len(data)/size
    key_fmt = "<" + str(key_len) + type;
    data_fmt = "<" + str(data_len) + type;

    key_list = struct.unpack(key_fmt, key)
    data_list = struct.unpack(data_fmt, data)

    result = []
    for i in range(data_len):
        result.append (key_list[i % key_len] ^ data_list[i])

    return struct.pack(data_fmt, *result)

def romfs( a_region, s_param, a_size, an_offset, xorbin ):
  with open(\
  filter( lambda x: x[ 0 ] == '--' + a_region + '3ds' , s_param )[ 0 ][ 1 ],\
  'rb' ) as rom__us:
    with open( 'EncryptedRomFS.bin', 'wb' ) as ebin:
      ebin__size = a_size 
      ebin__offset= an_offset 
      rom__us.seek( ebin__offset )
      #Don't do that: #xorbin.seek( ebin__offset )
      every = 128 / 8 * 1
      progress = 0
      while True:
        if progress == 0:
          print "%d bytes" % ( ebin__size )
        progress = ( progress + 1 ) % every
        s_byte = None
        if ebin__size > 8 * 1048576:
          s_byte = rom__us.read( 8 * 1048576 )
          s_xor  = xorbin.read( 8 * 1048576 )
          ebin__size -= 8 * 1048576
        else:
          s_byte = rom__us.read( ebin__size )
          s_xor  = xorbin.read( ebin__size )
          ebin__size = 0
        if s_byte and s_xor:
          ebin.write( xor( s_byte, s_xor ) )
        else:
          print "Error creating EncryptedRomFS.bin"
        if ebin__size == 0:
          break
      
  rom__us.close()
  ebin.close()
  print "(" + a_region + ") EncryptedRomFS.bin created"

def xorpad( s_param ):
  global s_rom__byte
  s_file = [\
    filter( lambda x: x[ 0 ] == '--US3ds' , s_param )[ 0 ][ 1 ],\
    filter( lambda x: x[ 0 ] == '--JP3ds' , s_param )[ 0 ][ 1 ]\
  ]
  s_region = [\
     'US', 'JP'\
  ]
  entries = 0
  data    = ''
  i = 0

  for file in s_file:
    
    with open( file ,'rb') as the_rom:
      
        result = []
        
        result = parseNCSD( the_rom )
        s_rom__byte.append( ncch_title )
        s_rom__byte.append( ncch_offset )
        s_rom__byte.append( romfs_offset )
        s_rom__byte.append( romfs_size )
      
        if result:
          entries += result[ 0 ]
          data     = data + result[ 1 ]
      
  dndFix = os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])),\
    'ncchinfo.bin' )    
  #  s_region[ i ] + '_ncchinfo.bin') #Fix drag'n'drop
  with open(dndFix, 'wb') as binfile:
    binfile.write(struct.pack('<IIII',0xFFFFFFFF, 0xF0000003, entries, 0))
    binfile.write(data)
  binfile.close()
  
  i += 1

# TODO rewrite

from ctypes import *
from binascii import hexlify

mediaUnitSize = 0x200

class ncchHdr(Structure):
  _fields_ = [
    ('signature', c_uint8 * 0x100),
    ('magic', c_char * 4),
    ('ncchSize', c_uint32),
    ('titleId', c_uint8 * 0x8),
    ('makerCode', c_uint16),
    ('formatVersion', c_uint8),
    ('formatVersion2', c_uint8),
    ('padding0', c_uint32),
    ('programId', c_uint8 * 0x8),
    ('padding1', c_uint8 * 0x10),
    ('logoHash', c_uint8 * 0x20),
    ('productCode', c_uint8 * 0x10),
    ('exhdrHash', c_uint8 * 0x20),
    ('exhdrSize', c_uint32),
    ('padding2', c_uint32),
    ('flags', c_uint8 * 0x8),
    ('plainRegionOffset', c_uint32),
    ('plainRegionSize', c_uint32),
    ('logoOffset', c_uint32),
    ('logoSize', c_uint32),
    ('exefsOffset', c_uint32),
    ('exefsSize', c_uint32),
    ('exefsHashSize', c_uint32),
    ('padding4', c_uint32),
    ('romfsOffset', c_uint32),
    ('romfsSize', c_uint32),
    ('romfsHashSize', c_uint32),
    ('padding5', c_uint32),
    ('exefsHash', c_uint8 * 0x20),
    ('romfsHash', c_uint8 * 0x20),
  ]

class ncchSection:
  exheader = 1
  exefs = 2
  romfs = 3

class ncch_offsetsize(Structure):
  _fields_ = [
    ('offset', c_uint32),
    ('size', c_uint32),
  ]

class ncsdHdr(Structure):
  _fields_ = [
    ('signature', c_uint8 * 0x100),
    ('magic', c_char * 4),
    ('mediaSize', c_uint32),
    ('titleId', c_uint8 * 0x8),
    ('padding0', c_uint8 * 0x10),
    ('offset_sizeTable', ncch_offsetsize * 0x8),
    ('padding1', c_uint8 * 0x28),
    ('flags', c_uint8 * 0x8),
    ('ncchIdTable', c_uint8 * 0x40),
    ('padding2', c_uint8 * 0x30),
  ]

ncsdPartitions = [b'Main', b'Manual', b'DownloadPlay', b'Partition4', b'Partition5', b'Partition6', b'Partition7', b'UpdateData']

def roundUp(numToRound, multiple):  #From http://stackoverflow.com/a/3407254
  if (multiple == 0):
    return numToRound
  
  remainder = abs(numToRound) % multiple
  if (remainder == 0):
    return numToRound
  if (numToRound < 0):
    return -(abs(numToRound) - remainder)
  return numToRound + multiple - remainder

def reverseCtypeArray(ctypeArray): #Reverses a ctype array and converts it to a hex string.
  return ''.join('%02X' % x for x in ctypeArray[::-1])
  #Is there a better way to do this?

def getNcchAesCounter(header, type): #Function based on code from ctrtool's source: https://github.com/3DSGuy/Project_CTR
  counter = bytearray(b'\x00' * 16)
  if header.formatVersion == 2 or header.formatVersion == 0:
    counter[:8] = bytearray(header.titleId[::-1])
    counter[8:9] = chr(type)
  elif header.formatVersion == 1:
    x = 0
    if type == ncchSection.exheader:
      x = 0x200 #ExHeader is always 0x200 bytes into the NCCH
    if type == ncchSection.exefs:
      x = header.exefsOffset * mediaUnitSize
    if type == ncchSection.romfs:
      x = header.romfsOffset * mediaUnitSize
    counter[:8] = bytearray(header.titleId)
    for i in xrange(4):
      counter[12+i] = chr((x>>((3-i)*8)) & 0xFF)
  
  return bytes(counter)


def parseNCSD(fh):
  print 'Parsing NCSD in file "%s":' % os.path.basename(fh.name)
  entries = 0
  data = ''
  
  fh.seek(0)
  header = ncsdHdr()
  fh.readinto(header) #Reads header into structure
  
  for i in xrange(len(header.offset_sizeTable)):
    if header.offset_sizeTable[i].offset:
      result = parseNCCH(fh, header.offset_sizeTable[i].offset * mediaUnitSize, i, reverseCtypeArray(header.titleId), 0)
      entries += result[0]
      data = data + result[1]
  return [entries, data]

def parseNCCH(fh, offs=0, idx=0, titleId='', standAlone=1):
  global ncch_title, ncch_offset 
  tab = '    ' if not standAlone else '  '
  if not standAlone and ncsdPartitions[idx] == "Main":
    print '  Parsing %s NCCH' % ncsdPartitions[idx]
  else:
    pass #print 'Parsing NCCH in file "%s":' % os.path.basename(fh.name)
  entries = 0
  data = ''
  
  fh.seek(offs)
  header = ncchHdr()
  fh.readinto(header) #Reads header into structure
  
  if titleId == '':
    titleId = reverseCtypeArray(header.titleId)
  
  keyY = bytearray(header.signature[:16])
  
  if not standAlone and ncsdPartitions[idx] == "Main":
    print tab + 'NCCH Offset: %08X' % offs
    print tab + 'Product code: ' + str(bytearray(header.productCode)).rstrip('\x00')
    ncch_offset = offs
  if not standAlone and ncsdPartitions[idx] == "Main":
    print tab + 'Partition number: %d' % idx
    print tab + 'KeyY: %s' % hexlify(keyY).upper()
    print tab + 'Title ID: %s' % reverseCtypeArray(header.titleId)
    ncch_title = reverseCtypeArray(header.titleId)
    print tab + 'Format version: %d' % header.formatVersion
  
  uses7xCrypto = bytearray(header.flags)[3]
  if uses7xCrypto:
    print tab + 'Uses 7.x NCCH crypto'
  
  print ''
  
  if header.exhdrSize:
    data = data + parseNCCHSection(header, ncchSection.exheader, 0, 1, tab, ncsdPartitions[idx] )
    data = data + genOutName(titleId, ncsdPartitions[idx], b'exheader')
    entries += 1
    print ''
  if header.exefsSize: #We need generate two xorpads for exefs if it uses 7.x crypto, since only a part of it uses the new crypto.
    data = data + parseNCCHSection(header, ncchSection.exefs, 0, 1, tab, ncsdPartitions[idx] )
    data = data + genOutName(titleId, ncsdPartitions[idx], b'exefs_norm')
    entries += 1
    if uses7xCrypto:
      data = data + parseNCCHSection(header, ncchSection.exefs, uses7xCrypto, 0, tab, ncsdPartitions[idx] )
      data = data + genOutName(titleId, ncsdPartitions[idx], b'exefs_7x')
      entries += 1
    print ''
  if header.romfsSize:
    data = data + parseNCCHSection(header, ncchSection.romfs, uses7xCrypto, 1, tab, ncsdPartitions[idx] )
    data = data + genOutName(titleId, ncsdPartitions[idx], b'romfs')
    entries += 1
    print ''
  
  print ''
  
  return [entries, data]

def parseNCCHSection(header, type, uses7xCrypto, doPrint, tab, partition_id):
  global romfs_offset, romfs_size
  if type == ncchSection.exheader:
    sectionName = 'ExHeader'
    offset = 0x200 #Always 0x200
    sectionSize = header.exhdrSize * mediaUnitSize
  elif type == ncchSection.exefs:
    sectionName = 'ExeFS'
    offset = header.exefsOffset * mediaUnitSize
    sectionSize = header.exefsSize * mediaUnitSize
  elif type == ncchSection.romfs:
    sectionName = 'RomFS'
    offset = header.romfsOffset * mediaUnitSize
    sectionSize = header.romfsSize * mediaUnitSize
  else:
    print 'Invalid NCCH section type was somehow passed in. :/'
    sys.exit()
  
  counter = getNcchAesCounter(header, type)
  keyY = bytearray(header.signature[:16])
  
  sectionMb = roundUp(sectionSize, 1024*1024) / (1024*1024)
  if sectionMb == 0:
    sectionMb = 1 #Should never happen, but meh.
  
  if doPrint and partition_id == "Main":
    if sectionName == "RomFS":
      romfs_offset = offset
      romfs_size   = sectionSize
    print tab + '%s offset:  %08X' % (sectionName, offset)
    print tab + '%s counter: %s' % (sectionName, hexlify(counter))
    print tab + '%s Megabytes(rounded up): %d' % (sectionName, sectionMb)
  
  return struct.pack('<16s16sIIII', str(counter), str(keyY), sectionMb, 0, 0, uses7xCrypto)

def genOutName(titleId, partitionName, sectionName):
  outName = b'sdmc:/%s.%s.%s.xorpad' % (titleId, partitionName, sectionName)
  outName = outName.encode('utf-16le') + b'\x00\x00'
  if len(outName) > 112:
    print "Output file name too large. This shouldn't happen."
    sys.exit()
  
  return outName + (b'\x00'*(112-len(outName))) #Pad out so whole entry is 160 bytes (48 bytes are set before filename)


if __name__ == "__main__":
   main(sys.argv[1:])
 
  • Like
Reactions: octopus

Ankoku

Active Member
Newcomer
Joined
Apr 25, 2010
Messages
39
Trophies
0
XP
119
Country
Malaysia
Some tidbit to report on the Persona Q undub:
Some major freezes.
Some voices, namely the battle quips, are still in English.
I'll update the list as I'll play through it.

Major issues:
Freezing when opening You in Wonderland's 100% map chest. (From the v1 undub apparently, the one with the tutorial crash.)

Minor audio issues:
Normal attack quips. Spells are unaffected.
Akihiko being knocked down (other characters might be affected)
Aigis missing (other characters might be affected)

Unconfirmed at the moment:
Elizabeth repeating a dialog in the beginning.
Elizabeth repeating another dialog during shop apron scene. ("Try it on" or something)
 
  • Like
Reactions: MarkDarkness

Canzah

Well-Known Member
OP
Member
Joined
Jul 8, 2012
Messages
492
Trophies
0
XP
1,410
Country
United Kingdom
I'm sure it's compatible with it then, seeing as I didn't change anything other than audio.
 

Shinon

Well-Known Member
Member
Joined
Jul 30, 2014
Messages
106
Trophies
0
Age
26
XP
182
Country
Malaysia
I'm sure it's compatible with it then, seeing as I didn't change anything other than audio.
canzah could you do more undubs? I want Starfox 64 3d ,devil summoner soul hackers ,spirit camera:cursed nemoir (us ver) etrian odesseyrune factkry 4 ptof layton ace artorney dual destinies tobe undub
 

Frieren

Well-Known Member
Newcomer
Joined
Oct 31, 2014
Messages
95
Trophies
0
XP
228
Country
Poland
etrian odesseyrune factkry 4
You can read about rune factory and etrian odyssey in this thread.
I done some more experiments with rune factory. I able to change almost all japanese text after some manual editing. But game randomly crashes after this no matter what i do.
So i decided to give up.
 

Canzah

Well-Known Member
OP
Member
Joined
Jul 8, 2012
Messages
492
Trophies
0
XP
1,410
Country
United Kingdom
canzah could you do more undubs? I want Starfox 64 3d ,devil summoner soul hackers ,spirit camera:cursed nemoir (us ver) etrian odesseyrune factkry 4 tobe undub
Sorry but I don't take requests. Soul Hackers currently is not possible due to the way it stores audio.

Also Persona Q Undub is finished, I'll make a thread for it in a moment, you'll have to find links yourself though in the "usual" places.
 

Shinon

Well-Known Member
Member
Joined
Jul 30, 2014
Messages
106
Trophies
0
Age
26
XP
182
Country
Malaysia
Sorry but I don't take requests. Soul Hackers currently is not possible due to the way it stores audio.

Also Persona Q Undub is finished, I'll make a thread for it in a moment, you'll have to find links yourself though in the "usual" places.

Tq!
 

OrangeFlavored

Well-Known Member
Newcomer
Joined
May 22, 2010
Messages
87
Trophies
0
XP
284
Country
United States
The idea of paid dlc is disgusting by definition

I think there's nothing wrong with it if it's used for the original purpose of DLC, which is to add content to the game after it has been released. In this case, provided the content is significant enough, I have no problem paying extra for their trouble in creating it after they've already released their game.

Of course if you're paying to unlock stuff already in the game, or that they made before its release but decided to hold back to nickle and dime you a bit more, then this is completely unethical and should be discouraged.
 

Ashtonx

n0l1f3
Member
Joined
Oct 31, 2013
Messages
514
Trophies
0
Age
37
XP
313
Country
Poland
And how many dlc's are like that ? handful, while there's ton of bullshit like locked content or short side missions
 

Arisato Minato

New Member
Newbie
Joined
Aug 8, 2013
Messages
3
Trophies
0
Age
34
XP
94
Country
Does using the Undub version corrupt your save file ?

When i load the Persona Q undub for the first time, it corrupted and deleted my save file so i want to ask just to make sure.
 

Askedforthis

Well-Known Member
Member
Joined
Oct 15, 2013
Messages
117
Trophies
0
Age
32
XP
170
Country
Norway
Does using the Undub version corrupt your save file ?

When i load the Persona Q undub for the first time, it corrupted and deleted my save file so i want to ask just to make sure.

No. No it shouldn't.

Sorry to hear about the corruption, my game hung once at the home menu as I was attempting to exit the game it and corrupted itself after starting it again, but it doesn't have anything to do with the undub, or at least it shouldn't. PQ has completely bulls*** save system that deletes the save data when it gets "corrupted".

The game should use the same header as the Persona Q VENOM release, so it should work just fine with the US game cartridge. At least I didn't have any problems during the four dungeons I played. The only files that were altered in our undub was the voices, some sound effects that included voices and the videos that were changed with the Japanese ones and we added subs to them.

If you plan on starting over again I'd highly recommend having several saves and taking backups once in a while. Corruption seems to be extremely rare, but can happen, so take no risks.
 
Status
Not open for further replies.

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    Xdqwerty @ Xdqwerty: