Initial commit

master
Pete Ley 3 months ago
commit b3e95e244f

1
.gitignore vendored

@ -0,0 +1 @@
/build

@ -0,0 +1,80 @@
ifndef WASI_SDK_PATH
$(error Download the WASI SDK (https://github.com/WebAssembly/wasi-sdk) and set $$WASI_SDK_PATH)
endif
CC = "$(WASI_SDK_PATH)/bin/clang" --sysroot="$(WASI_SDK_PATH)/share/wasi-sysroot"
CXX = "$(WASI_SDK_PATH)/bin/clang++" --sysroot="$(WASI_SDK_PATH)/share/wasi-sysroot"
# Optional dependency from binaryen for smaller builds
WASM_OPT = wasm-opt
WASM_OPT_FLAGS = -Oz --zero-filled-memory --strip-producers
# Whether to build for debugging instead of release
DEBUG = 0
# Compilation flags
CFLAGS = -W -Wall -Wextra -Werror -Wno-unused -Wconversion -Wsign-conversion -MMD -MP -fno-exceptions
ifeq ($(DEBUG), 1)
CFLAGS += -DDEBUG -O0 -g
else
CFLAGS += -DNDEBUG -Oz -flto
endif
# Linker flags
LDFLAGS = -Wl,-zstack-size=14752,--no-entry,--import-memory -mexec-model=reactor \
-Wl,--initial-memory=65536,--max-memory=65536,--stack-first
ifeq ($(DEBUG), 1)
LDFLAGS += -Wl,--export-all,--no-gc-sections
else
LDFLAGS += -Wl,--strip-all,--gc-sections,--lto-O3 -Oz
endif
OBJECTS = $(patsubst src/%.c, build/%.o, $(wildcard src/*.c))
OBJECTS += $(patsubst src/%.cpp, build/%.o, $(wildcard src/*.cpp))
DEPS = $(OBJECTS:.o=.d)
ifeq '$(findstring ;,$(PATH))' ';'
DETECTED_OS := Windows
else
DETECTED_OS := $(shell uname 2>/dev/null || echo Unknown)
DETECTED_OS := $(patsubst CYGWIN%,Cygwin,$(DETECTED_OS))
DETECTED_OS := $(patsubst MSYS%,MSYS,$(DETECTED_OS))
DETECTED_OS := $(patsubst MINGW%,MSYS,$(DETECTED_OS))
endif
ifeq ($(DETECTED_OS), Windows)
MKDIR_BUILD = if not exist build md build
RMDIR = rd /s /q
else
MKDIR_BUILD = mkdir -p build
RMDIR = rm -rf
endif
all: build/cart.wasm
# Link cart.wasm from all object files and run wasm-opt
build/cart.wasm: $(OBJECTS)
$(CXX) -o $@ $(OBJECTS) $(LDFLAGS)
ifneq ($(DEBUG), 1)
ifeq (, $(shell command -v $(WASM_OPT)))
@echo Tip: $(WASM_OPT) was not found. Install it from binaryen for smaller builds!
else
$(WASM_OPT) $(WASM_OPT_FLAGS) $@ -o $@
endif
endif
# Compile C sources
build/%.o: src/%.c
@$(MKDIR_BUILD)
$(CC) -c $< -o $@ $(CFLAGS)
# Compile C++ sources
build/%.o: src/%.cpp
@$(MKDIR_BUILD)
$(CXX) -c $< -o $@ $(CFLAGS)
.PHONY: clean
clean:
$(RMDIR) build
-include $(DEPS)

@ -0,0 +1,26 @@
# test
A game written in C for the [WASM-4](https://wasm4.org) fantasy console.
## Building
Build the cart by running:
```shell
make
```
Then run it with:
```shell
w4 run build/cart.wasm
```
For more info about setting up WASM-4, see the [quickstart guide](https://wasm4.org/docs/getting-started/setup?code-lang=c#quickstart).
## Links
- [Documentation](https://wasm4.org/docs): Learn more about WASM-4.
- [Snake Tutorial](https://wasm4.org/docs/tutorials/snake/goal): Learn how to build a complete game
with a step-by-step tutorial.
- [GitHub](https://github.com/aduros/wasm4): Submit an issue or PR. Contributions are welcome!

@ -0,0 +1,40 @@
#include "wasm4.h"
const uint8_t smiley[] = {
0b11000011,
0b10000001,
0b00100100,
0b00100100,
0b00000000,
0b00100100,
0b10011001,
0b11000011,
};
void draw_bg() {
*DRAW_COLORS = 4;
text("Hello from C!", 10, 10);
text("Press X to blink", 16, 90);
}
#define FPS 60
#define PPS 30
int frame_count = 0;
int smiley_x = 76;
int smiley_y = 76;
void blit_smiley() {
blit(smiley, smiley_x, smiley_y, 8, 8, BLIT_1BPP);
}
void update () {
frame_count++;
uint8_t gamepad = *GAMEPAD1;
if ((gamepad & BUTTON_UP) && (frame_count % 2 == 0)) {
smiley_y--;
}
draw_bg();
blit_smiley();
}

@ -0,0 +1,140 @@
//
// WASM-4: https://wasm4.org/docs
#pragma once
#include <stdint.h>
#define WASM_EXPORT(name) __attribute__((export_name(name)))
#define WASM_IMPORT(name) __attribute__((import_name(name)))
WASM_EXPORT("start") void start ();
WASM_EXPORT("update") void update ();
// ┌───────────────────────────────────────────────────────────────────────────┐
// │ │
// │ Platform Constants │
// │ │
// └───────────────────────────────────────────────────────────────────────────┘
#define SCREEN_SIZE 160
// ┌───────────────────────────────────────────────────────────────────────────┐
// │ │
// │ Memory Addresses │
// │ │
// └───────────────────────────────────────────────────────────────────────────┘
#define PALETTE ((uint32_t*)0x04)
#define DRAW_COLORS ((uint16_t*)0x14)
#define GAMEPAD1 ((const uint8_t*)0x16)
#define GAMEPAD2 ((const uint8_t*)0x17)
#define GAMEPAD3 ((const uint8_t*)0x18)
#define GAMEPAD4 ((const uint8_t*)0x19)
#define MOUSE_X ((const int16_t*)0x1a)
#define MOUSE_Y ((const int16_t*)0x1c)
#define MOUSE_BUTTONS ((const uint8_t*)0x1e)
#define SYSTEM_FLAGS ((uint8_t*)0x1f)
#define NETPLAY ((const uint8_t*)0x20)
#define FRAMEBUFFER ((uint8_t*)0xa0)
#define BUTTON_1 1
#define BUTTON_2 2
#define BUTTON_LEFT 16
#define BUTTON_RIGHT 32
#define BUTTON_UP 64
#define BUTTON_DOWN 128
#define MOUSE_LEFT 1
#define MOUSE_RIGHT 2
#define MOUSE_MIDDLE 4
#define SYSTEM_PRESERVE_FRAMEBUFFER 1
#define SYSTEM_HIDE_GAMEPAD_OVERLAY 2
// ┌───────────────────────────────────────────────────────────────────────────┐
// │ │
// │ Drawing Functions │
// │ │
// └───────────────────────────────────────────────────────────────────────────┘
/** Copies pixels to the framebuffer. */
WASM_IMPORT("blit")
void blit (const uint8_t* data, int32_t x, int32_t y, uint32_t width, uint32_t height, uint32_t flags);
/** Copies a subregion within a larger sprite atlas to the framebuffer. */
WASM_IMPORT("blitSub")
void blitSub (const uint8_t* data, int32_t x, int32_t y, uint32_t width, uint32_t height,
uint32_t srcX, uint32_t srcY, uint32_t stride, uint32_t flags);
#define BLIT_2BPP 1
#define BLIT_1BPP 0
#define BLIT_FLIP_X 2
#define BLIT_FLIP_Y 4
#define BLIT_ROTATE 8
/** Draws a line between two points. */
WASM_IMPORT("line")
void line (int32_t x1, int32_t y1, int32_t x2, int32_t y2);
/** Draws a horizontal line. */
WASM_IMPORT("hline")
void hline (int32_t x, int32_t y, uint32_t len);
/** Draws a vertical line. */
WASM_IMPORT("vline")
void vline (int32_t x, int32_t y, uint32_t len);
/** Draws an oval (or circle). */
WASM_IMPORT("oval")
void oval (int32_t x, int32_t y, uint32_t width, uint32_t height);
/** Draws a rectangle. */
WASM_IMPORT("rect")
void rect (int32_t x, int32_t y, uint32_t width, uint32_t height);
/** Draws text using the built-in system font. */
WASM_IMPORT("text")
void text (const char* text, int32_t x, int32_t y);
// ┌───────────────────────────────────────────────────────────────────────────┐
// │ │
// │ Sound Functions │
// │ │
// └───────────────────────────────────────────────────────────────────────────┘
/** Plays a sound tone. */
WASM_IMPORT("tone")
void tone (uint32_t frequency, uint32_t duration, uint32_t volume, uint32_t flags);
#define TONE_PULSE1 0
#define TONE_PULSE2 1
#define TONE_TRIANGLE 2
#define TONE_NOISE 3
#define TONE_MODE1 0
#define TONE_MODE2 4
#define TONE_MODE3 8
#define TONE_MODE4 12
#define TONE_PAN_LEFT 16
#define TONE_PAN_RIGHT 32
// ┌───────────────────────────────────────────────────────────────────────────┐
// │ │
// │ Storage Functions │
// │ │
// └───────────────────────────────────────────────────────────────────────────┘
/** Reads up to `size` bytes from persistent storage into the pointer `dest`. */
WASM_IMPORT("diskr")
uint32_t diskr (void* dest, uint32_t size);
/** Writes up to `size` bytes from the pointer `src` into persistent storage. */
WASM_IMPORT("diskw")
uint32_t diskw (const void* src, uint32_t size);
/** Prints a message to the debug console. */
WASM_IMPORT("trace") void trace (const char* str);
/** Prints a message to the debug console. */
__attribute__((__format__ (__printf__, 1, 2)))
WASM_IMPORT("tracef") void tracef (const char* fmt, ...);
Loading…
Cancel
Save