diff --git a/src/app/games/game/game-progress/game-chart/game-chart.component.ts b/src/app/games/game/game-progress/game-chart/game-chart.component.ts index d582d6c..b674840 100644 --- a/src/app/games/game/game-progress/game-chart/game-chart.component.ts +++ b/src/app/games/game/game-progress/game-chart/game-chart.component.ts @@ -41,13 +41,17 @@ export class GameChartComponent implements OnChanges { // set up chart data const metadata = this.metadata; let nonmatchingData = this.parseData(this.csvData[0]); - let matchingData = this.parseData(this.csvData[1]); - - // Names for lines let nonmatchingName = this.metadata.series[0].name; - let matchingName = this.metadata.series[1].name; let nonmatchingVisibility = this.metadata.series[0].visibility; - let matchingVisibility = this.metadata.series[1].visibility; + + let matchingData = []; + let matchingName = ""; + let matchingVisibility = false; + if (this.metadata.series.length > 1) { + matchingData = this.parseData(this.csvData[1]); + matchingName = this.metadata.series[1].name; + matchingVisibility = this.metadata.series[1].visibility; + } let joined = Array.prototype.concat(matchingData, nonmatchingData); @@ -59,7 +63,7 @@ export class GameChartComponent implements OnChanges { max = null; } - const options: Options = { + let options: Options = { chart: { type: "line" }, @@ -102,7 +106,13 @@ export class GameChartComponent implements OnChanges { data: nonmatchingData, color: "#DDDF0D", visible: nonmatchingVisibility - }, + } + ], + }; + + + if (this.metadata.series.length > 1) { + options.series.push( { type: "line", name: matchingName, @@ -110,8 +120,8 @@ export class GameChartComponent implements OnChanges { color: "#55BF3B", visible: matchingVisibility } - ], - }; + ); + } if (this.chart === null) { this.chart = new Chart(options); diff --git a/src/app/games/game/game-progress/game-progress.component.ts b/src/app/games/game/game-progress/game-progress.component.ts index 1491c64..3ceb4f6 100644 --- a/src/app/games/game/game-progress/game-progress.component.ts +++ b/src/app/games/game/game-progress/game-progress.component.ts @@ -50,7 +50,9 @@ export class GameProgressComponent implements OnChanges { this.lastUpdate = null; // Collect the latest numbers from the CSV data - for (const data of this.csvData) { + for (let k = 0; k < this.meta.series.length; k++) { + const data = this.csvData[k]; + const points = data.split("\n").filter((line) => line != ""); const latestPoint = points[points.length - 1]; const column = latestPoint.split(","); diff --git a/src/assets/json/games.json b/src/assets/json/games.json index 516eb01..0bccd60 100644 --- a/src/assets/json/games.json +++ b/src/assets/json/games.json @@ -93,35 +93,80 @@ "subdivisions": [ { "metric": "Assets", - "description": "{0} / {1} bytes of all assets decompiled ({2}%)" + "description": "{0} / {1} bytes of all assets ({2}%)" }, { "metric": "Archives", - "description": "{0} / {1} bytes of archived assets decompiled ({2}%)" + "description": "{0} / {1} bytes of archived assets ({2}%)" }, { "metric": "Audio", - "description": "{0} / {1} bytes of audio assets decompiled ({2}%)" + "description": "{0} / {1} bytes of audio assets ({2}%)" }, { "metric": "Interface", - "description": "{0} / {1} bytes of interface-related assets decompiled ({2}%)" + "description": "{0} / {1} bytes of interface-related assets ({2}%)" }, { "metric": "Miscellaneous", - "description": "{0} / {1} bytes of miscellaneous assets decompiled ({2}%)" + "description": "{0} / {1} bytes of miscellaneous assets ({2}%)" }, { "metric": "Objects", - "description": "{0} / {1} bytes of object assets decompiled ({2}%)" + "description": "{0} / {1} bytes of object assets ({2}%)" }, { "metric": "Scenes", - "description": "{0} / {1} bytes of scene assets decompiled ({2}%)" + "description": "{0} / {1} bytes of scene assets ({2}%)" }, { "metric": "Text", - "description": "{0} / {1} bytes of text assets decompiled ({2}%)" + "description": "{0} / {1} bytes of text assets ({2}%)" + } + ] + } + ] + }, + { + "slug": "tmc", + "title": "The Minish Cap", + "links": { + "github": "https://www.github.com/zeldaret/mm" + }, + "faq": "tmc_faq", + "csvs": { + "matching": "progress-tmc-matching", + "nonmatching": "progress-tmc-nonmatching" + }, + "progressMeta": [ + { + "type": "code", + "title": "The Minish Cap", + "subtitle": "Code decompilation progress", + "series": [ + {"name": "Nonmatching", "visibility": true}, + {"name": "Matching", "visibility": true} + ], + "index": 3, + "subdivisions": [ + { + "metric": "Code", + "description": "{0} / {1} bytes of all code decompiled ({2}%)" + } + ] + }, + { + "type": "assets", + "title": "The Minish Cap", + "subtitle": "Data analysis progress", + "series": [ + {"name": "Analyzed", "visibility": true} + ], + "index": 5, + "subdivisions": [ + { + "metric": "Assets", + "description": "{0} / {1} bytes of all data ({2}%)" } ] } diff --git a/src/assets/md/tmc_faq.md b/src/assets/md/tmc_faq.md new file mode 100644 index 0000000..3f20b6d --- /dev/null +++ b/src/assets/md/tmc_faq.md @@ -0,0 +1,147 @@ +- [What programming language is The Minish Cap + in?](#what-programming-language-is-the-minish-cap-in) +- [What compiler does it use?](#what-compiler-does-it-use) +- [Do you have a decompiler like mips2c? How hard is it to + match?](#do-you-have-a-decompiler-like-mips2c-how-hard-is-it-to-match) +- [What's the goal of this + project?](#whats-the-goal-of-this-project) +- [How many versions are there? Are all of them going to be + decompiled?](#how-many-versions-are-there-are-all-of-them-going-to-be-decompiled) +- [You only track progress for one version. How different are the + versions, and how different is the progress on + them?](#you-only-track-progress-for-one-version.-how-different-are-the-versions-and-how-different-is-the-progress-on-them) +- [How large is the game's code in total? How large is the + rom?](#how-large-is-the-games-code-in-total-how-large-is-the-rom) +- [PC port?](#pc-port) +- [Can this be used for modding?](#can-this-be-used-for-modding) +- [Have you found out anything + interesting?](#have-you-found-out-anything-interesting) +- [Is what you find out here useful for any other + games?](#is-what-you-find-out-here-useful-for-any-other-games) +- [How do I get the third Oracle's + house?](#how-do-i-get-the-third-oracles-house) +- [I'd like to help. How should I get + started?](#id-like-to-help.-how-should-i-get-started) +- [What do I need to know to + contribute?](#what-do-i-need-to-know-to-contribute) +- [I'd like to write/blog/make a video about this project. Where + can I get more + information?](#id-like-to-writeblogmake-a-video-about-this-project.-where-can-i-get-more-information) + +The Minish Cap Decompilation Project FAQ +======================================== + +What programming language is The Minish Cap in? +----------------------------------------------- + +It was originally written in C, which is compiled to ARMv4T, which is +the language the Gameboy Advance uses. + +What compiler does it use? +-------------------------- + +abgcc, a standard C compiler for GameBoy Advance games (also used by +Pokemon, for example) + +Do you have a decompiler like mips2c? How hard is it to match? +-------------------------------------------------------------- + +No specialist decompiler for ARM exists, so people read the assembly +themselves or use Ghidra or the HexRays decompiler for a first +approximation. There are also specialist data/hex analysis tools made +for the project: [ask in Discord for +details](https://discord.zelda64.dev/) + +What's the goal of this project? +-------------------------------- + +To decompile every version of the game, to learn about its inner +workings for curiosity, and also for applications in speedrunning. + +How many versions are there? Are all of them going to be decompiled? +-------------------------------------------------------------------- + +There are 5 versions: - US retail - EU retail - JP retail - US demo - JP +demo + +All will eventually be decompiled, and they are being worked on +concurrently (see next question for why this is efficient). + +You only track progress for one version. How different are the versions, and how different is the progress on them? +------------------------------------------------------------------------------------------------------------------- + +Currently it seems that the versions are sufficiently similar that +there's not a lot of point tracking the differences: as of writing the +difference between US and DEMO JP is only 0.017%! + +How large is the game's code in total? How large is the rom? +------------------------------------------------------------ + +The code that can be decompiled to C is about 640 kB. The whole ROM is +16 MB. + +PC port? +-------- + +Yes, it will be possible, just like the Pokemon Emerald one. But we will +not be making it. + +Can this be used for modding? +----------------------------- + +In theory, yes. The rom is already shiftable, but not everything is +decompiled yet and the repository is subject to major changes as more is +worked on, so we do not recommend it unless you really know what you are +doing. + +Have you found out anything interesting? +---------------------------------------- + +Yes! - Unlike a lot of 2D games, some parts of TMC use 3D hit boxes - +The engine has many similarities to Four Swords' - There's some left +over development information like unused strings corresponding to game +flags, and some graphics config files. + +Is what you find out here useful for any other games? +----------------------------------------------------- + +TMC will aid with the decompilation of Four Swords. It is currently +unknown whether other games share portions of code with it. + +How do I get the third Oracle's house? +-------------------------------------- + +Sadly you can't, and from the code, it looks like it never intended to +be possible: the function which determines which of the Oracles appear +in the Inn is specifically written for two being accommodated, and the +overcomplicated way that they check the conditions suggests that there +was never a case for a third option (or hopefully they would have done +it a different way if there had been). + +I'd like to help. How should I get started? +------------------------------------------- + +Great, we're always happy to get new contributors! Most importantly, +[join the Discord](https://discord.zelda64.dev/), since this is where +all the discussion takes place. Start by reading the project +[README.md](https://github.com/zeldaret/tmc/blob/master/README.md) for +general information, follow the instructions in +[INSTALL.md](https://github.com/zeldaret/tmc/blob/master/INSTALL.md) to +get set up, and then read the +[CONTRIBUTING.md](https://github.com/zeldaret/tmc/blob/master/CONTRIBUTING.md) +for how to work on your first file. + +What do I need to know to contribute? +------------------------------------- + +The three most important things are knowledge of C, knowledge of ARM +assembly, and general knowledge about how the game works. Ask in the +Discord for how to acquire the first two: most people have learnt at +least the assembly part while working on this project, if not both. You +can do the third yourself by playing it again and paying attention! + +I'd like to write/blog/make a video about this project. Where can I get more information? +----------------------------------------------------------------------------------------- + +Please reach out to the project lead on Discord, who will be happy to +answer any questions.