Skip to content

Commit

Permalink
Merge pull request nesbox#1981 from Gota7/main
Browse files Browse the repository at this point in the history
Add C template
  • Loading branch information
nesbox authored Jul 20, 2022
2 parents b56dc40 + a5e4eba commit 66da4a7
Show file tree
Hide file tree
Showing 8 changed files with 549 additions and 1 deletion.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ Makefile
!build/baremetalpi/Makefile
!build/baremetalpi/boot/Makefile
!build/baremetalpi/toolchain.cmake
!templates/c/Makefile
build/android/.gradle/
build/android/app/.externalNativeBuild/
build/android/app/build/
Expand Down Expand Up @@ -176,4 +177,4 @@ tic_mruby_wasm_build_config.rb.lock
build/mruby_vendor-prefix/
**/zig-cache
**/zig-out
.cache
.cache
71 changes: 71 additions & 0 deletions templates/c/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
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=8192,--no-entry,--import-memory -mexec-model=reactor \
-Wl,--initial-memory=262144,--max-memory=262144,--global-base=98304
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 ($(OS), Windows_NT)
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)
51 changes: 51 additions & 0 deletions templates/c/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# C Starter Project Template

## Pre-requisites

- [WASI SDK](https://github.com/WebAssembly/wasi-sdk)

## Files in this template

- ```buildcart.sh``` - convenience script to build and run the game cartridge
- ```buildwasm.sh``` - convenience script to build and run the Wasm program
- ```Makefile``` - convenience Makefile that builds the project
- ```wasmdemo.wasmp``` - TIC-80 Wasm 'script' file. Note the embedded game assets data at the end of the file.

## Building your game

Define the environment variable WASI_SDK_PATH; e.g., if you installed WASI
into ```$HOME/wasi-sdk```, then ```export WASI_SDK_PATH=$HOME/wasi-sdk```.

Edit ```src/main.c``` to implement your game. You are of course free to
organize your code in more than one C source file.

If you create sprites, map, music, etc., for your game, remember to
replace the game asset data at the end of ```wasmdemo.wasmp``` with
your creations.

To build the Wasm file, execute ```make```. This generates ```cart.wasm```
in the build directory. To run:

```
% tic80 --fs . --cmd 'load wasmdemo.wasmp & import binary cart.wasm & run & exit'
```

The script ```buildwasm.sh``` contains above steps as a convenience.

To build a TIC-80 cartridge, first build the Wasm file, then build the
cartridge file:

```
% tic80 --fs . --cmd 'load wasmdemo.wasmp & import binary cart.wasm & save game.tic & exit'
```

You can then run your cartridge as follows:

```
% tic80 --fs . --cmd 'load game.tic & run & exit'
```

The script ```buildcart.sh``` does the above steps as a convenience.

## Additional Notes
TIC-80 API functions that merely duplicate standard library functionality are not imported. Please use the `memcpy` and `memset` functions provided by the C standard library instead.
6 changes: 6 additions & 0 deletions templates/c/buildcart.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh
rm -f game.tic
make clean
make
tic80 --fs . --cmd 'load wasmdemo.wasmp & import binary build/cart.wasm & save game.tic & exit'
tic80 --fs . --cmd 'load game.tic & run & exit'
4 changes: 4 additions & 0 deletions templates/c/buildwasm.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh
make clean
make
tic80 --fs . --cmd 'load wasmdemo.wasmp & import binary build/cart.wasm & run & exit'
50 changes: 50 additions & 0 deletions templates/c/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include "tic80.h"

#define max(a, b) (a > b) ? a : b
#define min(a, b) (a < b) ? a : b

// From WASI libc:
WASM_IMPORT("snprintf")
int snprintf(char* s, size_t n, const char* format, ...);

int t, x, y;
const char* m = "HELLO WORLD FROM C!";
int r = 0;
MouseData md;
uint8_t transcolors = { 14 };

WASM_EXPORT("BOOT")
void BOOT() {
t = 1;
x = 96;
y = 24;
}

WASM_EXPORT("TIC")
void TIC() {
cls(13);

// The standard demo.
if (btn(0) > 0) { y--; }
if (btn(1) > 0) { y++; }
if (btn(2) > 0) { x--; }
if (btn(3) > 0) { x++; }

spr(1+t%60/30*2, x, y, &transcolors, 1, 3, 0, 0, 2, 2);
print(m, 60, 84, 15, 1, 1, 0);
t++;

// Mouse example demonstrating use of libc function.
mouse(&md);
if (md.left) { r = r + 2; }
r--;
r = max(0, min(32, r));
line(md.x, 0, md.x, 136, 11);
line(0, md.y, 240, md.y, 11);
circ(md.x, md.y, r, 11);

const int BUFSIZ = 10;
char buf[BUFSIZ];
snprintf(buf, BUFSIZ, "(%03d,%03d)", md.x, md.y);
print(buf, 3, 3, 15, 0, 1, 1);
}
Loading

0 comments on commit 66da4a7

Please sign in to comment.