diff --git a/src/nds.ts b/src/nds.ts index d2a5021..ce2c606 100644 --- a/src/nds.ts +++ b/src/nds.ts @@ -1,7 +1,7 @@ import * as THREE from "three"; import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js"; import { ScreenManager } from "./screen-manager"; -import { HomeScreen } from "./screens/home-screen"; +import { HomeScreen } from "./screens/home"; const SCREEN_SOURCE_TEX_SIZE = 1024; const TOP_SCREEN_SOURCE_TEX_HEIGHT = SCREEN_SOURCE_TEX_SIZE / 404; diff --git a/src/screens/contact-screen.ts b/src/screens/contact-screen.ts index f21f834..60697e1 100644 --- a/src/screens/contact-screen.ts +++ b/src/screens/contact-screen.ts @@ -1,12 +1,9 @@ import type { Screen, ScreenContext } from "../screen"; -import { HomeScreen } from "./home-screen"; +import { HomeScreen } from "./home"; export class ContactScreen implements Screen { renderTop(ctx: CanvasRenderingContext2D) { - ctx.fillStyle = "#ffffff"; - ctx.font = "10px NDS10"; - ctx.textBaseline = "top"; - ctx.fillText("CONTACT", 1, 1); + ctx; } renderBottom(ctx: CanvasRenderingContext2D) { diff --git a/src/screens/home-screen.ts b/src/screens/home-screen.ts deleted file mode 100644 index c150de6..0000000 --- a/src/screens/home-screen.ts +++ /dev/null @@ -1,25 +0,0 @@ -import type { Screen, ScreenContext } from "../screen"; -import { ContactScreen } from "./contact-screen"; - -export class HomeScreen implements Screen { - renderTop(ctx: CanvasRenderingContext2D) { - ctx.fillStyle = "#ffffff"; - ctx.font = "10px NDS10"; - ctx.textBaseline = "top"; - ctx.fillText("HOME", 1, 1); - } - - renderBottom(ctx: CanvasRenderingContext2D) { - ctx.fillStyle = "#ffffff"; - ctx.font = "10px NDS10"; - ctx.textAlign = "right"; - ctx.textBaseline = "bottom"; - ctx.fillText("Contact >", 255, 191); - } - - handleTouch(x: number, y: number, context: ScreenContext): void { - if (x >= 205 && x <= 256 && y >= 178 && y <= 192) { - context.navigate(new ContactScreen()); - } - } -} diff --git a/src/screens/home/bottom/index.ts b/src/screens/home/bottom/index.ts new file mode 100644 index 0000000..b0b50d0 --- /dev/null +++ b/src/screens/home/bottom/index.ts @@ -0,0 +1,9 @@ +export class HomeBottomScreen { + render(ctx: CanvasRenderingContext2D): void { + ctx.fillStyle = "#ffffff"; + ctx.font = "10px NDS10"; + ctx.textAlign = "right"; + ctx.textBaseline = "bottom"; + ctx.fillText("Contact >", 255, 191); + } +} diff --git a/src/screens/home/index.ts b/src/screens/home/index.ts new file mode 100644 index 0000000..73c3ec8 --- /dev/null +++ b/src/screens/home/index.ts @@ -0,0 +1,23 @@ +import type { Screen, ScreenContext } from "../../screen"; +import { ContactScreen } from "../contact-screen"; +import { HomeTopScreen } from "./top"; +import { HomeBottomScreen } from "./bottom"; + +export class HomeScreen implements Screen { + private topScreen = new HomeTopScreen(); + private bottomScreen = new HomeBottomScreen(); + + renderTop(ctx: CanvasRenderingContext2D) { + this.topScreen.render(ctx); + } + + renderBottom(ctx: CanvasRenderingContext2D) { + this.bottomScreen.render(ctx); + } + + handleTouch(x: number, y: number, context: ScreenContext): void { + if (x >= 205 && x <= 256 && y >= 178 && y <= 192) { + context.navigate(new ContactScreen()); + } + } +} diff --git a/src/screens/home/top/index.ts b/src/screens/home/top/index.ts new file mode 100644 index 0000000..435026b --- /dev/null +++ b/src/screens/home/top/index.ts @@ -0,0 +1,9 @@ +import { StatusBar } from "./statusBar"; + +export class HomeTopScreen { + private statusBar = new StatusBar(); + + render(ctx: CanvasRenderingContext2D): void { + this.statusBar.render(ctx); + } +} diff --git a/src/screens/home/top/statusBar.ts b/src/screens/home/top/statusBar.ts new file mode 100644 index 0000000..877b62a --- /dev/null +++ b/src/screens/home/top/statusBar.ts @@ -0,0 +1,48 @@ +import { ImageLoader } from "../../../utils/loadImages"; + +export class StatusBar { + private images = new ImageLoader({ + statusBar: "/images/home/top-screen/status-bar/status-bar.webp", + gbaDisplay: "/images/home/top-screen/status-bar/gba-display.webp", + startupMode: "/images/home/top-screen/status-bar/startup-mode.webp", + battery: "/images/home/top-screen/status-bar/battery.webp", + }); + + public render(ctx: CanvasRenderingContext2D): void { + if (!this.images.isReady) return; + + // background + ctx.drawImage(this.images.require("statusBar"), 0, 0); + + // username + ctx.fillStyle = "#ffffff"; + ctx.font = "7px NDS7"; + ctx.fillText("pihkaal", 3, 11); + + // time and date + const fillNumberCell = (value: number, cellX: number, offset: number) => { + const text = value.toFixed().padStart(2, "0"); + const { actualBoundingBoxRight: width } = ctx.measureText(text); + + const x = cellX * 16; + ctx.fillText(text, Math.floor(x + offset + (16 - width) / 2), 11); + }; + + const now = new Date(); + + fillNumberCell(now.getHours(), 9, 1); + if (Math.floor(now.getMilliseconds() / 500) % 2 === 0) { + ctx.fillText(":", 159, 11); + } + fillNumberCell(now.getMinutes(), 10, -1); + + fillNumberCell(now.getDate(), 11, 1); + ctx.fillText("/", 190, 11); + fillNumberCell(now.getMonth() + 1, 12, -1); + + // icons + ctx.drawImage(this.images.require("gbaDisplay"), 210, 2); + ctx.drawImage(this.images.require("startupMode"), 226, 2); + ctx.drawImage(this.images.require("battery"), 242, 4); + } +}