diff --git a/jsconfig.json b/jsconfig.json index c24ac80..f9b29f6 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -1,5 +1,8 @@ { "compilerOptions": { - "target": "ESNext" + "target": "ESNext", + "noImplicitAny": true, + "checkJs": true, + "strict": true } } diff --git a/source/data_asset_generator.py b/source/data_asset_generator.py index 88d575f..b8044e8 100755 --- a/source/data_asset_generator.py +++ b/source/data_asset_generator.py @@ -1,7 +1,6 @@ #!/usr/bin/env python3 import argparse from pathlib import Path -from PIL import Image parser = argparse.ArgumentParser() parser.add_argument("input") @@ -34,9 +33,11 @@ def generate_data(): def generate_hashmap_init(): string_list = list() for index, data in enumerate(file_array): - string_list.append(f"if (strcmp(filename, \"{data["filename"]}\") == 0) {{ *data = &data{index}; *size = sizeof(data{index}); return 1; }}") + filename = '"' + data["filename"] + '"' + string_list.append(f"if (strcmp(filename, {filename}) == 0) {{ *data = &data{index}; *size = sizeof(data{index}); return 1; }}") + strings = '\n'.join(string_list) return f"""int get_file_pointer(const char* filename, void ** data, size_t * size) {{ -{'\n'.join(string_list)} +{strings} return 0; }}""" diff --git a/source/game.js b/source/game.js index 9d2da69..5486f29 100644 --- a/source/game.js +++ b/source/game.js @@ -9,6 +9,19 @@ const TERMINAL_VELOCITY_SPEED = 500; const PIPE_SPAWN_TIME = 4; const PIPE_MAX_TIME = 5; +/** + * throws if input is nullish. + * @template T + * @param {T | null | undefined} value + * @returns {T} + */ +function nonNull(value) { + if (value == null) { + throw new Error("unexpected " + (value === null ? 'null' : 'undefined')) + } + return value +} + /** * clamps a number to the min and max values. * @param {number} num @@ -20,25 +33,31 @@ function clamp(num, min, max) { return Math.min(Math.max(num, min), max); } +/** + * picks a random number between the min and max values. + * @param {number} min + * @param {number} max + * @returns a random number + */ function random_range(min, max) { const minCeiled = Math.ceil(min); const maxFloored = Math.floor(max); return Math.floor(Math.random() * (maxFloored - minCeiled) + minCeiled); } -/** @type {GRRLibTexture} */ +/** @type {GRRLibTexture | null} */ globalThis.background = null; -/** @type {DrawableObject} */ +/** @type {{velocity: number, position: number, texture?: GRRLibTexture}} */ globalThis.bird = { velocity: 0, position: 0 }; -/** @type {GRRLibTexture} */ +/** @type {GRRLibTexture | null} */ globalThis.pipe = null; -/** @type {GRRLibTexture} */ +/** @type {GRRLibTexture | null} */ globalThis.pipe_flipped = null; /** @type {Pipe[]} */ @@ -63,16 +82,16 @@ function update_bird() { const deltatime = wii.get_deltatime(); bird.position -= bird.velocity * deltatime; bird.velocity = clamp(bird.velocity - (FALLING_SPEED * deltatime), -TERMINAL_VELOCITY_SPEED, TERMINAL_VELOCITY_SPEED); - - wii.grrlib.draw_img(0, bird.position, bird.texture, 0, 1, 1, WHITE_COLOR); + + wii.grrlib.draw_img(0, bird.position, nonNull(bird.texture), 0, 1, 1, WHITE_COLOR); } function create_pipe() { const top_max = 200; const top_y = random_range(0, top_max); - wii.grrlib.draw_img(100, -top_y, pipe_flipped, 0, 1, 1, WHITE_COLOR); - wii.grrlib.draw_img(100, top_y + 400, pipe, 0, 1, 1, WHITE_COLOR); + wii.grrlib.draw_img(100, -top_y, nonNull(pipe_flipped), 0, 1, 1, WHITE_COLOR); + wii.grrlib.draw_img(100, top_y + 400, nonNull(pipe), 0, 1, 1, WHITE_COLOR); return { top_y: -top_y, @@ -91,8 +110,8 @@ function update_pipe(pipe) { pipes.splice(index, -1); return; } - wii.grrlib.draw_img(pipe.position, pipe.top_y, pipe_flipped, 0, 1, 1, WHITE_COLOR); - wii.grrlib.draw_img(pipe.position, pipe.bottom_y, globalThis.pipe, 0, 1, 1, WHITE_COLOR); + wii.grrlib.draw_img(pipe.position, pipe.top_y, nonNull(pipe_flipped), 0, 1, 1, WHITE_COLOR); + wii.grrlib.draw_img(pipe.position, pipe.bottom_y, nonNull(globalThis.pipe), 0, 1, 1, WHITE_COLOR); pipe.position -= 100 * wii.get_deltatime(); pipe.time_active += wii.get_deltatime(); } @@ -110,18 +129,18 @@ function update() { } if (timer >= PIPE_SPAWN_TIME) { - timer = 0; + globalThis.timer = 0; } if (timer == 0) { pipes.push(create_pipe()); } - wii.grrlib.draw_img(0, 0, background, 0, 1, 1, WHITE_COLOR); + wii.grrlib.draw_img(0, 0, nonNull(background), 0, 1, 1, WHITE_COLOR); update_bird(); for (var i = 0; i < pipes.length; i++) { update_pipe(pipes[i]); } wii.print("deltatime: " + wii.get_deltatime()) - timer += wii.get_deltatime(); + globalThis.timer += wii.get_deltatime(); } diff --git a/types.d.ts b/types.d.ts index 064f9ff..d7a9d1e 100644 --- a/types.d.ts +++ b/types.d.ts @@ -1,9 +1,12 @@ -declare interface RGBA {} -declare interface FilePtr {} -declare interface GRRLibTexture {} -declare interface DrawableObject { - texture: GRRLibTexture -}; +declare interface RGBA { + __brand: "RGBA" +} +declare interface FilePtr { + __brand: "FilePtr" +} +declare interface GRRLibTexture { + __brand: "GRRLibTexture" +} declare interface Pipe { top_y: number bottom_y: number @@ -12,17 +15,20 @@ declare interface Pipe { }; declare namespace wii { + function print(message: string): void function exit(): void - function get_file(filename: string) : FilePtr - function get_deltatime() : number - function compare_rgba(color1: RGBA, color2: RGBA) : boolean - function print(message: string) : void - function rgba(r: number, g: number, b: number, a: number): RGBA - namespace grrlib { - function load_texture(file: FilePtr) : GRRLibTexture - function fill_screen(color: RGBA): void - function draw_img(xPos: number, yPos: number, texture: GRRLibTexture, degrees: number, scaleX: number, scaleY: number, color: RGBA) : void - function rectangle(x: number, y: number, width: number, height: number, color: RGBA, filled: bool) : void + namespace pad { + function buttons_down(): number } + namespace grrlib { + function load_texture(file: FilePtr): GRRLibTexture + function fill_screen(color: RGBA): void + function draw_img(xPos: number, yPos: number, texture: GRRLibTexture, degrees: number, scaleX: number, scaleY: number, color: RGBA): void + function rectangle(x: number, y: number, width: number, height: number, color: RGBA, filled: bool): void + } + function get_file(filename: string): FilePtr + function get_deltatime(): number + function rgba(r: number, g: number, b: number, a: number): RGBA + function compare_rgba(color1: RGBA, color2: RGBA): boolean }