Skip to content

AvighnaBasak/avi-portfolio

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

8 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Vlintendo3DS - Avighna Basak's Portfolio

Vlintendo3DS Banner

"Experience the nostalgia of 2005, reimagined for the web of 2025."

Welcome to Vlintendo3DS, a revolutionary portfolio interface designed by Avighna Basak. This project is not merely a website; it is a fully immersive, interactive operating system emulation that transforms the standard browsing experience into a nostalgic journey through the dual-screen era of gaming.

Built with the latest advancements in Next.js 16 and React 19, Vlintendo3DS leverages WebAssembly (WASM) to run native Nintendo DS machine code directly in your browser, bridging the gap between retro hardware and modern software engineering.


πŸ“š Table of Contents


🌟 Overview

The Vlintendo3DS project began with a simple question: Can a web portfolio be as engaging as a video game console?

To answer this, we reconstructed the iconic dual-screen interface using modern web technologies. Every pixel, sound effect, and interaction has been painstakingly crafted to replicate the authentic feel of the original hardware, while housing a suite of functional applications including a real Camera, Mail Client, and Web Browser.

At its core lies a technical marvel: a fully integrated Nintendo DS emulator capable of running retail games like Mario Kart DS at full speed, complete with audio and save functionality, all within the portfolio interface.


πŸš€ Key Features

πŸ•ΉοΈ Native NDS Emulation

Vlintendo3DS is one of the few web projects to successfully integrate the Desmond emulator (a port of DeSmuME) into a React framework.

  • WebAssembly (WASM) Core: Runs highly efficient machine code in the browser.
  • Retail Game Support: Confirmed compatibility with Mario Kart DS, PokΓ©mon, and more.
  • Persistent State: Save games and settings are stored locally, so your progress is never lost.
  • Full Speed Rendering: Optimized 60FPS playback on standard hardware.

πŸ‘† Advanced Touch Integration

We’ve solved the notorious "offset click" and "ghost touch" issues common in web-based emulators.

  • Direct Input Layer: A transparent overlay captures raw pointer events, bypassing synthetic event lag.
  • Stylus Emulation: Mouse clicks are translated into precise stylus touch coordinates (pressure simulation included).
  • Multi-Touch: Full support for mobile devices.

πŸ“± The App Ecosystem

The OS comes pre-loaded with a suite of custom-built applications:

πŸ“Έ Camera App

Access the user's webcam with a retro twist.

  • Live Feed: Real-time video stream on the top screen.
  • Filters & Overlay: CRT scanlines and UI overlays match the NDS aesthetic.
  • Time-Stamping: Photos are saved with custom digital timestamps.

πŸ“§ QuestMail

A gamified contact form.

  • Interactive Formatting: Styled like an RPG quest log.
  • Real-Time Validation: Instant feedback on form inputs.

🌐 NetBrowser

A browser-within-a-browser.

  • Functional Navigation: Browse simplified web content.
  • History Stack: Backward/Forward navigation built-in.

πŸ› οΈ Engineering Deep Dive

The "Mirror Canvas" Strategy

One of the most complex challenges we faced was integrating the emulator's canvas into a responsive React layout without breaking its internal coordinate system.

The Problem: The emulator expects a fixed 256x192 resolution and strict coordinate mapping. CSS transforms (scaling) broke the input hitboxes, causing clicks to register in the wrong place.

Our Solution:

  1. The Hidden Core: We instantiate the <desmond-player> and position it accurately within the DOM but set its opacity to 0.01. It receives all raw input events directly, ensuring 100% accuracy.
  2. The Visual Mirror: A separate, high-performance <canvas> element sits on top of the hidden player.
  3. The Render Loop: A custom requestAnimationFrame loop copies pixel data from the hidden emulator canvas to the visible mirror canvas in real-time.
// Simplified Render Loop Logic
const render = () => {
  const hiddenCanvas = player.shadowRoot.getElementById('bottom');
  const visibleCtx = mirrorCanvas.getContext('2d');
  visibleCtx.drawImage(hiddenCanvas, 0, 0, width, height);
  requestAnimationFrame(render);
};

Result: We get the pixel-perfect styling of a modern web canvas AND the native input accuracy of the raw emulator.

The "Nuclear" Lifecycle Management

Single Page Applications (SPAs) like Next.js and global WASM modules don't always play nicely. We encountered issues where closing the emulator left "zombie" audio contexts running in the background, or crashed the browser on re-launch due to memory leaks.

Our Solution: The Nuclear Option. When a user exits a game, instead of attempting a "soft close", we trigger a Hard Reload of the viewport.

  • Immediate Cleanup: Forces the browser to garbage collect the WASM heap.
  • Audio Kill Switch: Instantly terminates the AudioContext, preventing looping sound artifacts.
  • Fresh State: Ensures every game launch happens in a pristine environment.

Performance Optimizations

  • Turbopack: Leveraged Next.js 15's Turbopack for lightning-fast HMR and builds.
  • Lazy Loading: Heavy assets (ROMs, emulator scripts) are only fetched when needed.
  • Shadow DOM Styling: CSS injection ensures emulator styles are encapsulated and don't leak into the global scope.

οΏ½ Installation & Setup

Get Vlintendo3DS running on your local machine in minutes.

  1. Clone the Repository

    git clone https://github.com/yourusername/vlintendo-3ds.git
    cd vlintendo-3ds
  2. Install Dependencies

    npm install
    # or
    yarn install
  3. Add ROMs Place your .nds files in the public/roms/ directory. (Note: No ROMs are included in this repo for copyright reasons.)

  4. Run Development Server

    npm run dev
  5. Launch Open http://localhost:3000 in your browser.


πŸ”§ Configuration & Customization

Adding New Apps

You can extend the ecosystem by adding new entries to the projects array in src/app/page.tsx.

const projects = [
  { 
    id: "new-app", 
    title: "My New App", 
    category: "Game", 
    iconImage: "star", 
    color: "bg-yellow-400" 
  },
  // ...
];

Theming

The project uses Tailwind CSS for styling. You can customize the color palette in tailwind.config.ts.

  • System Theme: Modify src/app/globals.css to change the base variables.
  • Icons: We use Lucide React icons. Import new ones in src/app/page.tsx.

🀝 Contributing

We welcome contributions from the community! whether it's fixing bugs, improving the emulation wrapper, or designing new apps for the OS.

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/NewFeature)
  3. Commit your Changes (git commit -m 'Add NewFeature')
  4. Push to the Branch (git push origin feature/NewFeature)
  5. Open a Pull Request

πŸ“œ License

This project is licensed under the MIT License - see the LICENSE file for details.


πŸ™Œ Acknowledgements

A massive shoutout to the giants on whose shoulders this project stands:

  • Desmond Emulator: The incredible WASM port of DeSmuME that makes browser-based emulation possible.
  • The Next.js Team: For building the React framework for the web.
  • Nintendo: For the original hardware design that inspired this entire project. (Note: This project is a fan creation and is not affiliated with Nintendo.)

Created by Avighna Basak

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors