summaryrefslogtreecommitdiff
path: root/docs/tww_class_to_cpp.py
blob: ba531b76f3984ebab6e638dcd55d98992d859edf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# Dumps structure members to C format with comments and names
#@Pheenoh / Taka / LagoLunatic
#@category #Decomp
#@keybinding 
#@menupath 
#@toolbar 

import re

dtm = currentProgram.getDataTypeManager();

type_name = askString("Generate Struct Members", "Enter a data type name: ")
struct_path = type_name.replace("::", "/")
struct = dtm.getDataType("/" + struct_path)
if struct is None:
    struct = dtm.getDataType("/Demangler/" + struct_path)
if struct is None:
    raise Exception("Could not find struct with name: %s" % type_name)

size = struct.getLength()
size_str = str("{:X}".format(size))

offset_pad_size = len(size_str)

check = False
start_address = ""
member_name = ""
undefined_member_name = ""

datatype_remaps = {
    'byte': 'u8',
    'uchar': 'u8',
    'sbyte': 's8',
    'short': 's16',
    'ushort': 'u16',
    'undefined1': 'u8',
    'undefined2': 'u16',
    'undefined4': 'u32',
    'undefined1 *': 'u8*',
    'undefined2 *': 'u16*',
    'undefined4 *': 'u32*',
    #'int': 's32', # Breaks matches sometimes
    'long': 's32',
    'unsigned int': 'uint',
    'ulong': 'u32',
    'float': 'f32',
    'pointer': 'void*',
    'MTX34': 'Mtx',
    'MTX34 *': 'MtxP',
    #'PTMF': 
    'TVec3<float>': 'JGeometry::TVec3<f32>',
    '_GXColor': 'GXColor',
    '_GXColorS10': 'GXColorS10',
}

undefined_member_name_prefix = "field_0x"
# undefined_member_name_prefix = "m"

out_lines = []
for i in range (struct.getNumComponents()):
    data_type = str(struct.getComponent(i).getDataType().getName())
    offset = struct.getComponent(i).getOffset()
    hex_offset_string = str("%0*X" % (offset_pad_size, offset))
    
    if struct.getComponent(i).getFieldName() is not None:
        member_name = str(struct.getComponent(i).getFieldName())
    else:
        member_name = undefined_member_name_prefix+hex_offset_string
    
    if member_name in ["parent", "base"] and data_type in ['fopAc_ac_c', 'dBgS_MoveBgActor', 'fopNpc_npc_c', 'fopEn_enemy_c', 'daPy_py_c', 'daPy_npc_c']:
      if type_name.endswith("_class"):
        # C-style actors use composition instead of inheritance
        member_name = "actor"
      else:
        # Not a member, inheritance
        continue
    
    # if undefined member
    if data_type == 'undefined' or check == True:
        if data_type == 'undefined':
            if check == False:
                check = True
                start_address = hex_offset_string
            continue
        
        check = False
        undefined_member_name = undefined_member_name_prefix+start_address+"[0x"+hex_offset_string+" - 0x"+start_address+"]"
    
    if undefined_member_name != "":
        undefined_member_name = "    /* 0x" +start_address+" */ u8 "+undefined_member_name+";"
        out_lines.append(undefined_member_name)
        undefined_member_name = ""
    
    print(data_type)
    data_type = str(data_type)
    
    if data_type in datatype_remaps:
        data_type = datatype_remaps[data_type]
    
    if "[" in data_type:
        # move array to member name
        array_start_idx = data_type.find("[")
        array = data_type[array_start_idx:]
        data_type = data_type[0:array_start_idx]
        if data_type in datatype_remaps:
            data_type = datatype_remaps[data_type]
        member_name = member_name+array
    elif data_type == "char":
        data_type = "s8"
    
    if data_type == "PTMF": # Pointer to member function
        match = re.search("^mCurr?(\S+Func)$", member_name)
        if match:
          data_type = match.group(1)
        else:
          # Just guess at the return type and parameters
          data_type = "int"
          member_name = "("+type_name+"::*"+member_name+")()"
    
    member_string = "    /* 0x" +hex_offset_string+" */ "+str(data_type).replace(" ","")+" "+member_name+";"
    out_lines.append(member_string)

hex_end_offset_string = str("%0*X" % (offset_pad_size, struct.getLength()))
if check:
    undefined_member_name = undefined_member_name_prefix+start_address+"[0x"+hex_end_offset_string+" - 0x"+start_address+"]"
    member_string = "    /* 0x" +start_address+" */ "+"u8"+" "+undefined_member_name+";"
    out_lines.append(member_string)

out_lines.append("};  // Size: 0x%s" % hex_end_offset_string)

out_str = "\n".join(out_lines)
print(out_str)

# Copy to clipboard
from docking.dnd import GClipboard
from java.awt.datatransfer import Clipboard, StringSelection
clipboard = GClipboard.getSystemClipboard()
data = StringSelection(out_str)
clipboard.setContents(data, None)