diff --git a/Jenkinsfile b/Jenkinsfile index a01f6b2d..66549a57 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -26,8 +26,9 @@ pipeline { } steps { sh 'mkdir reports' - sh 'python3 progress.py >> reports/progress_tmc.csv' - sh 'python3 progress.py -m >> reports/progress_tmc_matching.csv' + sh 'python3 progress.py csv >> reports/progress-tmc-nonmatching.csv' + sh 'python3 progress.py csv -m >> reports/progress-tmc-matching.csv' + sh 'python3 progress.py shield-json > reports/progress-tmc-shield.json' stash includes: 'reports/*', name: 'reports' } } @@ -40,8 +41,9 @@ pipeline { } steps { unstash 'reports' - sh 'cat reports/progress_tmc.csv >> /var/www/html/reports/progress_tmc.csv' - sh 'cat reports/progress_tmc_matching.csv >> /var/www/html/reports/progress_tmc_matching.csv' + sh 'cat reports/progress-tmc-nonmatching.csv >> /var/www/zelda64.dev/assets/csv/progress-tmc-nonmatching.csv' + sh 'cat reports/progress-tmc-matching.csv >> /var/www/zelda64.dev/assets/csv/progress-tmc-matching.csv' + sh 'cat reports/progress-tmc-shield.json > /var/www/zelda64.dev/assets/csv/progress-tmc-shield.json' } } } diff --git a/README.md b/README.md index 5b3e1a88..5663c817 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,19 @@ # The Legend of Zelda: The Minish Cap -**Progress:** [⬛⬛⬛⬛⬛⬛⬛⬛⬛⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜] 45% + +[![Build Status][jenkins-badge]][jenkins] [![Decompilation Progress][progress-badge]][progress] [![Contributors][contributors-badge]][contributors] [![Discord Channel][discord-badge]][discord] + +[jenkins]: https://jenkins.deco.mp/job/TMC/job/master +[jenkins-badge]: https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fjenkins.deco.mp%2Fjob%2FTMC%2Fjob%2Fmaster + +[progress]: https://zelda64.dev/games/tmc +[progress-badge]: https://img.shields.io/endpoint?url=https://zelda64.dev/assets/csv/progress-tmc-shield.json + +[contributors]: https://github.com/zeldaret/tmc/graphs/contributors +[contributors-badge]: https://img.shields.io/github/contributors/zeldaret/tmc + +[discord]: https://discord.zelda64.dev +[discord-badge]: https://img.shields.io/discord/688807550715560050?color=%237289DA&logo=discord&logoColor=%23FFFFFF ```diff - WARNING! - diff --git a/asm/objectOnPillar.s b/asm/objectOnPillar.s index a6f43db9..64542d7e 100644 --- a/asm/objectOnPillar.s +++ b/asm/objectOnPillar.s @@ -699,7 +699,7 @@ _08097346: sub_08097348: @ 0x08097348 push {lr} adds r3, r0, #0 - ldr r1, _08097360 @ =gUnk_02017660 + ldr r1, _08097360 @ =gSmallChests movs r2, #0 _08097350: ldrh r0, [r1, #4] @@ -709,7 +709,7 @@ _08097350: bl CheckLocalFlag b _0809736E .align 2, 0 -_08097360: .4byte gUnk_02017660 +_08097360: .4byte gSmallChests _08097364: adds r2, #1 adds r1, #8 diff --git a/include/room.h b/include/room.h index aafac5bd..568c3f61 100644 --- a/include/room.h +++ b/include/room.h @@ -152,7 +152,24 @@ typedef struct { u8 _6; u8 _7; } TileEntity; -extern TileEntity gUnk_02017660[]; +extern TileEntity gSmallChests[]; + +typedef enum { + NONE, + ROOM_VISIT_MARKER, + SMALL_CHEST, + BIG_CHEST, + BOMBABLE_WALL, + SIGN, + TILE_ENTITY_6, + MUSIC_SETTER, + TILE_ENTITY_8, + DARKNESS, + DESTRUCTIBLE_TILE, + GRASS_DROP_CHANGER, + TILE_ENTITY_C, + TILE_ENTITY_D +} TileEntityType; extern void SetTileType(u32, u32, u32); extern void sub_08080964(u32 time, u32 magnitude); // shake screen diff --git a/linker.ld b/linker.ld index d98c69d0..896a56fb 100644 --- a/linker.ld +++ b/linker.ld @@ -65,7 +65,7 @@ SECTIONS { . = 0x00012654; gMetatilesTop = .; . = 0x00016654; gUnk_02016654 = .; . = 0x00017654; gCurrentRoomProperties = .; - . = 0x00017660; gUnk_02017660 = .; + . = 0x00017660; gSmallChests = .; . = 0x000176A0; gPaletteBuffer = .; . = 0x000176E0; gUnk_020176E0 = .; . = 0x00017700; gUnk_02017700 = .; diff --git a/progress.py b/progress.py old mode 100644 new mode 100755 index 512dc31a..141fbc30 --- a/progress.py +++ b/progress.py @@ -1,4 +1,7 @@ +#!/usr/bin/env python3 + import argparse +import json import git import os import re @@ -80,9 +83,13 @@ def parse_map(non_matching_funcs): def main(): parser = argparse.ArgumentParser() - parser.add_argument('-m', '--matching', dest='matching', action='store_true', - help='Output matching progress instead of decompilation progress') + + parser = argparse.ArgumentParser(description="Computes current progress throughout the whole project.") + parser.add_argument("format", nargs="?", default="text", choices=["text", "csv", "shield-json"]) + parser.add_argument("-m", "--matching", dest='matching', action='store_true', + help="Output matching progress instead of decompilation progress") args = parser.parse_args() + matching = args.matching non_matching_funcs = [] @@ -101,21 +108,42 @@ def main(): total = src + asm data_total = src_data + data - src_pct = '%.4f' % (100 * src / total) - asm_pct = '%.4f' % (100 * asm / total) + src_percent = 100 * src / total + asm_percent = 100 * asm / total - src_data_pct = '%.4f' % (100 * src_data / data_total) - data_pct = '%.4f' % (100 * data / data_total) + src_data_percent = 100 * src_data / data_total + data_percent = 100 * data / data_total - version = 1 - git_object = git.Repo().head.object - timestamp = str(git_object.committed_date) - git_hash = git_object.hexsha - csv_list = [str(version), timestamp, git_hash, str(src_pct), - str(asm_pct), str(src_data_pct), str(data_pct)] + if args.format == 'csv': + version = 2 + git_object = git.Repo().head.object + timestamp = str(git_object.committed_date) + git_hash = git_object.hexsha - print(','.join(csv_list)) + csv_list = [str(version), timestamp, git_hash, str(src), + str(total), str(src_data), str(data_total)] + + print(','.join(csv_list)) + + elif args.format == 'shield-json': + # https://shields.io/endpoint + print(json.dumps({ + "schemaVersion": 1, + "label": "progress", + "message": f"{src_percent:.3g}%", + "color": 'yellow', + })) + + elif args.format == 'text': + adjective = "decompiled" if not args.matching else "matched" + + print("src: {:>9} / {:>8} total bytes {:<10} {:>9.4f}%".format(src, total, adjective, round(src_percent, 4))) + # print() + print("data: {:>9} / {:>8} total bytes analysed {:>9.4f}%".format(src_data, data_total, round(src_data_percent, 4))) + + else: + print("Unknown format argument: " + args.format) if __name__ == '__main__': diff --git a/src/playerItemUtils.c b/src/playerItemUtils.c index 98bd0309..5863d96f 100644 --- a/src/playerItemUtils.c +++ b/src/playerItemUtils.c @@ -6,6 +6,7 @@ #include "audio.h" #include "flags.h" #include "textbox.h" +#include "object.h" Entity* GiveItemWithCutscene(u32, u32, u32); Entity* sub_080A276C(Entity*, u32, u32); @@ -13,15 +14,15 @@ void sub_08078AF0(Entity*, u32, u32); Entity* sub_0805E744(void); void sub_080A7D44(u32, u32); -void CreateItemEntity(u32 a, u32 b, u32 c) { - Entity* e = GiveItemWithCutscene(a, b, c); +void CreateItemEntity(u32 type, u32 type2, u32 delay) { + Entity* e = GiveItemWithCutscene(type, type2, delay); if (e != NULL) { e->parent = sub_080A276C(e, e->type, 0); } } -void sub_080A7C18(u32 a, u32 b, u32 c) { - Entity* e = GiveItemWithCutscene(a, b, c); +void sub_080A7C18(u32 type, u32 type2, u32 delay) { + Entity* e = GiveItemWithCutscene(type, type2, delay); if (e != NULL) { e->parent = &gPlayerEntity; sub_08078AF0(e, e->type, 0); @@ -39,19 +40,19 @@ Entity* GiveItemWithCutscene(u32 type, u32 type2, u32 delay) { e->type = type; e->type2 = type2; e->actionDelay = delay; - e->id = 11; - e->kind = 6; + e->id = OBJECT_B; + e->kind = OBJECT; AppendEntityToList(e, 6); } return e; } -void sub_080A7C7C(void) { - MemClear(gUnk_02017660, 0x40); +void ClearSmallChests(void) { + MemClear(gSmallChests, 0x40); } void sub_080A7C8C(u32 pos, u32 layer) { - TileEntity* t = gUnk_02017660; + TileEntity* t = gSmallChests; u32 found = 0; u32 i; for (i = 0; i < 8; ++i, ++t) { @@ -69,25 +70,25 @@ void sub_080A7C8C(u32 pos, u32 layer) { } sub_0807B7D8(0x74, pos, layer); RequestPriorityDuration(NULL, 120); - SoundReq(283); + SoundReq(SFX_11B); } } u32 sub_080A7CFC(u32 a1) { - u32 ta = 0x600; - u32 tb = 0; + u32 msg = 0x600; + u32 isTileEntity6 = 0; TileEntity* t = GetCurrentRoomProperty(3); if (t != 0) { do { if (t->_4 == a1) { switch (t->type) { - case 5: - tb = 0; - ta = *(u16*)&t->_6; + case SIGN: + isTileEntity6 = 0; + msg = *(u16*)&t->_6; break; - case 6: - tb = 1; - ta = *(u16*)&t->_6; + case TILE_ENTITY_6: + isTileEntity6 = 1; + msg = *(u16*)&t->_6; break; } break; @@ -95,12 +96,13 @@ u32 sub_080A7CFC(u32 a1) { t++; } while (t->_4 != 0); } - sub_080A7D44(ta, tb); + sub_080A7D44(msg, isTileEntity6); } -void sub_080A7D44(u32 msg, u32 a2) { - if (a2) +void sub_080A7D44(u32 msg, u32 isTileEntity6) { + if (isTileEntity6) sub_08078AA8(msg, 0); else + // Read sign text MessageFromTarget(msg); } diff --git a/src/room.c b/src/room.c index e892739e..d4feb11f 100644 --- a/src/room.c +++ b/src/room.c @@ -17,7 +17,7 @@ extern u8 gUnk_081091E4[]; extern void sub_080186EC(); extern void sub_0804B16C(); -extern void sub_080A7C7C(void); +extern void ClearSmallChests(void); extern Entity* GetEmptyEntityByKind(u32 kind); void RegisterRoomEntity(Entity*, EntityData*); @@ -134,7 +134,7 @@ void sub_0804AF0C(Entity* ent, EntityData* dat) { void sub_0804AF90(void) { sub_0804AFB0(gArea.pCurrentRoomInfo->properties); - sub_080A7C7C(); + ClearSmallChests(); } void sub_0804AFB0(void** properties) { @@ -254,12 +254,12 @@ void* GetCurrentRoomProperty(u32 idx) { } void sub_0804B16C(void) { - TileEntity* tile = gUnk_02017660; + TileEntity* tile = gSmallChests; do { if (tile->_4 != 0 && CheckLocalFlag(tile->_1)) { SetTileType(0x74, tile->_4, tile->_6 & 1 ? 2 : 1); } - } while (++tile < gUnk_02017660 + 8); + } while (++tile < gSmallChests + 8); } void LoadRoomTileEntities(TileEntity* list) { @@ -315,7 +315,7 @@ static void sub_0804B290(TileEntity* tile) { } static void sub_0804B29C(TileEntity* tile) { - TileEntity* t = gUnk_02017660; + TileEntity* t = gSmallChests; u32 i = 0; for (i = 0; i < 8; ++i, ++t) { if (!t->_4) {