commit
b3e95e244f
@ -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…
Reference in new issue