ROM Hack [Release] Sm4shCommand

gudenau

Largely ignored
Member
Joined
Jul 7, 2010
Messages
3,882
Trophies
2
Location
/dev/random
Website
www.gudenau.net
XP
5,404
Country
United States
This is both fixed scripts merged.
Code:
import struct, sys, zlib, os
from collections import OrderedDict
from cStringIO import StringIO

dtfn, lsfn, outdir, dtlstype = sys.argv[1:]
if not os.path.exists(outdir):
    os.makedirs(outdir)
tmpPath = os.getcwd()+'/tmp'
if not os.path.exists(tmpPath):
    os.makedirs(tmpPath)
dtfp = open(dtfn, 'rb')
lsfp = open(lsfn, 'rb')
lsfp.read(4)
count, = struct.unpack('<I', lsfp.read(4))
dt_offsets = OrderedDict()
dt_total_size = 0
for i in xrange(count):
    if dtlstype == 'u':
        crc, start, size, dt_index, unk = struct.unpack('<IIIHH', lsfp.read(16)) #TODO: Apparently there's indexed dt files (ie dt00, dt01)
    else:
       crc, start, size = struct.unpack('<III', lsfp.read(12))
    dt_offsets[crc] = (start, size)
    dt_total_size += size
#assert lsfp.read(1) == ''

def get_file((start, size)):
    dtfp.seek(start)
    compressed = dtfp.read(size)
    data = compressed
    if compressed.startswith('\xcc\xcc\xcc\xcc'):
        z = compressed.find('\x78\x9c')
        if z != -1 and z <= 0x300:
            decompressed = zlib.decompress(compressed[z:])
            return decompressed, True
    return data, False

def invertify(msg):
    return ''.join(chr(~ord(msg[i]) & 0xff) for i in xrange(4)) + msg[4:]

def stupidcrc(filename):
    return zlib.crc32(invertify(filename)) & 0xffffffff

resource = dt_offsets[stupidcrc('resource')]
resource_data, was_compressed = get_file(resource)
open(tmpPath+'/resource.dec', 'wb').write(resource_data)
assert resource_data.startswith('RF')
offset_to_compressed, = struct.unpack('<I', resource_data[4:8])
rf, hl1, _, hl2, \
_0x18_entries_len, timestamp, compressed_len, decompressed_len, \
start_of_strs_plus, len_strs \
    = struct.unpack('<10I', resource_data[:0x28])

resource_dec = zlib.decompress(resource_data[offset_to_compressed:])
rdfp = StringIO(resource_dec)
open(tmpPath+'/resource.bin', 'wb').write(resource_dec)

rdfp.seek(start_of_strs_plus - hl1)
num_segments, = struct.unpack('<I', rdfp.read(4))
segments = [rdfp.read(0x2000) for seg in xrange(num_segments)]

def get_from_offset(off, len):
    # this is actually just a linear mapping, so pretty useless - but at least
    # this documents what needs to happen for any repackers
    seg_off = off & 0x1fff
    return segments[off / 0x2000][seg_off:seg_off + len]

parts = []
offset_parts = []

known_crcs = set()
resource_total_size = 0

if 1:
    num_offsets, = struct.unpack('<I', rdfp.read(4))
    extension_offsets = struct.unpack('<%dI' % num_offsets, rdfp.read(4 * num_offsets))
    extensions = []
    for i, exto in enumerate(extension_offsets):
        ext = get_from_offset(exto, 64)
        ext = ext[:ext.find('\0')]
        extensions.append(ext)
        #print i, repr(ext)

    rdfp.seek(0)
    num_8sized, = struct.unpack('<I', rdfp.read(4))
    rdfp.read(num_8sized * 8)
    another_size, = struct.unpack('<I', rdfp.read(4))
    rdfp.read(another_size)
    while rdfp.tell() < _0x18_entries_len:
        off_in_chunk, name_offset_etc, cmp_size, dec_size, timestamp, derp1 = struct.unpack('<IIIIII', rdfp.read(0x18))
        ext = name_offset_etc >> 24
        name_offset = name_offset_etc & 0xfffff
        name = get_from_offset(name_offset, 128)
        if name_offset_etc & 0x00800000:
            reference, = struct.unpack('<H', name[:2])
            ref_len = (reference & 0x1f) + 4
            ref_reloff = (reference & 0xe0) >> 6 << 8 | (reference >> 8)
            name = get_from_offset(name_offset - ref_reloff, ref_len) + name[2:]
        if '\0' in name:
            name = name[:name.find('\0')]
        name += extensions[ext]

        nesting_level = derp1 & 0xff
        localized = bool(derp1 & 0x800)
        final = bool(derp1 & 0x400)
        compressed = bool(derp1 & 0x200)
        parts = parts[:nesting_level - 1] + [name]


        path = ''.join(parts)

        if final:
            start, size = None, None
            crc_path = 'data/' + path.rstrip('/') + ('/packed' if compressed else '')
            crc = stupidcrc(crc_path)
            if crc in dt_offsets:
                offset = dt_offsets[crc]
            else:
                offset = None
        else:
            offset = None
        offset_parts = offset_parts[:nesting_level - 1] + [offset]

        outfn = os.path.join(outdir, path)
        if path.endswith('/'):
            if not os.path.exists(outfn):
                os.mkdir(outfn)
        else:
            for part in offset_parts[::-1]:
                if part is not None:
                    chunk_start, chunk_size = part
                    break
            else:
                if dtlstype == 'u':
                    continue
                else:
                    raise Exception("%s: nothing to look at" % path)
            assert off_in_chunk + cmp_size <= chunk_size
            dtfp.seek(chunk_start + off_in_chunk)
            cmp_data = dtfp.read(cmp_size)
            # XXX why isn't 'compressed' right?
            if cmp_data.startswith('x\x9c'):
                file_data = zlib.decompress(cmp_data)
            else:
                file_data = cmp_data
            assert len(file_data) == dec_size
            open(outfn, 'wb').write(file_data)


        resource_total_size += cmp_size

if 0:
    for missing in set(dt_offsets.keys()) - known_crcs:
        print 'Missing', missing

Edit:
Tell me as soon as you can edit the models/dt/ls, if you would.

Edit2:
Has anyone done anything fun with the debug files?
 
Last edited by gudenau,

Trinitro21

Well-Known Member
Member
Joined
Oct 14, 2015
Messages
133
Trophies
0
Location
Userland
XP
206
Country
United States
I'm having a problem with AnimCmd.
I opened a fighter, parsed the animations, edited a value, and saved. Then when I tried to open it again to make sure that it worked, AnimCmd crashed, without even the error dialog box popping up.
I tried this whole process repeatedly, extracting dt and ls again as well as making a backup, and kept getting the same results.
I think the problem might be in how AnimCmd saves the files, since it opens the unedited files but not the edited files.
 
  • Like
Reactions: Margen67

Sammi Husky

Well-Known Member
OP
Member
Joined
Jul 6, 2014
Messages
312
Trophies
0
Age
29
XP
498
Country
United States
Could you send me a copy of the files you were working with before and after editing? There really shouldn't be a reason for it to corrupt files.
 
  • Like
Reactions: Margen67

Trinitro21

Well-Known Member
Member
Joined
Oct 14, 2015
Messages
133
Trophies
0
Location
Userland
XP
206
Country
United States
Here are the files in animcmd\fighter\captain. I was trying to make the knee do 80%.
 

Attachments

  • captain-before.zip
    21.2 KB · Views: 192
  • captain-after.zip
    21.8 KB · Views: 186
  • Like
Reactions: Margen67

Sammi Husky

Well-Known Member
OP
Member
Joined
Jul 6, 2014
Messages
312
Trophies
0
Age
29
XP
498
Country
United States
Thanks. I know exactly what the problem is. Unfortunately i'm not sure if i'll be able to get around to fixing this until Saturday. What's more, this only affects 3ds users. Which kinda stinks since that's predominantly what console users have right now.
 
  • Like
Reactions: Margen67

darklordrs

Well-Known Member
Member
Joined
Aug 16, 2015
Messages
791
Trophies
0
Age
23
XP
434
Country
United States
Is there any tutorial or steps on how to get started? IM really interested in it and possible recreating of entire game
Definitely not going to be that easy at all - you sure as hell don't have the data necessary, honestly nobody does atm, but you're going to need a combination of

opensa.dantarion.com/s4/mastercore3/ Dantarion's Mastercore
http://opensa.dantarion.com/wiki/Category:SSB4-3DS_Documentation and his general S3DS documentation, specifically the Events
this program, for moveset editing
https://gbatemp.net/threads/tutoria...d-3ds-roms-run-xy-oras-without-update.383055/ PackHack English 3.5 from here, to extract and rebuild romfs
https://gbatemp.net/threads/braindump-prerelease-dump-game-contents-on-any-system-version.400920 for obvious reasons unless you have a ROM already
and the new dt rebuilder.. whenever that's a thing.

Ohana3DS should be able to edit models, such as for stages, though I have no idea how one would also edit collision for a stage.
 
  • Like
Reactions: Margen67

Trainer_Zorax

Member
Newcomer
Joined
Oct 30, 2015
Messages
5
Trophies
0
Age
24
XP
44
Country
United States
Definitely not going to be that easy at all - you sure as hell don't have the data necessary, honestly nobody does atm, but you're going to need a combination of

opensa.dantarion.com/s4/mastercore3/ Dantarion's Mastercore
http://opensa.dantarion.com/wiki/Category:SSB4-3DS_Documentation and his general S3DS documentation, specifically the Events
this program, for moveset editing
https://gbatemp.net/threads/tutoria...d-3ds-roms-run-xy-oras-without-update.383055/ PackHack English 3.5 from here, to extract and rebuild romfs
https://gbatemp.net/threads/braindump-prerelease-dump-game-contents-on-any-system-version.400920 for obvious reasons unless you have a ROM already
and the new dt rebuilder.. whenever that's a thing.

Ohana3DS should be able to edit models, such as for stages, though I have no idea how one would also edit collision for a stage.
yeah so far i got past the step and ripped the files in CMD so i dont know where to go from there
 
  • Like
Reactions: Margen67

darklordrs

Well-Known Member
Member
Joined
Aug 16, 2015
Messages
791
Trophies
0
Age
23
XP
434
Country
United States
yeah so far i got past the step and ripped the files in CMD so i dont know where to go from there
which step? If you mean everything down to the dt is ripped, open outputfolder>animcmd or whatever>fighter>the character you want to edit>game.bin (from the dt extract) in Sm4shCommand\AnimCMD. Then you can edit stuff freely using the info above until you're done, save and start reversing the unpacks.
 

Trainer_Zorax

Member
Newcomer
Joined
Oct 30, 2015
Messages
5
Trophies
0
Age
24
XP
44
Country
United States
which step? If you mean everything down to the dt is ripped, open outputfolder>animcmd or whatever>fighter>the character you want to edit>game.bin (from the dt extract) in Sm4shCommand\AnimCMD. Then you can edit stuff freely using the info above until you're done, save and start reversing the unpacks.

This is so far what i have, but not sure what to open in the ACMD
 

Attachments

  • smash bros file.png
    smash bros file.png
    10.2 KB · Views: 356

Sammi Husky

Well-Known Member
OP
Member
Joined
Jul 6, 2014
Messages
312
Trophies
0
Age
29
XP
498
Country
United States
This is so far what i have, but not sure what to open in the ACMD
You have to unpack the dt and ls files using the script posted earlier on this page. Then you will have the all the files.

Also, I'm probably going to refactor the front page with instructions on how to use the tool and it's features. Maybe video tut as well.
 

Trainer_Zorax

Member
Newcomer
Joined
Oct 30, 2015
Messages
5
Trophies
0
Age
24
XP
44
Country
United States
You have to unpack the dt and ls files using the script posted earlier on this page. Then you will have the all the files.

Also, I'm probably going to refactor the front page with instructions on how to use the tool and it's features. Maybe video tut as well.

so does that mean i have to restart?

Would instructions mean like from start like dumping the files from homebrew?
 

chaojimbo

Well-Known Member
Newcomer
Joined
Aug 25, 2015
Messages
97
Trophies
0
Age
27
Location
California
XP
144
Country
United States
Just a question. Would it be possible to implement L-canceling with this? As an example, pressing a shield button before hitting the floor triggers the "Smooth-Lander" item effect.

What about Melee's directional air-dodging?
 

Sammi Husky

Well-Known Member
OP
Member
Joined
Jul 6, 2014
Messages
312
Trophies
0
Age
29
XP
498
Country
United States
Just a question. Would it be possible to implement L-canceling with this? As an example, pressing a shield button before hitting the floor triggers the "Smooth-Lander" item effect.

What about Melee's directional air-dodging?

AFAIK, there is probably a command that sets the values loaded in by the param files on the fly in memory, in which case one of the params could be landing lag for all i know. Of course i wouldn't know how to hook into the L-cancel window anyways. So in short, maybe but probably not with this alone.

As far as melee air dodging, that would require new animations. And even then, this app doesn't deal with them at the moment. But probably in the future.
 
Last edited by Sammi Husky,

chaojimbo

Well-Known Member
Newcomer
Joined
Aug 25, 2015
Messages
97
Trophies
0
Age
27
Location
California
XP
144
Country
United States
AFAIK, there is probably a command that sets the values loaded in by the param files on the fly in memory, in which case one of the params could be landing lag for all i know. Of course i wouldn't know how to hook into the L-cancel window anyways. So in short, maybe but probably not with this alone.
Well if it's possible, you could hook it to the "tech-roll" window but keep it always active? I'm sorry; I know nothing about programming but just giving some ideas that might be possible.
 

Jonna

Some sort of musician.
Member
Joined
May 15, 2015
Messages
1,234
Trophies
1
Age
35
Location
Canada
Website
twitter.com
XP
3,153
Country
Canada
Definitely not going to be that easy at all - you sure as hell don't have the data necessary, honestly nobody does atm, but you're going to need a combination of

opensa.dantarion.com/s4/mastercore3/ Dantarion's Mastercore
http://opensa.dantarion.com/wiki/Category:SSB4-3DS_Documentation and his general S3DS documentation, specifically the Events
this program, for moveset editing
https://gbatemp.net/threads/tutoria...d-3ds-roms-run-xy-oras-without-update.383055/ PackHack English 3.5 from here, to extract and rebuild romfs
https://gbatemp.net/threads/braindump-prerelease-dump-game-contents-on-any-system-version.400920 for obvious reasons unless you have a ROM already
and the new dt rebuilder.. whenever that's a thing.

Ohana3DS should be able to edit models, such as for stages, though I have no idea how one would also edit collision for a stage.
I feel as though the collision is mapped to the model itself, as there obviously isn't preset collision data for custom-made stages.
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    Psionic Roshambo @ Psionic Roshambo: https://www.youtube.com/watch?v=MGhhGhvxbvI