mirror of https://github.com/zeldaret/mm.git
Normalize line endings
This commit is contained in:
parent
bfcc1d6a9a
commit
e45d0ef673
|
@ -1,20 +1,20 @@
|
||||||
*.z64
|
*.z64
|
||||||
*.bin
|
*.bin
|
||||||
*.elf
|
*.elf
|
||||||
doc/*
|
doc/*
|
||||||
archive/*
|
archive/*
|
||||||
build/*
|
build/*
|
||||||
baserom/*
|
baserom/*
|
||||||
decomp/*
|
decomp/*
|
||||||
S/*
|
S/*
|
||||||
asm/*
|
asm/*
|
||||||
font_test/*
|
font_test/*
|
||||||
ido/*
|
ido/*
|
||||||
__pychahe__/*
|
__pychahe__/*
|
||||||
*.pyc
|
*.pyc
|
||||||
test.txt
|
test.txt
|
||||||
*.xlsx
|
*.xlsx
|
||||||
src/test.c
|
src/test.c
|
||||||
*.dump
|
*.dump
|
||||||
tools/ido5.3_compiler/*
|
tools/ido5.3_compiler/*
|
||||||
tools/ido7.1_compiler/*
|
tools/ido7.1_compiler/*
|
|
@ -12,9 +12,9 @@ GLOBAL_ASM("./asm/nonmatching/z_scene/Scene_FindSceneObjectIndex.asm")
|
||||||
s32 Scene_IsObjectLoaded(SceneContext* iParm1, s32 index) {
|
s32 Scene_IsObjectLoaded(SceneContext* iParm1, s32 index) {
|
||||||
if (iParm1->objects[index].id > 0) {
|
if (iParm1->objects[index].id > 0) {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GLOBAL_ASM("./asm/nonmatching/z_scene/Scene_DmaAllObjects.asm")
|
GLOBAL_ASM("./asm/nonmatching/z_scene/Scene_DmaAllObjects.asm")
|
||||||
|
@ -25,34 +25,33 @@ GLOBAL_ASM("./asm/nonmatching/z_scene/func_8012F73C.asm")
|
||||||
#ifdef NONMATCHING
|
#ifdef NONMATCHING
|
||||||
// Regalloc differences only
|
// Regalloc differences only
|
||||||
void Scene_HeaderCommand00(GlobalContext* ctxt, SceneCmd* entry) {
|
void Scene_HeaderCommand00(GlobalContext* ctxt, SceneCmd* entry) {
|
||||||
|
|
||||||
ActorEntry* linkEntry;
|
ActorEntry* linkEntry;
|
||||||
s32 loadReturn;
|
s32 loadReturn;
|
||||||
void* objectVramAddr;
|
void* objectVramAddr;
|
||||||
s16 temp16;
|
s16 temp16;
|
||||||
|
|
||||||
linkEntry = (ActorEntry*)Lib_PtrSegToVirt((void*)entry->base.unk4) + (ctxt->entranceList[ctxt->curSpawn].spawn & 0xFF);
|
linkEntry = (ActorEntry*)Lib_PtrSegToVirt((void*)entry->base.unk4) + (ctxt->entranceList[ctxt->curSpawn].spawn & 0xFF);
|
||||||
ctxt->linkActorEntry = linkEntry;
|
ctxt->linkActorEntry = linkEntry;
|
||||||
|
|
||||||
if ( (ctxt->linkActorEntry->params & 0x0F00) >> 8 == 0x0C ||
|
if ( (ctxt->linkActorEntry->params & 0x0F00) >> 8 == 0x0C ||
|
||||||
(gSaveContext.extra.unk010 == 0x02 && gSaveContext.extra.unk042 == 0x0CFF)
|
(gSaveContext.extra.unk010 == 0x02 && gSaveContext.extra.unk042 == 0x0CFF)
|
||||||
) {
|
) {
|
||||||
Scene_LoadObject(&ctxt->sceneContext, 0x192);
|
Scene_LoadObject(&ctxt->sceneContext, 0x192);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
loadReturn = Scene_LoadObject(&ctxt->sceneContext, 0x11);
|
loadReturn = Scene_LoadObject(&ctxt->sceneContext, 0x11);
|
||||||
|
|
||||||
temp16 = (&ctxt->sceneContext)->unk8;
|
temp16 = (&ctxt->sceneContext)->unk8;
|
||||||
objectVramAddr = ctxt->sceneContext.objects[temp16].vramAddr;
|
objectVramAddr = ctxt->sceneContext.objects[temp16].vramAddr;
|
||||||
ctxt->sceneContext.unk8 = loadReturn & 0xFF;
|
ctxt->sceneContext.unk8 = loadReturn & 0xFF;
|
||||||
ctxt->sceneContext.unk9 = loadReturn & 0xFF;
|
ctxt->sceneContext.unk9 = loadReturn & 0xFF;
|
||||||
|
|
||||||
temp16 = D_801C2730[gSaveContext.perm.unk20];
|
temp16 = D_801C2730[gSaveContext.perm.unk20];
|
||||||
actorOverlayTable[0].initValues->objectDependency = temp16;
|
actorOverlayTable[0].initValues->objectDependency = temp16;
|
||||||
|
|
||||||
Scene_LoadObject(&ctxt->sceneContext, temp16);
|
Scene_LoadObject(&ctxt->sceneContext, temp16);
|
||||||
|
|
||||||
ctxt->sceneContext.objects[(&ctxt->sceneContext)->unk8].vramAddr = objectVramAddr;
|
ctxt->sceneContext.objects[(&ctxt->sceneContext)->unk8].vramAddr = objectVramAddr;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -73,7 +72,7 @@ void Scene_HeaderCommand01(GlobalContext* ctxt, SceneCmd* entry) {
|
||||||
// Scene Command 0x02: Cutscene Camera List
|
// Scene Command 0x02: Cutscene Camera List
|
||||||
void Scene_HeaderCommand02(GlobalContext* ctxt, SceneCmd* entry) {
|
void Scene_HeaderCommand02(GlobalContext* ctxt, SceneCmd* entry) {
|
||||||
ctxt->unk18858 = (UNK_PTR)Lib_PtrSegToVirt((void*)entry->base.unk4);
|
ctxt->unk18858 = (UNK_PTR)Lib_PtrSegToVirt((void*)entry->base.unk4);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scene Command 0x03: Collision Header
|
// Scene Command 0x03: Collision Header
|
||||||
void Scene_HeaderCommand03(GlobalContext* ctxt, SceneCmd* entry) {
|
void Scene_HeaderCommand03(GlobalContext* ctxt, SceneCmd* entry) {
|
||||||
|
@ -93,7 +92,7 @@ void Scene_HeaderCommand03(GlobalContext* ctxt, SceneCmd* entry) {
|
||||||
if (temp_s0->waterboxes != 0) {
|
if (temp_s0->waterboxes != 0) {
|
||||||
temp_s0->waterboxes = (BgWaterBox*)Lib_PtrSegToVirt(temp_s0->waterboxes);
|
temp_s0->waterboxes = (BgWaterBox*)Lib_PtrSegToVirt(temp_s0->waterboxes);
|
||||||
}
|
}
|
||||||
|
|
||||||
BgCheck_Init(&ctxt->bgCheckContext, ctxt, temp_s0);
|
BgCheck_Init(&ctxt->bgCheckContext, ctxt, temp_s0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,14 +108,14 @@ void Scene_HeaderCommand06(GlobalContext* ctxt, SceneCmd* entry) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scene Command 0x07: Special Files
|
// Scene Command 0x07: Special Files
|
||||||
void Scene_HeaderCommand07(GlobalContext* ctxt, SceneCmd* entry) {
|
void Scene_HeaderCommand07(GlobalContext* ctxt, SceneCmd* entry) {
|
||||||
if (entry->base.unk4 != 0) {
|
if (entry->base.unk4 != 0) {
|
||||||
ctxt->sceneContext.keepObjectId = Scene_LoadObject(&ctxt->sceneContext, entry->base.unk4);
|
ctxt->sceneContext.keepObjectId = Scene_LoadObject(&ctxt->sceneContext, entry->base.unk4);
|
||||||
gRspSegmentPhysAddrs[5] = (u32)(ctxt->sceneContext.objects[ctxt->sceneContext.keepObjectId].vramAddr) + 0x80000000;
|
gRspSegmentPhysAddrs[5] = (u32)(ctxt->sceneContext.objects[ctxt->sceneContext.keepObjectId].vramAddr) + 0x80000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry->base.unk1 != 0) {
|
if (entry->base.unk1 != 0) {
|
||||||
// TODO:
|
// TODO:
|
||||||
// OOT has D_801C2650's equivalent as a list of navi messages that store SceneTableEntry structs.
|
// OOT has D_801C2650's equivalent as a list of navi messages that store SceneTableEntry structs.
|
||||||
// This needs to be something like (SceneTableEntry*)(&D_801C2650[entry->unk1])
|
// This needs to be something like (SceneTableEntry*)(&D_801C2650[entry->unk1])
|
||||||
// Currently D_801C2650 is not typed so that can't be completed at this moment.
|
// Currently D_801C2650 is not typed so that can't be completed at this moment.
|
||||||
|
@ -167,7 +166,7 @@ GLOBAL_ASM("./asm/nonmatching/z_scene/Scene_HeaderCommand13.asm")
|
||||||
|
|
||||||
// Scene Command 0x09: Undefined
|
// Scene Command 0x09: Undefined
|
||||||
void Scene_HeaderCommand09(GlobalContext* ctxt, SceneCmd* entry) {
|
void Scene_HeaderCommand09(GlobalContext* ctxt, SceneCmd* entry) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLOBAL_ASM("./asm/nonmatching/z_scene/Scene_HeaderCommand15.asm")
|
GLOBAL_ASM("./asm/nonmatching/z_scene/Scene_HeaderCommand15.asm")
|
||||||
|
@ -188,7 +187,7 @@ GLOBAL_ASM("./asm/nonmatching/z_scene/Scene_HeaderCommand1C.asm")
|
||||||
|
|
||||||
// Scene Command 0x1D: Undefined
|
// Scene Command 0x1D: Undefined
|
||||||
void Scene_HeaderCommand1D(GlobalContext* ctxt, SceneCmd* entry) {
|
void Scene_HeaderCommand1D(GlobalContext* ctxt, SceneCmd* entry) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLOBAL_ASM("./asm/nonmatching/z_scene/Scene_HeaderCommand1E.asm")
|
GLOBAL_ASM("./asm/nonmatching/z_scene/Scene_HeaderCommand1E.asm")
|
||||||
|
|
1244
tables/files.py
1244
tables/files.py
File diff suppressed because it is too large
Load Diff
|
@ -1,13 +1,13 @@
|
||||||
# Follows the format of Address:(Name, Type, Array Info, Size)
|
# Follows the format of Address:(Name, Type, Array Info, Size)
|
||||||
{
|
{
|
||||||
0x80000300:("osTvType","UNK_TYPE","",0x4),
|
0x80000300:("osTvType","UNK_TYPE","",0x4),
|
||||||
0x80000304:("osRomType","UNK_TYPE","",0x4),
|
0x80000304:("osRomType","UNK_TYPE","",0x4),
|
||||||
0x80000308:("osRomBase","UNK_TYPE","",0x4),
|
0x80000308:("osRomBase","UNK_TYPE","",0x4),
|
||||||
0x8000030C:("osResetType","UNK_TYPE","",0x4),
|
0x8000030C:("osResetType","UNK_TYPE","",0x4),
|
||||||
0x80000310:("osCicId","UNK_TYPE","",0x4),
|
0x80000310:("osCicId","UNK_TYPE","",0x4),
|
||||||
0x80000314:("osVersion","UNK_TYPE","",0x4),
|
0x80000314:("osVersion","UNK_TYPE","",0x4),
|
||||||
0x80000318:("osMemSize","UNK_TYPE","",0x4),
|
0x80000318:("osMemSize","UNK_TYPE","",0x4),
|
||||||
0x8000031C:("D_8000031C","UNK_TYPE","",0x4), # TODO size
|
0x8000031C:("D_8000031C","UNK_TYPE","",0x4), # TODO size
|
||||||
0x80000500:("D_80000500","UNK_TYPE","",0x1), # TODO size
|
0x80000500:("D_80000500","UNK_TYPE","",0x1), # TODO size
|
||||||
0x80025D00:("D_80025D00","UNK_TYPE","",0x1), # TODO size
|
0x80025D00:("D_80025D00","UNK_TYPE","",0x1), # TODO size
|
||||||
}
|
}
|
|
@ -1,68 +1,68 @@
|
||||||
# Follows the format of Address:(Name, Type, Array Info, Size)
|
# Follows the format of Address:(Name, Type, Array Info, Size)
|
||||||
{
|
{
|
||||||
# NOTE These symbols could be one of two symbols: the start of a file or the end of a file before it.
|
# NOTE These symbols could be one of two symbols: the start of a file or the end of a file before it.
|
||||||
# The choice for disassembly is arbitrary but in code it should be the one that makes sense.
|
# The choice for disassembly is arbitrary but in code it should be the one that makes sense.
|
||||||
0x0001A500:("dmadata_vrom_start","u32","",0x4), # Start of dmadata
|
0x0001A500:("dmadata_vrom_start","u32","",0x4), # Start of dmadata
|
||||||
0x00020700:("dmadata_vrom_end","u32","",0x4), # Byte immediately after end of dmadata
|
0x00020700:("dmadata_vrom_end","u32","",0x4), # Byte immediately after end of dmadata
|
||||||
0x00046AF0:("Audioseq_vrom_start","UNK_TYPE","",0x4),
|
0x00046AF0:("Audioseq_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x00097F70:("Audioseq_vrom_end","UNK_TYPE","",0x4),
|
0x00097F70:("Audioseq_vrom_end","UNK_TYPE","",0x4),
|
||||||
0x0065D000:("link_animetion_vrom_start","UNK_TYPE","",0x4),
|
0x0065D000:("link_animetion_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x00957000:("","UNK_TYPE","",0x4), # ovl_kaleido_scope uses this. It is the start of vrom for a null entry in dmadata???
|
0x00957000:("","UNK_TYPE","",0x4), # ovl_kaleido_scope uses this. It is the start of vrom for a null entry in dmadata???
|
||||||
0x009ECEC0:("","UNK_TYPE","",0x4), # ovl_kaleido_scope uses this. It is the end of vrom for a null entry in dmadata???
|
0x009ECEC0:("","UNK_TYPE","",0x4), # ovl_kaleido_scope uses this. It is the end of vrom for a null entry in dmadata???
|
||||||
0x009ED000:("","UNK_TYPE","",0x4), # ovl_kaleido_scope uses this. It is the start of vrom for a null entry in dmadata???
|
0x009ED000:("","UNK_TYPE","",0x4), # ovl_kaleido_scope uses this. It is the start of vrom for a null entry in dmadata???
|
||||||
0x009F4700:("","UNK_TYPE","",0x4), # ovl_kaleido_scope uses this. It is the end of vrom for a null entry in dmadata???
|
0x009F4700:("","UNK_TYPE","",0x4), # ovl_kaleido_scope uses this. It is the end of vrom for a null entry in dmadata???
|
||||||
0x009F5000:("icon_item_field_static_vrom_start","UNK_TYPE","",0x4),
|
0x009F5000:("icon_item_field_static_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x00A09AF0:("icon_item_field_static_vrom_end","UNK_TYPE","",0x4),
|
0x00A09AF0:("icon_item_field_static_vrom_end","UNK_TYPE","",0x4),
|
||||||
0x00A0A000:("icon_item_dungeon_static_vrom_start","UNK_TYPE","",0x4),
|
0x00A0A000:("icon_item_dungeon_static_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x00A0EB80:("icon_item_dungeon_static_vrom_end","UNK_TYPE","",0x4),
|
0x00A0EB80:("icon_item_dungeon_static_vrom_end","UNK_TYPE","",0x4),
|
||||||
0x00A0F000:("icon_item_gameover_static_vrom_start","UNK_TYPE","",0x4),
|
0x00A0F000:("icon_item_gameover_static_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x00A12300:("icon_item_gameover_static_vrom_end","UNK_TYPE","",0x4),
|
0x00A12300:("icon_item_gameover_static_vrom_end","UNK_TYPE","",0x4),
|
||||||
0x00A13000:("_013_0x00963540_vrom_start","UNK_TYPE","",0x4),
|
0x00A13000:("_013_0x00963540_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x00A1BA00:("_013_0x00963540_vrom_end","UNK_TYPE","",0x4),
|
0x00A1BA00:("_013_0x00963540_vrom_end","UNK_TYPE","",0x4),
|
||||||
0x00A1C000:("_014_0x00967260_vrom_start","UNK_TYPE","",0x4),
|
0x00A1C000:("_014_0x00967260_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x00A1C2E0:("_014_0x00967260_vrom_end","UNK_TYPE","",0x4),
|
0x00A1C2E0:("_014_0x00967260_vrom_end","UNK_TYPE","",0x4),
|
||||||
0x00A1D000:("map_i_static_vrom_start","UNK_TYPE","",0x4),
|
0x00A1D000:("map_i_static_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x00A1E310:("map_grand_static_vrom_start","UNK_TYPE","",0x4),
|
0x00A1E310:("map_grand_static_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x00A27660:("item_name_static_vrom_start","UNK_TYPE","",0x4),
|
0x00A27660:("item_name_static_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x00A352F0:("map_name_static_vrom_start","UNK_TYPE","",0x4),
|
0x00A352F0:("map_name_static_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x00A36C10:("_019_0x00980f60_vrom_start","UNK_TYPE","",0x4),
|
0x00A36C10:("_019_0x00980f60_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x00A7BEE0:("_020_0x009c6230_vrom_start","UNK_TYPE","",0x4),
|
0x00A7BEE0:("_020_0x009c6230_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x00A807A0:("_020_0x009c6230_vrom_end","UNK_TYPE","",0x4),
|
0x00A807A0:("_020_0x009c6230_vrom_end","UNK_TYPE","",0x4),
|
||||||
0x00A8C000:("_022_0x009caaf0_vrom_start","UNK_TYPE","",0x4),
|
0x00A8C000:("_022_0x009caaf0_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x00A92A10:("_023_0x009d1500_vrom_start","UNK_TYPE","",0x4),
|
0x00A92A10:("_023_0x009d1500_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x00A990E0:("_023_0x009d1500_vrom_end","UNK_TYPE","",0x4),
|
0x00A990E0:("_023_0x009d1500_vrom_end","UNK_TYPE","",0x4),
|
||||||
0x00A9A000:("_024_0x009d3760_vrom_start","UNK_TYPE","",0x4),
|
0x00A9A000:("_024_0x009d3760_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x00ABFC00:("_024_0x009d3760_vrom_end","UNK_TYPE","",0x4),
|
0x00ABFC00:("_024_0x009d3760_vrom_end","UNK_TYPE","",0x4),
|
||||||
0x00AC0000:("do_action_static_vrom_start","UNK_TYPE","",0x4),
|
0x00AC0000:("do_action_static_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x00AC4000:("message_static_vrom_start","UNK_TYPE","",0x4),
|
0x00AC4000:("message_static_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x00ACA000:("message_texture_static_vrom_start","UNK_TYPE","",0x4),
|
0x00ACA000:("message_texture_static_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x00ACC000:("nes_font_static_vrom_start","UNK_TYPE","",0x4),
|
0x00ACC000:("nes_font_static_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x00AD1000:("en_message_data_static_vrom_start","UNK_TYPE","",0x4),
|
0x00AD1000:("en_message_data_static_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x00B3B000:("staff_message_data_static_vrom_start","UNK_TYPE","",0x4),
|
0x00B3B000:("staff_message_data_static_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x00B3C000:("code_vrom_start","UNK_TYPE","",0x4),
|
0x00B3C000:("code_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x00C7A4E0:("code_vrom_end","UNK_TYPE","",0x4),
|
0x00C7A4E0:("code_vrom_end","UNK_TYPE","",0x4),
|
||||||
0x01E85000:("nintendo_rogo_static_vrom_start","UNK_TYPE","",0x4),
|
0x01E85000:("nintendo_rogo_static_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x01E87DC0:("nintendo_rogo_static_vrom_end","UNK_TYPE","",0x4),
|
0x01E87DC0:("nintendo_rogo_static_vrom_end","UNK_TYPE","",0x4),
|
||||||
0x01E88000:("title_static_vrom_start","UNK_TYPE","",0x4),
|
0x01E88000:("title_static_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x01EB9730:("title_static_vrom_end","UNK_TYPE","",0x4),
|
0x01EB9730:("title_static_vrom_end","UNK_TYPE","",0x4),
|
||||||
0x01EBA000:("_1124_0x0163f490_vrom_start","UNK_TYPE","",0x4),
|
0x01EBA000:("_1124_0x0163f490_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x01EBB280:("_1124_0x0163f490_vrom_end","UNK_TYPE","",0x4),
|
0x01EBB280:("_1124_0x0163f490_vrom_end","UNK_TYPE","",0x4),
|
||||||
0x01EBC000:("_1125_0x0163fc10_vrom_start","UNK_TYPE","",0x4),
|
0x01EBC000:("_1125_0x0163fc10_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x01EBC680:("_1125_0x0163fc10_vrom_end","UNK_TYPE","",0x4),
|
0x01EBC680:("_1125_0x0163fc10_vrom_end","UNK_TYPE","",0x4),
|
||||||
0x01EBD000:("_1126_0x0163ffc0_vrom_start","UNK_TYPE","",0x4),
|
0x01EBD000:("_1126_0x0163ffc0_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x01EC8B20:("_1126_0x0163ffc0_vrom_end","UNK_TYPE","",0x4),
|
0x01EC8B20:("_1126_0x0163ffc0_vrom_end","UNK_TYPE","",0x4),
|
||||||
0x01EC9000:("_1127_0x01643d50_vrom_start","UNK_TYPE","",0x4),
|
0x01EC9000:("_1127_0x01643d50_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x01EC9F30:("_1127_0x01643d50_vrom_end","UNK_TYPE","",0x4),
|
0x01EC9F30:("_1127_0x01643d50_vrom_end","UNK_TYPE","",0x4),
|
||||||
0x01ECA000:("_1128_0x01644c80_vrom_start","UNK_TYPE","",0x4),
|
0x01ECA000:("_1128_0x01644c80_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x01ED3B00:("_1128_0x01644c80_vrom_end","UNK_TYPE","",0x4),
|
0x01ED3B00:("_1128_0x01644c80_vrom_end","UNK_TYPE","",0x4),
|
||||||
0x01ED4000:("_1129_0x01646b60_vrom_start","UNK_TYPE","",0x4),
|
0x01ED4000:("_1129_0x01646b60_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x01EDDB00:("_1129_0x01646b60_vrom_end","UNK_TYPE","",0x4),
|
0x01EDDB00:("_1129_0x01646b60_vrom_end","UNK_TYPE","",0x4),
|
||||||
0x01EDE000:("_1130_0x01649020_vrom_start","UNK_TYPE","",0x4),
|
0x01EDE000:("_1130_0x01649020_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x01EE7B00:("_1130_0x01649020_vrom_end","UNK_TYPE","",0x4),
|
0x01EE7B00:("_1130_0x01649020_vrom_end","UNK_TYPE","",0x4),
|
||||||
0x01EE8000:("_1131_0x0164ad90_vrom_start","UNK_TYPE","",0x4),
|
0x01EE8000:("_1131_0x0164ad90_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x01EF1B00:("_1131_0x0164ad90_vrom_end","UNK_TYPE","",0x4),
|
0x01EF1B00:("_1131_0x0164ad90_vrom_end","UNK_TYPE","",0x4),
|
||||||
0x01EF2000:("vr_fine_static_vrom_start","UNK_TYPE","",0x4),
|
0x01EF2000:("vr_fine_static_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x01EFE000:("vr_cloud_static_vrom_start","UNK_TYPE","",0x4),
|
0x01EFE000:("vr_cloud_static_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x01F0A000:("vr_pal_static_vrom_start","UNK_TYPE","",0x4),
|
0x01F0A000:("vr_pal_static_vrom_start","UNK_TYPE","",0x4),
|
||||||
0x01F0A200:("vr_pal_static_vrom_end","UNK_TYPE","",0x4),
|
0x01F0A200:("vr_pal_static_vrom_end","UNK_TYPE","",0x4),
|
||||||
}
|
}
|
7950
textures.csv
7950
textures.csv
File diff suppressed because it is too large
Load Diff
2034
tools/disasm.py
2034
tools/disasm.py
File diff suppressed because it is too large
Load Diff
|
@ -1,178 +1,178 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import struct;
|
import struct;
|
||||||
from tkinter import *;
|
from tkinter import *;
|
||||||
from tkinter.ttk import *
|
from tkinter.ttk import *
|
||||||
from PIL import Image, ImageTk, ImageDraw
|
from PIL import Image, ImageTk, ImageDraw
|
||||||
|
|
||||||
import png;
|
import png;
|
||||||
|
|
||||||
#FILE_NAME = 'baserom/jpn_font_static'
|
#FILE_NAME = 'baserom/jpn_font_static'
|
||||||
FILE_NAME = 'decomp/object_boss03'
|
FILE_NAME = 'decomp/object_boss03'
|
||||||
|
|
||||||
data = []
|
data = []
|
||||||
image_data = [];
|
image_data = [];
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(FILE_NAME, 'rb') as f:
|
with open(FILE_NAME, 'rb') as f:
|
||||||
data = f.read()
|
data = f.read()
|
||||||
except IOError:
|
except IOError:
|
||||||
print('failed to read file ' + FILE_NAME)
|
print('failed to read file ' + FILE_NAME)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
#size = 0x80
|
#size = 0x80
|
||||||
height = 32
|
height = 32
|
||||||
width = 32
|
width = 32
|
||||||
pixel_width = 2
|
pixel_width = 2
|
||||||
size = height*width*pixel_width
|
size = height*width*pixel_width
|
||||||
scale = 4
|
scale = 4
|
||||||
|
|
||||||
window = Tk()
|
window = Tk()
|
||||||
|
|
||||||
window.title("MM Texture viewer")
|
window.title("MM Texture viewer")
|
||||||
window.geometry('500x500')
|
window.geometry('500x500')
|
||||||
|
|
||||||
def load_file():
|
def load_file():
|
||||||
print('load')
|
print('load')
|
||||||
update_image()
|
update_image()
|
||||||
|
|
||||||
def read_i4_image(data, image_data):
|
def read_i4_image(data, image_data):
|
||||||
for i in range(0, len(data)):
|
for i in range(0, len(data)):
|
||||||
byte = data[i]
|
byte = data[i]
|
||||||
color1 = ((byte >> 4) & 0xF) * 17
|
color1 = ((byte >> 4) & 0xF) * 17
|
||||||
color2 = (byte & 0xF) * 17
|
color2 = (byte & 0xF) * 17
|
||||||
image_data.append(color1)
|
image_data.append(color1)
|
||||||
image_data.append(color1)
|
image_data.append(color1)
|
||||||
image_data.append(color1)
|
image_data.append(color1)
|
||||||
image_data.append(255)
|
image_data.append(255)
|
||||||
image_data.append(color2)
|
image_data.append(color2)
|
||||||
image_data.append(color2)
|
image_data.append(color2)
|
||||||
image_data.append(color2)
|
image_data.append(color2)
|
||||||
image_data.append(255)
|
image_data.append(255)
|
||||||
|
|
||||||
def read_i8_image(data, image_data):
|
def read_i8_image(data, image_data):
|
||||||
for i in range(0, len(data)):
|
for i in range(0, len(data)):
|
||||||
byte = data[i]
|
byte = data[i]
|
||||||
image_data.append(byte)
|
image_data.append(byte)
|
||||||
image_data.append(byte)
|
image_data.append(byte)
|
||||||
image_data.append(byte)
|
image_data.append(byte)
|
||||||
image_data.append(255)
|
image_data.append(255)
|
||||||
|
|
||||||
def read_ia4_image(data, image_data):
|
def read_ia4_image(data, image_data):
|
||||||
None
|
None
|
||||||
|
|
||||||
def read_ia8_image(data, image_data):
|
def read_ia8_image(data, image_data):
|
||||||
None
|
None
|
||||||
|
|
||||||
def read_ia16_image(data, image_data):
|
def read_ia16_image(data, image_data):
|
||||||
None
|
None
|
||||||
|
|
||||||
def read_rbg5a1_image(data, image_data):
|
def read_rbg5a1_image(data, image_data):
|
||||||
for i in range(0, len(data) // 2):
|
for i in range(0, len(data) // 2):
|
||||||
byte1 = data[i*2]
|
byte1 = data[i*2]
|
||||||
byte2 = data[i*2 + 1]
|
byte2 = data[i*2 + 1]
|
||||||
red = (byte1 >> 3)*8
|
red = (byte1 >> 3)*8
|
||||||
green = (((byte1&0x7)<<2) | ((byte2>>6)&0x3))*8
|
green = (((byte1&0x7)<<2) | ((byte2>>6)&0x3))*8
|
||||||
blue = ((byte2 >> 1) & 0x1F)*8
|
blue = ((byte2 >> 1) & 0x1F)*8
|
||||||
alpha = (byte2&0x1)*0xFF
|
alpha = (byte2&0x1)*0xFF
|
||||||
image_data.append(red)
|
image_data.append(red)
|
||||||
image_data.append(green)
|
image_data.append(green)
|
||||||
image_data.append(blue)
|
image_data.append(blue)
|
||||||
image_data.append(alpha)
|
image_data.append(alpha)
|
||||||
|
|
||||||
def read_rbga32_image(data, image_data):
|
def read_rbga32_image(data, image_data):
|
||||||
for i in range(0, len(data)):
|
for i in range(0, len(data)):
|
||||||
byte = data[i]
|
byte = data[i]
|
||||||
image_data.append(byte)
|
image_data.append(byte)
|
||||||
|
|
||||||
def read_ci4_image(data, image_data):
|
def read_ci4_image(data, image_data):
|
||||||
None
|
None
|
||||||
|
|
||||||
def read_ci8_image(data, image_data):
|
def read_ci8_image(data, image_data):
|
||||||
None
|
None
|
||||||
|
|
||||||
def update_image(*args):
|
def update_image(*args):
|
||||||
global image_label
|
global image_label
|
||||||
global image_data
|
global image_data
|
||||||
global data
|
global data
|
||||||
|
|
||||||
image_data = []
|
image_data = []
|
||||||
|
|
||||||
texture_type = texture_type_combo.get()
|
texture_type = texture_type_combo.get()
|
||||||
if texture_type == 'i4':
|
if texture_type == 'i4':
|
||||||
read_i4_image(data, image_data)
|
read_i4_image(data, image_data)
|
||||||
elif texture_type == 'i8':
|
elif texture_type == 'i8':
|
||||||
read_i8_image(data, image_data)
|
read_i8_image(data, image_data)
|
||||||
elif texture_type == 'ia4':
|
elif texture_type == 'ia4':
|
||||||
read_ia4_image(data, image_data)
|
read_ia4_image(data, image_data)
|
||||||
elif texture_type == 'ia8':
|
elif texture_type == 'ia8':
|
||||||
read_ia8_image(data, image_data)
|
read_ia8_image(data, image_data)
|
||||||
elif texture_type == 'ia16':
|
elif texture_type == 'ia16':
|
||||||
read_ia16_image(data, image_data)
|
read_ia16_image(data, image_data)
|
||||||
elif texture_type == 'rbg5a1':
|
elif texture_type == 'rbg5a1':
|
||||||
read_rbg5a1_image(data, image_data)
|
read_rbg5a1_image(data, image_data)
|
||||||
elif texture_type == 'rbga32':
|
elif texture_type == 'rbga32':
|
||||||
read_rbga32_image(data, image_data)
|
read_rbga32_image(data, image_data)
|
||||||
elif texture_type == 'ci4':
|
elif texture_type == 'ci4':
|
||||||
read_ci4_image(data, image_data)
|
read_ci4_image(data, image_data)
|
||||||
elif texture_type == 'ci8':
|
elif texture_type == 'ci8':
|
||||||
read_ci8_image(data, image_data)
|
read_ci8_image(data, image_data)
|
||||||
else:
|
else:
|
||||||
print('other type')
|
print('other type')
|
||||||
|
|
||||||
offset = int(offset_spinbox.get())
|
offset = int(offset_spinbox.get())
|
||||||
|
|
||||||
image = Image.frombytes("RGBA", (width, height), bytes(image_data[offset*4:])).resize((width*scale, height*scale))
|
image = Image.frombytes("RGBA", (width, height), bytes(image_data[offset*4:])).resize((width*scale, height*scale))
|
||||||
image_tk = ImageTk.PhotoImage(image=image)
|
image_tk = ImageTk.PhotoImage(image=image)
|
||||||
image_label.configure(image=image_tk)
|
image_label.configure(image=image_tk)
|
||||||
image_label.image = image_tk # prevent GC?
|
image_label.image = image_tk # prevent GC?
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
load_button = Button(window, text='Load File', command=load_file)
|
load_button = Button(window, text='Load File', command=load_file)
|
||||||
load_button.pack()
|
load_button.pack()
|
||||||
|
|
||||||
texture_type_combo = Combobox(window)
|
texture_type_combo = Combobox(window)
|
||||||
texture_type_combo['values'] = ('i4', 'i8', 'ia4', 'ia8', 'ia16', 'rbg5a1', 'rbga32', 'ci4', 'ci8')
|
texture_type_combo['values'] = ('i4', 'i8', 'ia4', 'ia8', 'ia16', 'rbg5a1', 'rbga32', 'ci4', 'ci8')
|
||||||
texture_type_combo.current(5)
|
texture_type_combo.current(5)
|
||||||
texture_type_combo.bind("<<ComboboxSelected>>", update_image)
|
texture_type_combo.bind("<<ComboboxSelected>>", update_image)
|
||||||
texture_type_combo.pack()
|
texture_type_combo.pack()
|
||||||
|
|
||||||
# TODO textures should be able to only take a few discret values, find them
|
# TODO textures should be able to only take a few discret values, find them
|
||||||
width_default = StringVar(window)
|
width_default = StringVar(window)
|
||||||
width_default.set("32")
|
width_default.set("32")
|
||||||
width_spinbox = Spinbox(window, from_=1, to=48, textvariable=width_default, command=update_image)
|
width_spinbox = Spinbox(window, from_=1, to=48, textvariable=width_default, command=update_image)
|
||||||
width_spinbox.pack();
|
width_spinbox.pack();
|
||||||
|
|
||||||
offset_default = StringVar(window)
|
offset_default = StringVar(window)
|
||||||
offset_default.set("0")
|
offset_default.set("0")
|
||||||
offset_spinbox = Spinbox(window, from_=0, to=len(data), textvariable=offset_default, command=update_image)
|
offset_spinbox = Spinbox(window, from_=0, to=len(data), textvariable=offset_default, command=update_image)
|
||||||
offset_spinbox.pack();
|
offset_spinbox.pack();
|
||||||
|
|
||||||
image_label = Label(window)
|
image_label = Label(window)
|
||||||
image_label.pack()
|
image_label.pack()
|
||||||
|
|
||||||
update_image()
|
update_image()
|
||||||
|
|
||||||
window.mainloop()
|
window.mainloop()
|
||||||
|
|
||||||
#for i in range(0, len(data) // size):
|
#for i in range(0, len(data) // size):
|
||||||
# texture_data = data[(i * size):((i + 1) * size)]
|
# texture_data = data[(i * size):((i + 1) * size)]
|
||||||
#
|
#
|
||||||
# with open('font_test2/' + str(i) + '.png', 'wb') as f:
|
# with open('font_test2/' + str(i) + '.png', 'wb') as f:
|
||||||
# w = png.Writer(width, height, alpha=True)#, greyscale=True)#
|
# w = png.Writer(width, height, alpha=True)#, greyscale=True)#
|
||||||
# png_data = [];
|
# png_data = [];
|
||||||
# for y in range(0, height):
|
# for y in range(0, height):
|
||||||
# row = []
|
# row = []
|
||||||
# '''
|
# '''
|
||||||
# for x in range(0, 16//2):
|
# for x in range(0, 16//2):
|
||||||
# byte = texture_data[8*y + x]
|
# byte = texture_data[8*y + x]
|
||||||
# row.append(((byte >> 4) & 0xF) * 17)
|
# row.append(((byte >> 4) & 0xF) * 17)
|
||||||
# row.append((byte & 0xF) * 17)
|
# row.append((byte & 0xF) * 17)
|
||||||
# '''
|
# '''
|
||||||
# '''
|
# '''
|
||||||
# for x in range(0, width*pixel_width):
|
# for x in range(0, width*pixel_width):
|
||||||
# byte = texture_data[width*pixel_width*y + x]
|
# byte = texture_data[width*pixel_width*y + x]
|
||||||
# row.append(byte)
|
# row.append(byte)
|
||||||
# '''
|
# '''
|
||||||
# png_data.append(row)
|
# png_data.append(row)
|
||||||
# w.write(f, png_data)
|
# w.write(f, png_data)
|
130
tools/overlay.py
130
tools/overlay.py
|
@ -1,65 +1,65 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import sys, argparse
|
import sys, argparse
|
||||||
|
|
||||||
from elftools.elf.elffile import ELFFile
|
from elftools.elf.elffile import ELFFile
|
||||||
from elftools.elf.relocation import RelocationSection
|
from elftools.elf.relocation import RelocationSection
|
||||||
|
|
||||||
def get_section_type_from_name(name):
|
def get_section_type_from_name(name):
|
||||||
if name == '.text':
|
if name == '.text':
|
||||||
return 1
|
return 1
|
||||||
elif name == '.data':
|
elif name == '.data':
|
||||||
return 2
|
return 2
|
||||||
elif name == '.rodata':
|
elif name == '.rodata':
|
||||||
return 3
|
return 3
|
||||||
elif name == '.bss': # TODO is this actually a thing? It doesn't fit in 2 bits and why would there be a relocation in .bss?
|
elif name == '.bss': # TODO is this actually a thing? It doesn't fit in 2 bits and why would there be a relocation in .bss?
|
||||||
return 4
|
return 4
|
||||||
else:
|
else:
|
||||||
assert False, 'Unrecognized section for relocation: ' + name
|
assert False, 'Unrecognized section for relocation: ' + name
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('input', help='Input object file to create overlay info', metavar='input')
|
parser.add_argument('input', help='Input object file to create overlay info', metavar='input')
|
||||||
parser.add_argument('output', help='Overlay info output', metavar='output')
|
parser.add_argument('output', help='Overlay info output', metavar='output')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
with open(args.input, 'rb') as f, open(args.output, 'w') as out:
|
with open(args.input, 'rb') as f, open(args.output, 'w') as out:
|
||||||
elffile = ELFFile(f)
|
elffile = ELFFile(f)
|
||||||
|
|
||||||
out.write('.section .ovl\n');
|
out.write('.section .ovl\n');
|
||||||
|
|
||||||
relocs = []
|
relocs = []
|
||||||
for section in elffile.iter_sections():
|
for section in elffile.iter_sections():
|
||||||
if isinstance(section, RelocationSection):
|
if isinstance(section, RelocationSection):
|
||||||
symtab = elffile.get_section(section['sh_link'])
|
symtab = elffile.get_section(section['sh_link'])
|
||||||
for reloc in section.iter_relocations():
|
for reloc in section.iter_relocations():
|
||||||
symbol = symtab.get_symbol(reloc['r_info_sym'])
|
symbol = symtab.get_symbol(reloc['r_info_sym'])
|
||||||
if symbol.entry['st_shndx'] != 'SHN_UNDEF':
|
if symbol.entry['st_shndx'] != 'SHN_UNDEF':
|
||||||
section_id = get_section_type_from_name(section.name[4:])
|
section_id = get_section_type_from_name(section.name[4:])
|
||||||
relocation_type = reloc['r_info_type']
|
relocation_type = reloc['r_info_type']
|
||||||
offset = reloc['r_offset']
|
offset = reloc['r_offset']
|
||||||
assert offset <= 0xFFFFFF, 'Object too big to convert into overlay'
|
assert offset <= 0xFFFFFF, 'Object too big to convert into overlay'
|
||||||
word = (section_id << 30) | (relocation_type << 24) | (offset)
|
word = (section_id << 30) | (relocation_type << 24) | (offset)
|
||||||
relocs.append(word)
|
relocs.append(word)
|
||||||
|
|
||||||
text_section = elffile.get_section_by_name('.text')
|
text_section = elffile.get_section_by_name('.text')
|
||||||
data_section = elffile.get_section_by_name('.data')
|
data_section = elffile.get_section_by_name('.data')
|
||||||
rodata_section = elffile.get_section_by_name('.rodata')
|
rodata_section = elffile.get_section_by_name('.rodata')
|
||||||
bss_section = elffile.get_section_by_name('.bss')
|
bss_section = elffile.get_section_by_name('.bss')
|
||||||
|
|
||||||
text_size = text_section.data_size if text_section is not None else 0
|
text_size = text_section.data_size if text_section is not None else 0
|
||||||
data_size = data_section.data_size if data_section is not None else 0
|
data_size = data_section.data_size if data_section is not None else 0
|
||||||
rodata_size = rodata_section.data_size if rodata_section is not None else 0
|
rodata_size = rodata_section.data_size if rodata_section is not None else 0
|
||||||
bss_size = bss_section.data_size if bss_section is not None else 0
|
bss_size = bss_section.data_size if bss_section is not None else 0
|
||||||
|
|
||||||
out.write('.word 0x{:08X}\n'.format(text_size));
|
out.write('.word 0x{:08X}\n'.format(text_size));
|
||||||
out.write('.word 0x{:08X}\n'.format(data_size));
|
out.write('.word 0x{:08X}\n'.format(data_size));
|
||||||
out.write('.word 0x{:08X}\n'.format(rodata_size));
|
out.write('.word 0x{:08X}\n'.format(rodata_size));
|
||||||
out.write('.word 0x{:08X}\n'.format(bss_size));
|
out.write('.word 0x{:08X}\n'.format(bss_size));
|
||||||
out.write('.word 0x{:08X}\n'.format(len(relocs)));
|
out.write('.word 0x{:08X}\n'.format(len(relocs)));
|
||||||
for reloc in relocs:
|
for reloc in relocs:
|
||||||
out.write('.word 0x{:08X}\n'.format(reloc));
|
out.write('.word 0x{:08X}\n'.format(reloc));
|
||||||
offset = len(relocs) + 5
|
offset = len(relocs) + 5
|
||||||
while (offset % 4) != 3:
|
while (offset % 4) != 3:
|
||||||
out.write('.word 0\n');
|
out.write('.word 0\n');
|
||||||
offset += 1
|
offset += 1
|
||||||
out.write('.word 0x{:08X}\n'.format(offset*4 + 4));
|
out.write('.word 0x{:08X}\n'.format(offset*4 + 4));
|
||||||
|
|
|
@ -1,57 +1,57 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# TODO generalize
|
# TODO generalize
|
||||||
|
|
||||||
data = [
|
data = [
|
||||||
0xC8580005,
|
0xC8580005,
|
||||||
0xB874FE0C,
|
0xB874FE0C,
|
||||||
0x801F0002,
|
0x801F0002,
|
||||||
0x30540FA0
|
0x30540FA0
|
||||||
]
|
]
|
||||||
|
|
||||||
last_continue = True
|
last_continue = True
|
||||||
for entry in data:
|
for entry in data:
|
||||||
if not last_continue:
|
if not last_continue:
|
||||||
print('Error: entries after entry without continue bit')
|
print('Error: entries after entry without continue bit')
|
||||||
|
|
||||||
value = entry & 0xFFFF
|
value = entry & 0xFFFF
|
||||||
offset = (entry >> 16) & 0x7FF
|
offset = (entry >> 16) & 0x7FF
|
||||||
type = (entry >> 27) & 0xF
|
type = (entry >> 27) & 0xF
|
||||||
_continue = (entry >> 31) & 0x1
|
_continue = (entry >> 31) & 0x1
|
||||||
|
|
||||||
# convert to signed short
|
# convert to signed short
|
||||||
if value >= 0x8000:
|
if value >= 0x8000:
|
||||||
value -= 0x10000
|
value -= 0x10000
|
||||||
|
|
||||||
# TODO which ones are signed?
|
# TODO which ones are signed?
|
||||||
print('0x{:X}: '.format(offset), end='')
|
print('0x{:X}: '.format(offset), end='')
|
||||||
if type == 0:
|
if type == 0:
|
||||||
print('char {}'.format(value))
|
print('char {}'.format(value))
|
||||||
elif type == 1:
|
elif type == 1:
|
||||||
print('char {}'.format(value))
|
print('char {}'.format(value))
|
||||||
elif type == 2:
|
elif type == 2:
|
||||||
print('short {}'.format(value))
|
print('short {}'.format(value))
|
||||||
elif type == 3:
|
elif type == 3:
|
||||||
print('short {}'.format(value))
|
print('short {}'.format(value))
|
||||||
elif type == 4:
|
elif type == 4:
|
||||||
print('int {}'.format(value))
|
print('int {}'.format(value))
|
||||||
elif type == 5:
|
elif type == 5:
|
||||||
print('int {}'.format(value))
|
print('int {}'.format(value))
|
||||||
elif type == 6:
|
elif type == 6:
|
||||||
print('float {:f}'.format(value))
|
print('float {:f}'.format(value))
|
||||||
elif type == 7:
|
elif type == 7:
|
||||||
print('float {:f}'.format(value / 1000))
|
print('float {:f}'.format(value / 1000))
|
||||||
elif type == 8:
|
elif type == 8:
|
||||||
print('Vector3f ({0:f}, {0:f}, {0:f})'.format(value))
|
print('Vector3f ({0:f}, {0:f}, {0:f})'.format(value))
|
||||||
elif type == 9:
|
elif type == 9:
|
||||||
value /= 1000
|
value /= 1000
|
||||||
print('Vector3f ({0:f}, {0:f}, {0:f})'.format(value))
|
print('Vector3f ({0:f}, {0:f}, {0:f})'.format(value))
|
||||||
elif type == 10:
|
elif type == 10:
|
||||||
print('Vector3f ({0}, {0}, {0})'.format(value))
|
print('Vector3f ({0}, {0}, {0})'.format(value))
|
||||||
else:
|
else:
|
||||||
print('Error: invalid type ' + str(value))
|
print('Error: invalid type ' + str(value))
|
||||||
|
|
||||||
if not _continue:
|
if not _continue:
|
||||||
print('END')
|
print('END')
|
||||||
|
|
||||||
last_continue = _continue
|
last_continue = _continue
|
||||||
|
|
||||||
|
|
2138
tools/parse_dl.py
2138
tools/parse_dl.py
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
||||||
.set noat
|
.set noat
|
||||||
.set noreorder
|
.set noreorder
|
||||||
.set gp=64
|
.set gp=64
|
||||||
.macro glabel label
|
.macro glabel label
|
||||||
.global \label
|
.global \label
|
||||||
\label:
|
\label:
|
||||||
|
|
|
@ -1,39 +1,39 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import shlex
|
import shlex
|
||||||
import subprocess
|
import subprocess
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
dir_path = os.path.dirname(os.path.realpath(__file__))
|
dir_path = os.path.dirname(os.path.realpath(__file__))
|
||||||
asm_processor = ['python3', os.path.join(dir_path, "asm-processor/asm-processor.py")]
|
asm_processor = ['python3', os.path.join(dir_path, "asm-processor/asm-processor.py")]
|
||||||
prelude = os.path.join(dir_path, "prelude.inc")
|
prelude = os.path.join(dir_path, "prelude.inc")
|
||||||
|
|
||||||
all_args = sys.argv[1:]
|
all_args = sys.argv[1:]
|
||||||
sep1 = all_args.index('--')
|
sep1 = all_args.index('--')
|
||||||
sep2 = all_args.index('--', sep1+1)
|
sep2 = all_args.index('--', sep1+1)
|
||||||
|
|
||||||
compiler = all_args[:sep1]
|
compiler = all_args[:sep1]
|
||||||
|
|
||||||
assembler = all_args[sep1+1:sep2]
|
assembler = all_args[sep1+1:sep2]
|
||||||
assembler_sh = ' '.join(shlex.quote(x) for x in assembler)
|
assembler_sh = ' '.join(shlex.quote(x) for x in assembler)
|
||||||
|
|
||||||
compile_args = all_args[sep2+1:]
|
compile_args = all_args[sep2+1:]
|
||||||
in_file = compile_args[-1]
|
in_file = compile_args[-1]
|
||||||
out_ind = compile_args.index('-o')
|
out_ind = compile_args.index('-o')
|
||||||
out_file = compile_args[out_ind + 1]
|
out_file = compile_args[out_ind + 1]
|
||||||
del compile_args[-1]
|
del compile_args[-1]
|
||||||
del compile_args[out_ind + 1]
|
del compile_args[out_ind + 1]
|
||||||
del compile_args[out_ind]
|
del compile_args[out_ind]
|
||||||
|
|
||||||
in_dir = os.path.split(os.path.realpath(in_file))[0]
|
in_dir = os.path.split(os.path.realpath(in_file))[0]
|
||||||
opt_flags = [x for x in compile_args if x in ['-g', '-O2', '-framepointer', '-g3', '-O1']]
|
opt_flags = [x for x in compile_args if x in ['-g', '-O2', '-framepointer', '-g3', '-O1']]
|
||||||
|
|
||||||
preprocessed_file = tempfile.NamedTemporaryFile(prefix='preprocessed', suffix='.c')
|
preprocessed_file = tempfile.NamedTemporaryFile(prefix='preprocessed', suffix='.c')
|
||||||
|
|
||||||
if opt_flags != []:
|
if opt_flags != []:
|
||||||
subprocess.check_call(asm_processor + opt_flags + [in_file], stdout=preprocessed_file)
|
subprocess.check_call(asm_processor + opt_flags + [in_file], stdout=preprocessed_file)
|
||||||
subprocess.check_call(compiler + compile_args + ['-I', in_dir, '-o', out_file, preprocessed_file.name])
|
subprocess.check_call(compiler + compile_args + ['-I', in_dir, '-o', out_file, preprocessed_file.name])
|
||||||
subprocess.check_call(asm_processor + opt_flags + [in_file, '--post-process', out_file, '--assembler', assembler_sh, '--asm-prelude', prelude])
|
subprocess.check_call(asm_processor + opt_flags + [in_file, '--post-process', out_file, '--assembler', assembler_sh, '--asm-prelude', prelude])
|
||||||
else:
|
else:
|
||||||
subprocess.check_call(compiler + compile_args + ['-I', in_dir, '-o', out_file, in_file])
|
subprocess.check_call(compiler + compile_args + ['-I', in_dir, '-o', out_file, in_file])
|
|
@ -1,488 +1,488 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
'''
|
'''
|
||||||
Resources:
|
Resources:
|
||||||
http://www.cs.unibo.it/~solmi/teaching/arch_2002-2003/AssemblyLanguageProgDoc.pdf
|
http://www.cs.unibo.it/~solmi/teaching/arch_2002-2003/AssemblyLanguageProgDoc.pdf
|
||||||
https://github.com/pathscale/binutils/blob/5c2c133020e41fc4aadd80a99156d2cea4754b96/include/coff/sym.h
|
https://github.com/pathscale/binutils/blob/5c2c133020e41fc4aadd80a99156d2cea4754b96/include/coff/sym.h
|
||||||
https://github.com/pathscale/binutils/blob/5c2c133020e41fc4aadd80a99156d2cea4754b96/include/coff/symconst.h
|
https://github.com/pathscale/binutils/blob/5c2c133020e41fc4aadd80a99156d2cea4754b96/include/coff/symconst.h
|
||||||
https://github.com/pathscale/binutils/blob/5c2c133020e41fc4aadd80a99156d2cea4754b96/gas/ecoff.c
|
https://github.com/pathscale/binutils/blob/5c2c133020e41fc4aadd80a99156d2cea4754b96/gas/ecoff.c
|
||||||
https://github.com/pathscale/binutils/blob/5c2c133020e41fc4aadd80a99156d2cea4754b96/bfd/ecoff.c
|
https://github.com/pathscale/binutils/blob/5c2c133020e41fc4aadd80a99156d2cea4754b96/bfd/ecoff.c
|
||||||
https://github.com/pathscale/absoft/blob/master/svn/trunk/ekopath-gcc/ekopath-gcc-4.2.0/gcc/mips-tdump.c
|
https://github.com/pathscale/absoft/blob/master/svn/trunk/ekopath-gcc/ekopath-gcc-4.2.0/gcc/mips-tdump.c
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import struct
|
import struct
|
||||||
import collections
|
import collections
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
OFFSET = 0 # TODO why are the offsets in the symbolic header off by some amount?
|
OFFSET = 0 # TODO why are the offsets in the symbolic header off by some amount?
|
||||||
|
|
||||||
indent_level = 0
|
indent_level = 0
|
||||||
is_comment = False
|
is_comment = False
|
||||||
|
|
||||||
symbol_type_list = [
|
symbol_type_list = [
|
||||||
'stNil', 'stGlobal', 'stStatic', 'stParam', 'stLocal', 'stLabel', 'stProc', 'stBlock',
|
'stNil', 'stGlobal', 'stStatic', 'stParam', 'stLocal', 'stLabel', 'stProc', 'stBlock',
|
||||||
'stEnd', 'stMember', 'stTypedef', 'stFile', 'INVALID', 'INVALID', 'stStaticProc', 'stConstant',
|
'stEnd', 'stMember', 'stTypedef', 'stFile', 'INVALID', 'INVALID', 'stStaticProc', 'stConstant',
|
||||||
'stStaParam', 'INVALID', 'INVALID', 'INVALID', 'INVALID', 'INVALID', 'INVALID', 'INVALID',
|
'stStaParam', 'INVALID', 'INVALID', 'INVALID', 'INVALID', 'INVALID', 'INVALID', 'INVALID',
|
||||||
'INVALID', 'INVALID', 'stStruct', 'stUnion', 'stEnum', 'INVALID', 'INVALID', 'INVALID',
|
'INVALID', 'INVALID', 'stStruct', 'stUnion', 'stEnum', 'INVALID', 'INVALID', 'INVALID',
|
||||||
'INVALID', 'INVALID', 'stIndirect']
|
'INVALID', 'INVALID', 'stIndirect']
|
||||||
storage_class_list = ['scNil', 'scText', 'scData', 'scBss', 'scRegister', 'scAbs', 'scUndefined', 'reserved',
|
storage_class_list = ['scNil', 'scText', 'scData', 'scBss', 'scRegister', 'scAbs', 'scUndefined', 'reserved',
|
||||||
'scBits', 'scDbx', 'scRegImage', 'scInfo', 'scUserStruct', 'scSData', 'scSBss', 'scRData',
|
'scBits', 'scDbx', 'scRegImage', 'scInfo', 'scUserStruct', 'scSData', 'scSBss', 'scRData',
|
||||||
'scVar', 'scCommon', 'scSCommon', 'scVarRegister', 'scVariant', 'scUndefined', 'scInit']
|
'scVar', 'scCommon', 'scSCommon', 'scVarRegister', 'scVariant', 'scUndefined', 'scInit']
|
||||||
basic_type_c_list = ['nil', 'addr', 'signed char', 'unsigned char', 'short', 'unsigned short', 'int', 'unsigned int',
|
basic_type_c_list = ['nil', 'addr', 'signed char', 'unsigned char', 'short', 'unsigned short', 'int', 'unsigned int',
|
||||||
'long', 'unsigned long', 'float', 'double', 'struct', 'union', 'enum', 'typedef',
|
'long', 'unsigned long', 'float', 'double', 'struct', 'union', 'enum', 'typedef',
|
||||||
'range', 'set', 'complex', 'double complex', 'indirect', 'fixed decimal', 'float decimal', 'string',
|
'range', 'set', 'complex', 'double complex', 'indirect', 'fixed decimal', 'float decimal', 'string',
|
||||||
'bit', 'picture', 'void', 'long long', 'unsigned long long', 'INVALID', 'long', 'unsigned long',
|
'bit', 'picture', 'void', 'long long', 'unsigned long long', 'INVALID', 'long', 'unsigned long',
|
||||||
'long long', 'unsigned long long', 'addr', 'int64', 'unsigned int64']
|
'long long', 'unsigned long long', 'addr', 'int64', 'unsigned int64']
|
||||||
|
|
||||||
def increase_indent():
|
def increase_indent():
|
||||||
global indent_level
|
global indent_level
|
||||||
indent_level += 1
|
indent_level += 1
|
||||||
|
|
||||||
def decrease_indent():
|
def decrease_indent():
|
||||||
global indent_level
|
global indent_level
|
||||||
indent_level -= 1
|
indent_level -= 1
|
||||||
|
|
||||||
def set_is_comment(set_to):
|
def set_is_comment(set_to):
|
||||||
global is_comment
|
global is_comment
|
||||||
old = is_comment
|
old = is_comment
|
||||||
is_comment = set_to
|
is_comment = set_to
|
||||||
return old
|
return old
|
||||||
|
|
||||||
def get_indent():
|
def get_indent():
|
||||||
global indent_level
|
global indent_level
|
||||||
global is_comment
|
global is_comment
|
||||||
ret = '//' if is_comment else ''
|
ret = '//' if is_comment else ''
|
||||||
for i in range(indent_level):
|
for i in range(indent_level):
|
||||||
ret += ' '
|
ret += ' '
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def read_uint32_be(file_data, offset):
|
def read_uint32_be(file_data, offset):
|
||||||
return struct.unpack('>I', file_data[offset:offset+4])[0]
|
return struct.unpack('>I', file_data[offset:offset+4])[0]
|
||||||
|
|
||||||
def read_uint16_be(file_data, offset):
|
def read_uint16_be(file_data, offset):
|
||||||
return struct.unpack('>H', file_data[offset:offset+2])[0]
|
return struct.unpack('>H', file_data[offset:offset+2])[0]
|
||||||
|
|
||||||
def read_uint8_be(file_data, offset):
|
def read_uint8_be(file_data, offset):
|
||||||
return struct.unpack('>B', file_data[offset:offset+1])[0]
|
return struct.unpack('>B', file_data[offset:offset+1])[0]
|
||||||
|
|
||||||
def read_elf_header(file_data, offset):
|
def read_elf_header(file_data, offset):
|
||||||
Header = collections.namedtuple('ElfHeader',
|
Header = collections.namedtuple('ElfHeader',
|
||||||
'''e_magic e_class e_data e_version e_osabi e_abiversion e_pad
|
'''e_magic e_class e_data e_version e_osabi e_abiversion e_pad
|
||||||
e_type e_machine e_version2 e_entry e_phoff e_shoff e_flags
|
e_type e_machine e_version2 e_entry e_phoff e_shoff e_flags
|
||||||
e_ehsize e_phentsize e_phnum e_shentsize e_shnum e_shstrndx''')
|
e_ehsize e_phentsize e_phnum e_shentsize e_shnum e_shstrndx''')
|
||||||
return Header._make(struct.unpack('>I5B7s2H5I6H', file_data[offset:offset+52]))
|
return Header._make(struct.unpack('>I5B7s2H5I6H', file_data[offset:offset+52]))
|
||||||
|
|
||||||
def read_elf_section_header(file_data, offset):
|
def read_elf_section_header(file_data, offset):
|
||||||
Header = collections.namedtuple('SectionHeader',
|
Header = collections.namedtuple('SectionHeader',
|
||||||
'''sh_name sh_type sh_flags sh_addr sh_offset sh_size sh_link
|
'''sh_name sh_type sh_flags sh_addr sh_offset sh_size sh_link
|
||||||
sh_info sh_addralign sh_entsize''')
|
sh_info sh_addralign sh_entsize''')
|
||||||
return Header._make(struct.unpack('>10I', file_data[offset:offset+40]))
|
return Header._make(struct.unpack('>10I', file_data[offset:offset+40]))
|
||||||
|
|
||||||
def read_symbolic_header(file_data, offset):
|
def read_symbolic_header(file_data, offset):
|
||||||
Header = collections.namedtuple('SymbolicHeader',
|
Header = collections.namedtuple('SymbolicHeader',
|
||||||
'''magic vstamp ilineMax cbLine cbLineOffset idnMax cbDnOffset
|
'''magic vstamp ilineMax cbLine cbLineOffset idnMax cbDnOffset
|
||||||
ipdMax cbPdOffset isymMax cbSymOffset ioptMax cbOptOffset
|
ipdMax cbPdOffset isymMax cbSymOffset ioptMax cbOptOffset
|
||||||
iauxMax cbAuxOffset issMax cbSsOffset issExtMax cbSsExtOffset
|
iauxMax cbAuxOffset issMax cbSsOffset issExtMax cbSsExtOffset
|
||||||
ifdMax cbFdOffset crfd cbRfdOffset iextMax cbExtOffset''')
|
ifdMax cbFdOffset crfd cbRfdOffset iextMax cbExtOffset''')
|
||||||
return Header._make(struct.unpack('>2H23I', file_data[offset:offset+96]))
|
return Header._make(struct.unpack('>2H23I', file_data[offset:offset+96]))
|
||||||
|
|
||||||
# TODO find a better solution for the bitfield
|
# TODO find a better solution for the bitfield
|
||||||
def read_file_descriptor(file_data, offset):
|
def read_file_descriptor(file_data, offset):
|
||||||
if 'init' not in read_file_descriptor.__dict__:
|
if 'init' not in read_file_descriptor.__dict__:
|
||||||
read_file_descriptor.cache = {}
|
read_file_descriptor.cache = {}
|
||||||
read_file_descriptor.header = collections.namedtuple('FileDescriptor',
|
read_file_descriptor.header = collections.namedtuple('FileDescriptor',
|
||||||
'''adr rss issBase cbSs isymBase csym ilineBase cline ioptBase
|
'''adr rss issBase cbSs isymBase csym ilineBase cline ioptBase
|
||||||
copt ipdFirst cpd iauxBase caux rfdBase crfd XXX_bitfield
|
copt ipdFirst cpd iauxBase caux rfdBase crfd XXX_bitfield
|
||||||
cbLineOffset cbLine''')
|
cbLineOffset cbLine''')
|
||||||
read_file_descriptor.init = True
|
read_file_descriptor.init = True
|
||||||
if offset in read_file_descriptor.cache:
|
if offset in read_file_descriptor.cache:
|
||||||
return read_file_descriptor.cache[offset]
|
return read_file_descriptor.cache[offset]
|
||||||
read_file_descriptor.cache[offset] = read_file_descriptor.header._make(
|
read_file_descriptor.cache[offset] = read_file_descriptor.header._make(
|
||||||
struct.unpack('>I2iI6iHh4iI2I', file_data[offset:offset+72]))
|
struct.unpack('>I2iI6iHh4iI2I', file_data[offset:offset+72]))
|
||||||
return read_file_descriptor.cache[offset]
|
return read_file_descriptor.cache[offset]
|
||||||
|
|
||||||
def read_procedure_descriptor(file_data, offset):
|
def read_procedure_descriptor(file_data, offset):
|
||||||
Header = collections.namedtuple('ProcedureDescriptor',
|
Header = collections.namedtuple('ProcedureDescriptor',
|
||||||
'''adr isym iline regmask regoffset iopt fregmask fregoffset
|
'''adr isym iline regmask regoffset iopt fregmask fregoffset
|
||||||
frameoffset framereg pcreg lnLow lnHigh cbLineOffset''')
|
frameoffset framereg pcreg lnLow lnHigh cbLineOffset''')
|
||||||
return Header._make(struct.unpack('>I8i2h2iI', file_data[offset:offset+52]))
|
return Header._make(struct.unpack('>I8i2h2iI', file_data[offset:offset+52]))
|
||||||
|
|
||||||
def read_symbol(file_data, offset):
|
def read_symbol(file_data, offset):
|
||||||
if 'init' not in read_symbol.__dict__:
|
if 'init' not in read_symbol.__dict__:
|
||||||
read_symbol.cache = {}
|
read_symbol.cache = {}
|
||||||
read_symbol.header = collections.namedtuple('Symbol', '''iss value st sc index''')
|
read_symbol.header = collections.namedtuple('Symbol', '''iss value st sc index''')
|
||||||
read_symbol.init = True
|
read_symbol.init = True
|
||||||
if offset in read_symbol.cache:
|
if offset in read_symbol.cache:
|
||||||
return read_symbol.cache[offset]
|
return read_symbol.cache[offset]
|
||||||
(word0, word1, word2) = struct.unpack('>iII', file_data[offset:offset+12])
|
(word0, word1, word2) = struct.unpack('>iII', file_data[offset:offset+12])
|
||||||
read_symbol.cache[offset] = read_symbol.header._make((
|
read_symbol.cache[offset] = read_symbol.header._make((
|
||||||
word0, word1, (word2 >> 26) & 0x3F, (word2 >> 21) & 0x1F, word2 & 0xFFFFF))
|
word0, word1, (word2 >> 26) & 0x3F, (word2 >> 21) & 0x1F, word2 & 0xFFFFF))
|
||||||
return read_symbol.cache[offset]
|
return read_symbol.cache[offset]
|
||||||
|
|
||||||
def read_auxiliary_symbol(file_data, offset):
|
def read_auxiliary_symbol(file_data, offset):
|
||||||
if 'init' not in read_auxiliary_symbol.__dict__:
|
if 'init' not in read_auxiliary_symbol.__dict__:
|
||||||
read_auxiliary_symbol.cache = {}
|
read_auxiliary_symbol.cache = {}
|
||||||
read_auxiliary_symbol.header = collections.namedtuple('AuxSymbol',
|
read_auxiliary_symbol.header = collections.namedtuple('AuxSymbol',
|
||||||
'''ti rndx dnLow dnHigh isym iss width count''')
|
'''ti rndx dnLow dnHigh isym iss width count''')
|
||||||
read_auxiliary_symbol.type_info = collections.namedtuple('TypeInfo',
|
read_auxiliary_symbol.type_info = collections.namedtuple('TypeInfo',
|
||||||
'''fBitfield continued bt tq4 tq5 tq0 tq1 tq2 tq3''')
|
'''fBitfield continued bt tq4 tq5 tq0 tq1 tq2 tq3''')
|
||||||
read_auxiliary_symbol.rel_sym = collections.namedtuple('RelativeSymbol', '''rfd index''')
|
read_auxiliary_symbol.rel_sym = collections.namedtuple('RelativeSymbol', '''rfd index''')
|
||||||
read_auxiliary_symbol.init = True
|
read_auxiliary_symbol.init = True
|
||||||
if offset in read_auxiliary_symbol.cache:
|
if offset in read_auxiliary_symbol.cache:
|
||||||
return read_auxiliary_symbol.cache[offset]
|
return read_auxiliary_symbol.cache[offset]
|
||||||
word0 = struct.unpack('>I', file_data[offset:offset+4])[0]
|
word0 = struct.unpack('>I', file_data[offset:offset+4])[0]
|
||||||
read_auxiliary_symbol.cache[offset] = read_auxiliary_symbol.header._make((
|
read_auxiliary_symbol.cache[offset] = read_auxiliary_symbol.header._make((
|
||||||
read_auxiliary_symbol.type_info._make(((word0 >> 31) & 1, (word0 >> 30) & 1, (word0 >> 24) & 0x3F, (word0 >> 20) & 0xF, (word0 >> 16) & 0xF, (word0 >> 12) & 0xF, (word0 >> 8) & 0xF, (word0 >> 4) & 0xF, word0 & 0xF)),
|
read_auxiliary_symbol.type_info._make(((word0 >> 31) & 1, (word0 >> 30) & 1, (word0 >> 24) & 0x3F, (word0 >> 20) & 0xF, (word0 >> 16) & 0xF, (word0 >> 12) & 0xF, (word0 >> 8) & 0xF, (word0 >> 4) & 0xF, word0 & 0xF)),
|
||||||
read_auxiliary_symbol.rel_sym._make(((word0 >> 20) & 0xFFF, word0 & 0xFFFFF)),
|
read_auxiliary_symbol.rel_sym._make(((word0 >> 20) & 0xFFF, word0 & 0xFFFFF)),
|
||||||
word0, word0, word0, word0, word0, word0))
|
word0, word0, word0, word0, word0, word0))
|
||||||
return read_auxiliary_symbol.cache[offset]
|
return read_auxiliary_symbol.cache[offset]
|
||||||
|
|
||||||
def read_string(file_data, offset):
|
def read_string(file_data, offset):
|
||||||
current_offset = 0
|
current_offset = 0
|
||||||
current_string = b''
|
current_string = b''
|
||||||
while True:
|
while True:
|
||||||
char = struct.unpack('c', file_data[offset+current_offset:offset+current_offset+1])[0]
|
char = struct.unpack('c', file_data[offset+current_offset:offset+current_offset+1])[0]
|
||||||
if char == b'\0':
|
if char == b'\0':
|
||||||
return current_string.decode('ascii')
|
return current_string.decode('ascii')
|
||||||
else:
|
else:
|
||||||
current_string += char
|
current_string += char
|
||||||
current_offset += 1
|
current_offset += 1
|
||||||
|
|
||||||
def get_symbol_name_from_aux(file_data, fd, symbolic_header, aux_num, search_for_typedef):
|
def get_symbol_name_from_aux(file_data, fd, symbolic_header, aux_num, search_for_typedef):
|
||||||
aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + aux_num)*4)
|
aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + aux_num)*4)
|
||||||
fd_num = aux.rndx.rfd
|
fd_num = aux.rndx.rfd
|
||||||
next_aux = aux_num+1
|
next_aux = aux_num+1
|
||||||
if fd_num == 4095:
|
if fd_num == 4095:
|
||||||
aux2 = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + next_aux)*4)
|
aux2 = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + next_aux)*4)
|
||||||
fd_num = aux2.isym
|
fd_num = aux2.isym
|
||||||
next_aux = next_aux+1;
|
next_aux = next_aux+1;
|
||||||
fd2 = read_file_descriptor(file_data, symbolic_header.cbFdOffset - OFFSET + fd_num*72)
|
fd2 = read_file_descriptor(file_data, symbolic_header.cbFdOffset - OFFSET + fd_num*72)
|
||||||
sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + (fd2.isymBase + aux.rndx.index)*12)
|
sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + (fd2.isymBase + aux.rndx.index)*12)
|
||||||
ret = ''
|
ret = ''
|
||||||
#print('%r' % (aux,));
|
#print('%r' % (aux,));
|
||||||
#print('%r' % (aux2,));
|
#print('%r' % (aux2,));
|
||||||
#print('%r' % (sym,));
|
#print('%r' % (sym,));
|
||||||
if sym.st == 26 or sym.st == 27: #stStruct, stunion
|
if sym.st == 26 or sym.st == 27: #stStruct, stunion
|
||||||
ret = get_struct_or_union_string(file_data, fd2, symbolic_header, fd2.isymBase + aux.rndx.index, search_for_typedef)
|
ret = get_struct_or_union_string(file_data, fd2, symbolic_header, fd2.isymBase + aux.rndx.index, search_for_typedef)
|
||||||
elif sym.st == 28: #stEnum:
|
elif sym.st == 28: #stEnum:
|
||||||
ret = get_enum_string(file_data, fd2, symbolic_header, fd2.isymBase + aux.rndx.index)
|
ret = get_enum_string(file_data, fd2, symbolic_header, fd2.isymBase + aux.rndx.index)
|
||||||
else:
|
else:
|
||||||
ret = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd2.issBase + sym.iss)
|
ret = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd2.issBase + sym.iss)
|
||||||
return (ret, next_aux)
|
return (ret, next_aux)
|
||||||
|
|
||||||
def get_type_string(file_data, fd, symbolic_header, aux_num, name, search_for_typedef):
|
def get_type_string(file_data, fd, symbolic_header, aux_num, name, search_for_typedef):
|
||||||
ret = ''
|
ret = ''
|
||||||
aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + aux_num)*4)
|
aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + aux_num)*4)
|
||||||
#print('');
|
#print('');
|
||||||
#print('%r' % (aux,));
|
#print('%r' % (aux,));
|
||||||
next_aux = aux_num+1
|
next_aux = aux_num+1
|
||||||
has_bitfield = aux.ti.fBitfield == 1
|
has_bitfield = aux.ti.fBitfield == 1
|
||||||
bitwidth = 0
|
bitwidth = 0
|
||||||
if has_bitfield:
|
if has_bitfield:
|
||||||
bit_aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + next_aux)*4)
|
bit_aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + next_aux)*4)
|
||||||
bitwidth = bit_aux.isym
|
bitwidth = bit_aux.isym
|
||||||
next_aux = next_aux+1
|
next_aux = next_aux+1
|
||||||
if aux.ti.bt == 12: # btStruct
|
if aux.ti.bt == 12: # btStruct
|
||||||
(ret, next_aux) = get_symbol_name_from_aux(file_data, fd, symbolic_header, next_aux, search_for_typedef)
|
(ret, next_aux) = get_symbol_name_from_aux(file_data, fd, symbolic_header, next_aux, search_for_typedef)
|
||||||
elif aux.ti.bt == 13: # btUnion
|
elif aux.ti.bt == 13: # btUnion
|
||||||
(ret, next_aux) = get_symbol_name_from_aux(file_data, fd, symbolic_header, next_aux, search_for_typedef)
|
(ret, next_aux) = get_symbol_name_from_aux(file_data, fd, symbolic_header, next_aux, search_for_typedef)
|
||||||
elif aux.ti.bt == 15: # btTypedef
|
elif aux.ti.bt == 15: # btTypedef
|
||||||
(ret, next_aux) = get_symbol_name_from_aux(file_data, fd, symbolic_header, next_aux, search_for_typedef)
|
(ret, next_aux) = get_symbol_name_from_aux(file_data, fd, symbolic_header, next_aux, search_for_typedef)
|
||||||
elif aux.ti.bt == 14: # btEnum
|
elif aux.ti.bt == 14: # btEnum
|
||||||
(ret, next_aux) = get_symbol_name_from_aux(file_data, fd, symbolic_header, next_aux, search_for_typedef)
|
(ret, next_aux) = get_symbol_name_from_aux(file_data, fd, symbolic_header, next_aux, search_for_typedef)
|
||||||
else:
|
else:
|
||||||
ret = basic_type_c_list[aux.ti.bt]
|
ret = basic_type_c_list[aux.ti.bt]
|
||||||
|
|
||||||
tq_list = (aux.ti.tq0, aux.ti.tq1, aux.ti.tq2, aux.ti.tq3, aux.ti.tq4, aux.ti.tq5)
|
tq_list = (aux.ti.tq0, aux.ti.tq1, aux.ti.tq2, aux.ti.tq3, aux.ti.tq4, aux.ti.tq5)
|
||||||
|
|
||||||
# TODO this is very naive and probably does not work in a large amount of cases
|
# TODO this is very naive and probably does not work in a large amount of cases
|
||||||
last_was_proc = False # if we see a tqProc, assume the next will be a tqPtr
|
last_was_proc = False # if we see a tqProc, assume the next will be a tqPtr
|
||||||
for tq in tq_list:
|
for tq in tq_list:
|
||||||
if tq == 0: # tqNil
|
if tq == 0: # tqNil
|
||||||
break;
|
break;
|
||||||
elif tq == 1: # tqPtr
|
elif tq == 1: # tqPtr
|
||||||
if last_was_proc:
|
if last_was_proc:
|
||||||
last_was_proc = False
|
last_was_proc = False
|
||||||
continue
|
continue
|
||||||
ret += '*'
|
ret += '*'
|
||||||
elif tq == 2: # tqProc
|
elif tq == 2: # tqProc
|
||||||
last_was_proc = True
|
last_was_proc = True
|
||||||
name = '(*%s)(... /* ECOFF does not store param types */)' % name
|
name = '(*%s)(... /* ECOFF does not store param types */)' % name
|
||||||
elif tq == 3: # tqArray
|
elif tq == 3: # tqArray
|
||||||
next_aux += 2 # todo what does this skip over? (Apparantly the type of the index, so always int for C)
|
next_aux += 2 # todo what does this skip over? (Apparantly the type of the index, so always int for C)
|
||||||
array_low_aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + next_aux)*4)
|
array_low_aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + next_aux)*4)
|
||||||
array_high_aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + next_aux+1)*4)
|
array_high_aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + next_aux+1)*4)
|
||||||
stride_aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + next_aux+2)*4)
|
stride_aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + next_aux+2)*4)
|
||||||
next_aux += 3
|
next_aux += 3
|
||||||
if array_high_aux.dnHigh == 0xFFFFFFFF:
|
if array_high_aux.dnHigh == 0xFFFFFFFF:
|
||||||
name += '[]'
|
name += '[]'
|
||||||
else:
|
else:
|
||||||
name += '[%d]' % (array_high_aux.dnHigh + 1)
|
name += '[%d]' % (array_high_aux.dnHigh + 1)
|
||||||
elif tq == 4: # tqFar
|
elif tq == 4: # tqFar
|
||||||
print('ERROR tqFar in get_type_name')
|
print('ERROR tqFar in get_type_name')
|
||||||
elif tq == 5: # tqVol
|
elif tq == 5: # tqVol
|
||||||
ret = 'volatile ' + ret
|
ret = 'volatile ' + ret
|
||||||
elif tq == 6: # tqConst
|
elif tq == 6: # tqConst
|
||||||
ret = 'const ' + ret
|
ret = 'const ' + ret
|
||||||
if has_bitfield:
|
if has_bitfield:
|
||||||
name += ' : %d' % bitwidth
|
name += ' : %d' % bitwidth
|
||||||
return ret + ' ' + name
|
return ret + ' ' + name
|
||||||
|
|
||||||
def get_enum_string(file_data, fd, symbolic_header, enum_sym_num):
|
def get_enum_string(file_data, fd, symbolic_header, enum_sym_num):
|
||||||
ret = ''
|
ret = ''
|
||||||
start_sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + enum_sym_num*12)
|
start_sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + enum_sym_num*12)
|
||||||
if start_sym.st != 28:
|
if start_sym.st != 28:
|
||||||
print('ERROR unkown type in get_enum_string start:%d' % start_sym.st)
|
print('ERROR unkown type in get_enum_string start:%d' % start_sym.st)
|
||||||
return ret
|
return ret
|
||||||
ret += 'enum {\n'
|
ret += 'enum {\n'
|
||||||
increase_indent()
|
increase_indent()
|
||||||
sym_num = enum_sym_num + 1
|
sym_num = enum_sym_num + 1
|
||||||
while sym_num < fd.isymBase + start_sym.index:
|
while sym_num < fd.isymBase + start_sym.index:
|
||||||
sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + sym_num*12)
|
sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + sym_num*12)
|
||||||
if sym.st == 8: # stEnd
|
if sym.st == 8: # stEnd
|
||||||
decrease_indent()
|
decrease_indent()
|
||||||
ret += get_indent()
|
ret += get_indent()
|
||||||
ret += '}'
|
ret += '}'
|
||||||
elif sym.st == 9: # stMember
|
elif sym.st == 9: # stMember
|
||||||
name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + sym.iss)
|
name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + sym.iss)
|
||||||
ret += get_indent()
|
ret += get_indent()
|
||||||
ret += '%s = %d,\n' % (name, sym.value)
|
ret += '%s = %d,\n' % (name, sym.value)
|
||||||
else:
|
else:
|
||||||
print('ERROR unkown type in get_enum_string:%d' % sym.st)
|
print('ERROR unkown type in get_enum_string:%d' % sym.st)
|
||||||
break
|
break
|
||||||
sym_num += 1
|
sym_num += 1
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def get_struct_or_union_string(file_data, fd, symbolic_header, union_sym_num, search_for_typedef):
|
def get_struct_or_union_string(file_data, fd, symbolic_header, union_sym_num, search_for_typedef):
|
||||||
ret = ''
|
ret = ''
|
||||||
start_sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + union_sym_num*12)
|
start_sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + union_sym_num*12)
|
||||||
if search_for_typedef:
|
if search_for_typedef:
|
||||||
typedef_sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + (fd.isymBase + start_sym.index)*12)
|
typedef_sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + (fd.isymBase + start_sym.index)*12)
|
||||||
if typedef_sym.st == 10: # stTypedef
|
if typedef_sym.st == 10: # stTypedef
|
||||||
return read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + typedef_sym.iss)
|
return read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + typedef_sym.iss)
|
||||||
else:
|
else:
|
||||||
name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + start_sym.iss)
|
name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + start_sym.iss)
|
||||||
if name != '':
|
if name != '':
|
||||||
return name
|
return name
|
||||||
if start_sym.st == 26: # stStruct
|
if start_sym.st == 26: # stStruct
|
||||||
ret += 'struct {\n'
|
ret += 'struct {\n'
|
||||||
increase_indent()
|
increase_indent()
|
||||||
elif start_sym.st == 27: # stUnion
|
elif start_sym.st == 27: # stUnion
|
||||||
ret += 'union {\n'
|
ret += 'union {\n'
|
||||||
increase_indent()
|
increase_indent()
|
||||||
else:
|
else:
|
||||||
print('ERROR unkown type in get_struct_or_union_string start:%d' % start_sym.st)
|
print('ERROR unkown type in get_struct_or_union_string start:%d' % start_sym.st)
|
||||||
return ret
|
return ret
|
||||||
sym_num = union_sym_num + 1
|
sym_num = union_sym_num + 1
|
||||||
while sym_num < fd.isymBase + start_sym.index:
|
while sym_num < fd.isymBase + start_sym.index:
|
||||||
sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + sym_num*12)
|
sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + sym_num*12)
|
||||||
if sym.st == 8: # stEnd
|
if sym.st == 8: # stEnd
|
||||||
decrease_indent()
|
decrease_indent()
|
||||||
ret += get_indent()
|
ret += get_indent()
|
||||||
ret += '}'
|
ret += '}'
|
||||||
elif sym.st == 9: # stMember
|
elif sym.st == 9: # stMember
|
||||||
name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + sym.iss)
|
name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + sym.iss)
|
||||||
ret += get_indent()
|
ret += get_indent()
|
||||||
ret += '/* 0x%X */ %s;\n' % (sym.value // 8, get_type_string(file_data, fd, symbolic_header, sym.index, name, True))
|
ret += '/* 0x%X */ %s;\n' % (sym.value // 8, get_type_string(file_data, fd, symbolic_header, sym.index, name, True))
|
||||||
elif sym.st == 26 or sym.st == 27: #stStruct, stUnion
|
elif sym.st == 26 or sym.st == 27: #stStruct, stUnion
|
||||||
sym_num = fd.isymBase + sym.index
|
sym_num = fd.isymBase + sym.index
|
||||||
continue
|
continue
|
||||||
elif sym.st == 34: # stIndirect
|
elif sym.st == 34: # stIndirect
|
||||||
# TODO what even is a stIndirect?
|
# TODO what even is a stIndirect?
|
||||||
sym_num += 1
|
sym_num += 1
|
||||||
else:
|
else:
|
||||||
print('ERROR unkown type in get_struct_or_union_string:%d' % sym.st)
|
print('ERROR unkown type in get_struct_or_union_string:%d' % sym.st)
|
||||||
break
|
break
|
||||||
sym_num += 1
|
sym_num += 1
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def print_typedef_symbols(file_data, fd, symbolic_header, typedef_sym_num):
|
def print_typedef_symbols(file_data, fd, symbolic_header, typedef_sym_num):
|
||||||
typedef_sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + typedef_sym_num*12)
|
typedef_sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + typedef_sym_num*12)
|
||||||
if typedef_sym.st != 10: # stTypedef
|
if typedef_sym.st != 10: # stTypedef
|
||||||
print('ERROR expected stTypedef symbol in print_typedef_symbols, found:%d' % typedef_sym.st)
|
print('ERROR expected stTypedef symbol in print_typedef_symbols, found:%d' % typedef_sym.st)
|
||||||
return
|
return
|
||||||
name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + typedef_sym.iss)
|
name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + typedef_sym.iss)
|
||||||
print('typedef %s;' % get_type_string(file_data, fd, symbolic_header, typedef_sym.index, name, False))
|
print('typedef %s;' % get_type_string(file_data, fd, symbolic_header, typedef_sym.index, name, False))
|
||||||
|
|
||||||
def print_procedure(file_data, fd, symbolic_header, proc_sym_num):
|
def print_procedure(file_data, fd, symbolic_header, proc_sym_num):
|
||||||
proc_sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + proc_sym_num*12)
|
proc_sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + proc_sym_num*12)
|
||||||
proc_name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + proc_sym.iss)
|
proc_name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + proc_sym.iss)
|
||||||
print('%s(' % get_type_string(file_data, fd, symbolic_header, proc_sym.index+1, proc_name, True), end='')
|
print('%s(' % get_type_string(file_data, fd, symbolic_header, proc_sym.index+1, proc_name, True), end='')
|
||||||
sym_num = proc_sym_num+1
|
sym_num = proc_sym_num+1
|
||||||
param_sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + sym_num*12)
|
param_sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + sym_num*12)
|
||||||
first = True
|
first = True
|
||||||
while param_sym.st == 3: # stParam
|
while param_sym.st == 3: # stParam
|
||||||
param_name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + param_sym.iss)
|
param_name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + param_sym.iss)
|
||||||
print('%s%s' % ('' if first else ', ',
|
print('%s%s' % ('' if first else ', ',
|
||||||
get_type_string(file_data, fd, symbolic_header, param_sym.index, param_name, True)),
|
get_type_string(file_data, fd, symbolic_header, param_sym.index, param_name, True)),
|
||||||
end='')
|
end='')
|
||||||
sym_num += 1
|
sym_num += 1
|
||||||
param_sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + sym_num*12)
|
param_sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + sym_num*12)
|
||||||
first = False
|
first = False
|
||||||
|
|
||||||
print(');')
|
print(');')
|
||||||
comment_old = set_is_comment(True)
|
comment_old = set_is_comment(True)
|
||||||
while sym_num < fd.isymBase + fd.csym:
|
while sym_num < fd.isymBase + fd.csym:
|
||||||
sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + sym_num*12)
|
sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + sym_num*12)
|
||||||
sym_num += 1
|
sym_num += 1
|
||||||
if sym.st == 7: # stBlock
|
if sym.st == 7: # stBlock
|
||||||
print('%s{' % get_indent())
|
print('%s{' % get_indent())
|
||||||
increase_indent()
|
increase_indent()
|
||||||
elif sym.st == 8: # stEnd
|
elif sym.st == 8: # stEnd
|
||||||
if proc_name == read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + sym.iss):
|
if proc_name == read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + sym.iss):
|
||||||
set_is_comment(comment_old)
|
set_is_comment(comment_old)
|
||||||
return sym_num
|
return sym_num
|
||||||
decrease_indent()
|
decrease_indent()
|
||||||
print('%s}' % get_indent())
|
print('%s}' % get_indent())
|
||||||
elif sym.st == 4: # stLocal
|
elif sym.st == 4: # stLocal
|
||||||
local_name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + sym.iss)
|
local_name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + sym.iss)
|
||||||
is_reg = sym.sc == 4 # scRegister
|
is_reg = sym.sc == 4 # scRegister
|
||||||
print('%s%s%s;' % (get_indent(),
|
print('%s%s%s;' % (get_indent(),
|
||||||
'register ' if is_reg else '',
|
'register ' if is_reg else '',
|
||||||
get_type_string(file_data, fd, symbolic_header, sym.index, local_name, True)))
|
get_type_string(file_data, fd, symbolic_header, sym.index, local_name, True)))
|
||||||
elif sym.st == 2: # stStatic
|
elif sym.st == 2: # stStatic
|
||||||
static_name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + sym.iss)
|
static_name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + sym.iss)
|
||||||
print('%sstatic %s;' % (get_indent(),get_type_string(file_data, fd, symbolic_header, sym.index, static_name, True)))
|
print('%sstatic %s;' % (get_indent(),get_type_string(file_data, fd, symbolic_header, sym.index, static_name, True)))
|
||||||
elif sym.st == 5: # stLabel
|
elif sym.st == 5: # stLabel
|
||||||
static_name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + sym.iss)
|
static_name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + sym.iss)
|
||||||
print('%sLabel: %s @ %d;' % (get_indent(), static_name, sym.value))
|
print('%sLabel: %s @ %d;' % (get_indent(), static_name, sym.value))
|
||||||
elif sym.st == 6: # stProc
|
elif sym.st == 6: # stProc
|
||||||
# multiple name for function?
|
# multiple name for function?
|
||||||
sym_num = print_procedure(file_data, fd, symbolic_header, sym_num-1)
|
sym_num = print_procedure(file_data, fd, symbolic_header, sym_num-1)
|
||||||
elif sym.st == 26 or sym.st == 27: #stStruct, stUnion
|
elif sym.st == 26 or sym.st == 27: #stStruct, stUnion
|
||||||
sym_num = fd.isymBase + sym.index
|
sym_num = fd.isymBase + sym.index
|
||||||
elif sym.st == 34: # stIndirect
|
elif sym.st == 34: # stIndirect
|
||||||
# TODO what even is a stIndirect?
|
# TODO what even is a stIndirect?
|
||||||
sym_num += 1
|
sym_num += 1
|
||||||
else:
|
else:
|
||||||
print('ERROR unkown st in print_procedure: %d' % sym.st)
|
print('ERROR unkown st in print_procedure: %d' % sym.st)
|
||||||
set_is_comment(comment_old)
|
set_is_comment(comment_old)
|
||||||
return sym_num
|
return sym_num
|
||||||
|
|
||||||
def print_symbols(file_data, fd, symbolic_header):
|
def print_symbols(file_data, fd, symbolic_header):
|
||||||
sym_num = fd.isymBase
|
sym_num = fd.isymBase
|
||||||
while sym_num < fd.isymBase + fd.csym:
|
while sym_num < fd.isymBase + fd.csym:
|
||||||
root_sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + sym_num*12)
|
root_sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + sym_num*12)
|
||||||
if root_sym.st == 11: # stFile
|
if root_sym.st == 11: # stFile
|
||||||
file_name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + root_sym.iss)
|
file_name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + root_sym.iss)
|
||||||
print('// begin file %s\n' % file_name)
|
print('// begin file %s\n' % file_name)
|
||||||
sym_num += 1
|
sym_num += 1
|
||||||
leaf_sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + sym_num*12)
|
leaf_sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + sym_num*12)
|
||||||
while leaf_sym.st != 8: # stEnd
|
while leaf_sym.st != 8: # stEnd
|
||||||
if leaf_sym.st == 26 or leaf_sym.st == 27 or leaf_sym.st == 28: # stStruct, stUnion, stEnum
|
if leaf_sym.st == 26 or leaf_sym.st == 27 or leaf_sym.st == 28: # stStruct, stUnion, stEnum
|
||||||
sym_num = fd.isymBase + leaf_sym.index
|
sym_num = fd.isymBase + leaf_sym.index
|
||||||
print('')
|
print('')
|
||||||
elif leaf_sym.st == 10: # stTypedef
|
elif leaf_sym.st == 10: # stTypedef
|
||||||
print_typedef_symbols(file_data, fd, symbolic_header, sym_num)
|
print_typedef_symbols(file_data, fd, symbolic_header, sym_num)
|
||||||
sym_num += 1
|
sym_num += 1
|
||||||
print('')
|
print('')
|
||||||
elif leaf_sym.st == 6 or leaf_sym.st == 14: # stProc, stStaticProc
|
elif leaf_sym.st == 6 or leaf_sym.st == 14: # stProc, stStaticProc
|
||||||
# TODO how do stProc and stStaticProc differ? stStaticProc isn't exported?
|
# TODO how do stProc and stStaticProc differ? stStaticProc isn't exported?
|
||||||
sym_num = print_procedure(file_data, fd, symbolic_header, sym_num)
|
sym_num = print_procedure(file_data, fd, symbolic_header, sym_num)
|
||||||
print('')
|
print('')
|
||||||
elif leaf_sym.st == 2: # stStatic
|
elif leaf_sym.st == 2: # stStatic
|
||||||
static_name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + leaf_sym.iss)
|
static_name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + leaf_sym.iss)
|
||||||
if leaf_sym.sc == 2 or leaf_sym.sc == 3 or leaf_sym.sc == 15: # scData, scBss, scRData
|
if leaf_sym.sc == 2 or leaf_sym.sc == 3 or leaf_sym.sc == 15: # scData, scBss, scRData
|
||||||
if leaf_sym.index != 0xFFFFF: # looks like it's an invalid value for .s files
|
if leaf_sym.index != 0xFFFFF: # looks like it's an invalid value for .s files
|
||||||
print('static %s;\n' % get_type_string(file_data, fd, symbolic_header, leaf_sym.index, static_name, True))
|
print('static %s;\n' % get_type_string(file_data, fd, symbolic_header, leaf_sym.index, static_name, True))
|
||||||
else:
|
else:
|
||||||
print('static %s;\n' % static_name)
|
print('static %s;\n' % static_name)
|
||||||
else:
|
else:
|
||||||
print('ERROR unkown sc for stStatic in print_symbols: %d' % leaf_sym.sc)
|
print('ERROR unkown sc for stStatic in print_symbols: %d' % leaf_sym.sc)
|
||||||
sym_num += 1
|
sym_num += 1
|
||||||
else:
|
else:
|
||||||
print('ERROR unkown st in leaf_sym in print_symbols: %d' % leaf_sym.st)
|
print('ERROR unkown st in leaf_sym in print_symbols: %d' % leaf_sym.st)
|
||||||
sym_num += 1
|
sym_num += 1
|
||||||
leaf_sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + sym_num*12)
|
leaf_sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + sym_num*12)
|
||||||
sym_num = fd.isymBase + root_sym.index
|
sym_num = fd.isymBase + root_sym.index
|
||||||
print('// end file %s' % file_name)
|
print('// end file %s' % file_name)
|
||||||
else:
|
else:
|
||||||
print('ERROR expected st of stFile as only root type in print_symbols:%d' % root_sym.st)
|
print('ERROR expected st of stFile as only root type in print_symbols:%d' % root_sym.st)
|
||||||
return
|
return
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
global OFFSET
|
global OFFSET
|
||||||
if len(sys.argv) < 2:
|
if len(sys.argv) < 2:
|
||||||
return # TODO print usage
|
return # TODO print usage
|
||||||
|
|
||||||
filename = sys.argv[1]
|
filename = sys.argv[1]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(filename, 'rb') as f:
|
with open(filename, 'rb') as f:
|
||||||
file_data = f.read()
|
file_data = f.read()
|
||||||
except IOError:
|
except IOError:
|
||||||
print('failed to read file ' + filename)
|
print('failed to read file ' + filename)
|
||||||
return
|
return
|
||||||
|
|
||||||
elf_header = read_elf_header(file_data, 0)
|
elf_header = read_elf_header(file_data, 0)
|
||||||
section_headers = []
|
section_headers = []
|
||||||
debug_index = 0xFFFFFFFF
|
debug_index = 0xFFFFFFFF
|
||||||
#print('%r' % (elf_header,))
|
#print('%r' % (elf_header,))
|
||||||
for i in range(elf_header.e_shnum):
|
for i in range(elf_header.e_shnum):
|
||||||
section_headers.append(read_elf_section_header(file_data, elf_header.e_shoff + i*40))
|
section_headers.append(read_elf_section_header(file_data, elf_header.e_shoff + i*40))
|
||||||
#print('%r' % (section_headers[i],))
|
#print('%r' % (section_headers[i],))
|
||||||
if section_headers[i].sh_type == 0x70000005:
|
if section_headers[i].sh_type == 0x70000005:
|
||||||
debug_index = i
|
debug_index = i
|
||||||
|
|
||||||
if debug_index != 0xFFFFFFFF:
|
if debug_index != 0xFFFFFFFF:
|
||||||
symbolic_header = read_symbolic_header(file_data, section_headers[debug_index].sh_offset)
|
symbolic_header = read_symbolic_header(file_data, section_headers[debug_index].sh_offset)
|
||||||
file_descriptors = []
|
file_descriptors = []
|
||||||
print('%r' % (symbolic_header,))
|
print('%r' % (symbolic_header,))
|
||||||
# Set offset by assuming that there are no optimization symbols so cbOptOffset points to the start of the symbolic header
|
# Set offset by assuming that there are no optimization symbols so cbOptOffset points to the start of the symbolic header
|
||||||
OFFSET = symbolic_header.cbOptOffset - section_headers[debug_index].sh_offset
|
OFFSET = symbolic_header.cbOptOffset - section_headers[debug_index].sh_offset
|
||||||
print('Using OFFSET of %d' % OFFSET)
|
print('Using OFFSET of %d' % OFFSET)
|
||||||
#for sym_num in range(symbolic_header.isymMax):
|
#for sym_num in range(symbolic_header.isymMax):
|
||||||
#sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + sym_num*12)
|
#sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + sym_num*12)
|
||||||
#print('%d:%r' % (sym_num, (sym,)));
|
#print('%d:%r' % (sym_num, (sym,)));
|
||||||
#for aux_num in range(symbolic_header.iauxMax):
|
#for aux_num in range(symbolic_header.iauxMax):
|
||||||
#aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + aux_num*4)
|
#aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + aux_num*4)
|
||||||
#print('%d:%r' % (aux_num, (aux,)));
|
#print('%d:%r' % (aux_num, (aux,)));
|
||||||
for file_num in range(symbolic_header.ifdMax):
|
for file_num in range(symbolic_header.ifdMax):
|
||||||
fd = read_file_descriptor(file_data, symbolic_header.cbFdOffset - OFFSET + file_num*72)
|
fd = read_file_descriptor(file_data, symbolic_header.cbFdOffset - OFFSET + file_num*72)
|
||||||
file_descriptors.append(fd)
|
file_descriptors.append(fd)
|
||||||
for file_num in range(symbolic_header.ifdMax):
|
for file_num in range(symbolic_header.ifdMax):
|
||||||
fd = read_file_descriptor(file_data, symbolic_header.cbFdOffset - OFFSET + file_num*72)
|
fd = read_file_descriptor(file_data, symbolic_header.cbFdOffset - OFFSET + file_num*72)
|
||||||
print('%r' % (fd,))
|
print('%r' % (fd,))
|
||||||
print(' name:%s' % read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + fd.rss))
|
print(' name:%s' % read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + fd.rss))
|
||||||
|
|
||||||
print(' procedures:')
|
print(' procedures:')
|
||||||
for proc_num in range(fd.ipdFirst, fd.ipdFirst + fd.cpd):
|
for proc_num in range(fd.ipdFirst, fd.ipdFirst + fd.cpd):
|
||||||
pd = read_procedure_descriptor(file_data, symbolic_header.cbPdOffset - OFFSET + proc_num*52)
|
pd = read_procedure_descriptor(file_data, symbolic_header.cbPdOffset - OFFSET + proc_num*52)
|
||||||
print(' %r' % ((pd,)))
|
print(' %r' % ((pd,)))
|
||||||
|
|
||||||
print(' symbols:')
|
print(' symbols:')
|
||||||
for sym_num in range(fd.isymBase, fd.isymBase + fd.csym):
|
for sym_num in range(fd.isymBase, fd.isymBase + fd.csym):
|
||||||
sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + sym_num*12)
|
sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + sym_num*12)
|
||||||
print(' %r' % ((sym,)))
|
print(' %r' % ((sym,)))
|
||||||
print(' name:%s' % read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + sym.iss))
|
print(' name:%s' % read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + sym.iss))
|
||||||
print(' type:%s(%d)' % (symbol_type_list[sym.st], sym.st))
|
print(' type:%s(%d)' % (symbol_type_list[sym.st], sym.st))
|
||||||
print(' storage class:%s(%d)' % (storage_class_list[sym.sc], sym.sc))
|
print(' storage class:%s(%d)' % (storage_class_list[sym.sc], sym.sc))
|
||||||
if sym.st == 3 or sym.st == 4 or sym.st == 9 or sym.st == 10 or sym.st == 28: # stParam, stLocal, stMember, stTypedef, stEnum
|
if sym.st == 3 or sym.st == 4 or sym.st == 9 or sym.st == 10 or sym.st == 28: # stParam, stLocal, stMember, stTypedef, stEnum
|
||||||
aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + sym.index)*4)
|
aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + sym.index)*4)
|
||||||
print(' %r' % ((aux,)))
|
print(' %r' % ((aux,)))
|
||||||
offset = 0
|
offset = 0
|
||||||
if aux.ti.fBitfield == 1:
|
if aux.ti.fBitfield == 1:
|
||||||
bitfield_aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + sym.index + 1)*4)
|
bitfield_aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + sym.index + 1)*4)
|
||||||
print(' %r' % ((bitfield_aux,)))
|
print(' %r' % ((bitfield_aux,)))
|
||||||
offset = 1
|
offset = 1
|
||||||
if aux.ti.bt == 12 or aux.ti.bt == 13 or aux.ti.bt == 14 or aux.ti.bt == 15: # btStruct, btUnion, btEnum, btTypedef
|
if aux.ti.bt == 12 or aux.ti.bt == 13 or aux.ti.bt == 14 or aux.ti.bt == 15: # btStruct, btUnion, btEnum, btTypedef
|
||||||
aux2 = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + sym.index + 1 + offset)*4)
|
aux2 = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + sym.index + 1 + offset)*4)
|
||||||
print(' %r' % ((aux2,)))
|
print(' %r' % ((aux2,)))
|
||||||
if aux2.rndx.rfd == 4095:
|
if aux2.rndx.rfd == 4095:
|
||||||
aux3 = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + sym.index + 2 + offset)*4)
|
aux3 = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + sym.index + 2 + offset)*4)
|
||||||
print(' %r' % ((aux3,)))
|
print(' %r' % ((aux3,)))
|
||||||
sym2 = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + (file_descriptors[aux3.isym].isymBase + aux2.rndx.index)*12)
|
sym2 = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + (file_descriptors[aux3.isym].isymBase + aux2.rndx.index)*12)
|
||||||
print(' %r' % (sym2,))
|
print(' %r' % (sym2,))
|
||||||
print(' name:%s' % read_string(file_data, symbolic_header.cbSsOffset - OFFSET + file_descriptors[aux3.isym].issBase + sym2.iss))
|
print(' name:%s' % read_string(file_data, symbolic_header.cbSsOffset - OFFSET + file_descriptors[aux3.isym].issBase + sym2.iss))
|
||||||
if sym.st == 6: # stProc
|
if sym.st == 6: # stProc
|
||||||
# TODO what is the first aux symbol for?
|
# TODO what is the first aux symbol for?
|
||||||
aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + sym.index)*4)
|
aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + sym.index)*4)
|
||||||
type_aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + sym.index+1)*4)
|
type_aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + sym.index+1)*4)
|
||||||
print(' %r' % ((aux,)))
|
print(' %r' % ((aux,)))
|
||||||
print(' %r' % ((type_aux,)))
|
print(' %r' % ((type_aux,)))
|
||||||
|
|
||||||
print(' pretty print:')
|
print(' pretty print:')
|
||||||
print_symbols(file_data, fd, symbolic_header)
|
print_symbols(file_data, fd, symbolic_header)
|
||||||
|
|
||||||
|
|
||||||
main()
|
main()
|
|
@ -1,102 +1,102 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import os, struct, sys, ast, argparse
|
import os, struct, sys, ast, argparse
|
||||||
|
|
||||||
def read_all_lines(file_name):
|
def read_all_lines(file_name):
|
||||||
lines = list()
|
lines = list()
|
||||||
try:
|
try:
|
||||||
with open(file_name) as f:
|
with open(file_name) as f:
|
||||||
lines = f.readlines()
|
lines = f.readlines()
|
||||||
except IOError:
|
except IOError:
|
||||||
print('failed to read file ' + file_name)
|
print('failed to read file ' + file_name)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
|
|
||||||
parser.add_argument('--file', help='File to print progress off. If excluded, defaults to all files.')
|
parser.add_argument('--file', help='File to print progress off. If excluded, defaults to all files.')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
map_lines = read_all_lines('build/mm.map')
|
map_lines = read_all_lines('build/mm.map')
|
||||||
|
|
||||||
current_section = ''
|
current_section = ''
|
||||||
in_section_list = False
|
in_section_list = False
|
||||||
asm_amounts = dict()
|
asm_amounts = dict()
|
||||||
src_amounts = dict()
|
src_amounts = dict()
|
||||||
src_files = dict()
|
src_files = dict()
|
||||||
for line in map_lines:
|
for line in map_lines:
|
||||||
if in_section_list:
|
if in_section_list:
|
||||||
if line.startswith('OUTPUT(build/code.elf elf32-tradbigmips)'):
|
if line.startswith('OUTPUT(build/code.elf elf32-tradbigmips)'):
|
||||||
break
|
break
|
||||||
|
|
||||||
line_split = list(filter(None, line.split()))
|
line_split = list(filter(None, line.split()))
|
||||||
|
|
||||||
if (len(line_split) > 0 and not line.startswith(' ')):
|
if (len(line_split) > 0 and not line.startswith(' ')):
|
||||||
current_section = line_split[0]
|
current_section = line_split[0]
|
||||||
src_amounts[current_section] = 0
|
src_amounts[current_section] = 0
|
||||||
asm_amounts[current_section] = 0
|
asm_amounts[current_section] = 0
|
||||||
src_files[current_section] = []
|
src_files[current_section] = []
|
||||||
|
|
||||||
if (len(line_split) == 4 and line_split[0].startswith(".")):
|
if (len(line_split) == 4 and line_split[0].startswith(".")):
|
||||||
section = line_split[0]
|
section = line_split[0]
|
||||||
size = int(line_split[2], 16)
|
size = int(line_split[2], 16)
|
||||||
obj_file = line_split[3]
|
obj_file = line_split[3]
|
||||||
|
|
||||||
if (section == ".text" and not current_section + '_data' in obj_file and not current_section + '_rodata' in obj_file):
|
if (section == ".text" and not current_section + '_data' in obj_file and not current_section + '_rodata' in obj_file):
|
||||||
if (obj_file.startswith("build/src")):
|
if (obj_file.startswith("build/src")):
|
||||||
src_amounts[current_section] += size
|
src_amounts[current_section] += size
|
||||||
formatted_name = obj_file[len('build/'):] # remove build/ prefix
|
formatted_name = obj_file[len('build/'):] # remove build/ prefix
|
||||||
formatted_name = formatted_name[:-1] + 'c' # replace .o preface with .c
|
formatted_name = formatted_name[:-1] + 'c' # replace .o preface with .c
|
||||||
src_files[current_section].append(formatted_name)
|
src_files[current_section].append(formatted_name)
|
||||||
elif (obj_file.startswith("build/asm")):
|
elif (obj_file.startswith("build/asm")):
|
||||||
asm_amounts[current_section] += size
|
asm_amounts[current_section] += size
|
||||||
else:
|
else:
|
||||||
in_section_list = line.startswith('Linker script and memory map')
|
in_section_list = line.startswith('Linker script and memory map')
|
||||||
|
|
||||||
for section in src_files:
|
for section in src_files:
|
||||||
for file in src_files[section]:
|
for file in src_files[section]:
|
||||||
file_lines = read_all_lines(file)
|
file_lines = read_all_lines(file)
|
||||||
for line in file_lines:
|
for line in file_lines:
|
||||||
if line.startswith('GLOBAL_ASM'):
|
if line.startswith('GLOBAL_ASM'):
|
||||||
line_split = list(filter(None, line.split('\"')))
|
line_split = list(filter(None, line.split('\"')))
|
||||||
asm_lines = read_all_lines(line_split[1])
|
asm_lines = read_all_lines(line_split[1])
|
||||||
for asm_line in asm_lines:
|
for asm_line in asm_lines:
|
||||||
if asm_line.startswith('/*'):
|
if asm_line.startswith('/*'):
|
||||||
asm_amounts[section] += 4
|
asm_amounts[section] += 4
|
||||||
src_amounts[section] -= 4
|
src_amounts[section] -= 4
|
||||||
|
|
||||||
src = 0
|
src = 0
|
||||||
asm = 0
|
asm = 0
|
||||||
if args.file == None:
|
if args.file == None:
|
||||||
for section in src_amounts:
|
for section in src_amounts:
|
||||||
src += src_amounts[section]
|
src += src_amounts[section]
|
||||||
for section in asm_amounts:
|
for section in asm_amounts:
|
||||||
asm += asm_amounts[section]
|
asm += asm_amounts[section]
|
||||||
else:
|
else:
|
||||||
if args.file not in src_amounts or args.file not in asm_amounts:
|
if args.file not in src_amounts or args.file not in asm_amounts:
|
||||||
sys.exit('{} not found in map file'.format(args.file))
|
sys.exit('{} not found in map file'.format(args.file))
|
||||||
src += src_amounts[args.file]
|
src += src_amounts[args.file]
|
||||||
asm += asm_amounts[args.file]
|
asm += asm_amounts[args.file]
|
||||||
|
|
||||||
total = src + asm
|
total = src + asm
|
||||||
src_percent = 100 * src / total
|
src_percent = 100 * src / total
|
||||||
asm_percent = 100 * asm / total
|
asm_percent = 100 * asm / total
|
||||||
|
|
||||||
print('{} total bytes of decompilable code\n'.format(total))
|
print('{} total bytes of decompilable code\n'.format(total))
|
||||||
print('{} bytes of code in src {}%'.format(src, src_percent))
|
print('{} bytes of code in src {}%'.format(src, src_percent))
|
||||||
print('{} bytes of code in asm {}%\n'.format(asm, asm_percent))
|
print('{} bytes of code in asm {}%\n'.format(asm, asm_percent))
|
||||||
print("------------------------------------\n")
|
print("------------------------------------\n")
|
||||||
|
|
||||||
num_masks = 24
|
num_masks = 24
|
||||||
max_rupees = 500
|
max_rupees = 500
|
||||||
bytes_per_mask = total / num_masks
|
bytes_per_mask = total / num_masks
|
||||||
bytes_per_rupee = bytes_per_mask / max_rupees
|
bytes_per_rupee = bytes_per_mask / max_rupees
|
||||||
masks = int(src / bytes_per_mask)
|
masks = int(src / bytes_per_mask)
|
||||||
rupees = int((src % bytes_per_mask) / bytes_per_rupee)
|
rupees = int((src % bytes_per_mask) / bytes_per_rupee)
|
||||||
|
|
||||||
if (rupees > 0):
|
if (rupees > 0):
|
||||||
print('You have {}/{} masks and {}/{} rupee(s).\n'.format(masks, num_masks, rupees, max_rupees));
|
print('You have {}/{} masks and {}/{} rupee(s).\n'.format(masks, num_masks, rupees, max_rupees));
|
||||||
else:
|
else:
|
||||||
print('You have {}/{} masks .\n'.format(masks, num_masks));
|
print('You have {}/{} masks .\n'.format(masks, num_masks));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue