{project.data.name}
+{project.name}
-{project.desc}
+{project.data.desc}
-diff --git a/package.json b/package.json
index 4e45069..f406dbf 100644
--- a/package.json
+++ b/package.json
@@ -9,6 +9,7 @@
},
"dependencies": {
"astro": "^5.7.0",
+ "marked": "^17.0.4",
"sharp": "^0.34.5"
},
"pnpm": {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index de6d189..5182892 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -11,6 +11,9 @@ importers:
astro:
specifier: ^5.7.0
version: 5.18.0(rollup@4.59.0)(typescript@5.9.3)
+ marked:
+ specifier: ^17.0.4
+ version: 17.0.4
sharp:
specifier: ^0.34.5
version: 0.34.5
@@ -400,89 +403,105 @@ packages:
resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==}
cpu: [arm64]
os: [linux]
+ libc: [glibc]
'@img/sharp-libvips-linux-arm@1.2.4':
resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==}
cpu: [arm]
os: [linux]
+ libc: [glibc]
'@img/sharp-libvips-linux-ppc64@1.2.4':
resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==}
cpu: [ppc64]
os: [linux]
+ libc: [glibc]
'@img/sharp-libvips-linux-riscv64@1.2.4':
resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==}
cpu: [riscv64]
os: [linux]
+ libc: [glibc]
'@img/sharp-libvips-linux-s390x@1.2.4':
resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==}
cpu: [s390x]
os: [linux]
+ libc: [glibc]
'@img/sharp-libvips-linux-x64@1.2.4':
resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==}
cpu: [x64]
os: [linux]
+ libc: [glibc]
'@img/sharp-libvips-linuxmusl-arm64@1.2.4':
resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==}
cpu: [arm64]
os: [linux]
+ libc: [musl]
'@img/sharp-libvips-linuxmusl-x64@1.2.4':
resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==}
cpu: [x64]
os: [linux]
+ libc: [musl]
'@img/sharp-linux-arm64@0.34.5':
resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm64]
os: [linux]
+ libc: [glibc]
'@img/sharp-linux-arm@0.34.5':
resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm]
os: [linux]
+ libc: [glibc]
'@img/sharp-linux-ppc64@0.34.5':
resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [ppc64]
os: [linux]
+ libc: [glibc]
'@img/sharp-linux-riscv64@0.34.5':
resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [riscv64]
os: [linux]
+ libc: [glibc]
'@img/sharp-linux-s390x@0.34.5':
resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [s390x]
os: [linux]
+ libc: [glibc]
'@img/sharp-linux-x64@0.34.5':
resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [x64]
os: [linux]
+ libc: [glibc]
'@img/sharp-linuxmusl-arm64@0.34.5':
resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm64]
os: [linux]
+ libc: [musl]
'@img/sharp-linuxmusl-x64@0.34.5':
resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [x64]
os: [linux]
+ libc: [musl]
'@img/sharp-wasm32@0.34.5':
resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==}
@@ -556,66 +575,79 @@ packages:
resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==}
cpu: [arm]
os: [linux]
+ libc: [glibc]
'@rollup/rollup-linux-arm-musleabihf@4.59.0':
resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==}
cpu: [arm]
os: [linux]
+ libc: [musl]
'@rollup/rollup-linux-arm64-gnu@4.59.0':
resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==}
cpu: [arm64]
os: [linux]
+ libc: [glibc]
'@rollup/rollup-linux-arm64-musl@4.59.0':
resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==}
cpu: [arm64]
os: [linux]
+ libc: [musl]
'@rollup/rollup-linux-loong64-gnu@4.59.0':
resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==}
cpu: [loong64]
os: [linux]
+ libc: [glibc]
'@rollup/rollup-linux-loong64-musl@4.59.0':
resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==}
cpu: [loong64]
os: [linux]
+ libc: [musl]
'@rollup/rollup-linux-ppc64-gnu@4.59.0':
resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==}
cpu: [ppc64]
os: [linux]
+ libc: [glibc]
'@rollup/rollup-linux-ppc64-musl@4.59.0':
resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==}
cpu: [ppc64]
os: [linux]
+ libc: [musl]
'@rollup/rollup-linux-riscv64-gnu@4.59.0':
resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==}
cpu: [riscv64]
os: [linux]
+ libc: [glibc]
'@rollup/rollup-linux-riscv64-musl@4.59.0':
resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==}
cpu: [riscv64]
os: [linux]
+ libc: [musl]
'@rollup/rollup-linux-s390x-gnu@4.59.0':
resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==}
cpu: [s390x]
os: [linux]
+ libc: [glibc]
'@rollup/rollup-linux-x64-gnu@4.59.0':
resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==}
cpu: [x64]
os: [linux]
+ libc: [glibc]
'@rollup/rollup-linux-x64-musl@4.59.0':
resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==}
cpu: [x64]
os: [linux]
+ libc: [musl]
'@rollup/rollup-openbsd-x64@4.59.0':
resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==}
@@ -1057,6 +1089,11 @@ packages:
markdown-table@3.0.4:
resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==}
+ marked@17.0.4:
+ resolution: {integrity: sha512-NOmVMM+KAokHMvjWmC5N/ZOvgmSWuqJB8FoYI019j4ogb/PeRMKoKIjReZ2w3376kkA8dSJIP8uD993Kxc0iRQ==}
+ engines: {node: '>= 20'}
+ hasBin: true
+
mdast-util-definitions@6.0.0:
resolution: {integrity: sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==}
@@ -2614,6 +2651,8 @@ snapshots:
markdown-table@3.0.4: {}
+ marked@17.0.4: {}
+
mdast-util-definitions@6.0.0:
dependencies:
'@types/mdast': 4.0.4
diff --git a/src/components/ProjectCard.astro b/src/components/ProjectCard.astro
index 917c9ff..55547b2 100644
--- a/src/components/ProjectCard.astro
+++ b/src/components/ProjectCard.astro
@@ -1,54 +1,66 @@
---
-import { Image } from 'astro:assets';
-import type { Project } from '../data/projects';
+import { Image } from "astro:assets";
+import type { CollectionEntry } from "astro:content";
+import { marked } from "marked";
interface Props {
- project: Project;
+ project: CollectionEntry<"projects">;
}
const { project } = Astro.props;
+const { Content } = await project.render();
+
+// Render meta as markdown inline
+const metaHtml = project.data.meta
+ ? marked.parseInline(project.data.meta)
+ : null;
---
{project.desc} {project.data.desc}{project.data.name}
+
{project.name}
-
objdiff compares object files across functions and data. It supports ARM, ARM64, MIPS, PowerPC, SuperH, and x86(-64). It provides a GUI, TUI, and JSON output for integration with other tools and agentic workflows.
The core diffing engine compiles to WASM and runs as a web frontend in decomp.me and as a VS Code extension. Its progress reporting system powers decomp.dev.
- `, - images: [ - { - src: screenSymbols, - alt: 'Symbol Screenshot', - href: 'https://raw.githubusercontent.com/encounter/objdiff/refs/heads/main/assets/screen-symbols.png', - }, - { - src: screenDiff, - alt: 'Diff Screenshot', - href: 'https://raw.githubusercontent.com/encounter/objdiff/refs/heads/main/assets/screen-diff.png', - }, - ], - }, - { - name: 'decomp.dev', - url: 'https://decomp.dev', - repo: 'encounter/decomp.dev', - desc: 'Progress hub for decompilation projects', - langs: [LANG.Rust], - body: ` -decomp.dev tracks progress for more than 80 decompilation projects. With data driven by objdiff's progress reports, it provides granular information down to individual translation units and functions, plus a tree view for exploring project structure. Projects can categorize units, track multiple game versions, and navigate full commit-by-commit history.
All of this information is also exposed through its API, along with a badge system for embedding live progress in project READMEs.
wibo runs 32-bit Windows command-line tools with minimal overhead. It implements a substantial portion of the Win32 API: file I/O, threading, heap management, DLL loading, TLS, and async I/O with platform-specific backends (io_uring, epoll, kqueue). On 64-bit hosts, it constrains the guest address space to the lower 2GB and bridges calling conventions with generated trampolines. Runs on macOS under Rosetta 2.
decomp-toolkit takes a compiled binary and produces fully relinkable objects. Its analyzer handles function and object boundary detection, signature analysis, and rebuilding relocations, all with minimal configuration. dtk-template is a project template and build system built on top of decomp-toolkit.
Its approach to matching decompilation has since been applied to other platforms, including ds-decomp for Nintendo DS and jeff for Xbox 360.
- `, - meta: 'Used by more than 50 decompilation projects, including several now-complete ones like The Legend of Zelda: Twilight Princess and Mario Party 4.', - }, - { - name: 'nod', - url: 'https://github.com/encounter/nod', - repo: 'encounter/nod', - desc: 'GameCube and Wii disc image library and CLI tool', - langs: [LANG.Rust], - body: ` -nod supports reading and converting all GameCube and Wii disc image formats, with a simple and performant API. Open any disc image and get a Read + Seek + BufRead handle. Converting to ISO is just reading from that handle and writing to a file, regardless of the source format. Open a partition and get the same interface, transparently handling Wii encryption and hashing.
Reading and writing are multithreaded, and nod produces smaller disc images faster than both Dolphin and NKit v2. C bindings are available for FFI.
powerpc-rs is driven by a declarative instruction set definition that is compiled into Rust at build time, similar to LLVM's TableGen. It supports the full PowerPC instruction set along with Gekko/Broadway paired singles (GameCube/Wii) and Xenon VMX128 (Xbox 360) extensions.
The disassembler has been fuzzed over all 4.29 billion possible 32-bit instruction values and runs at ~275M instructions per second.
- `, - meta: 'Used as the PowerPC backend for objdiff and decomp-toolkit.', - }, - { - name: 'ghidra-panel', - url: 'https://github.com/encounter/ghidra-panel', - repo: 'encounter/ghidra-panel', - desc: 'Self-service portal for managing access to shared Ghidra repositories', - langs: [LANG.Go, LANG.Java], - body: ` -ghidra-panel integrates with Ghidra Server through an in-process gRPC plugin, allowing repository administrators to manage users and permissions. Users authenticate with Discord and can request repository access, sending a notification with a one-click approval link for admins.
Aurora reimplements the GX API, translating the calls to native graphics backends like Vulkan, Metal, D3D12, and WebGPU.
- `, - }, - { - name: 'metaforce', - url: 'https://github.com/AxioDL/metaforce', - repo: 'AxioDL/metaforce', - desc: 'Native reimplementation of the Metroid Prime engine', - langs: [LANG.Cpp], - body: ` -Metaforce (formerly URDE) started as a passion project reimplementing parts of the Metroid Prime engine, and eventually transformed into a nearly-complete non-matching decompilation.
- - `, - meta: 'Currently on hiatus as the matching decompilation of Metroid Prime progresses.', - }, -]; diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro index 1eb6f97..e09be39 100644 --- a/src/layouts/Layout.astro +++ b/src/layouts/Layout.astro @@ -23,7 +23,10 @@ const canonicalURL = new URL(Astro.url.pathname, Astro.site); {description && } - + @@ -36,7 +39,11 @@ const canonicalURL = new URL(Astro.url.pathname, Astro.site); rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;500;600&display=swap" /> - + @@ -104,10 +111,10 @@ const canonicalURL = new URL(Astro.url.pathname, Astro.site); .masthead-title small { display: block; - margin-top: .25rem; + margin-top: 0.25rem; font-family: var(--body-font); font-weight: 400; - font-size: .875rem; + font-size: 0.875rem; color: var(--gray-500); letter-spacing: 0.02em; } @@ -117,11 +124,11 @@ const canonicalURL = new URL(Astro.url.pathname, Astro.site); padding-bottom: var(--spacer-2); border-top: 1px solid var(--border-color); font-family: var(--heading-font); - font-size: .75rem; + font-size: 0.75rem; color: var(--gray-500); } diff --git a/src/pages/404.astro b/src/pages/404.astro index b6547c7..8b0b409 100644 --- a/src/pages/404.astro +++ b/src/pages/404.astro @@ -1,11 +1,12 @@ --- -import Layout from '../layouts/Layout.astro'; +import Layout from "../layouts/Layout.astro"; --- -- Sorry, we've misplaced that URL or it's pointing to something that doesn't exist. + Sorry, we've misplaced that URL or it's pointing to something that doesn't + exist. Head back home to try finding it again.
- I build tools for game decompilation and reverse engineering, with a focus on GameCube and Wii. + I build tools for game decompilation and reverse engineering, with a focus + on GameCube and Wii.