tuxanci2-engine
Game engine for tuxanci2
Log | Files | Refs | README | LICENSE
commit bc90c91a7e7c5180fcc0e27ba3bdd9743d23f48f
parent de8d6aa793a3b2a46ace986b7b1bb8cb0b9afa55
Author: Connor Thomson <connor@gnufault.org>
Date: Sat, 31 Oct 2026 14:53:29 -0700
Add old source files
Diffstat:
57 files changed, 2 insertions(+), 4908 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -1 +0,0 @@
-build
diff --git a/.gitmodules b/.gitmodules
@@ -1,12 +0,0 @@
-[submodule "platforms/xbox/nxdk"]
- path = platforms/xbox/nxdk
- url = https://github.com/XboxDev/nxdk.git
-[submodule "platforms/dreamcast/KallistiOS"]
- path = platforms/dreamcast/KallistiOS
- url = https://github.com/KallistiOS/KallistiOS.git
-[submodule "platforms/saturn/joengine"]
- path = platforms/saturn/joengine
- url = https://github.com/johannes-fetz/joengine.git
-[submodule "platforms/ps1/nugget"]
- path = platforms/ps1/nugget
- url = https://github.com/pcsx-redux/nugget.git
diff --git a/Makefile b/Makefile
@@ -1,466 +0,0 @@
-SELF := $(abspath $(firstword $(MAKEFILE_LIST)))
-ROOT := $(patsubst %/,%,$(dir $(SELF)))
-PLATFORMS := $(shell ls "$(ROOT)/platforms")
-OUT_DIR := $(ROOT)/build
-OBJ_ROOT := $(OUT_DIR)
-
-XXD ?= xxd
-
-
-TAB_DIR := $(OBJ_ROOT)/game
-TAB_FILE := $(TAB_DIR)/tuxanci2.tab
-
-$(TAB_FILE): FORCE
- env -u MAKEFLAGS -u MFLAGS $(MAKE) -C "$(ROOT)/game" BUILD="$(TAB_DIR)" $(if $(CROSS),CROSS="$(CROSS)")
-
-FORCE:
-.PHONY: FORCE
-
-ifeq ($(TA_PLATFORM),)
-
-.DEFAULT_GOAL := help
-.NOTPARALLEL:
-.PHONY: help tab clean distclean win32-installer $(PLATFORMS)
-
-help:
- @echo 'Usage: make <platform>'
-
-$(PLATFORMS):
- rm -rf "$(OUT_DIR)"
- mkdir -p "$(OUT_DIR)"
- $(MAKE) TA_PLATFORM=$@
-
-win32-installer:
- $(MAKE) TA_PLATFORM=win32 INSTALLER=1
-
-tab: $(TAB_FILE)
- if [ -d "$(OUT_DIR)" ]; then cp -f "$(TAB_FILE)" "$(OUT_DIR)/"; fi
-
-clean:
- rm -rf "$(OUT_DIR)"
- if [ -d "$(OBJ_ROOT)" ]; then \
- find "$(OBJ_ROOT)" -mindepth 1 -maxdepth 1 ! -name dreamcast -exec rm -rf {} + ; \
- if [ -d "$(OBJ_ROOT)/dreamcast" ]; then \
- find "$(OBJ_ROOT)/dreamcast" -mindepth 1 -maxdepth 1 \
- ! -name KallistiOS ! -name toolchain ! -name environ.sh ! -name .kos-source-copied \
- -exec rm -rf {} + ; \
- fi; \
- fi
- find "$(ROOT)/platforms/saturn/joengine/jo_engine" -name '*.o' -delete 2>/dev/null || true
-
-distclean:
- rm -rf "$(OUT_DIR)" "$(OBJ_ROOT)"
- find "$(ROOT)/platforms/saturn/joengine/jo_engine" -name '*.o' -delete 2>/dev/null || true
-
-else
-
-ifeq ($(filter $(TA_PLATFORM),$(PLATFORMS)),)
-$(error unknown platform '$(TA_PLATFORM)' (platforms: $(PLATFORMS)))
-endif
-
-.DEFAULT_GOAL := build
-
-OBJ := $(OBJ_ROOT)
-
-OPT ?= -O2
-BITS := $(shell getconf LONG_BIT)
-MARCH := native
-
-ENGINE_SRCS := $(shell find "$(ROOT)/src" -type f -name '*.c' | sort)
-ASSETS := $(shell find "$(ROOT)/files" -type f -not -name 'LICENSE' | sort)
-HEADERS := $(wildcard $(ROOT)/include/*.h)
-GENERATED_SRCS := $(patsubst $(ROOT)/files/%,$(OBJ)/%,$(addsuffix .c,$(basename $(ASSETS))))
-ENGINE_SRC_OBJS := $(patsubst $(ROOT)/src/%.c,$(OBJ)/src/%.o,$(ENGINE_SRCS))
-GENERATED_OBJS := $(GENERATED_SRCS:.c=.o)
-ENGINE_OBJS := $(ENGINE_SRC_OBJS) $(GENERATED_OBJS)
-
-CONFIG_HEADER := $(OBJ)/ta_config.h
-FLAGS_STAMP := $(OBJ)/.engine-flags
-ENGINE_LIB := $(OBJ)/tuxanci2.a
-
-PLATFORM_FILES :=
-
-ifeq ($(TA_PLATFORM),x11)
-HOST_SRC := $(ROOT)/platforms/x11/x11.c
-HOST_CFLAGS := -O2
-HOST_LDLIBS := -lX11
-endif
-
-ifeq ($(TA_PLATFORM),wayland)
-HOST_SRC := $(ROOT)/platforms/wayland/wayland.c
-HOST_CFLAGS := -O2
-HOST_LDLIBS := -lwayland-client -lxkbcommon -lrt -lm
-XDG_SHELL_H := $(OBJ)/xdg-shell-client-protocol.h
-XDG_SHELL_C := $(OBJ)/xdg-shell-protocol.c
-HOST_EXTRA_SRCS := $(XDG_SHELL_C)
-HOST_DEPS := $(XDG_SHELL_H)
-
-$(XDG_SHELL_H):
- mkdir -p $(@D)
- wayland-scanner client-header $$(pkg-config --variable=pkgdatadir wayland-protocols)/stable/xdg-shell/xdg-shell.xml $@
-
-$(XDG_SHELL_C):
- mkdir -p $(@D)
- wayland-scanner private-code $$(pkg-config --variable=pkgdatadir wayland-protocols)/stable/xdg-shell/xdg-shell.xml $@
-endif
-
-ifeq ($(TA_PLATFORM),cocoa)
-HOST_SRC := $(ROOT)/platforms/cocoa/cocoa.m
-COCOA_TRIPLE := $(shell $(CC) -dumpmachine 2>/dev/null)
-ifneq ($(findstring darwin,$(COCOA_TRIPLE))$(findstring macos,$(COCOA_TRIPLE)),)
-HOST_CFLAGS := -O2 -Wno-deprecated-declarations
-HOST_LDLIBS := -framework Cocoa
-else
-HOST_CFLAGS := -O2 $(filter-out -MMD -MP,$(shell gnustep-config --objc-flags))
-HOST_LDLIBS := $(shell gnustep-config --gui-libs)
-endif
-endif
-
-ifeq ($(TA_PLATFORM),dos)
-CC := i586-pc-msdosdjgpp-gcc
-AR := i586-pc-msdosdjgpp-ar
-BITS := 32
-MARCH := i386
-HOST_SRC := $(ROOT)/platforms/dos/dos.c
-HOST_CFLAGS := -O2 -march=$(MARCH) -mtune=$(MARCH)
-EXE_EXT := .exe
-PLATFORM_FILES += $(wildcard $(ROOT)/platforms/dos/CWSDPMI.EXE)
-endif
-
-ifeq ($(TA_PLATFORM),win32)
-CC := i686-w64-mingw32-gcc
-AR := i686-w64-mingw32-ar
-BITS := 32
-MARCH := i686
-HOST_SRC := $(ROOT)/platforms/win32/win32.c
-HOST_CFLAGS := -O2 -Wall
-HOST_LDFLAGS := -Wl,--subsystem,windows:95
-HOST_LDLIBS := -lgdi32 -luser32
-EXE_EXT := .exe
-endif
-
-ifeq ($(TA_PLATFORM),ps1)
-NUGGET ?= $(ROOT)/platforms/ps1/nugget
-NUGGET := $(abspath $(NUGGET))
-ifndef PS1_PREFIX
-PS1_PREFIX := $(firstword $(foreach p,mipsel-none-elf mipsel-linux-gnu,$(if $(shell command -v $(p)-gcc 2>/dev/null),$(p))))
-endif
-ifeq ($(PS1_PREFIX),)
-$(error You need to install mipsel-none-elf-gcc or mipsel-linux-gnu-gcc or set PS1_PREFIX)
-endif
-ifeq ($(wildcard $(NUGGET)/ps-exe.ld),)
-$(error nugget not found at '$(NUGGET)')
-endif
-PS1_OFORMAT ?= $(if $(filter mipsel-none-elf,$(PS1_PREFIX)),elf32-littlemips,elf32-tradlittlemips)
-PS1_REGION ?= US
-PS1_TEXT ?=
-PS1_TMD ?= $(ROOT)/platforms/ps1/logo.tmd
-MKPSXISO ?= mkpsxiso
-PSXLICENSEPATCH ?= psxlicensepatch
-
-CC := $(PS1_PREFIX)-gcc
-AR := $(PS1_PREFIX)-gcc-ar
-PS1_OBJCOPY := $(PS1_PREFIX)-objcopy
-BITS := 32
-
-PS1_OBJ := $(OBJ)/platform
-PS1_ISO_DIR := $(OBJ)/iso
-PS1_ELF := $(OBJ)/psx.elf
-PS1_MAP := $(OBJ)/psx.map
-PS1_EXE := $(PS1_ISO_DIR)/PSX.EXE
-PS1_CNF := $(PS1_ISO_DIR)/SYSTEM.CNF
-PS1_XML := $(PS1_ISO_DIR)/tuxanci2.xml
-PS1_BIN := $(OBJ)/tuxanci2.bin
-PS1_CUE := $(OBJ)/tuxanci2.cue
-
-PS1_ARCHFLAGS := -march=mips1 -mabi=32 -EL -fno-pic -mno-shared -mno-abicalls -mfp32 -msoft-float -mno-llsc -G0 -fno-stack-protector -nostdlib -ffreestanding
-PS1_COMMONFLAGS := -ffunction-sections -fdata-sections -mno-gpopt -fomit-frame-pointer -fno-builtin -fno-strict-aliasing -Wno-attributes
-PS1_CFLAGS := -O2 $(PS1_ARCHFLAGS) $(PS1_COMMONFLAGS) -Wall -Wextra \
- -I$(ROOT)/include -I$(OBJ) -I$(NUGGET) -DTA_32BIT
-PS1_NUGGET_CFLAGS := -O2 $(PS1_ARCHFLAGS) $(PS1_COMMONFLAGS) -I$(NUGGET)
-PS1_LDFLAGS := -Wl,-Map=$(PS1_MAP) -nostdlib -T$(NUGGET)/nooverlay.ld -T$(NUGGET)/ps-exe.ld -static -Wl,--gc-sections $(PS1_ARCHFLAGS) -Wl,--oformat=$(PS1_OFORMAT)
-
-ENGINE_CFLAGS := -O2 $(PS1_ARCHFLAGS) $(PS1_COMMONFLAGS) -DTA_32BIT -DTA_DISABLE_BILINEAR_FILTERING -I$(ROOT)/include -I$(OBJ) -std=c99 -nostdinc -Wall -Wextra -Werror -pedantic -pedantic-errors
-
-PS1_NUGGET_SRCS := common/crt0/crt0.s common/crt0/memory-s.s common/crt0/memory-c.c common/crt0/clz.c third_party/arith64/arith64.c
-PS1_NUGGET_OBJS := $(addprefix $(PS1_OBJ)/nugget/,$(addsuffix .o,$(basename $(PS1_NUGGET_SRCS))))
-PS1_OBJS := $(PS1_NUGGET_OBJS) $(PS1_OBJ)/ps1.o
-
-$(PS1_OBJ)/ps1.o: $(ROOT)/platforms/ps1/ps1.c $(ENGINE_LIB) $(HEADERS)
- mkdir -p $(@D)
- $(CC) $(PS1_CFLAGS) -c $< -o $@
-
-$(PS1_OBJ)/nugget/%.o: $(NUGGET)/%.c
- mkdir -p $(@D)
- $(CC) $(PS1_NUGGET_CFLAGS) -c $< -o $@
-
-$(PS1_OBJ)/nugget/%.o: $(NUGGET)/%.s
- mkdir -p $(@D)
- $(CC) $(PS1_ARCHFLAGS) -I$(NUGGET) -c $< -o $@
-
-$(PS1_ELF): $(PS1_OBJS) $(ENGINE_LIB)
- $(CC) -o $@ $(PS1_OBJS) $(ENGINE_LIB) $(PS1_LDFLAGS)
-
-$(PS1_EXE): $(PS1_ELF)
- mkdir -p $(@D)
- $(PS1_OBJCOPY) -O binary $< $@
-
-$(PS1_CNF): $(SELF)
- mkdir -p $(@D)
- printf 'BOOT = cdrom:\\PSX.EXE;1\r\nTCB = 4\r\nEVENT = 10\r\nSTACK = 801FFF00\r\n' > $@
-
-$(PS1_XML): $(SELF) $(TAB_FILE)
- mkdir -p $(@D)
- { \
- echo '<?xml version="1.0" encoding="UTF-8"?>'; \
- echo '<iso_project>'; \
- echo ' <track type="data">'; \
- echo ' <identifiers system="PLAYSTATION" application="PLAYSTATION" volume="TUXANCI2" volume_set="TUXANCI2"/>'; \
- echo ' <directory_tree>'; \
- echo ' <file name="SYSTEM.CNF" type="data" source="$(PS1_CNF)"/>'; \
- echo ' <file name="PSX.EXE" type="data" source="$(PS1_EXE)"/>'; \
- echo ' <file name="TUXANCI2.TAB" type="data" source="$(TAB_FILE)"/>'; \
- echo ' <dummy sectors="1024"/>'; \
- echo ' </directory_tree>'; \
- echo ' </track>'; \
- echo '</iso_project>'; \
- } > $@
-
-$(PS1_BIN) $(PS1_CUE) &: $(PS1_EXE) $(PS1_CNF) $(PS1_XML) $(TAB_FILE)
- $(MKPSXISO) -y -q -o "$(PS1_BIN)" -c "$(PS1_CUE)" "$(PS1_XML)"
- $(PSXLICENSEPATCH) --region $(PS1_REGION) $(if $(PS1_TEXT),--text "$(PS1_TEXT)") $(if $(PS1_TMD),--tmd "$(abspath $(PS1_TMD))") "$(PS1_BIN)"
-
-PLATFORM_FILES += $(PS1_BIN) $(PS1_CUE)
-endif
-
-ifeq ($(TA_PLATFORM),saturn)
-BITS := 32
-JOENGINE ?= $(ROOT)/platforms/saturn/joengine
-JOENGINE := $(abspath $(JOENGINE))
-
-SATURN_ENGINE_LINKS := $(patsubst $(ROOT)/src/%.c,$(OBJ)/src/%.c,$(ENGINE_SRCS))
-SATURN_PLATFORM_LINK := $(OBJ)/saturn.c
-SATURN_CUE := $(OBJ)/game.cue
-SATURN_ISO := $(OBJ)/game.iso
-
-$(SATURN_ENGINE_LINKS): $(OBJ)/src/%.c: $(ROOT)/src/%.c
- mkdir -p $(@D)
- ln -sf "$<" "$@"
-
-$(SATURN_PLATFORM_LINK): $(ROOT)/platforms/saturn/saturn.c
- mkdir -p $(@D)
- ln -sf "$<" "$@"
-
-$(SATURN_CUE) $(SATURN_ISO) &: $(CONFIG_HEADER) $(GENERATED_SRCS) $(SATURN_ENGINE_LINKS) $(SATURN_PLATFORM_LINK) $(TAB_FILE) FORCE
- mkdir -p "$(OBJ)/cd"
- printf 'TUXANCI 2\r\n' > "$(OBJ)/cd/ABS.TXT"
- printf 'TUXANCI 2\r\n' > "$(OBJ)/cd/CPY.TXT"
- printf 'TUXANCI 2\r\n' > "$(OBJ)/cd/BIB.TXT"
- cp -f "$(TAB_FILE)" "$(OBJ)/cd/TUXANCI2.TAB"
- $(MAKE) -C "$(OBJ)" -f "$(ROOT)/platforms/saturn/jo.mk" MAKEFILE="$(ROOT)/platforms/saturn/jo.mk" JOENGINE="$(JOENGINE)" ROOT_DIR="$(ROOT)" SATURN_BUILD_DIR="$(OBJ)"
-
-PLATFORM_FILES += $(SATURN_CUE) $(SATURN_ISO)
-endif
-
-ifeq ($(TA_PLATFORM),xbox)
-BITS := 32
-NXDK_DIR ?= $(ROOT)/platforms/xbox/nxdk
-NXDK_DIR := $(abspath $(NXDK_DIR))
-export NXDK_DIR
-export PATH := $(NXDK_DIR)/bin:$(PATH)
-
-XBOX_ENTRY := $(OBJ)/src/xbox.c
-XBOX_STAGED := $(patsubst $(ROOT)/src/%.c,$(OBJ)/src/%.c,$(ENGINE_SRCS))
-XBOX_SRCS := $(XBOX_ENTRY) $(XBOX_STAGED) $(GENERATED_SRCS)
-XBOX_ISO := $(OBJ)/tuxanci2.iso
-
-NXDK_CFLAGS += -I$(ROOT)/include -I$(OBJ)
-export NXDK_CFLAGS
-
-$(XBOX_ENTRY): $(ROOT)/platforms/xbox/xbox.c
- mkdir -p $(@D)
- printf '#include "%s"\n' '$(abspath $<)' > $@
-
-$(XBOX_STAGED): $(OBJ)/src/%.c: $(ROOT)/src/%.c
- mkdir -p $(@D)
- printf '#include "%s"\n' '$(abspath $<)' > $@
-
-$(XBOX_ISO): $(XBOX_ENTRY) $(XBOX_STAGED) $(GENERATED_SRCS) $(CONFIG_HEADER) $(TAB_FILE) FORCE
- cp -f "$(TAB_FILE)" "$(OBJ)/"
- SRCS="$(XBOX_SRCS)" $(MAKE) -C "$(OBJ)" -f "$(NXDK_DIR)/Makefile" NXDK_DIR="$(NXDK_DIR)" NXDK_SDL=y OUTPUT_DIR="$(OBJ)" 'XBE_TITLE=Tuxanci\ 2' GEN_XISO="$(XBOX_ISO)"
-
-PLATFORM_FILES += $(XBOX_ISO)
-endif
-
-ifeq ($(TA_PLATFORM),n64)
-N64_INST ?= /opt/libdragon
-export N64_INST
-N64_MK := $(N64_INST)/include/n64.mk
-ifeq ($(wildcard $(N64_MK)),)
-$(error libdragon n64.mk not found under N64_INST='$(N64_INST)')
-endif
-
-CC := $(N64_INST)/bin/mips64-elf-gcc
-AR := $(N64_INST)/bin/mips64-elf-ar
-BITS := 32
-MARCH := vr4300
-
-BUILD_DIR := $(OBJ)/rom
-SOURCE_DIR := $(ROOT)/platforms/n64
-ROMNAME := tuxanci2
-N64_LIBRARY := $(ENGINE_LIB)
-include $(N64_MK)
-N64_CFLAGS += -I$(ROOT)/include -I$(OBJ)
-
-ENGINE_CFLAGS := $(N64_CFLAGS) -DTA_32BIT -DTA_DISABLE_BILINEAR_FILTERING -I$(ROOT)/include -I$(OBJ) -std=c99 -ffreestanding -nostdlib -nostdinc -fno-builtin -fno-stack-protector -Wall -Wextra -Werror -pedantic -pedantic-errors
-
-N64_ROM := $(OBJ)/tuxanci2.z64
-
-ifeq ($(TA_STAGE),)
-$(N64_ROM): $(ENGINE_LIB) $(ROOT)/platforms/n64/n64.c $(CONFIG_HEADER) $(HEADERS) FORCE
- $(MAKE) -C "$(OBJ)" -f "$(SELF)" TA_PLATFORM=n64 TA_STAGE=rom tuxanci2.z64
-
-PLATFORM_FILES += $(N64_ROM)
-else
-tuxanci2.z64: N64_ROM_TITLE = "Tuxanci 2"
-$(BUILD_DIR)/n64.o: $(ROOT)/platforms/n64/n64.c $(CONFIG_HEADER) $(HEADERS)
-$(BUILD_DIR)/$(ROMNAME).elf: $(BUILD_DIR)/n64.o $(N64_LIBRARY)
-ifneq ($(wildcard $(BUILD_DIR)),)
--include $(shell find $(BUILD_DIR) -name '*.d')
-endif
-endif
-endif
-
-ifeq ($(TA_PLATFORM),dreamcast)
-KOS_SOURCE ?= $(ROOT)/platforms/dreamcast/KallistiOS
-KOS_SOURCE := $(abspath $(KOS_SOURCE))
-KOS_BASE := $(OBJ)/KallistiOS
-KOS_CHAIN_DIR := $(KOS_BASE)/utils/kos-chain
-KOS_SOURCE_STAMP := $(OBJ)/.kos-source-copied
-TOOLCHAIN_PREFIX := $(OBJ)/toolchain/sh-elf
-KOS_CC_PATH := $(TOOLCHAIN_PREFIX)/bin/sh-elf-gcc
-KOS_ENV := $(OBJ)/environ.sh
-KOS_CC_WRAPPER := $(KOS_BASE)/utils/build_wrappers/kos-cc
-KOS_LIBRARY := $(KOS_BASE)/lib/dreamcast/libkallisti.a
-KOS_CHAIN_JOBS ?= 2
-KOS_BUILD_JOBS ?= 2
-DC_APP_OBJ := $(OBJ)/app/dreamcast.o
-DC_ELF := $(OBJ)/tuxanci2.elf
-
-BITS := 32
-CC = $(KOS_CC_WRAPPER)
-AR = $(KOS_AR)
-
-ENGINE_CFLAGS := -DTA_32BIT -DTA_DISABLE_BILINEAR_FILTERING -I$(ROOT)/include -I$(OBJ) -std=c99 -ffreestanding -nostdlib -nostdinc -fno-builtin -fno-stack-protector -Wall -Wextra -Werror -pedantic -pedantic-errors
-
-CPPFLAGS += -I$(ROOT)/include -I$(OBJ)
-export CPPFLAGS
-export KOS_BASE
-
-.PHONY: dc-kos-source
-dc-kos-source:
- mkdir -p "$(OBJ)"
- if [ ! -f "$(KOS_SOURCE_STAMP)" ]; then \
- mkdir -p "$(KOS_BASE)"; \
- tar --exclude=.git -C "$(KOS_SOURCE)" -cf - . | tar -C "$(KOS_BASE)" -xf -; \
- touch "$(KOS_SOURCE_STAMP)"; \
- fi
-
-$(KOS_CC_PATH): | dc-kos-source
- $(MAKE) -C "$(KOS_CHAIN_DIR)" platform=dreamcast kos_base="$(KOS_BASE)" toolchain_path="$(TOOLCHAIN_PREFIX)" makejobs="$(KOS_CHAIN_JOBS)" enable_cpp=0 enable_objc=0 enable_objcpp=0
- test -x "$@"
-
-$(KOS_ENV): $(KOS_CC_PATH) $(KOS_SOURCE)/doc/environ.sh.sample
- mkdir -p "$(@D)"
- sed -e 's|^export KOS_BASE=.*|export KOS_BASE="$(KOS_BASE)"|' -e 's|^export KOS_CC_BASE=.*|export KOS_CC_BASE="$(TOOLCHAIN_PREFIX)"|' "$(KOS_SOURCE)/doc/environ.sh.sample" > "$@"
-
-ifeq ($(TA_STAGE),)
-$(DC_ELF): $(KOS_ENV) FORCE
- . "$(KOS_ENV)" && $(MAKE) TA_PLATFORM=dreamcast TA_STAGE=kos "$@"
-
-PLATFORM_FILES += $(DC_ELF)
-else
-include $(KOS_SOURCE)/Makefile.rules
-
-$(KOS_LIBRARY): $(KOS_ENV)
- . "$(KOS_ENV)" && $(MAKE) -C "$(KOS_BASE)" -j"$(KOS_BUILD_JOBS)"
-
-$(DC_APP_OBJ): $(ROOT)/platforms/dreamcast/dreamcast.c $(ENGINE_LIB)
- mkdir -p "$(@D)"
- $(KOS_CC_WRAPPER) $(CFLAGS) $(CPPFLAGS) -c "$<" -o "$@"
-
-$(DC_ELF): $(DC_APP_OBJ) $(ENGINE_LIB) | $(KOS_LIBRARY)
- $(KOS_CC_WRAPPER) -o "$@" $(DC_APP_OBJ) $(ENGINE_LIB)
-endif
-endif
-
-ifneq ($(filter 64,$(BITS)),)
-ARCH_DEFINE := -DTA_64BIT
-else
-ARCH_DEFINE := -DTA_32BIT
-endif
-
-ENGINE_CFLAGS ?= $(OPT) -march=$(MARCH) -mtune=$(MARCH) -m$(BITS) $(ARCH_DEFINE) -I$(ROOT)/include -I$(OBJ) -std=c99 -ffreestanding -nostdlib -nostdinc -fno-builtin -fno-stack-protector -Wall -Wextra -Werror -pedantic -pedantic-errors
-
-ifeq ($(TA_DISABLE_BILINEAR_FILTERING),true)
-ENGINE_CFLAGS += -DTA_DISABLE_BILINEAR_FILTERING
-endif
-
-$(FLAGS_STAMP): FORCE
- mkdir -p $(@D)
- printf '%s\n' '$(CC) $(AR) $(ENGINE_CFLAGS)' > $@.tmp
- if cmp -s $@.tmp $@; then rm -f $@.tmp; else mv -f $@.tmp $@; fi
-
-$(CONFIG_HEADER): $(ROOT)/include/ta_config.h.in $(FLAGS_STAMP)
- mkdir -p $(@D)
- sed 's/\$$BITS/$(BITS)/g' $< > $@
-
-asset_sym = $(shell printf '%s' 'ta_file_$(notdir $(basename $(1)))' | sed 's/[^a-zA-Z0-9_]/_/g')
-
-define ASSET_RULE
-$(OBJ)/$(basename $(patsubst $(ROOT)/files/%,%,$(1))).c: $(1)
- mkdir -p $$(@D)
- $$(XXD) -i -n $(call asset_sym,$(1)) $$< $$@
-endef
-$(foreach a,$(ASSETS),$(eval $(call ASSET_RULE,$(a))))
-
-$(ENGINE_SRC_OBJS): $(OBJ)/src/%.o: $(ROOT)/src/%.c $(CONFIG_HEADER) $(FLAGS_STAMP)
- mkdir -p $(@D)
- $(CC) $(ENGINE_CFLAGS) -MMD -MP -c $< -o $@
-
-$(GENERATED_OBJS): $(OBJ)/%.o: $(OBJ)/%.c $(CONFIG_HEADER) $(FLAGS_STAMP)
- mkdir -p $(@D)
- $(CC) $(ENGINE_CFLAGS) -MMD -MP -c $< -o $@
-
-$(ENGINE_LIB): $(ENGINE_OBJS)
- rm -f $@
- $(AR) rcs $@ $^
-
--include $(ENGINE_OBJS:.o=.d)
-
-ifneq ($(HOST_SRC),)
-HOST_EXE := $(OBJ)/tuxanci2$(EXE_EXT)
-
-$(HOST_EXE): $(HOST_SRC) $(HOST_EXTRA_SRCS) $(HOST_DEPS) $(ENGINE_LIB) $(HEADERS)
- $(CC) $(HOST_CFLAGS) -I"$(ROOT)/include" -I"$(OBJ)" $(HOST_SRC) $(HOST_EXTRA_SRCS) "$(ENGINE_LIB)" $(HOST_LDFLAGS) $(HOST_LDLIBS) -o $@
-
-PLATFORM_FILES += $(HOST_EXE)
-
-ifdef INSTALLER
-INSTALLER_EXE := $(OBJ)/tuxanci2-win32-i686.exe
-
-$(INSTALLER_EXE): $(ROOT)/platforms/win32/installer.nsi $(HOST_EXE) $(TAB_FILE)
- makensis -V2 -DEXE_FILE="$(HOST_EXE)" -DTAB_FILE="$(TAB_FILE)" -DOUT_FILE="$(INSTALLER_EXE)" $<
-
-PLATFORM_FILES += $(INSTALLER_EXE)
-endif
-endif
-
-ifeq ($(TA_STAGE),)
-.PHONY: build
-build: $(TAB_FILE) $(PLATFORM_FILES)
- printf '\nbuild/ ($(TA_PLATFORM)):\n'
- ls -1 "$(OUT_DIR)" | sed 's/^/ /'
-endif
-
-endif
diff --git a/README.md b/README.md
@@ -1,28 +1,2 @@
-# Tuxánci 2
-Top down shooter game
-
-## Platforms
-Tuxánci currently supports:
-
-- Cocoa
-- DOS
-- Dreamcast
-- N64
-- PS1
-- Saturn
-- Wayland
-- Win32
-- X11
-- Xbox (2001)
-
-## Engine and game
-The engine (`src/`, `include/`) is platform independent C that owns text, display, framebuffer,
-images, keyboard, mods, screen management, the window title and the RV32IM virtual machine.
-
-The game (`game/`) is a flat `tuxanci2.tab` binary run inside that VM. It owns the button
-lists and every screen (loading, main menu). The engine only knows which screens exist and
-which one is current; it calls the game's init, update and destroy functions for the active screen.
-
-`include/ta_abi.h` and `include/ta_keys.h` are shared by both sides, and `sdk/tuxanci2.h`
-wraps the engine syscalls for the game. Build the game with `make tab`
-(`CROSS=riscv64-unknown-elf-` if you do not have a riscv32 toolchain).
+# Tuxánci 2 Engine
+The Game Engine for Tuxánci 2
diff --git a/engine.mk b/engine.mk
diff --git a/files/images/bg.tai b/files/images/bg.tai
Binary files differ.
diff --git a/files/images/loading_logo.tai b/files/images/loading_logo.tai
Binary files differ.
diff --git a/files/fonts/LICENSE b/font/LICENSE
diff --git a/files/fonts/dejavu_sans.ttf b/font/dejavu_sans.ttf
Binary files differ.
diff --git a/game/.gitignore b/game/.gitignore
@@ -1 +0,0 @@
-build
diff --git a/game/Makefile b/game/Makefile
@@ -1,5 +0,0 @@
-TARGET := tuxanci2
-SRCS := src
-INCLUDES := src
-
-include ../sdk/sdk.mk
diff --git a/game/src/main.c b/game/src/main.c
@@ -1,13 +0,0 @@
-#include <tuxanci2/screen.h>
-#include "ta_screens.h"
-#include "screens/ta_screen_loading.h"
-#include "screens/ta_screen_main_menu.h"
-
-int main(void) {
- ta_screen_register(TA_SCREEN_LOADING, ta_screen_loading_init, ta_screen_loading_update, ta_screen_loading_destroy);
- ta_screen_register(TA_SCREEN_MAIN_MENU, ta_screen_main_menu_init, ta_screen_main_menu_update, ta_screen_main_menu_destroy);
-
- ta_screen_switch(TA_SCREEN_LOADING);
-
- return 0;
-}
diff --git a/game/src/screens/ta_screen_loading.c b/game/src/screens/ta_screen_loading.c
@@ -1,44 +0,0 @@
-#include <tuxanci2/screen.h>
-#include <tuxanci2/display.h>
-#include <tuxanci2/image.h>
-#include <stdint.h>
-#include "ta_screen_loading.h"
-#include "../ta_screens.h"
-
-#define TA_LOADING_LOGO_SIZE TA_FIXED(0.3)
-
-void ta_screen_loading_init(void) {
- ta_image_init(TA_ASSET_LOADING_LOGO);
-}
-
-void ta_screen_loading_update(void) {
- uint32_t width;
- uint32_t height;
-
- if (!ta_image_get_size(TA_ASSET_LOADING_LOGO, &width, &height)) {
- return;
- }
-
- uint32_t frame_width = ta_display_width();
- uint32_t frame_height = ta_display_height();
- ta_fixed draw_width;
- ta_fixed draw_height;
-
- if (frame_width * height <= frame_height * width) {
- draw_width = TA_LOADING_LOGO_SIZE;
- draw_height = (ta_fixed)((TA_LOADING_LOGO_SIZE * (uint32_t)height * frame_width) / ((uint32_t)width * frame_height));
- } else {
- draw_height = TA_LOADING_LOGO_SIZE;
- draw_width = (ta_fixed)((TA_LOADING_LOGO_SIZE * (uint32_t)width * frame_height) / ((uint32_t)height * frame_width));
- }
-
- ta_fixed x = (TA_FIXED(1.0) - draw_width) / 2;
- ta_fixed y = (TA_FIXED(1.0) - draw_height) / 2;
-
- ta_image_draw(TA_ASSET_LOADING_LOGO, x, y, draw_width, draw_height, 0);
-
- ta_screen_switch(TA_SCREEN_MAIN_MENU);
-}
-
-void ta_screen_loading_destroy(void) {
-}
diff --git a/game/src/screens/ta_screen_loading.h b/game/src/screens/ta_screen_loading.h
@@ -1,8 +0,0 @@
-#ifndef TA_SCREEN_LOADING_H
-#define TA_SCREEN_LOADING_H
-
-void ta_screen_loading_init(void);
-void ta_screen_loading_update(void);
-void ta_screen_loading_destroy(void);
-
-#endif // TA_SCREEN_LOADING_H
diff --git a/game/src/screens/ta_screen_main_menu.c b/game/src/screens/ta_screen_main_menu.c
@@ -1,29 +0,0 @@
-#include <stdlib.h>
-#include <tuxanci2/image.h>
-#include "ta_screen_main_menu.h"
-#include "../ta_button.h"
-
-static ta_button_lists menu;
-
-static void quit(void) {
- exit(0);
-}
-
-void ta_screen_main_menu_init(void) {
- ta_image_init(TA_ASSET_BG);
-
- ta_button_lists_init(&menu);
- ta_button_lists_add(&menu, "Play", NULL);
- ta_button_lists_add(&menu, "Quit", quit);
-}
-
-void ta_screen_main_menu_update(void) {
- ta_button_lists_update(&menu);
-
- ta_image_draw(TA_ASSET_BG, 0, 0, TA_FIXED(1.0), TA_FIXED(1.0), 0);
- ta_button_lists_draw(&menu);
-}
-
-void ta_screen_main_menu_destroy(void) {
- ta_button_lists_destroy(&menu);
-}
diff --git a/game/src/screens/ta_screen_main_menu.h b/game/src/screens/ta_screen_main_menu.h
@@ -1,8 +0,0 @@
-#ifndef TA_SCREEN_MAIN_MENU_H
-#define TA_SCREEN_MAIN_MENU_H
-
-void ta_screen_main_menu_init(void);
-void ta_screen_main_menu_update(void);
-void ta_screen_main_menu_destroy(void);
-
-#endif // TA_SCREEN_MAIN_MENU_H
diff --git a/game/src/ta_button.c b/game/src/ta_button.c
@@ -1,163 +0,0 @@
-#include "ta_button.h"
-#include <tuxanci2/text.h>
-#include <tuxanci2/display.h>
-#include <tuxanci2/keyboard.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <stddef.h>
-
-#define TA_BUTTON_FONT_SIZE 32
-#define TA_BUTTON_FONT_SIZE_MAX 255
-#define TA_BUTTON_SPACING 48
-#define TA_BUTTON_COLOR_IDLE 118
-#define TA_BUTTON_COLOR_SELECTED 255
-#define TA_BUTTON_REFERENCE_WIDTH 800
-#define TA_BUTTON_REFERENCE_HEIGHT 600
-
-static uint32_t scale_to_display(uint32_t value) {
- uint32_t display_width = ta_display_width();
- uint32_t display_height = ta_display_height();
- uint32_t numerator = display_width;
- uint32_t denominator = TA_BUTTON_REFERENCE_WIDTH;
-
- if ((uint32_t)display_width * TA_BUTTON_REFERENCE_HEIGHT >= (uint32_t)display_height * TA_BUTTON_REFERENCE_WIDTH) {
- numerator = display_height;
- denominator = TA_BUTTON_REFERENCE_HEIGHT;
- }
-
- uint32_t scaled = (value * numerator * 2 + denominator) / (denominator * 2);
-
- return scaled == 0 ? 1 : scaled;
-}
-
-void ta_button_lists_init(ta_button_lists *list) {
- if (list == NULL) {
- return;
- }
-
- list->buttons = NULL;
- list->buttons_size = 0;
- list->size = 0;
- list->selected = 0;
- list->up_was_down = false;
- list->down_was_down = false;
- list->enter_was_down = false;
-}
-
-bool ta_button_lists_add(ta_button_lists *list, const char *label, ta_button_callback callback) {
- if (list == NULL || label == NULL) {
- return false;
- }
-
- if (list->size >= list->buttons_size) {
- size_t new_capacity = list->buttons_size + 1;
-
- ta_button *temp = (ta_button *)realloc(list->buttons, new_capacity * sizeof(ta_button));
-
- if (temp == NULL) {
- return false;
- }
-
- list->buttons = temp;
- list->buttons_size = new_capacity;
- }
-
- uint32_t font_size = scale_to_display(TA_BUTTON_FONT_SIZE);
-
- if (font_size > TA_BUTTON_FONT_SIZE_MAX) {
- font_size = TA_BUTTON_FONT_SIZE_MAX;
- }
-
- ta_text text_idle = ta_text_create(label, font_size, TA_DISPLAY_RGB(TA_BUTTON_COLOR_IDLE, TA_BUTTON_COLOR_IDLE, TA_BUTTON_COLOR_IDLE), 1, TA_DISPLAY_RGB(0, 0, 0));
- ta_text text_selected = ta_text_create(label, font_size, TA_DISPLAY_RGB(TA_BUTTON_COLOR_SELECTED, TA_BUTTON_COLOR_SELECTED, TA_BUTTON_COLOR_SELECTED), 1, TA_DISPLAY_RGB(0, 0, 0));
-
- if (text_idle == 0 || text_selected == 0) {
- ta_text_destroy(text_idle);
- ta_text_destroy(text_selected);
- return false;
- }
-
- ta_button *button = &list->buttons[list->size];
-
- button->label = label;
- button->callback = callback;
- button->text_idle = text_idle;
- button->text_selected = text_selected;
- button->text_width = ta_text_width(text_idle);
- button->text_height = ta_text_height(text_idle);
-
- list->size++;
-
- return true;
-}
-
-void ta_button_lists_update(ta_button_lists *list) {
- if (list == NULL || list->size == 0) {
- return;
- }
-
- bool up_down = ta_keyboard_is_down(KEY_UP);
- bool down_down = ta_keyboard_is_down(KEY_DOWN);
- bool enter_down = ta_keyboard_is_down(KEY_ENTER);
- bool up_pressed = up_down && !list->up_was_down;
- bool down_pressed = down_down && !list->down_was_down;
- bool enter_pressed = enter_down && !list->enter_was_down;
-
- list->up_was_down = up_down;
- list->down_was_down = down_down;
- list->enter_was_down = enter_down;
-
- if (down_pressed || up_pressed) {
- if (down_pressed) {
- list->selected = (list->selected + 1) % list->size;
- } else {
- list->selected = list->selected == 0 ? list->size - 1 : list->selected - 1;
- }
- }
-
- if (enter_pressed && list->buttons[list->selected].callback != NULL) {
- list->buttons[list->selected].callback();
- }
-}
-
-void ta_button_lists_draw(const ta_button_lists *list) {
- if (list == NULL || list->size == 0) {
- return;
- }
-
- uint32_t display_width = ta_display_width();
- uint32_t display_height = ta_display_height();
- int32_t spacing = (int32_t)scale_to_display(TA_BUTTON_SPACING);
- int32_t center_y = (int32_t)(display_height / 2);
- int32_t total_span = (int32_t)(list->size - 1) * spacing;
- int32_t start_y = center_y - (total_span / 2);
-
- for (size_t i = 0; i < list->size; i++) {
- const ta_button *button = &list->buttons[i];
- ta_text text = i == list->selected ? button->text_selected : button->text_idle;
- int32_t y = start_y + (int32_t)i * spacing - (int32_t)(button->text_height / 2);
-
- if (y < 0 || (size_t)y >= display_height || button->text_width > display_width) {
- continue;
- }
-
- ta_text_draw(text, (display_width - button->text_width) / 2, (uint32_t)y);
- }
-}
-
-void ta_button_lists_destroy(ta_button_lists *list) {
- if (list == NULL) {
- return;
- }
-
- for (size_t i = 0; i < list->size; i++) {
- ta_text_destroy(list->buttons[i].text_idle);
- ta_text_destroy(list->buttons[i].text_selected);
- }
-
- if (list->buttons != NULL) {
- free(list->buttons);
- }
-
- ta_button_lists_init(list);
-}
diff --git a/game/src/ta_button.h b/game/src/ta_button.h
@@ -1,36 +0,0 @@
-#ifndef TA_BUTTON_H
-#define TA_BUTTON_H
-
-#include <tuxanci2/text.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <stddef.h>
-
-typedef void (*ta_button_callback)(void);
-
-typedef struct {
- const char *label;
- ta_button_callback callback;
- ta_text text_idle;
- ta_text text_selected;
- uint32_t text_width;
- uint32_t text_height;
-} ta_button;
-
-typedef struct {
- ta_button *buttons;
- size_t buttons_size;
- size_t size;
- size_t selected;
- bool up_was_down;
- bool down_was_down;
- bool enter_was_down;
-} ta_button_lists;
-
-void ta_button_lists_init(ta_button_lists *list);
-bool ta_button_lists_add(ta_button_lists *list, const char *label, ta_button_callback callback);
-void ta_button_lists_update(ta_button_lists *list);
-void ta_button_lists_draw(const ta_button_lists *list);
-void ta_button_lists_destroy(ta_button_lists *list);
-
-#endif // TA_BUTTON_H
diff --git a/game/src/ta_screens.h b/game/src/ta_screens.h
@@ -1,9 +0,0 @@
-#ifndef TA_SCREENS_H
-#define TA_SCREENS_H
-
-typedef enum {
- TA_SCREEN_LOADING,
- TA_SCREEN_MAIN_MENU
-} ta_screens;
-
-#endif // TA_SCREENS_H
diff --git a/platforms/cocoa/cocoa.m b/platforms/cocoa/cocoa.m
@@ -1,461 +0,0 @@
-#include "ta_api.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#import <Foundation/Foundation.h>
-#import <AppKit/AppKit.h>
-
-#define WINDOW_WIDTH 800
-#define WINDOW_HEIGHT 600
-#define WINDOW_BPP 32
-#define TARGET_FPS 60
-
-#if defined(__APPLE__) && defined(MAC_OS_X_VERSION_10_12) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_12
-#define TA_STYLE_MASK (NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable)
-#define TA_NUMPAD_FLAG NSEventModifierFlagNumericPad
-#define TA_SHIFT_FLAG NSEventModifierFlagShift
-#define TA_CTRL_FLAG NSEventModifierFlagControl
-#define TA_ALT_FLAG NSEventModifierFlagOption
-#define TA_CMD_FLAG NSEventModifierFlagCommand
-#define TA_CAPS_FLAG NSEventModifierFlagCapsLock
-#else
-#define TA_STYLE_MASK (NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask)
-#define TA_NUMPAD_FLAG NSNumericPadKeyMask
-#define TA_SHIFT_FLAG NSShiftKeyMask
-#define TA_CTRL_FLAG NSControlKeyMask
-#define TA_ALT_FLAG NSAlternateKeyMask
-#define TA_CMD_FLAG NSCommandKeyMask
-#define TA_CAPS_FLAG NSAlphaShiftKeyMask
-#endif
-
-#define KEYCODE_TABLE_SIZE 256
-
-static ta_keyboard_keys pressed_keys[KEYCODE_TABLE_SIZE];
-
-static ta_uint8 modifier_down[KEYCODE_TABLE_SIZE];
-
-static ta_keyboard_keys key_from_function_key(unichar c) {
- if (c >= NSF1FunctionKey && c <= NSF1FunctionKey + 11) {
- return (ta_keyboard_keys)(KEY_F1 + (c - NSF1FunctionKey));
- }
-
- switch (c) {
- case NSUpArrowFunctionKey: return KEY_UP;
- case NSDownArrowFunctionKey: return KEY_DOWN;
- case NSLeftArrowFunctionKey: return KEY_LEFT;
- case NSRightArrowFunctionKey: return KEY_RIGHT;
- case NSDeleteFunctionKey: return KEY_DELETE;
- case NSHomeFunctionKey: return KEY_HOME;
- case NSEndFunctionKey: return KEY_END;
- case NSPageUpFunctionKey: return KEY_PAGE_UP;
- case NSPageDownFunctionKey: return KEY_PAGE_DOWN;
- case NSInsertFunctionKey: return KEY_INSERT;
- case NSPrintScreenFunctionKey: return KEY_PRINT_SCREEN;
- case NSScrollLockFunctionKey: return KEY_SCROLL_LOCK;
- case NSPauseFunctionKey: return KEY_PAUSE;
- case NSMenuFunctionKey: return KEY_MENU;
- default: return KEY_NONE;
- }
-}
-
-static ta_keyboard_keys key_from_keypad(unichar c) {
- if (c >= '0' && c <= '9') {
- return (ta_keyboard_keys)(KEY_KP_0 + (c - '0'));
- }
-
- switch (c) {
- case '.': return KEY_KP_DECIMAL;
- case '/': return KEY_KP_DIVIDE;
- case '*': return KEY_KP_MULTIPLY;
- case '-': return KEY_KP_SUBTRACT;
- case '+': return KEY_KP_ADD;
- case '=': return KEY_KP_EQUALS;
- case '\r':
- case '\n':
- case 3: return KEY_KP_ENTER;
- default: return KEY_NONE;
- }
-}
-
-static ta_keyboard_keys key_from_event(NSEvent *event) {
- NSString *characters = [event charactersIgnoringModifiers];
- if ([characters length] == 0) {
- return KEY_NONE;
- }
-
- unichar c = [characters characterAtIndex: 0];
-
- if (c >= 0xF700 && c <= 0xF8FF) {
- return key_from_function_key(c);
- }
-
- if ([event modifierFlags] & TA_NUMPAD_FLAG) {
- ta_keyboard_keys keypad = key_from_keypad(c);
- if (keypad != KEY_NONE) {
- return keypad;
- }
- }
-
- if (c >= 'A' && c <= 'Z') {
- c = (unichar)(c - 'A' + 'a');
- }
-
- if (c >= 32 && c <= 126) {
- return (ta_keyboard_keys)c;
- }
-
- switch (c) {
- case 8:
- case 127: return KEY_BACKSPACE;
- case 9:
- case 0x19: return KEY_TAB;
- case 13:
- case 3: return KEY_ENTER;
- case 27: return KEY_ESCAPE;
- default: return KEY_NONE;
- }
-}
-
-static void clear_input(void) {
- memset(pressed_keys, 0, sizeof(pressed_keys));
- memset(modifier_down, 0, sizeof(modifier_down));
- ta_keyboard_clear();
-}
-
-@interface TAView : NSView {
- NSBitmapImageRep *image;
-}
-- (void)present;
-@end
-
-@implementation TAView
-
-- (id)initWithFrame:(NSRect)frame {
- self = [super initWithFrame: frame];
- if (!self) {
- return nil;
- }
-
- image = [[NSBitmapImageRep alloc]
- initWithBitmapDataPlanes: NULL
- pixelsWide: WINDOW_WIDTH
- pixelsHigh: WINDOW_HEIGHT
- bitsPerSample: 8
- samplesPerPixel: 4
- hasAlpha: YES
- isPlanar: NO
- colorSpaceName: NSDeviceRGBColorSpace
- bytesPerRow: WINDOW_WIDTH * 4
- bitsPerPixel: 32];
-
- return self;
-}
-
-- (void)dealloc {
- [image release];
- [super dealloc];
-}
-
-- (BOOL)isOpaque {
- return YES;
-}
-
-- (BOOL)acceptsFirstResponder {
- return YES;
-}
-
-- (BOOL)acceptsFirstMouse:(NSEvent *)event {
- return YES;
-}
-
-- (void)present {
- if (!image || !ta_fb.buffers[0]) {
- return;
- }
-
- const ta_uint32 *source = (const ta_uint32 *)ta_fb.buffers[0];
- unsigned char *destination = [image bitmapData];
- NSInteger row_bytes = [image bytesPerRow];
- int x, y;
-
- for (y = 0; y < WINDOW_HEIGHT; y++) {
- unsigned char *row = destination + (NSInteger)y * row_bytes;
-
- for (x = 0; x < WINDOW_WIDTH; x++) {
- ta_uint32 pixel = source[y * WINDOW_WIDTH + x];
-
- row[x * 4 + 0] = (unsigned char)((pixel >> 16) & 0xff);
- row[x * 4 + 1] = (unsigned char)((pixel >> 8) & 0xff);
- row[x * 4 + 2] = (unsigned char)(pixel & 0xff);
- row[x * 4 + 3] = 0xff;
- }
- }
-
- [self setNeedsDisplay: YES];
-}
-
-- (void)drawRect:(NSRect)rect {
- if (!image) {
- return;
- }
-
- [[NSGraphicsContext currentContext] setImageInterpolation: NSImageInterpolationNone];
- [image drawInRect: [self bounds]];
-}
-
-- (void)keyDown:(NSEvent *)event {
- if ([event isARepeat]) {
- return;
- }
-
- unsigned short code = [event keyCode] % KEYCODE_TABLE_SIZE;
- ta_keyboard_keys key = key_from_event(event);
-
- if (pressed_keys[code] != KEY_NONE) {
- ta_keyboard_key_up(pressed_keys[code]);
- }
-
- pressed_keys[code] = key;
- ta_keyboard_key_down(key);
-}
-
-- (void)keyUp:(NSEvent *)event {
- unsigned short code = [event keyCode] % KEYCODE_TABLE_SIZE;
-
- if (pressed_keys[code] != KEY_NONE) {
- ta_keyboard_key_up(pressed_keys[code]);
- pressed_keys[code] = KEY_NONE;
- }
-}
-
-- (void)flagsChanged:(NSEvent *)event {
- unsigned short code = [event keyCode];
- NSUInteger flags = [event modifierFlags];
- ta_keyboard_keys key = KEY_NONE;
- NSUInteger mask = 0;
-
- switch (code) {
- case 56: key = KEY_LEFT_SHIFT; mask = TA_SHIFT_FLAG; break;
- case 60: key = KEY_RIGHT_SHIFT; mask = TA_SHIFT_FLAG; break;
- case 59: key = KEY_LEFT_CTRL; mask = TA_CTRL_FLAG; break;
- case 62: key = KEY_RIGHT_CTRL; mask = TA_CTRL_FLAG; break;
- case 58: key = KEY_LEFT_ALT; mask = TA_ALT_FLAG; break;
- case 61: key = KEY_RIGHT_ALT; mask = TA_ALT_FLAG; break;
- case 55: key = KEY_LEFT_SUPER; mask = TA_CMD_FLAG; break;
- case 54: key = KEY_RIGHT_SUPER; mask = TA_CMD_FLAG; break;
- case 57: key = KEY_CAPS_LOCK; mask = TA_CAPS_FLAG; break;
- default: return;
- }
-
- if (code >= KEYCODE_TABLE_SIZE) {
- return;
- }
-
- if (key == KEY_CAPS_LOCK) {
- ta_keyboard_key_down(key);
- ta_keyboard_key_up(key);
- return;
- }
-
- if (flags & mask) {
- modifier_down[code] = 1;
- ta_keyboard_key_down(key);
- } else if (modifier_down[code]) {
- modifier_down[code] = 0;
- ta_keyboard_key_up(key);
- }
-}
-
-@end
-
-@interface TAController : NSObject {
- NSWindow *window;
- TAView *view;
- char title[256];
-}
-- (void)start;
-- (void)tick:(NSTimer *)timer;
-@end
-
-@implementation TAController
-
-- (void)start {
- NSRect content = NSMakeRect(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
-
- window = [[NSWindow alloc] initWithContentRect: content
- styleMask: TA_STYLE_MASK
- backing: NSBackingStoreBuffered
- defer: NO];
- [window setReleasedWhenClosed: NO];
- [window setDelegate: self];
-
- view = [[TAView alloc] initWithFrame: content];
- [window setContentView: view];
- [window makeFirstResponder: view];
- [window center];
-
- title[0] = '\0';
- [self tick: nil];
- [window makeKeyAndOrderFront: nil];
-
- NSTimer *timer = [NSTimer timerWithTimeInterval: 1.0 / TARGET_FPS
- target: self
- selector: @selector(tick:)
- userInfo: nil
- repeats: YES];
-#ifdef __APPLE__
- [[NSRunLoop currentRunLoop] addTimer: timer forMode: NSRunLoopCommonModes];
-#else
- [[NSRunLoop currentRunLoop] addTimer: timer forMode: NSDefaultRunLoopMode];
-#endif
-}
-
-- (void)tick:(NSTimer *)timer {
- ta_main_update();
-
- if (ta_title && strncmp(title, ta_title, sizeof(title)) != 0) {
- strncpy(title, ta_title, sizeof(title) - 1);
- title[sizeof(title) - 1] = '\0';
- [window setTitle: [NSString stringWithUTF8String: title]];
- }
-
- [view present];
-}
-
-- (void)applicationDidFinishLaunching:(NSNotification *)notification {
-#ifdef __APPLE__
- if ([NSApp respondsToSelector: @selector(setActivationPolicy:)]) {
- [NSApp setActivationPolicy: NSApplicationActivationPolicyRegular];
- }
-#endif
- [NSApp activateIgnoringOtherApps: YES];
-}
-
-- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)application {
- return YES;
-}
-
-- (void)windowDidResignKey:(NSNotification *)notification {
- clear_input();
-}
-
-@end
-
-static void build_menu(void) {
- NSMenu *menubar = [[[NSMenu alloc] init] autorelease];
- NSMenuItem *app_item = [[[NSMenuItem alloc] initWithTitle: @"" action: NULL keyEquivalent: @""] autorelease];
- NSMenu *app_menu = [[[NSMenu alloc] initWithTitle: @""] autorelease];
- NSMenuItem *quit_item = [[[NSMenuItem alloc] initWithTitle: @"Quit"
- action: @selector(terminate:)
- keyEquivalent: @"q"] autorelease];
-
- [app_menu addItem: quit_item];
- [app_item setSubmenu: app_menu];
- [menubar addItem: app_item];
- [NSApp setMainMenu: menubar];
-}
-
-int main(void) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
- ta_fb.width = WINDOW_WIDTH;
- ta_fb.height = WINDOW_HEIGHT;
- ta_fb.bpp = WINDOW_BPP;
-
- ta_main_init();
-
- clear_input();
-
- [NSApplication sharedApplication];
-
- TAController *controller = [[TAController alloc] init];
- [NSApp setDelegate: controller];
- build_menu();
- [controller start];
-
- [NSApp run];
-
- [controller release];
- [pool release];
-
- return 0;
-}
-
-void *ta_malloc(ta_size size) {
- return malloc(size);
-}
-
-void *ta_realloc(void *ptr, ta_size new_size) {
- return realloc(ptr, new_size);
-}
-
-void ta_free(void *ptr) {
- free(ptr);
-}
-
-ta_fs_file ta_read_file(const char *path) {
- ta_fs_file file = {
- .data = NULL,
- .size = 0
- };
-
- FILE *file_pointer = fopen(path, "rb");
- if (!file_pointer) {
- return file;
- }
-
- if (fseek(file_pointer, 0, SEEK_END) != 0) {
- fclose(file_pointer);
-
- return file;
- }
-
- long file_size = ftell(file_pointer);
- if (file_size < 0) {
- fclose(file_pointer);
-
- return file;
- }
-
- rewind(file_pointer);
-
- file.data = ta_malloc((ta_size)file_size);
- if (!file.data) {
- fclose(file_pointer);
-
- return file;
- }
-
- ta_size bytes_read = fread(file.data, 1, (size_t)file_size, file_pointer);
-
- if (bytes_read != (ta_size)file_size) {
- ta_free(file.data);
- file.data = NULL;
- fclose(file_pointer);
-
- return file;
- }
-
- file.size = (ta_size)file_size;
-
- fclose(file_pointer);
-
- return file;
-}
-
-void ta_close_file(ta_fs_file *file) {
- if (!file) {
- return;
- }
-
- if (file->data) {
- ta_free(file->data);
- file->data = NULL;
- }
-
- file->size = 0;
-}
-
-void ta_exit(int status) {
- exit(status);
-}
diff --git a/platforms/dos/dos.c b/platforms/dos/dos.c
@@ -1,270 +0,0 @@
-#include "ta_api.h"
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <dos.h>
-#include <dpmi.h>
-#include <go32.h>
-#include <conio.h>
-#include <pc.h>
-
-#define WINDOW_WIDTH 320
-#define WINDOW_HEIGHT 200
-#define WINDOW_BPP 8
-
-#define VGA_FB_ADDR 0xA0000UL
-
-static void set_mode_13h(void) {
- __dpmi_regs regs;
- memset(®s, 0, sizeof(regs));
- regs.x.ax = 0x0013;
- __dpmi_int(0x10, ®s);
-}
-
-static void clear_text_screen(void) {
- static const unsigned char palette[16][3] = {
- { 0, 0, 0}, { 0, 0, 42}, { 0, 42, 0}, { 0, 42, 42},
- {42, 0, 0}, {42, 0, 42}, {42, 21, 0}, {42, 42, 42},
- {21, 21, 21}, {21, 21, 63}, {21, 63, 21}, {21, 63, 63},
- {63, 21, 21}, {63, 21, 63}, {63, 63, 21}, {63, 63, 63}
- };
- __dpmi_regs regs;
- memset(®s, 0, sizeof(regs));
- regs.x.ax = 0x0003;
- __dpmi_int(0x10, ®s);
-
- outportb(0x3C8, 0);
- for (int i = 0; i < 16; i++) {
- outportb(0x3C9, palette[i][0]);
- outportb(0x3C9, palette[i][1]);
- outportb(0x3C9, palette[i][2]);
- }
-
- memset(®s, 0, sizeof(regs));
- regs.x.ax = 0x0100;
- regs.x.cx = 0x0607;
- __dpmi_int(0x10, ®s);
-
- memset(®s, 0, sizeof(regs));
- regs.x.ax = 0x0600;
- regs.x.bx = 0x0700;
- regs.x.cx = 0;
- regs.x.dx = 0x184F;
- __dpmi_int(0x10, ®s);
-
- memset(®s, 0, sizeof(regs));
- regs.x.ax = 0x0200;
- regs.x.bx = 0;
- regs.x.dx = 0;
- __dpmi_int(0x10, ®s);
-}
-
-static void set_palette_332(void) {
- int i;
- outportb(0x3C8, 0);
- for (i = 0; i < 256; i++) {
- outportb(0x3C9, ((i >> 5) & 7) * 63 / 7);
- outportb(0x3C9, ((i >> 2) & 7) * 63 / 7);
- outportb(0x3C9, (i & 3) * 63 / 3);
- }
-}
-
-static void blit(void) {
- dosmemput(ta_fb.buffers[0], WINDOW_WIDTH * WINDOW_HEIGHT, VGA_FB_ADDR);
-}
-
-static ta_keyboard_keys key_from_dos(int key, bool extended) {
- if (extended) {
- switch (key) {
- case 29: return KEY_LEFT_CTRL;
- case 42: return KEY_LEFT_SHIFT;
- case 54: return KEY_RIGHT_SHIFT;
- case 56: return KEY_LEFT_ALT;
- case 59: return KEY_F1;
- case 60: return KEY_F2;
- case 61: return KEY_F3;
- case 62: return KEY_F4;
- case 63: return KEY_F5;
- case 64: return KEY_F6;
- case 65: return KEY_F7;
- case 66: return KEY_F8;
- case 67: return KEY_F9;
- case 68: return KEY_F10;
- case 71: return KEY_HOME;
- case 72: return KEY_UP;
- case 73: return KEY_PAGE_UP;
- case 75: return KEY_LEFT;
- case 77: return KEY_RIGHT;
- case 79: return KEY_END;
- case 80: return KEY_DOWN;
- case 81: return KEY_PAGE_DOWN;
- case 82: return KEY_INSERT;
- case 83: return KEY_DELETE;
- case 133: return KEY_F11;
- case 134: return KEY_F12;
- default: return KEY_NONE;
- }
- }
-
- if (key >= 'A' && key <= 'Z') {
- key += 'a' - 'A';
- }
-
- if ((key >= 'a' && key <= 'z') || (key >= '0' && key <= '9') ||
- (key >= KEY_SPACE && key <= KEY_AT_SIGN) ||
- (key >= KEY_LEFT_BRACKET && key <= KEY_TILDE)) {
- return (ta_keyboard_keys)key;
- }
-
- switch (key) {
- case 8: return KEY_BACKSPACE;
- case 9: return KEY_TAB;
- case 13: return KEY_ENTER;
- case 27: return KEY_ESCAPE;
- case 127: return KEY_DELETE;
- case 42: return KEY_LEFT_SHIFT;
- case 54: return KEY_RIGHT_SHIFT;
- case 29: return KEY_LEFT_CTRL;
- case 56: return KEY_LEFT_ALT;
- case 71: return KEY_HOME;
- case 72: return KEY_UP;
- case 73: return KEY_PAGE_UP;
- case 75: return KEY_LEFT;
- case 77: return KEY_RIGHT;
- case 79: return KEY_END;
- case 80: return KEY_DOWN;
- case 81: return KEY_PAGE_DOWN;
- case 82: return KEY_INSERT;
- case 83: return KEY_DELETE;
- case 59: return KEY_F1;
- case 60: return KEY_F2;
- case 61: return KEY_F3;
- case 62: return KEY_F4;
- case 63: return KEY_F5;
- case 64: return KEY_F6;
- case 65: return KEY_F7;
- case 66: return KEY_F8;
- case 67: return KEY_F9;
- case 68: return KEY_F10;
- case 133: return KEY_F11;
- case 134: return KEY_F12;
- default: return KEY_NONE;
- }
-}
-
-int main(void) {
- ta_fb.width = WINDOW_WIDTH;
- ta_fb.height = WINDOW_HEIGHT;
- ta_fb.bpp = WINDOW_BPP;
-
- if (atexit(clear_text_screen) != 0) {
- return 1;
- }
-
- set_mode_13h();
- set_palette_332();
-
- ta_main_init();
-
- bool running = true;
- while (running) {
- ta_keyboard_clear();
- if (kbhit()) {
- int key = getch();
- bool extended = false;
- if (key == 0 || key == 224) {
- key = getch();
- extended = true;
- }
- ta_keyboard_keys mapped_key = key_from_dos(key, extended);
- ta_keyboard_key_down(mapped_key);
- if (mapped_key == KEY_ESCAPE) {
- running = false;
- }
- }
-
- if (ta_main_update()) {
- blit();
- }
- ta_keyboard_clear();
- delay(16);
- }
-
- return 0;
-}
-
-void *ta_malloc(ta_size size) {
- return malloc(size);
-}
-
-void ta_free(void *ptr) {
- free(ptr);
-}
-
-ta_fs_file ta_read_file(const char *path) {
- ta_fs_file file = {
- .data = NULL,
- .size = 0
- };
-
- FILE *file_pointer = fopen(path, "rb");
- if (!file_pointer) {
- return file;
- }
-
- if (fseek(file_pointer, 0, SEEK_END) != 0) {
- fclose(file_pointer);
-
- return file;
- }
-
- long file_size = ftell(file_pointer);
- if (file_size < 0) {
- fclose(file_pointer);
-
- return file;
- }
-
- rewind(file_pointer);
-
- file.data = ta_malloc((ta_size)file_size);
- if (!file.data) {
- fclose(file_pointer);
-
- return file;
- }
-
- ta_size bytes_read = fread(file.data, 1, (size_t)file_size, file_pointer);
-
- if (bytes_read != (ta_size)file_size) {
- ta_free(file.data);
- file.data = NULL;
- fclose(file_pointer);
-
- return file;
- }
-
- file.size = (ta_size)file_size;
-
- fclose(file_pointer);
-
- return file;
-}
-
-void ta_close_file(ta_fs_file *file) {
- if (!file) {
- return;
- }
-
- if (file->data) {
- ta_free(file->data);
- file->data = NULL;
- }
-
- file->size = 0;
-}
-
-void ta_exit(int status) {
- exit(status);
-}
diff --git a/platforms/dreamcast/KallistiOS b/platforms/dreamcast/KallistiOS
@@ -1 +0,0 @@
-Subproject commit 76e1b9ccf1c005908dcd1e309833ccbbd3704803
diff --git a/platforms/dreamcast/dreamcast.c b/platforms/dreamcast/dreamcast.c
@@ -1,251 +0,0 @@
-#include "ta_api.h"
-#include <kos.h>
-#include <dc/maple.h>
-#include <dc/maple/controller.h>
-#include <dc/pvr.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-KOS_INIT_FLAGS(INIT_DEFAULT);
-
-#define SCREEN_WIDTH 320
-#define SCREEN_HEIGHT 240
-#define WINDOW_BPP 32
-#define TARGET_FPS 60
-#define FRAME_TIME_MS (1000 / TARGET_FPS)
-
-typedef struct {
- pvr_ptr_t texture;
- uint16_t *pixels;
-} sprite_texture;
-
-static uint32_t next_power_of_two(uint32_t value) {
- uint32_t result = 1;
- while (result < value) {
- result <<= 1;
- }
- return result;
-}
-
-static void update_controller_input(void) {
- maple_device_t *controller = maple_enum_type(0, MAPLE_FUNC_CONTROLLER);
- cont_state_t *state = controller ? (cont_state_t *)maple_dev_status(controller) : NULL;
-
- const ta_keyboard_keys keys[] = {
- KEY_UP,
- KEY_DOWN,
- KEY_LEFT,
- KEY_RIGHT,
- KEY_ENTER
- };
- const uint32_t buttons[] = {
- CONT_DPAD_UP,
- CONT_DPAD_DOWN,
- CONT_DPAD_LEFT,
- CONT_DPAD_RIGHT,
- CONT_A
- };
-
- for (size_t i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) {
- if (state && (state->buttons & buttons[i])) {
- ta_keyboard_key_down(keys[i]);
- } else {
- ta_keyboard_key_up(keys[i]);
- }
- }
-}
-
-static void render_sprites(void) {
- sprite_texture textures[255] = {{0}};
- pvr_scene_begin();
-
- pvr_list_begin(PVR_LIST_TR_POLY);
- for (uint8_t i = 0; i < ta_display_sprites->count; i++) {
- ta_display_sprite *sprite = ta_display_sprites->sprites[i];
- uint32_t texture_width = next_power_of_two(sprite->width);
- uint32_t texture_height = next_power_of_two(sprite->height);
- size_t texture_size = (size_t)texture_width * texture_height * sizeof(uint16_t);
- uint16_t *pixels = (uint16_t *)ta_malloc(texture_size);
- if (!pixels) {
- continue;
- }
-
- for (uint32_t y = 0; y < texture_height; y++) {
- for (uint32_t x = 0; x < texture_width; x++) {
- uint32_t pixel = 0;
- if (x < sprite->width && y < sprite->height) {
- pixel = ((const uint32_t *)sprite->pixels)[(size_t)y * sprite->width + x];
- }
-
- uint16_t alpha = (uint16_t)((pixel & 0xff) >> 4);
- uint16_t red = (uint16_t)(((pixel >> 24) & 0xff) >> 4);
- uint16_t green = (uint16_t)(((pixel >> 16) & 0xff) >> 4);
- uint16_t blue = (uint16_t)(((pixel >> 8) & 0xff) >> 4);
- pixels[(size_t)y * texture_width + x] = (uint16_t)((alpha << 12) | (red << 8) | (green << 4) | blue);
- }
- }
-
- pvr_ptr_t texture = pvr_mem_malloc(texture_size);
- if (!texture) {
- ta_free(pixels);
- continue;
- }
-
- pvr_txr_load(pixels, texture, texture_size);
- textures[i].texture = texture;
- textures[i].pixels = pixels;
-
- pvr_sprite_cxt_t context;
- pvr_sprite_hdr_t header;
- pvr_sprite_cxt_txr(&context, PVR_LIST_TR_POLY, PVR_TXRFMT_ARGB4444 | PVR_TXRFMT_NONTWIDDLED, texture_width, texture_height, texture, PVR_FILTER_BILINEAR);
- pvr_sprite_compile(&header, &context);
- pvr_prim(&header, sizeof(header));
-
- pvr_sprite_txr_t quad = {
- .flags = PVR_CMD_VERTEX_EOL,
- .ax = (float)sprite->x,
- .ay = (float)(sprite->y + sprite->draw_height),
- .az = 1.0f,
- .bx = (float)sprite->x,
- .by = (float)sprite->y,
- .bz = 1.0f,
- .cx = (float)(sprite->x + sprite->draw_width),
- .cy = (float)sprite->y,
- .cz = 1.0f,
- .dx = (float)(sprite->x + sprite->draw_width),
- .dy = (float)(sprite->y + sprite->draw_height),
- .dummy = 0,
- .auv = PVR_PACK_16BIT_UV(0.0f, (float)sprite->height / texture_height),
- .buv = PVR_PACK_16BIT_UV(0.0f, 0.0f),
- .cuv = PVR_PACK_16BIT_UV((float)sprite->width / texture_width, 0.0f)
- };
- pvr_prim(&quad, sizeof(quad));
- }
-
- pvr_list_finish();
- pvr_scene_finish();
- pvr_wait_render_done();
-
- for (uint8_t i = 0; i < ta_display_sprites->count; i++) {
- pvr_mem_free(textures[i].texture);
- ta_free(textures[i].pixels);
- }
-}
-
-int main(void) {
- vid_set_mode(DM_320x240, PM_RGB565);
- if (pvr_init_defaults() < 0) {
- return 1;
- }
-
- pvr_set_bg_color(0.0f, 0.0f, 0.0f);
-
- ta_display->width = SCREEN_WIDTH;
- ta_display->height = SCREEN_HEIGHT;
- ta_display->bpp = WINDOW_BPP;
- ta_display->sprite_mode = ta_true;
- ta_main_init();
-
- while (1) {
- uint64_t frame_start = timer_ms_gettime64();
-
- update_controller_input();
- ta_main_update();
- render_sprites();
-
- uint64_t frame_time = timer_ms_gettime64() - frame_start;
- if (frame_time < FRAME_TIME_MS) {
- thd_sleep((int)(FRAME_TIME_MS - frame_time));
- }
- }
-
- pvr_shutdown();
- return 0;
-}
-
-void *ta_malloc(ta_size size) {
- return malloc(size);
-}
-
-void ta_free(void *ptr) {
- free(ptr);
-}
-
-ta_fs_file ta_read_file(const char *path) {
- ta_fs_file file = {
- .data = NULL,
- .size = 0
- };
-
- FILE *file_pointer = fopen(path, "rb");
- if (!file_pointer) {
- return file;
- }
-
- if (fseek(file_pointer, 0, SEEK_END) != 0) {
- fclose(file_pointer);
-
- return file;
- }
-
- long file_size = ftell(file_pointer);
- if (file_size < 0) {
- fclose(file_pointer);
-
- return file;
- }
-
- rewind(file_pointer);
-
- file.data = ta_malloc((ta_size)file_size);
- if (!file.data) {
- fclose(file_pointer);
-
- return file;
- }
-
- ta_size bytes_read = fread(file.data, 1, (size_t)file_size, file_pointer);
-
- if (bytes_read != (ta_size)file_size) {
- ta_free(file.data);
- file.data = NULL;
- fclose(file_pointer);
-
- return file;
- }
-
- file.size = (ta_size)file_size;
-
- fclose(file_pointer);
-
- return file;
-}
-
-void ta_close_file(ta_fs_file *file) {
- if (!file) {
- return;
- }
-
- if (file->data) {
- ta_free(file->data);
- file->data = NULL;
- }
-
- file->size = 0;
-}
-
-void ta_exit(int status) {
- (void)status;
-
- __asm__ volatile(
- "stc sr, r0\n\t"
- "or #0xf0, r0\n\t"
- "ldc r0, sr"
- : : : "r0", "memory"
- );
-
- while (1) {
- __asm__ volatile("sleep");
- }
-}
diff --git a/platforms/n64/n64.c b/platforms/n64/n64.c
@@ -1,131 +0,0 @@
-#include "ta_api.h"
-#include <display.h>
-#include <rdpq.h>
-#include <rdpq_attach.h>
-#include <rdpq_mode.h>
-#include <rdpq_tex.h>
-#include <joypad.h>
-#include <surface.h>
-#include <n64sys.h>
-#include <timer.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <malloc.h>
-
-#define SCREEN_WIDTH 320
-#define SCREEN_HEIGHT 240
-#define WINDOW_BPP 32
-#define TARGET_FPS 60
-#define FRAME_TIME_MS (1000 / TARGET_FPS)
-
-static void update_controller_input(void) {
- joypad_buttons_t buttons = joypad_get_buttons(JOYPAD_PORT_1);
-
- if (buttons.d_up) {
- ta_keyboard_key_down(KEY_UP);
- } else {
- ta_keyboard_key_up(KEY_UP);
- }
-
- if (buttons.d_down) {
- ta_keyboard_key_down(KEY_DOWN);
- } else {
- ta_keyboard_key_up(KEY_DOWN);
- }
-
- if (buttons.d_left) {
- ta_keyboard_key_down(KEY_LEFT);
- } else {
- ta_keyboard_key_up(KEY_LEFT);
- }
-
- if (buttons.d_right) {
- ta_keyboard_key_down(KEY_RIGHT);
- } else {
- ta_keyboard_key_up(KEY_RIGHT);
- }
-
- if (buttons.a || buttons.start) {
- ta_keyboard_key_down(KEY_ENTER);
- } else {
- ta_keyboard_key_up(KEY_ENTER);
- }
-}
-
-int main(void) {
- display_init(RESOLUTION_320x240, DEPTH_32_BPP, 2, GAMMA_NONE, FILTERS_RESAMPLE);
- rdpq_init();
- joypad_init();
-
- ta_display->width = SCREEN_WIDTH;
- ta_display->height = SCREEN_HEIGHT;
- ta_display->bpp = WINDOW_BPP;
- ta_display->sprite_mode = ta_true;
-
- ta_main_init();
-
- while (1) {
- uint32_t frame_start = get_ticks_ms();
- surface_t *display = display_get();
- joypad_poll();
- update_controller_input();
- ta_main_update();
-
- rdpq_attach_clear(display, NULL);
- rdpq_set_mode_standard();
- rdpq_mode_filter(FILTER_POINT);
- rdpq_mode_combiner(RDPQ_COMBINER_TEX);
- rdpq_mode_blender(RDPQ_BLENDER_MULTIPLY);
- for (ta_uint8 i = 0; i < ta_display_sprites->count; i++) {
- ta_display_sprite *sprite = ta_display_sprites->sprites[i];
- surface_t texture = surface_make_linear(sprite->pixels, FMT_RGBA32, sprite->width, sprite->height);
- data_cache_hit_writeback(sprite->pixels, (uint32_t)sprite->width * sprite->height * sizeof(uint32_t));
- rdpq_blitparms_t parameters = {
- .scale_x = (float)sprite->draw_width / sprite->width,
- .scale_y = (float)sprite->draw_height / sprite->height
- };
- rdpq_mode_filter(sprite->draw_width != sprite->width || sprite->draw_height != sprite->height ? FILTER_BILINEAR : FILTER_POINT);
- rdpq_tex_blit(&texture, sprite->x, sprite->y, ¶meters);
- }
- rdpq_detach_show();
-
- uint32_t frame_time = get_ticks_ms() - frame_start;
- if (frame_time < FRAME_TIME_MS) {
- wait_ms(FRAME_TIME_MS - frame_time);
- }
- }
-
- return 0;
-}
-
-void *ta_malloc(ta_size size) {
- return memalign(8, size);
-}
-
-void ta_free(void *ptr) {
- free(ptr);
-}
-
-ta_fs_file ta_read_file(const char *path) {
- ta_fs_file file = {
- .data = NULL,
- .size = 0
- };
-
- (void)path;
-
- return file;
-}
-
-void ta_close_file(ta_fs_file *file) {
- if (!file) {
- return;
- }
-
- file->data = NULL;
- file->size = 0;
-}
-
-void ta_exit(int status) {
- exit(status);
-}
diff --git a/platforms/ps1/logo.tmd b/platforms/ps1/logo.tmd
Binary files differ.
diff --git a/platforms/ps1/nugget b/platforms/ps1/nugget
@@ -1 +0,0 @@
-Subproject commit 58d0cd1c5aa80f3eb338c8b94f70946314c9af36
diff --git a/platforms/ps1/ps1.c b/platforms/ps1/ps1.c
@@ -1,469 +0,0 @@
-#include <stddef.h>
-#include "ta_api.h"
-#include "common/hardware/hwregs.h"
-#include "common/hardware/irq.h"
-#include "common/hardware/gpu.h"
-
-#define SCREEN_WIDTH 320
-#define SCREEN_HEIGHT 240
-#define WINDOW_BPP 15
-
-#define STACK_RESERVE 0x20000u
-
-#define D2_MADR (*(volatile ta_uint32 *)0xbf8010a0)
-#define D2_BCR (*(volatile ta_uint32 *)0xbf8010a4)
-#define D2_CHCR (*(volatile ta_uint32 *)0xbf8010a8)
-
-#define SIO_DATA (*(volatile ta_uint8 *)0xbf801040)
-#define SIO_STAT (*(volatile ta_uint16 *)0xbf801044)
-#define SIO_MODE (*(volatile ta_uint16 *)0xbf801048)
-#define SIO_CTRL (*(volatile ta_uint16 *)0xbf80104a)
-#define SIO_BAUD (*(volatile ta_uint16 *)0xbf80104e)
-
-#define SIO_STAT_RXRDY 0x0002u
-#define SIO_STAT_IRQ 0x0200u
-#define SIO_CTRL_ACK 0x0010u
-#define SIO_CTRL_RESET 0x0040u
-#define SIO_CTRL_PAD 0x1003u
-
-extern char __bss_end[];
-extern char __ram_top[];
-
-typedef struct heap_block {
- ta_uint32 size;
- ta_uint32 reserved;
- struct heap_block *next;
-} heap_block;
-
-#define HEAP_HEADER 8u
-#define HEAP_MIN_PAYLOAD 8u
-
-static heap_block *heap_free_list;
-
-static void heap_init(void) {
- ta_uint32 start = ((ta_uint32)__bss_end + 7u) & ~7u;
- ta_uint32 end = ((ta_uint32)__ram_top - STACK_RESERVE) & ~7u;
-
- heap_free_list = (heap_block *)start;
- heap_free_list->size = end - start - HEAP_HEADER;
- heap_free_list->next = TA_NULL;
-}
-
-void *ta_malloc(ta_size size) {
- heap_block *previous = TA_NULL;
- heap_block *block = heap_free_list;
-
- if (size == 0) {
- return TA_NULL;
- }
-
- size = (size + 7u) & ~7u;
- if (size < HEAP_MIN_PAYLOAD) {
- size = HEAP_MIN_PAYLOAD;
- }
-
- while (block) {
- if (block->size >= size) {
- ta_uint32 remainder = block->size - (ta_uint32)size;
-
- if (remainder >= HEAP_HEADER + HEAP_MIN_PAYLOAD) {
- heap_block *rest = (heap_block *)((ta_uint8 *)block + HEAP_HEADER + size);
-
- rest->size = remainder - HEAP_HEADER;
- rest->next = block->next;
- block->size = (ta_uint32)size;
-
- if (previous) {
- previous->next = rest;
- } else {
- heap_free_list = rest;
- }
- } else if (previous) {
- previous->next = block->next;
- } else {
- heap_free_list = block->next;
- }
-
- return (ta_uint8 *)block + HEAP_HEADER;
- }
-
- previous = block;
- block = block->next;
- }
-
- return TA_NULL;
-}
-
-void ta_free(void *ptr) {
- heap_block *block;
- heap_block *previous = TA_NULL;
- heap_block *next = heap_free_list;
-
- if (!ptr) {
- return;
- }
-
- block = (heap_block *)((ta_uint8 *)ptr - HEAP_HEADER);
-
- while (next && next < block) {
- previous = next;
- next = next->next;
- }
-
- block->next = next;
-
- if (next && (ta_uint8 *)block + HEAP_HEADER + block->size == (ta_uint8 *)next) {
- block->size += HEAP_HEADER + next->size;
- block->next = next->next;
- }
-
- if (previous) {
- if ((ta_uint8 *)previous + HEAP_HEADER + previous->size == (ta_uint8 *)block) {
- previous->size += HEAP_HEADER + block->size;
- previous->next = block->next;
- } else {
- previous->next = block;
- }
- } else {
- heap_free_list = block;
- }
-}
-
-void *ta_realloc(void *ptr, ta_size new_size) {
- heap_block *block;
- ta_uint8 *fresh;
- ta_uint8 *source;
- ta_size copy;
-
- if (!ptr) {
- return ta_malloc(new_size);
- }
-
- if (new_size == 0) {
- ta_free(ptr);
- return TA_NULL;
- }
-
- block = (heap_block *)((ta_uint8 *)ptr - HEAP_HEADER);
- if (block->size >= new_size) {
- return ptr;
- }
-
- fresh = (ta_uint8 *)ta_malloc(new_size);
- if (!fresh) {
- return TA_NULL;
- }
-
- source = (ta_uint8 *)ptr;
- copy = block->size;
- for (ta_size i = 0; i < copy; i++) {
- fresh[i] = source[i];
- }
-
- ta_free(ptr);
- return fresh;
-}
-
-ta_fs_file ta_read_file(const char *path) {
- ta_fs_file file = {
- .data = NULL,
- .size = 0
- };
-
- (void)path;
-
- return file;
-}
-
-void ta_close_file(ta_fs_file *file) {
- if (!file) {
- return;
- }
-
- file->data = NULL;
- file->size = 0;
-}
-
-void ta_exit(int status) {
- (void)status;
-
- __asm__ volatile (
- "mfc0 $t0, $12\n\t"
- "li $t1, 0xfffffffe\n\t"
- "and $t0, $t0, $t1\n\t"
- "mtc0 $t0, $12\n\t"
- "lui $t0, 0xbfc0\n\t"
- "jr $t0\n\t"
- );
-}
-
-#define BUFFER_Y0 0
-#define BUFFER_Y1 SCREEN_HEIGHT
-
-static ta_uint16 framebuffer[SCREEN_WIDTH * SCREEN_HEIGHT] __attribute__((aligned(16)));
-static int back_buffer;
-
-static void disable_interrupts(void) {
- ta_uint32 status;
-
- __asm__ volatile("mfc0 %0, $12\n\tnop" : "=r"(status));
- status &= ~1u;
- __asm__ volatile("mtc0 %0, $12\n\tnop\n\tnop" : : "r"(status));
-}
-
-static void wait_vblank(void) {
- while ((IREG & IRQ_VBLANK) == 0) {}
- IREG = ~(ta_uint32)IRQ_VBLANK;
-}
-
-static ta_bool console_is_pal(void) {
- return (ta_bool)(*(volatile char *)0xbfc7ff52 == 'E');
-}
-
-static void video_init(void) {
- const ta_bool pal = console_is_pal();
- const ta_uint32 vertical_start = pal ? 0x23u : 0x10u;
- const ta_uint32 vertical_end = vertical_start + SCREEN_HEIGHT;
- struct FastFill fill;
-
- sendGPUStatus(0x00000000);
- sendGPUStatus(0x08000001u | (pal ? 0x08u : 0x00u));
- sendGPUStatus(0x06000000u | 0x260u | ((0x260u + SCREEN_WIDTH * 8u) << 12));
- sendGPUStatus(0x07000000u | vertical_start | (vertical_end << 10));
- sendGPUStatus(generateDisplayArea(0, BUFFER_Y0));
- sendGPUStatus(0x04000002u);
-
- fill.c.packed = 0;
- fill.x = 0;
- fill.y = 0;
- fill.w = SCREEN_WIDTH;
- fill.h = SCREEN_HEIGHT * 2;
- fastFill(&fill);
-
- enableDisplay();
- back_buffer = 1;
-}
-
-static ta_uint16 pack_rgb(ta_uint32 r, ta_uint32 g, ta_uint32 b) {
- return (ta_uint16)((r >> 3) | ((g >> 3) << 5) | ((b >> 3) << 10));
-}
-
-static void compose(void) {
- const ta_uint32 count = ta_display_sprites ? ta_display_sprites->count : 0;
-
- ta_uint32 *clear = (ta_uint32 *)framebuffer;
-
- for (ta_uint32 i = 0; i < SCREEN_WIDTH * SCREEN_HEIGHT / 2; i += 8) {
- clear[i + 0] = 0;
- clear[i + 1] = 0;
- clear[i + 2] = 0;
- clear[i + 3] = 0;
- clear[i + 4] = 0;
- clear[i + 5] = 0;
- clear[i + 6] = 0;
- clear[i + 7] = 0;
- }
-
- for (ta_uint32 s = 0; s < count; s++) {
- const ta_display_sprite *sprite = ta_display_sprites->sprites[s];
- const ta_uint32 *source;
- ta_uint32 width;
- ta_uint32 height;
-
- if (!sprite || sprite->format != TA_DISPLAY_PIXEL_FORMAT_32 ||
- sprite->x >= SCREEN_WIDTH || sprite->y >= SCREEN_HEIGHT) {
- continue;
- }
-
- source = (const ta_uint32 *)sprite->pixels;
- width = sprite->draw_width;
- height = sprite->draw_height;
-
- const ta_uint32 step_x = ((ta_uint32)sprite->width << 16) / width;
- const ta_uint32 step_y = ((ta_uint32)sprite->height << 16) / height;
-
- for (ta_uint32 y = 0; y < height && sprite->y + y < SCREEN_HEIGHT; y++) {
- const ta_uint32 *row = source + ((y * step_y) >> 16) * sprite->width;
- ta_uint16 *destination = framebuffer + (sprite->y + y) * SCREEN_WIDTH + sprite->x;
- ta_uint32 source_x = 0;
-
- for (ta_uint32 x = 0; x < width && sprite->x + x < SCREEN_WIDTH; x++, source_x += step_x) {
- const ta_uint32 pixel = row[source_x >> 16];
- const ta_uint32 alpha = pixel & 0xffu;
-
- if (alpha == 0) {
- continue;
- }
-
- if (alpha == 0xffu) {
- destination[x] = pack_rgb(pixel >> 24, (pixel >> 16) & 0xffu, (pixel >> 8) & 0xffu);
- } else {
- const ta_uint16 below = destination[x];
- const ta_int32 dr = below & 0x1f;
- const ta_int32 dg = (below >> 5) & 0x1f;
- const ta_int32 db = (below >> 10) & 0x1f;
- const ta_int32 sr = (ta_int32)(pixel >> 27);
- const ta_int32 sg = (ta_int32)((pixel >> 19) & 0x1f);
- const ta_int32 sb = (ta_int32)((pixel >> 11) & 0x1f);
- const ta_int32 a = (ta_int32)alpha;
-
- destination[x] = (ta_uint16)(
- (dr + (((sr - dr) * a + 128) >> 8)) |
- ((dg + (((sg - dg) * a + 128) >> 8)) << 5) |
- ((db + (((sb - db) * a + 128) >> 8)) << 10));
- }
- }
- }
- }
-}
-
-static void upload(int buffer) {
- const ta_uint32 y = buffer ? BUFFER_Y1 : BUFFER_Y0;
- const ta_uint32 words = SCREEN_WIDTH * SCREEN_HEIGHT / 2;
-
- waitGPU();
- GPU_DATA = 0xa0000000u;
- GPU_DATA = 0u | (y << 16);
- GPU_DATA = SCREEN_WIDTH | ((ta_uint32)SCREEN_HEIGHT << 16);
-
- DPCR |= 0x800u;
- D2_MADR = (ta_uint32)framebuffer & 0x1fffffffu;
- D2_BCR = ((words / 16u) << 16) | 16u;
- D2_CHCR = 0x01000201u;
-
- while (D2_CHCR & 0x01000000u) {}
-}
-
-static void flip(int buffer) {
- sendGPUStatus(generateDisplayArea(0, buffer ? BUFFER_Y1 : BUFFER_Y0));
-}
-
-static ta_bool pad_exchange(ta_uint8 out, ta_uint8 *in, ta_bool wait_ack) {
- ta_uint32 timeout = 0x4000;
-
- SIO_DATA = out;
-
- while (!(SIO_STAT & SIO_STAT_RXRDY)) {
- if (--timeout == 0) {
- return ta_false;
- }
- }
-
- *in = SIO_DATA;
-
- if (wait_ack) {
- timeout = 0x400;
-
- while (!(SIO_STAT & SIO_STAT_IRQ)) {
- if (--timeout == 0) {
- return ta_false;
- }
- }
-
- SIO_CTRL = SIO_CTRL_PAD | SIO_CTRL_ACK;
- }
-
- return ta_true;
-}
-
-static ta_bool pad_read(ta_uint16 *buttons) {
- static const ta_uint8 request[5] = {
- 0x01,
- 0x42,
- 0x00,
- 0x00,
- 0x00
- };
-
- ta_uint8 reply[5] = {
- 0xff,
- 0xff,
- 0xff,
- 0xff,
- 0xff
- };
-
- ta_bool ok = ta_true;
-
- SIO_CTRL = SIO_CTRL_PAD;
-
- for (ta_uint32 i = 0; i < 5 && ok; i++) {
- ok = pad_exchange(request[i], &reply[i], (ta_bool)(i < 4));
- }
-
- SIO_CTRL = 0;
-
- if (!ok || reply[2] != 0x5a) {
- return ta_false;
- }
-
- *buttons = (ta_uint16)(reply[3] | ((ta_uint16)reply[4] << 8));
- return ta_true;
-}
-
-static void pad_init(void) {
- SIO_CTRL = SIO_CTRL_RESET;
- SIO_MODE = 0x000d;
- SIO_BAUD = 0x0088;
- SIO_CTRL = 0;
-}
-
-static void set_key(ta_keyboard_keys key, ta_bool down) {
- if (down) {
- ta_keyboard_key_down(key);
- } else {
- ta_keyboard_key_up(key);
- }
-}
-
-static void update_controller_input(void) {
- ta_uint16 buttons;
-
- if (!pad_read(&buttons)) {
- ta_keyboard_clear();
- return;
- }
-
- buttons = (ta_uint16)~buttons;
-
- set_key(KEY_UP, (ta_bool)((buttons & 0x0010u) != 0));
- set_key(KEY_DOWN, (ta_bool)((buttons & 0x0040u) != 0));
- set_key(KEY_LEFT, (ta_bool)((buttons & 0x0080u) != 0));
- set_key(KEY_RIGHT, (ta_bool)((buttons & 0x0020u) != 0));
- set_key(KEY_ENTER, (ta_bool)((buttons & 0x0008u) != 0));
-}
-
-int main(void) {
- disable_interrupts();
- heap_init();
- video_init();
- pad_init();
-
- ta_display->width = SCREEN_WIDTH;
- ta_display->height = SCREEN_HEIGHT;
- ta_display->bpp = WINDOW_BPP;
- ta_display->sprite_mode = ta_true;
-
- ta_main_init();
-
- for (;;) {
- ta_bool redraw;
-
- update_controller_input();
- redraw = ta_main_update();
-
- if (redraw) {
- compose();
- upload(back_buffer);
- }
-
- wait_vblank();
-
- if (redraw) {
- flip(back_buffer);
- back_buffer ^= 1;
- }
- }
-
- return 0;
-}
diff --git a/platforms/saturn/jo.mk b/platforms/saturn/jo.mk
@@ -1,27 +0,0 @@
-JO_COMPILE_WITH_VIDEO_MODULE = 0
-JO_COMPILE_WITH_BACKUP_MODULE = 0
-JO_COMPILE_WITH_TGA_MODULE = 0
-JO_COMPILE_WITH_AUDIO_MODULE = 0
-JO_COMPILE_WITH_3D_MODULE = 0
-JO_COMPILE_WITH_PSEUDO_MODE7_MODULE = 0
-JO_COMPILE_WITH_EFFECTS_MODULE = 0
-JO_COMPILE_WITH_STORYBOARD_MODULE = 0
-JO_COMPILE_WITH_SOFTWARE_RENDERER_MODULE = 0
-
-JO_GLOBAL_MEMORY_SIZE_FOR_MALLOC = 262144
-
-JO_MAX_SPRITE = 16
-
-JO_ENGINE_SRC_DIR = $(JOENGINE)/jo_engine
-COMPILER_DIR = $(JOENGINE)/Compiler
-
-ENGINE_OBJ_SRCS := $(shell find src \( -type f -o -type l \) -name '*.c')
-ASSET_SRCS := $(shell find images fonts -type f -name '*.c')
-
-SRCS = saturn.c $(ENGINE_OBJ_SRCS) $(ASSET_SRCS)
-
-include $(COMPILER_DIR)/COMMON/jo_engine_makefile
-
-_CCFLAGS = -I$(ROOT_DIR)/include -I$(SATURN_BUILD_DIR) -DTA_32BIT -DTA_DISABLE_BILINEAR_FILTERING
-
-$(OBJS): $(wildcard $(ROOT_DIR)/include/*.h) $(SATURN_BUILD_DIR)/ta_config.h
diff --git a/platforms/saturn/joengine b/platforms/saturn/joengine
@@ -1 +0,0 @@
-Subproject commit 556d081146211b6a1cfa6591d70f9487d406758b
diff --git a/platforms/saturn/saturn.c b/platforms/saturn/saturn.c
@@ -1,240 +0,0 @@
-#include <jo/jo.h>
-#include "ta_api.h"
-
-#define SCREEN_WIDTH JO_TV_WIDTH
-#define SCREEN_HEIGHT JO_TV_HEIGHT
-#define WINDOW_BPP 32
-#define LWRAM 0x00200000
-#define LWRAM_HEAP_SIZE 0x00100000
-#define MAX_SLOTS 16
-#define VRAM_BUDGET 400000
-#define VDP1_MAX_WIDTH 504
-#define VDP1_MAX_HEIGHT 255
-#define BASE_Z 500
-#define RGB555_OPAQUE 0x8000
-#define ALPHA_THRESHOLD 128
-
-typedef struct {
- const ta_display_sprite *source;
- ta_uint16 x, y, draw_width, draw_height;
- ta_uint32 checksum;
- unsigned int vram_bytes;
-} slot_t;
-
-static slot_t slots[MAX_SLOTS];
-static unsigned int slot_count;
-static unsigned int vram_used;
-static int first_sprite_id;
-
-static jo_color upload_buffer[SCREEN_WIDTH * SCREEN_HEIGHT] __attribute__((aligned(32)));
-
-static void update_controller_input(void) {
- static const struct {
- jo_gamepad_keys pad;
- ta_keyboard_keys key;
- } map[] = {
- { JO_KEY_UP, KEY_UP },
- { JO_KEY_DOWN, KEY_DOWN },
- { JO_KEY_LEFT, KEY_LEFT },
- { JO_KEY_RIGHT, KEY_RIGHT },
- { JO_KEY_A, KEY_ENTER },
- { JO_KEY_C, KEY_ENTER },
- { JO_KEY_START, KEY_ENTER }
- };
- ta_bool enter_down = ta_false;
-
- for (unsigned int i = 0; i < sizeof(map) / sizeof(map[0]); i++) {
- ta_bool down = jo_is_pad1_available() && jo_is_pad1_key_pressed(map[i].pad);
-
- if (map[i].key == KEY_ENTER) {
- enter_down = (ta_bool)(enter_down || down);
- continue;
- }
-
- if (down) {
- ta_keyboard_key_down(map[i].key);
- } else {
- ta_keyboard_key_up(map[i].key);
- }
- }
-
- if (enter_down) {
- ta_keyboard_key_down(KEY_ENTER);
- } else {
- ta_keyboard_key_up(KEY_ENTER);
- }
-}
-
-static ta_uint32 sprite_checksum(const ta_display_sprite *sprite) {
- const ta_uint32 *pixels = (const ta_uint32 *)sprite->pixels;
- const unsigned int count = (unsigned int)sprite->width * sprite->height;
- const unsigned int stride = count / 64 + 1;
- ta_uint32 sum = count;
-
- for (unsigned int i = 0; i < count; i += stride) {
- sum = ((sum << 5) | (sum >> 27)) ^ pixels[i];
- }
-
- return sum;
-}
-
-static ta_bool slot_matches(const slot_t *slot, const ta_display_sprite *sprite) {
- return (ta_bool)(slot->source == sprite && slot->x == sprite->x && slot->y == sprite->y && slot->draw_width == sprite->draw_width && slot->draw_height == sprite->draw_height && slot->checksum == sprite_checksum(sprite));
-}
-
-static ta_bool upload_sprite(const ta_display_sprite *sprite) {
- if (slot_count >= MAX_SLOTS || sprite->format != TA_DISPLAY_PIXEL_FORMAT_32 || sprite->draw_width == 0 || sprite->draw_height == 0 || sprite->draw_width > VDP1_MAX_WIDTH || sprite->draw_height > VDP1_MAX_HEIGHT) {
- return ta_false;
- }
-
- const unsigned int padded_width = ((unsigned int)sprite->draw_width + 7) & ~7u;
- const unsigned int bytes = padded_width * sprite->draw_height * (unsigned int)sizeof(jo_color);
-
- if (padded_width * sprite->draw_height > sizeof(upload_buffer) / sizeof(upload_buffer[0]) ||
- vram_used + bytes > VRAM_BUDGET) {
- return ta_false;
- }
-
- const ta_uint32 *source = (const ta_uint32 *)sprite->pixels;
-
- const ta_uint32 step_x = ((ta_uint32)sprite->width << 16) / sprite->draw_width;
- const ta_uint32 step_y = ((ta_uint32)sprite->height << 16) / sprite->draw_height;
-
- for (unsigned int y = 0; y < sprite->draw_height; y++) {
- const ta_uint32 *row = source + ((y * step_y) >> 16) * sprite->width;
- jo_color *destination = upload_buffer + (unsigned int)y * padded_width;
- ta_uint32 source_x = 0;
- unsigned int x = 0;
-
- for (; x < sprite->draw_width; x++, source_x += step_x) {
- const ta_uint32 pixel = row[source_x >> 16];
-
- if ((pixel & 0xff) < ALPHA_THRESHOLD) {
- destination[x] = 0;
- } else {
- destination[x] = (jo_color)(RGB555_OPAQUE | (((pixel >> 11) & 0x1f) << 10) | (((pixel >> 19) & 0x1f) << 5) | ((pixel >> 27) & 0x1f));
- }
- }
-
- for (; x < padded_width; x++) {
- destination[x] = 0;
- }
- }
-
- jo_img image = {
- (unsigned short)padded_width, sprite->draw_height,
- upload_buffer
- };
-
- const int id = jo_sprite_add(&image);
-
- if (id != first_sprite_id + (int)slot_count) {
- return ta_false;
- }
-
- slot_t *slot = &slots[slot_count++];
- slot->source = sprite;
- slot->x = sprite->x;
- slot->y = sprite->y;
- slot->draw_width = sprite->draw_width;
- slot->draw_height = sprite->draw_height;
- slot->checksum = sprite_checksum(sprite);
- slot->vram_bytes = bytes;
- vram_used += bytes;
-
- return ta_true;
-}
-
-static void sync_sprites(void) {
- const unsigned int count = ta_display_sprites ? ta_display_sprites->count : 0;
- unsigned int keep = 0;
-
- while (keep < slot_count && keep < count && slot_matches(&slots[keep], ta_display_sprites->sprites[keep])) {
- keep++;
- }
-
- if (keep < slot_count) {
- jo_sprite_free_from(first_sprite_id + (int)keep);
-
- for (unsigned int i = keep; i < slot_count; i++) {
- vram_used -= slots[i].vram_bytes;
- }
-
- slot_count = keep;
- }
-
- for (unsigned int i = keep; i < count; i++) {
- if (!upload_sprite(ta_display_sprites->sprites[i])) {
- break;
- }
- }
-}
-
-static void game_frame_callback(void) {
- update_controller_input();
-
- if (ta_main_update()) {
- sync_sprites();
- }
-
- for (unsigned int i = 0; i < slot_count; i++) {
- jo_sprite_draw3D2(first_sprite_id + (int)i, slots[i].x, slots[i].y, BASE_Z - (int)i);
- }
-}
-
-void jo_main(void) {
- jo_core_init(JO_COLOR_Black);
- jo_add_memory_zone((unsigned char *)LWRAM, LWRAM_HEAP_SIZE);
-
- first_sprite_id = jo_get_last_sprite_id() + 1;
-
- ta_display->width = SCREEN_WIDTH;
- ta_display->height = SCREEN_HEIGHT;
- ta_display->bpp = WINDOW_BPP;
- ta_display->sprite_mode = ta_true;
-
- ta_main_init();
-
- jo_core_add_callback(game_frame_callback);
- jo_core_run();
-}
-
-void *ta_malloc(ta_size size) {
- if (size == 0) {
- return TA_NULL;
- }
-
- return jo_malloc((unsigned int)size);
-}
-
-void ta_free(void *ptr) {
- if (ptr) {
- jo_free(ptr);
- }
-}
-
-ta_fs_file ta_read_file(const char *path) {
- ta_fs_file file = {
- .data = NULL,
- .size = 0
- };
-
- (void)path;
-
- return file;
-}
-
-void ta_close_file(ta_fs_file *file) {
- if (!file) {
- return;
- }
-
- file->data = NULL;
- file->size = 0;
-}
-
-void ta_exit(int status) {
- (void)status;
-
- jo_goto_boot_menu();
-}
diff --git a/platforms/wayland/wayland.c b/platforms/wayland/wayland.c
@@ -1,629 +0,0 @@
-#define _POSIX_C_SOURCE 200809L
-
-#include "ta_api.h"
-#include <stdbool.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <linux/input-event-codes.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <unistd.h>
-#include <wayland-client.h>
-#include <xkbcommon/xkbcommon.h>
-#include <xkbcommon/xkbcommon-keysyms.h>
-#include "xdg-shell-client-protocol.h"
-
-#define WINDOW_WIDTH 800
-#define WINDOW_HEIGHT 600
-#define WINDOW_BPP 32
-
-typedef struct {
- struct wl_display *display;
- struct wl_registry *registry;
- struct wl_compositor *compositor;
- struct wl_shm *shm;
- struct wl_seat *seat;
- struct wl_keyboard *keyboard;
- struct xdg_wm_base *wm_base;
- struct wl_surface *surface;
- struct xdg_surface *xdg_surface;
- struct xdg_toplevel *toplevel;
- struct wl_buffer *buffer;
- struct wl_callback *frame_callback;
- struct xkb_context *xkb_context;
- struct xkb_keymap *xkb_keymap;
- struct xkb_state *xkb_state;
- void *pixels;
- size_t buffer_size;
- bool running;
- bool configured;
- bool frame_ready;
- bool buffer_released;
-} wayland_state;
-
-static ta_keyboard_keys key_from_keysym(xkb_keysym_t symbol) {
- symbol = xkb_keysym_to_lower(symbol);
- if (symbol >= XKB_KEY_a && symbol <= XKB_KEY_z) {
- return (ta_keyboard_keys)(KEY_A + symbol - XKB_KEY_a);
- }
- if (symbol >= XKB_KEY_0 && symbol <= XKB_KEY_9) {
- return (ta_keyboard_keys)(KEY_0 + symbol - XKB_KEY_0);
- }
-
- switch (symbol) {
- case XKB_KEY_BackSpace: return KEY_BACKSPACE;
- case XKB_KEY_Tab: return KEY_TAB;
- case XKB_KEY_Return: return KEY_ENTER;
- case XKB_KEY_Escape: return KEY_ESCAPE;
- case XKB_KEY_space: return KEY_SPACE;
- case XKB_KEY_exclam: return KEY_EXCLAMATION_MARK;
- case XKB_KEY_quotedbl: return KEY_QUOTATION_MARK;
- case XKB_KEY_numbersign: return KEY_HASH;
- case XKB_KEY_dollar: return KEY_DOLLAR_SIGN;
- case XKB_KEY_percent: return KEY_PERCENT_SIGN;
- case XKB_KEY_ampersand: return KEY_AMPERSAND;
- case XKB_KEY_apostrophe: return KEY_APOSTROPHE;
- case XKB_KEY_parenleft: return KEY_LEFT_PARENTHESIS;
- case XKB_KEY_parenright: return KEY_RIGHT_PARENTHESIS;
- case XKB_KEY_asterisk: return KEY_ASTERISK;
- case XKB_KEY_plus: return KEY_PLUS;
- case XKB_KEY_comma: return KEY_COMMA;
- case XKB_KEY_minus: return KEY_MINUS;
- case XKB_KEY_period: return KEY_PERIOD;
- case XKB_KEY_slash: return KEY_SLASH;
- case XKB_KEY_colon: return KEY_COLON;
- case XKB_KEY_semicolon: return KEY_SEMICOLON;
- case XKB_KEY_less: return KEY_LESS_THAN;
- case XKB_KEY_equal: return KEY_EQUALS;
- case XKB_KEY_greater: return KEY_GREATER_THAN;
- case XKB_KEY_question: return KEY_QUESTION_MARK;
- case XKB_KEY_at: return KEY_AT_SIGN;
- case XKB_KEY_bracketleft: return KEY_LEFT_BRACKET;
- case XKB_KEY_backslash: return KEY_BACKSLASH;
- case XKB_KEY_bracketright: return KEY_RIGHT_BRACKET;
- case XKB_KEY_asciicircum: return KEY_CARET;
- case XKB_KEY_underscore: return KEY_UNDERSCORE;
- case XKB_KEY_grave: return KEY_GRAVE_ACCENT;
- case XKB_KEY_braceleft: return KEY_LEFT_BRACE;
- case XKB_KEY_bar: return KEY_PIPE;
- case XKB_KEY_braceright: return KEY_RIGHT_BRACE;
- case XKB_KEY_asciitilde: return KEY_TILDE;
- case XKB_KEY_Delete: return KEY_DELETE;
- case XKB_KEY_Up: return KEY_UP;
- case XKB_KEY_Down: return KEY_DOWN;
- case XKB_KEY_Left: return KEY_LEFT;
- case XKB_KEY_Right: return KEY_RIGHT;
- case XKB_KEY_F1: return KEY_F1;
- case XKB_KEY_F2: return KEY_F2;
- case XKB_KEY_F3: return KEY_F3;
- case XKB_KEY_F4: return KEY_F4;
- case XKB_KEY_F5: return KEY_F5;
- case XKB_KEY_F6: return KEY_F6;
- case XKB_KEY_F7: return KEY_F7;
- case XKB_KEY_F8: return KEY_F8;
- case XKB_KEY_F9: return KEY_F9;
- case XKB_KEY_F10: return KEY_F10;
- case XKB_KEY_F11: return KEY_F11;
- case XKB_KEY_F12: return KEY_F12;
- case XKB_KEY_Home: return KEY_HOME;
- case XKB_KEY_End: return KEY_END;
- case XKB_KEY_Page_Up: return KEY_PAGE_UP;
- case XKB_KEY_Page_Down: return KEY_PAGE_DOWN;
- case XKB_KEY_Insert: return KEY_INSERT;
- case XKB_KEY_Caps_Lock: return KEY_CAPS_LOCK;
- case XKB_KEY_Num_Lock: return KEY_NUM_LOCK;
- case XKB_KEY_Scroll_Lock: return KEY_SCROLL_LOCK;
- case XKB_KEY_Print: return KEY_PRINT_SCREEN;
- case XKB_KEY_Pause: return KEY_PAUSE;
- case XKB_KEY_Menu: return KEY_MENU;
- case XKB_KEY_Shift_L: return KEY_LEFT_SHIFT;
- case XKB_KEY_Shift_R: return KEY_RIGHT_SHIFT;
- case XKB_KEY_Control_L: return KEY_LEFT_CTRL;
- case XKB_KEY_Control_R: return KEY_RIGHT_CTRL;
- case XKB_KEY_Alt_L: return KEY_LEFT_ALT;
- case XKB_KEY_Alt_R: return KEY_RIGHT_ALT;
- case XKB_KEY_Super_L: return KEY_LEFT_SUPER;
- case XKB_KEY_Super_R: return KEY_RIGHT_SUPER;
- case XKB_KEY_KP_0: return KEY_KP_0;
- case XKB_KEY_KP_1: return KEY_KP_1;
- case XKB_KEY_KP_2: return KEY_KP_2;
- case XKB_KEY_KP_3: return KEY_KP_3;
- case XKB_KEY_KP_4: return KEY_KP_4;
- case XKB_KEY_KP_5: return KEY_KP_5;
- case XKB_KEY_KP_6: return KEY_KP_6;
- case XKB_KEY_KP_7: return KEY_KP_7;
- case XKB_KEY_KP_8: return KEY_KP_8;
- case XKB_KEY_KP_9: return KEY_KP_9;
- case XKB_KEY_KP_Decimal: return KEY_KP_DECIMAL;
- case XKB_KEY_KP_Divide: return KEY_KP_DIVIDE;
- case XKB_KEY_KP_Multiply: return KEY_KP_MULTIPLY;
- case XKB_KEY_KP_Subtract: return KEY_KP_SUBTRACT;
- case XKB_KEY_KP_Add: return KEY_KP_ADD;
- case XKB_KEY_KP_Enter: return KEY_KP_ENTER;
- case XKB_KEY_KP_Equal: return KEY_KP_EQUALS;
- default: return KEY_NONE;
- }
-}
-
-static void wm_base_ping(void *data, struct xdg_wm_base *wm_base, uint32_t serial) {
- (void)data;
- xdg_wm_base_pong(wm_base, serial);
-}
-
-static const struct xdg_wm_base_listener wm_base_listener = {
- .ping = wm_base_ping
-};
-
-static void toplevel_configure(void *data, struct xdg_toplevel *toplevel, int32_t width, int32_t height, struct wl_array *states) {
- (void)data;
- (void)toplevel;
- (void)width;
- (void)height;
- (void)states;
-}
-
-static void toplevel_close(void *data, struct xdg_toplevel *toplevel) {
- wayland_state *state = data;
- (void)toplevel;
- state->running = false;
-}
-
-static const struct xdg_toplevel_listener toplevel_listener = {
- .configure = toplevel_configure,
- .close = toplevel_close
-};
-
-static void xdg_surface_configure(void *data, struct xdg_surface *xdg_surface, uint32_t serial) {
- wayland_state *state = data;
- xdg_surface_ack_configure(xdg_surface, serial);
- state->configured = true;
-}
-
-static const struct xdg_surface_listener xdg_surface_listener = {
- .configure = xdg_surface_configure
-};
-
-static int create_buffer(wayland_state *state) {
- char path[] = "/tmp/tuxanci2-wayland-XXXXXX";
- int fd = mkstemp(path);
- if (fd < 0) {
- fprintf(stderr, "cannot create shared buffer: %s\n", strerror(errno));
- return 0;
- }
- unlink(path);
-
- state->buffer_size = (size_t)ta_fb.width * (size_t)ta_fb.height * 4;
- if (ftruncate(fd, (off_t)state->buffer_size) < 0) {
- fprintf(stderr, "cannot size shared buffer: %s\n", strerror(errno));
- close(fd);
- return 0;
- }
-
- state->pixels = mmap(NULL, state->buffer_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
- if (state->pixels == MAP_FAILED) {
- state->pixels = NULL;
- fprintf(stderr, "cannot map shared buffer: %s\n", strerror(errno));
- close(fd);
- return 0;
- }
-
- struct wl_shm_pool *pool = wl_shm_create_pool(state->shm, fd, (int32_t)state->buffer_size);
- close(fd);
- if (!pool) {
- fprintf(stderr, "cannot create Wayland shared-memory pool\n");
- return 0;
- }
-
- state->buffer = wl_shm_pool_create_buffer(pool, 0, (int32_t)ta_fb.width, (int32_t)ta_fb.height, (int32_t)ta_fb.width * 4, WL_SHM_FORMAT_XRGB8888);
- wl_shm_pool_destroy(pool);
- if (!state->buffer) {
- fprintf(stderr, "cannot create Wayland framebuffer\n");
- return 0;
- }
- return 1;
-}
-
-static void buffer_release(void *data, struct wl_buffer *buffer) {
- wayland_state *state = data;
- (void)buffer;
- state->buffer_released = true;
-}
-
-static const struct wl_buffer_listener buffer_listener = {
- .release = buffer_release
-};
-
-static void frame_done(void *data, struct wl_callback *callback, uint32_t time) {
- (void)time;
- wayland_state *state = data;
- wl_callback_destroy(callback);
- state->frame_callback = NULL;
- state->frame_ready = true;
-}
-
-static const struct wl_callback_listener frame_listener = {
- .done = frame_done
-};
-
-static void keyboard_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format, int32_t fd, uint32_t size) {
- (void)keyboard;
- wayland_state *state = data;
-
- if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1 || size == 0) {
- close(fd);
- return;
- }
-
- char *keymap_text = malloc((size_t)size + 1);
- if (!keymap_text) {
- close(fd);
- return;
- }
- size_t offset = 0;
- while (offset < size) {
- ssize_t count = read(fd, keymap_text + offset, (size_t)size - offset);
- if (count <= 0) {
- break;
- }
- offset += (size_t)count;
- }
- close(fd);
- if (offset != size) {
- free(keymap_text);
- return;
- }
- keymap_text[size] = '\0';
-
- struct xkb_keymap *keymap = xkb_keymap_new_from_string(state->xkb_context, keymap_text, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
- free(keymap_text);
- if (!keymap) {
- return;
- }
-
- struct xkb_state *xkb_state = xkb_state_new(keymap);
- if (!xkb_state) {
- xkb_keymap_unref(keymap);
- return;
- }
-
- if (state->xkb_state) {
- xkb_state_unref(state->xkb_state);
- }
-
- if (state->xkb_keymap) {
- xkb_keymap_unref(state->xkb_keymap);
- }
-
- state->xkb_keymap = keymap;
- state->xkb_state = xkb_state;
-}
-
-static void keyboard_enter(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface, struct wl_array *keys) {
- (void)data;
- (void)keyboard;
- (void)serial;
- (void)surface;
- (void)keys;
- ta_keyboard_clear();
-}
-
-static void keyboard_leave(void *data, struct wl_keyboard *keyboard,
- uint32_t serial, struct wl_surface *surface) {
- (void)data;
- (void)keyboard;
- (void)serial;
- (void)surface;
- ta_keyboard_clear();
-}
-
-static void keyboard_key(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t key_state) {
- (void)keyboard;
- (void)serial;
- (void)time;
-
- wayland_state *state = data;
-
- if (!state->xkb_state) {
- return;
- }
-
- xkb_keysym_t symbol = xkb_state_key_get_one_sym(state->xkb_state, key + 8);
- ta_keyboard_keys mapped = key_from_keysym(symbol);
- if (key_state == WL_KEYBOARD_KEY_STATE_PRESSED) {
- ta_keyboard_key_down(mapped);
- if (mapped == KEY_ESCAPE) state->running = false;
- } else {
- ta_keyboard_key_up(mapped);
- }
-}
-
-static void keyboard_modifiers(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t depressed, uint32_t latched, uint32_t locked, uint32_t group) {
- (void)keyboard;
- (void)serial;
- wayland_state *state = data;
- if (state->xkb_state && state->xkb_keymap) {
- xkb_state_update_mask(state->xkb_state, depressed, latched, locked, 0, 0, group);
- }
-}
-
-static void keyboard_repeat_info(void *data, struct wl_keyboard *keyboard, int32_t rate, int32_t delay) {
- (void)data;
- (void)keyboard;
- (void)rate;
- (void)delay;
-}
-
-static const struct wl_keyboard_listener keyboard_listener = {
- .keymap = keyboard_keymap,
- .enter = keyboard_enter,
- .leave = keyboard_leave,
- .key = keyboard_key,
- .modifiers = keyboard_modifiers,
- .repeat_info = keyboard_repeat_info
-};
-
-static void seat_capabilities(void *data, struct wl_seat *seat, uint32_t capabilities) {
- wayland_state *state = data;
- if ((capabilities & WL_SEAT_CAPABILITY_KEYBOARD) && !state->keyboard) {
- state->keyboard = wl_seat_get_keyboard(seat);
- wl_keyboard_add_listener(state->keyboard, &keyboard_listener, state);
- } else if (!(capabilities & WL_SEAT_CAPABILITY_KEYBOARD) && state->keyboard) {
- wl_keyboard_destroy(state->keyboard);
- state->keyboard = NULL;
- ta_keyboard_clear();
- }
-}
-
-static void seat_name(void *data, struct wl_seat *seat, const char *name) {
- (void)data;
- (void)seat;
- (void)name;
-}
-
-static const struct wl_seat_listener seat_listener = {
- .capabilities = seat_capabilities,
- .name = seat_name
-};
-
-static void registry_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) {
- wayland_state *state = data;
- if (strcmp(interface, wl_compositor_interface.name) == 0) {
- state->compositor = wl_registry_bind(registry, name, &wl_compositor_interface, version < 4 ? version : 4);
- } else if (strcmp(interface, wl_shm_interface.name) == 0) {
- state->shm = wl_registry_bind(registry, name, &wl_shm_interface, 1);
- } else if (strcmp(interface, xdg_wm_base_interface.name) == 0) {
- state->wm_base = wl_registry_bind(registry, name, &xdg_wm_base_interface, version < 1 ? version : 1);
- xdg_wm_base_add_listener(state->wm_base, &wm_base_listener, state);
- } else if (strcmp(interface, wl_seat_interface.name) == 0) {
- state->seat = wl_registry_bind(registry, name, &wl_seat_interface, version < 5 ? version : 5);
- wl_seat_add_listener(state->seat, &seat_listener, state);
- }
-}
-
-static void registry_remove(void *data, struct wl_registry *registry, uint32_t name) {
- (void)data;
- (void)registry;
- (void)name;
-}
-
-static const struct wl_registry_listener registry_listener = {
- .global = registry_global,
- .global_remove = registry_remove
-};
-
-static void destroy_wayland(wayland_state *state) {
- if (state->frame_callback) {
- wl_callback_destroy(state->frame_callback);
- }
-
- if (state->buffer) {
- wl_buffer_destroy(state->buffer);
- }
-
- if (state->pixels) {
- munmap(state->pixels, state->buffer_size);
- }
-
- if (state->toplevel) {
- xdg_toplevel_destroy(state->toplevel);
- }
-
- if (state->xdg_surface) {
- xdg_surface_destroy(state->xdg_surface);
- }
-
- if (state->surface) {
- wl_surface_destroy(state->surface);
- }
-
- if (state->keyboard) {
- wl_keyboard_destroy(state->keyboard);
- }
-
- if (state->seat) {
- wl_seat_destroy(state->seat);
- }
-
- if (state->wm_base) {
- xdg_wm_base_destroy(state->wm_base);
- }
-
- if (state->shm) {
- wl_shm_destroy(state->shm);
- }
-
- if (state->compositor) {
- wl_compositor_destroy(state->compositor);
- }
-
- if (state->registry) {
- wl_registry_destroy(state->registry);
- }
-
- if (state->xkb_state) {
- xkb_state_unref(state->xkb_state);
- }
-
- if (state->xkb_keymap) {
- xkb_keymap_unref(state->xkb_keymap);
- }
-
- if (state->xkb_context) {
- xkb_context_unref(state->xkb_context);
- }
-
- if (state->display) {
- wl_display_flush(state->display);
- wl_display_disconnect(state->display);
- }
-}
-
-int main(void) {
- wayland_state state;
- memset(&state, 0, sizeof(state));
- state.running = true;
- state.frame_ready = true;
- state.buffer_released = true;
-
- state.display = wl_display_connect(NULL);
- if (!state.display) {
- fprintf(stderr, "cannot connect to the Wayland display\n");
- return 1;
- }
- state.xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
- state.registry = wl_display_get_registry(state.display);
- wl_registry_add_listener(state.registry, ®istry_listener, &state);
- if (wl_display_roundtrip(state.display) < 0 || !state.compositor ||
- !state.shm || !state.wm_base) {
- fprintf(stderr, "compositor is missing required Wayland globals\n");
- destroy_wayland(&state);
- return 1;
- }
-
- ta_fb.width = WINDOW_WIDTH;
- ta_fb.height = WINDOW_HEIGHT;
- ta_fb.bpp = WINDOW_BPP;
- ta_main_init();
-
- state.surface = wl_compositor_create_surface(state.compositor);
- state.xdg_surface = xdg_wm_base_get_xdg_surface(state.wm_base, state.surface);
- xdg_surface_add_listener(state.xdg_surface, &xdg_surface_listener, &state);
- state.toplevel = xdg_surface_get_toplevel(state.xdg_surface);
- xdg_toplevel_add_listener(state.toplevel, &toplevel_listener, &state);
- xdg_toplevel_set_title(state.toplevel, ta_title);
- xdg_toplevel_set_app_id(state.toplevel, "tuxanci2");
- xdg_toplevel_set_min_size(state.toplevel, WINDOW_WIDTH, WINDOW_HEIGHT);
- xdg_toplevel_set_max_size(state.toplevel, WINDOW_WIDTH, WINDOW_HEIGHT);
- wl_surface_commit(state.surface);
-
- while (state.running && !state.configured) {
- if (wl_display_dispatch(state.display) < 0) state.running = false;
- }
- if (!state.running || !create_buffer(&state)) {
- destroy_wayland(&state);
- return state.running ? 1 : 0;
- }
- wl_buffer_add_listener(state.buffer, &buffer_listener, &state);
-
- while (state.running) {
- while (state.running && (!state.frame_ready || !state.buffer_released)) {
- if (wl_display_dispatch(state.display) < 0) state.running = false;
- }
- if (!state.running) break;
-
- state.frame_ready = false;
- state.buffer_released = false;
- ta_main_update();
- xdg_toplevel_set_title(state.toplevel, ta_title);
- memcpy(state.pixels, ta_fb.buffers[0], state.buffer_size);
-
- state.frame_callback = wl_surface_frame(state.surface);
- wl_callback_add_listener(state.frame_callback, &frame_listener, &state);
- wl_surface_attach(state.surface, state.buffer, 0, 0);
- wl_surface_damage(state.surface, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
- wl_surface_commit(state.surface);
- if (wl_display_flush(state.display) < 0 && errno != EAGAIN) {
- state.running = false;
- }
- }
-
- destroy_wayland(&state);
- return 0;
-}
-
-void *ta_malloc(ta_size size) {
- return malloc(size);
-}
-
-void ta_free(void *ptr) {
- free(ptr);
-}
-
-ta_fs_file ta_read_file(const char *path) {
- ta_fs_file file = {
- .data = NULL,
- .size = 0
- };
-
- FILE *file_pointer = fopen(path, "rb");
- if (!file_pointer) {
- return file;
- }
-
- if (fseek(file_pointer, 0, SEEK_END) != 0) {
- fclose(file_pointer);
-
- return file;
- }
-
- long file_size = ftell(file_pointer);
- if (file_size < 0) {
- fclose(file_pointer);
-
- return file;
- }
-
- rewind(file_pointer);
-
- file.data = ta_malloc((ta_size)file_size);
- if (!file.data) {
- fclose(file_pointer);
-
- return file;
- }
-
- ta_size bytes_read = fread(file.data, 1, (size_t)file_size, file_pointer);
-
- if (bytes_read != (ta_size)file_size) {
- ta_free(file.data);
- file.data = NULL;
- fclose(file_pointer);
-
- return file;
- }
-
- file.size = (ta_size)file_size;
-
- fclose(file_pointer);
-
- return file;
-}
-
-void ta_close_file(ta_fs_file *file) {
- if (!file) {
- return;
- }
-
- if (file->data) {
- ta_free(file->data);
- file->data = NULL;
- }
-
- file->size = 0;
-}
-
-void ta_exit(int status) {
- exit(status);
-}
diff --git a/platforms/win32/header_banner.bmp b/platforms/win32/header_banner.bmp
Binary files differ.
diff --git a/platforms/win32/installer.ico b/platforms/win32/installer.ico
Binary files differ.
diff --git a/platforms/win32/installer.nsi b/platforms/win32/installer.nsi
@@ -1,67 +0,0 @@
-!include "MUI2.nsh"
-
-!define VERSION "0.30.0"
-
-!ifndef EXE_FILE
- !define EXE_FILE "../../obj/win32/tuxanci2.exe"
-!endif
-!ifndef TAB_FILE
- !define TAB_FILE "../../obj/game/tuxanci2.tab"
-!endif
-!ifndef OUT_FILE
- !define OUT_FILE "tuxanci2-win32-i686.exe"
-!endif
-
-Name "Tuxánci 2 v${VERSION}"
-OutFile "${OUT_FILE}"
-InstallDir "$PROGRAMFILES\tuxanci2"
-
-!define MUI_ICON "installer.ico"
-!define MUI_UNICON "installer.ico"
-
-!define MUI_HEADERIMAGE
-!define MUI_HEADERIMAGE_BITMAP "header_banner.bmp"
-
-!define MUI_WELCOMEPAGE_TITLE "Welcome to the Tuxánci 2 Setup Wizard"
-!define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of Tuxánci 2 v${VERSION}.$\r$\n$\r$\nClick Next to continue."
-
-!insertmacro MUI_PAGE_WELCOME
-!insertmacro MUI_PAGE_LICENSE "../../LICENSE"
-!insertmacro MUI_PAGE_DIRECTORY
-!insertmacro MUI_PAGE_INSTFILES
-!insertmacro MUI_PAGE_FINISH
-
-!insertmacro MUI_UNPAGE_WELCOME
-!insertmacro MUI_UNPAGE_CONFIRM
-!insertmacro MUI_UNPAGE_INSTFILES
-!insertmacro MUI_UNPAGE_FINISH
-
-!insertmacro MUI_LANGUAGE "English"
-
-Section "Core Files"
- SetOutPath "$INSTDIR"
-
- File "${EXE_FILE}"
- File "${TAB_FILE}"
- File "../../LICENSE"
-
- WriteUninstaller "$INSTDIR\uninstall.exe"
-
- WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tuxanci2" "DisplayName" "Tuxánci 2"
- WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tuxanci2" "UninstallString" "$\"$INSTDIR\uninstall.exe$\""
- WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tuxanci2" "QuietUninstallString" "$\"$INSTDIR\uninstall.exe /S$\""
- WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tuxanci2" "InstallLocation" "$INSTDIR"
- WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tuxanci2" "Publisher" "GNUfault"
- WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tuxanci2" "DisplayVersion" "${VERSION}"
- WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tuxanci2" "NoModify" 1
- WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tuxanci2" "NoRepair" 1
-SectionEnd
-
-Section "Uninstall"
- Delete "$INSTDIR\tuxanci2.exe"
- Delete "$INSTDIR\tuxanci2.tab"
- Delete "$INSTDIR\LICENSE"
- Delete "$INSTDIR\uninstall.exe"
-
- RMDir "$INSTDIR"
-SectionEnd
diff --git a/platforms/win32/win32.c b/platforms/win32/win32.c
@@ -1,270 +0,0 @@
-#include "ta_api.h"
-#include <windows.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <stdio.h>
-
-#define WINDOW_WIDTH 800
-#define WINDOW_HEIGHT 600
-#define WINDOW_BPP 32
-#define TARGET_FPS 60
-#define FRAME_TIME_MS (1000 / TARGET_FPS)
-
-static HWND window_handle = NULL;
-static BITMAPINFO bmi;
-static bool is_running = true;
-
-static ta_keyboard_keys key_from_vk(WPARAM vk) {
- if (vk >= 'A' && vk <= 'Z') {
- return (ta_keyboard_keys)(KEY_A + (vk - 'A'));
- }
- if (vk >= '0' && vk <= '9') {
- return (ta_keyboard_keys)(KEY_0 + (vk - '0'));
- }
-
- switch (vk) {
- case VK_BACK: return KEY_BACKSPACE;
- case VK_TAB: return KEY_TAB;
- case VK_RETURN: return KEY_ENTER;
- case VK_ESCAPE: return KEY_ESCAPE;
- case VK_SPACE: return KEY_SPACE;
- case VK_OEM_7: return KEY_APOSTROPHE;
- case VK_OEM_COMMA: return KEY_COMMA;
- case VK_OEM_MINUS: return KEY_MINUS;
- case VK_OEM_PERIOD: return KEY_PERIOD;
- case VK_OEM_2: return KEY_SLASH;
- case VK_OEM_1: return KEY_SEMICOLON;
- case VK_OEM_PLUS: return KEY_EQUALS;
- case VK_OEM_4: return KEY_LEFT_BRACKET;
- case VK_OEM_5: return KEY_BACKSLASH;
- case VK_OEM_6: return KEY_RIGHT_BRACKET;
- case VK_OEM_3: return KEY_GRAVE_ACCENT;
- case VK_DELETE: return KEY_DELETE;
- case VK_UP: return KEY_UP;
- case VK_DOWN: return KEY_DOWN;
- case VK_LEFT: return KEY_LEFT;
- case VK_RIGHT: return KEY_RIGHT;
- case VK_F1: return KEY_F1;
- case VK_F2: return KEY_F2;
- case VK_F3: return KEY_F3;
- case VK_F4: return KEY_F4;
- case VK_F5: return KEY_F5;
- case VK_F6: return KEY_F6;
- case VK_F7: return KEY_F7;
- case VK_F8: return KEY_F8;
- case VK_F9: return KEY_F9;
- case VK_F10: return KEY_F10;
- case VK_F11: return KEY_F11;
- case VK_F12: return KEY_F12;
- case VK_HOME: return KEY_HOME;
- case VK_END: return KEY_END;
- case VK_PRIOR: return KEY_PAGE_UP;
- case VK_NEXT: return KEY_PAGE_DOWN;
- case VK_INSERT: return KEY_INSERT;
- case VK_CAPITAL: return KEY_CAPS_LOCK;
- case VK_NUMLOCK: return KEY_NUM_LOCK;
- case VK_SCROLL: return KEY_SCROLL_LOCK;
- case VK_SNAPSHOT: return KEY_PRINT_SCREEN;
- case VK_PAUSE: return KEY_PAUSE;
- case VK_APPS: return KEY_MENU;
- case VK_SHIFT: return KEY_LEFT_SHIFT;
- case VK_CONTROL: return KEY_LEFT_CTRL;
- case VK_MENU: return KEY_LEFT_ALT;
- case VK_LWIN: return KEY_LEFT_SUPER;
- case VK_RWIN: return KEY_RIGHT_SUPER;
- case VK_NUMPAD0: return KEY_KP_0;
- case VK_NUMPAD1: return KEY_KP_1;
- case VK_NUMPAD2: return KEY_KP_2;
- case VK_NUMPAD3: return KEY_KP_3;
- case VK_NUMPAD4: return KEY_KP_4;
- case VK_NUMPAD5: return KEY_KP_5;
- case VK_NUMPAD6: return KEY_KP_6;
- case VK_NUMPAD7: return KEY_KP_7;
- case VK_NUMPAD8: return KEY_KP_8;
- case VK_NUMPAD9: return KEY_KP_9;
- case VK_DECIMAL: return KEY_KP_DECIMAL;
- case VK_DIVIDE: return KEY_KP_DIVIDE;
- case VK_MULTIPLY: return KEY_KP_MULTIPLY;
- case VK_SUBTRACT: return KEY_KP_SUBTRACT;
- case VK_ADD: return KEY_KP_ADD;
- default: return KEY_NONE;
- }
-}
-
-static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- switch (uMsg) {
- case WM_CLOSE:
- case WM_DESTROY:
- is_running = false;
- PostQuitMessage(0);
- return 0;
-
- case WM_KILLFOCUS:
- ta_keyboard_clear();
- return 0;
-
- case WM_KEYDOWN:
- case WM_SYSKEYDOWN: {
- ta_keyboard_key_down(key_from_vk(wParam));
- return 0;
- }
-
- case WM_KEYUP:
- case WM_SYSKEYUP: {
- ta_keyboard_key_up(key_from_vk(wParam));
- return 0;
- }
- }
- return DefWindowProc(hwnd, uMsg, wParam, lParam);
-}
-
-int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
- (void)hPrevInstance;
- (void)lpCmdLine;
-
- const char* CLASS_NAME = "tuxanci2";
-
- WNDCLASS wc = {0};
- wc.lpfnWndProc = WindowProc;
- wc.hInstance = hInstance;
- wc.lpszClassName = CLASS_NAME;
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
-
- if (!RegisterClass(&wc)) {
- return 1;
- }
-
- DWORD window_style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
-
- RECT wr = {0, 0, WINDOW_WIDTH, WINDOW_HEIGHT};
- AdjustWindowRect(&wr, window_style, FALSE);
-
- window_handle = CreateWindowEx(0, CLASS_NAME, ta_title, window_style, CW_USEDEFAULT, CW_USEDEFAULT, wr.right - wr.left, wr.bottom - wr.top, NULL, NULL, hInstance, NULL);
-
- if (!window_handle) {
- return 1;
- }
-
- ZeroMemory(&bmi, sizeof(bmi));
-
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmi.bmiHeader.biWidth = WINDOW_WIDTH;
- bmi.bmiHeader.biHeight = -WINDOW_HEIGHT;
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biBitCount = WINDOW_BPP;
- bmi.bmiHeader.biCompression = BI_RGB;
- ta_fb.width = WINDOW_WIDTH;
- ta_fb.height = WINDOW_HEIGHT;
- ta_fb.bpp = WINDOW_BPP;
-
- ta_main_init();
-
- ShowWindow(window_handle, nCmdShow);
- UpdateWindow(window_handle);
-
- HDC hdc = GetDC(window_handle);
-
- while (is_running) {
- MSG msg;
-
- while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
- if (msg.message == WM_QUIT) {
- is_running = false;
-
- break;
- }
-
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
- if (!is_running) {
- break;
- }
-
- ta_main_update();
- SetWindowText(window_handle, ta_title);
-
- StretchDIBits(hdc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, ta_fb.buffers[0], &bmi, DIB_RGB_COLORS, SRCCOPY);
-
- Sleep(FRAME_TIME_MS);
- }
-
- ReleaseDC(window_handle, hdc);
- return 0;
-}
-
-void *ta_malloc(ta_size size) {
- return malloc(size);
-}
-
-void ta_free(void *ptr) {
- free(ptr);
-}
-
-ta_fs_file ta_read_file(const char *path) {
- ta_fs_file file = {
- .data = NULL,
- .size = 0
- };
-
- FILE *file_pointer = fopen(path, "rb");
- if (!file_pointer) {
- return file;
- }
-
- if (fseek(file_pointer, 0, SEEK_END) != 0) {
- fclose(file_pointer);
-
- return file;
- }
-
- long file_size = ftell(file_pointer);
- if (file_size < 0) {
- fclose(file_pointer);
-
- return file;
- }
-
- rewind(file_pointer);
-
- file.data = ta_malloc((ta_size)file_size);
- if (!file.data) {
- fclose(file_pointer);
-
- return file;
- }
-
- ta_size bytes_read = fread(file.data, 1, (size_t)file_size, file_pointer);
-
- if (bytes_read != (ta_size)file_size) {
- ta_free(file.data);
- file.data = NULL;
- fclose(file_pointer);
-
- return file;
- }
-
- file.size = (ta_size)file_size;
-
- fclose(file_pointer);
-
- return file;
-}
-
-void ta_close_file(ta_fs_file *file) {
- if (!file) {
- return;
- }
-
- if (file->data) {
- ta_free(file->data);
- file->data = NULL;
- }
-
- file->size = 0;
-}
-
-void ta_exit(int status) {
- exit(status);
-}
diff --git a/platforms/x11/x11.c b/platforms/x11/x11.c
@@ -1,268 +0,0 @@
-#include "ta_api.h"
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/keysym.h>
-
-#define WINDOW_WIDTH 800
-#define WINDOW_HEIGHT 600
-#define WINDOW_BPP 32
-#define TARGET_FPS 60
-#define FRAME_TIME (1000000 / TARGET_FPS)
-
-static ta_keyboard_keys key_from_keysym(KeySym symbol) {
- if (symbol >= XK_a && symbol <= XK_z) {
- return (ta_keyboard_keys)(KEY_A + symbol - XK_a);
- }
- if (symbol >= XK_A && symbol <= XK_Z) {
- return (ta_keyboard_keys)(KEY_A + symbol - XK_A);
- }
- if (symbol >= XK_0 && symbol <= XK_9) {
- return (ta_keyboard_keys)(KEY_0 + symbol - XK_0);
- }
-
- switch (symbol) {
- case XK_BackSpace: return KEY_BACKSPACE;
- case XK_Tab: return KEY_TAB;
- case XK_Return: return KEY_ENTER;
- case XK_Escape: return KEY_ESCAPE;
- case XK_space: return KEY_SPACE;
- case XK_exclam: return KEY_EXCLAMATION_MARK;
- case XK_quotedbl: return KEY_QUOTATION_MARK;
- case XK_numbersign: return KEY_HASH;
- case XK_dollar: return KEY_DOLLAR_SIGN;
- case XK_percent: return KEY_PERCENT_SIGN;
- case XK_ampersand: return KEY_AMPERSAND;
- case XK_apostrophe: return KEY_APOSTROPHE;
- case XK_parenleft: return KEY_LEFT_PARENTHESIS;
- case XK_parenright: return KEY_RIGHT_PARENTHESIS;
- case XK_asterisk: return KEY_ASTERISK;
- case XK_plus: return KEY_PLUS;
- case XK_comma: return KEY_COMMA;
- case XK_minus: return KEY_MINUS;
- case XK_period: return KEY_PERIOD;
- case XK_slash: return KEY_SLASH;
- case XK_colon: return KEY_COLON;
- case XK_semicolon: return KEY_SEMICOLON;
- case XK_less: return KEY_LESS_THAN;
- case XK_equal: return KEY_EQUALS;
- case XK_greater: return KEY_GREATER_THAN;
- case XK_question: return KEY_QUESTION_MARK;
- case XK_at: return KEY_AT_SIGN;
- case XK_bracketleft: return KEY_LEFT_BRACKET;
- case XK_backslash: return KEY_BACKSLASH;
- case XK_bracketright: return KEY_RIGHT_BRACKET;
- case XK_asciicircum: return KEY_CARET;
- case XK_underscore: return KEY_UNDERSCORE;
- case XK_grave: return KEY_GRAVE_ACCENT;
- case XK_braceleft: return KEY_LEFT_BRACE;
- case XK_bar: return KEY_PIPE;
- case XK_braceright: return KEY_RIGHT_BRACE;
- case XK_asciitilde: return KEY_TILDE;
- case XK_Delete: return KEY_DELETE;
- case XK_Up: return KEY_UP;
- case XK_Down: return KEY_DOWN;
- case XK_Left: return KEY_LEFT;
- case XK_Right: return KEY_RIGHT;
- case XK_F1: return KEY_F1;
- case XK_F2: return KEY_F2;
- case XK_F3: return KEY_F3;
- case XK_F4: return KEY_F4;
- case XK_F5: return KEY_F5;
- case XK_F6: return KEY_F6;
- case XK_F7: return KEY_F7;
- case XK_F8: return KEY_F8;
- case XK_F9: return KEY_F9;
- case XK_F10: return KEY_F10;
- case XK_F11: return KEY_F11;
- case XK_F12: return KEY_F12;
- case XK_Home: return KEY_HOME;
- case XK_End: return KEY_END;
- case XK_Page_Up: return KEY_PAGE_UP;
- case XK_Page_Down: return KEY_PAGE_DOWN;
- case XK_Insert: return KEY_INSERT;
- case XK_Caps_Lock: return KEY_CAPS_LOCK;
- case XK_Num_Lock: return KEY_NUM_LOCK;
- case XK_Scroll_Lock: return KEY_SCROLL_LOCK;
- case XK_Print: return KEY_PRINT_SCREEN;
- case XK_Pause: return KEY_PAUSE;
- case XK_Menu: return KEY_MENU;
- case XK_Shift_L: return KEY_LEFT_SHIFT;
- case XK_Shift_R: return KEY_RIGHT_SHIFT;
- case XK_Control_L: return KEY_LEFT_CTRL;
- case XK_Control_R: return KEY_RIGHT_CTRL;
- case XK_Alt_L: return KEY_LEFT_ALT;
- case XK_Alt_R: return KEY_RIGHT_ALT;
- case XK_Super_L: return KEY_LEFT_SUPER;
- case XK_Super_R: return KEY_RIGHT_SUPER;
- case XK_KP_0: return KEY_KP_0;
- case XK_KP_1: return KEY_KP_1;
- case XK_KP_2: return KEY_KP_2;
- case XK_KP_3: return KEY_KP_3;
- case XK_KP_4: return KEY_KP_4;
- case XK_KP_5: return KEY_KP_5;
- case XK_KP_6: return KEY_KP_6;
- case XK_KP_7: return KEY_KP_7;
- case XK_KP_8: return KEY_KP_8;
- case XK_KP_9: return KEY_KP_9;
- case XK_KP_Decimal: return KEY_KP_DECIMAL;
- case XK_KP_Divide: return KEY_KP_DIVIDE;
- case XK_KP_Multiply: return KEY_KP_MULTIPLY;
- case XK_KP_Subtract: return KEY_KP_SUBTRACT;
- case XK_KP_Add: return KEY_KP_ADD;
- case XK_KP_Enter: return KEY_KP_ENTER;
- case XK_KP_Equal: return KEY_KP_EQUALS;
- default: return KEY_NONE;
- }
-}
-
-int main(void) {
- Display *display = XOpenDisplay(NULL);
- if (!display) {
- return 1;
- }
-
- int screen = DefaultScreen(display);
- Window root = RootWindow(display, screen);
-
- ta_fb.width = WINDOW_WIDTH;
- ta_fb.height = WINDOW_HEIGHT;
- ta_fb.bpp = WINDOW_BPP;
-
- ta_main_init();
-
- Window win = XCreateSimpleWindow(display, root, 0, 0, ta_fb.width, ta_fb.height, 0, BlackPixel(display, screen), WhitePixel(display, screen));
- XStoreName(display, win, ta_title);
-
- XSizeHints *hints = XAllocSizeHints();
- if (hints) {
- hints->flags = PMinSize | PMaxSize;
- hints->min_width = WINDOW_WIDTH;
- hints->min_height = WINDOW_HEIGHT;
- hints->max_width = WINDOW_WIDTH;
- hints->max_height = WINDOW_HEIGHT;
-
- XSetWMNormalHints(display, win, hints);
-
- XFree(hints);
- }
-
- XSelectInput(display, win, ExposureMask | KeyPressMask | KeyReleaseMask | FocusChangeMask);
- XMapWindow(display, win);
-
- Visual *visual = DefaultVisual(display, screen);
- int depth = DefaultDepth(display, screen);
-
- XImage *ximage = XCreateImage(display, visual, depth, ZPixmap, 0, (char *)ta_fb.buffers[0], ta_fb.width, ta_fb.height, ta_fb.bpp, 0);
-
- GC gc = DefaultGC(display, screen);
-
- while (1) {
- while (XPending(display) > 0) {
- XEvent event;
- XNextEvent(display, &event);
- if (event.type == KeyPress) {
- ta_keyboard_key_down(key_from_keysym(XLookupKeysym(&event.xkey, 0)));
- } else if (event.type == KeyRelease) {
- ta_keyboard_key_up(key_from_keysym(XLookupKeysym(&event.xkey, 0)));
- } else if (event.type == FocusOut) {
- ta_keyboard_clear();
- }
- }
-
- ta_main_update();
- XStoreName(display, win, ta_title);
-
- ximage->data = (char *)ta_fb.buffers[0];
- XPutImage(display, win, gc, ximage, 0, 0, 0, 0, ta_fb.width, ta_fb.height);
- XFlush(display);
-
- usleep(FRAME_TIME);
- }
-
- XDestroyWindow(display, win);
- XCloseDisplay(display);
- return 0;
-}
-
-void *ta_malloc(ta_size size) {
- return malloc(size);
-}
-
-void *ta_realloc(void *ptr, ta_size new_size) {
- return realloc(ptr, new_size);
-}
-
-void ta_free(void *ptr) {
- free(ptr);
-}
-
-ta_fs_file ta_read_file(const char *path) {
- ta_fs_file file = {
- .data = NULL,
- .size = 0
- };
-
- FILE *file_pointer = fopen(path, "rb");
- if (!file_pointer) {
- return file;
- }
-
- if (fseek(file_pointer, 0, SEEK_END) != 0) {
- fclose(file_pointer);
-
- return file;
- }
-
- long file_size = ftell(file_pointer);
- if (file_size == -1) {
- fclose(file_pointer);
-
- return file;
- }
-
- rewind(file_pointer);
-
- file.data = ta_malloc(file_size);
- if (!file.data) {
- fclose(file_pointer);
-
- return file;
- }
-
- ta_size element_size = 1;
- ta_size bytes_read = fread(file.data, element_size, file_size, file_pointer);
-
- if (bytes_read != (ta_size)file_size) {
- ta_free(file.data);
- file.data = NULL;
- fclose(file_pointer);
-
- return file;
- }
-
- file.size = file_size;
-
- fclose(file_pointer);
-
- return file;
-}
-
-void ta_close_file(ta_fs_file *file) {
- if (!file) {
- return;
- }
-
- if (file->data) {
- ta_free(file->data);
- file->data = NULL;
- }
-
- file->size = 0;
-}
-
-void ta_exit(int status) {
- exit(status);
-}
diff --git a/platforms/xbox/nxdk b/platforms/xbox/nxdk
@@ -1 +0,0 @@
-Subproject commit 14d5ee97e73347c973f1f57b68b79ec08c9e77f2
diff --git a/platforms/xbox/xbox.c b/platforms/xbox/xbox.c
@@ -1,182 +0,0 @@
-#include "ta_api.h"
-#include <SDL.h>
-#include <hal/video.h>
-#include <windows.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#define SCREEN_WIDTH 640
-#define SCREEN_HEIGHT 480
-#define WINDOW_BPP 32
-#define TARGET_FPS 60
-#define FRAME_TIME_MS (1000 / TARGET_FPS)
-
-static SDL_GameController *open_controller(void) {
- for (int i = 0; i < SDL_NumJoysticks(); i++) {
- if (SDL_IsGameController(i)) {
- return SDL_GameControllerOpen(i);
- }
- }
-
- return NULL;
-}
-
-static void update_controller_input(SDL_GameController *controller) {
- SDL_GameControllerUpdate();
-
- ta_keyboard_keys keys[] = {
- KEY_UP,
- KEY_DOWN,
- KEY_LEFT,
- KEY_RIGHT,
- KEY_ENTER
- };
-
- SDL_GameControllerButton buttons[] = {
- SDL_CONTROLLER_BUTTON_DPAD_UP,
- SDL_CONTROLLER_BUTTON_DPAD_DOWN,
- SDL_CONTROLLER_BUTTON_DPAD_LEFT,
- SDL_CONTROLLER_BUTTON_DPAD_RIGHT,
- SDL_CONTROLLER_BUTTON_A
- };
-
- for (int i = 0; i < 5; i++) {
- if (controller && SDL_GameControllerGetButton(controller, buttons[i])) {
- ta_keyboard_key_down(keys[i]);
- } else {
- ta_keyboard_key_up(keys[i]);
- }
- }
-}
-
-int main(void) {
- if (SDL_Init(SDL_INIT_GAMECONTROLLER) != 0) {
- return 1;
- }
-
- if (!XVideoSetMode(SCREEN_WIDTH, SCREEN_HEIGHT, WINDOW_BPP, REFRESH_DEFAULT)) {
- SDL_Quit();
- return 1;
- }
-
- ta_display->width = SCREEN_WIDTH;
- ta_display->height = SCREEN_HEIGHT;
- ta_display->bpp = WINDOW_BPP;
-
- ta_main_init();
- SDL_GameController *controller = open_controller();
-
- while (1) {
- SDL_Event event;
- while (SDL_PollEvent(&event)) {
- if (event.type == SDL_CONTROLLERDEVICEADDED && !controller) {
- controller = SDL_GameControllerOpen(event.cdevice.which);
- } else if (event.type == SDL_CONTROLLERDEVICEREMOVED && controller) {
- SDL_Joystick *joystick = SDL_GameControllerGetJoystick(controller);
- if (SDL_JoystickInstanceID(joystick) == event.cdevice.which) {
- SDL_GameControllerClose(controller);
- controller = NULL;
- }
- }
- }
-
- if (!controller) {
- controller = open_controller();
- }
-
- update_controller_input(controller);
- ta_main_update();
-
- uint32_t *dest = (uint32_t *)XVideoGetFB();
- uint32_t *src = (uint32_t *)ta_display->buffers[0];
-
- if (dest && src) {
- for (int i = 0; i < SCREEN_WIDTH * SCREEN_HEIGHT; i++) {
- dest[i] = src[i];
- }
- }
-
- XVideoFlushFB();
- Sleep(FRAME_TIME_MS);
- }
-
- SDL_GameControllerClose(controller);
- SDL_Quit();
- return 0;
-}
-
-void *ta_malloc(ta_size size) {
- return malloc(size);
-}
-
-void ta_free(void *ptr) {
- free(ptr);
-}
-
-ta_fs_file ta_read_file(const char *path) {
- ta_fs_file file = {
- .data = NULL,
- .size = 0
- };
-
- FILE *file_pointer = fopen(path, "rb");
- if (!file_pointer) {
- return file;
- }
-
- if (fseek(file_pointer, 0, SEEK_END) != 0) {
- fclose(file_pointer);
-
- return file;
- }
-
- long file_size = ftell(file_pointer);
- if (file_size < 0) {
- fclose(file_pointer);
-
- return file;
- }
-
- rewind(file_pointer);
-
- file.data = ta_malloc((ta_size)file_size);
- if (!file.data) {
- fclose(file_pointer);
-
- return file;
- }
-
- ta_size bytes_read = fread(file.data, 1, (size_t)file_size, file_pointer);
-
- if (bytes_read != (ta_size)file_size) {
- ta_free(file.data);
- file.data = NULL;
- fclose(file_pointer);
-
- return file;
- }
-
- file.size = (ta_size)file_size;
-
- fclose(file_pointer);
-
- return file;
-}
-
-void ta_close_file(ta_fs_file *file) {
- if (!file) {
- return;
- }
-
- if (file->data) {
- ta_free(file->data);
- file->data = NULL;
- }
-
- file->size = 0;
-}
-
-void ta_exit(int status) {
- exit(status);
-}
diff --git a/sdk/LICENSE b/sdk/LICENSE
@@ -1,18 +0,0 @@
-MIT License
-
-Copyright (c) 2026 Connor Thomson
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
-associated documentation files (the "Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
-following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial
-portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
-LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
-EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/sdk/include/stdbool.h b/sdk/include/stdbool.h
@@ -1,10 +0,0 @@
-#ifndef TA_STDBOOL_H
-#define TA_STDBOOL_H
-
-#define bool _Bool
-#define true 1
-#define false 0
-
-#define __bool_true_false_are_defined 1
-
-#endif // TA_STDBOOL_H
diff --git a/sdk/include/stddef.h b/sdk/include/stddef.h
@@ -1,8 +0,0 @@
-#ifndef TA_STDDEF_H
-#define TA_STDDEF_H
-
-#define NULL ((void*)0)
-
-typedef unsigned long size_t;
-
-#endif // TA_STDDEF_H
diff --git a/sdk/include/stdint.h b/sdk/include/stdint.h
@@ -1,12 +0,0 @@
-#ifndef TA_STDINT_H
-#define TA_STDINT_H
-
-typedef unsigned char uint8_t;
-typedef unsigned short uint16_t;
-typedef unsigned int uint32_t;
-
-typedef signed char int8_t;
-typedef short int16_t;
-typedef int int32_t;
-
-#endif // TA_STDINT_H
diff --git a/sdk/include/stdlib.h b/sdk/include/stdlib.h
@@ -1,20 +0,0 @@
-#ifndef TA_STDLIB_H
-#define TA_STDLIB_H
-
-#include <tuxanci2/syscall.h>
-#include <tuxanci2/abi.h>
-#include <stdint.h>
-#include <stddef.h>
-
-void *malloc(size_t size);
-void *calloc(size_t count, size_t size);
-void *realloc(void *ptr, size_t size);
-void free(void *ptr);
-
-static inline void exit(int status) {
- ta_syscall(TA_SYS_EXIT, (uint32_t)status, 0, 0, 0, 0, 0);
-
- while (1) {}
-}
-
-#endif // TA_STDLIB_H
diff --git a/sdk/include/string.h b/sdk/include/string.h
@@ -1,11 +0,0 @@
-#ifndef TA_STRING_H
-#define TA_STRING_H
-
-#include <stddef.h>
-
-void *memcpy(void *destination, const void *source, size_t count);
-void *memmove(void *destination, const void *source, size_t count);
-void *memset(void *destination, int value, size_t count);
-int memcmp(const void *first, const void *second, size_t count);
-
-#endif // TA_STRING_H
diff --git a/sdk/include/tuxanci2/abi.h b/sdk/include/tuxanci2/abi.h
@@ -1,25 +0,0 @@
-#ifndef TA_ABI_H
-#define TA_ABI_H
-
-#define TA_SYS_EXIT 0
-#define TA_SYS_READY 1
-#define TA_SYS_RETURN 2
-#define TA_SYS_DISPLAY_WIDTH 3
-#define TA_SYS_DISPLAY_HEIGHT 4
-#define TA_SYS_DISPLAY_SPRITE_MODE 5
-#define TA_SYS_KEYBOARD_IS_DOWN 10
-#define TA_SYS_IMAGE_INIT 11
-#define TA_SYS_IMAGE_DRAW 12
-#define TA_SYS_IMAGE_GET_SIZE 13
-#define TA_SYS_TEXT_CREATE 14
-#define TA_SYS_TEXT_WIDTH 15
-#define TA_SYS_TEXT_HEIGHT 16
-#define TA_SYS_TEXT_DRAW 17
-#define TA_SYS_TEXT_DESTROY 18
-#define TA_SYS_SCREEN_REGISTER 19
-#define TA_SYS_SCREEN_SWITCH 20
-
-#define TA_ASSET_BG 0
-#define TA_ASSET_LOADING_LOGO 1
-
-#endif // TA_ABI_H
diff --git a/sdk/include/tuxanci2/display.h b/sdk/include/tuxanci2/display.h
@@ -1,23 +0,0 @@
-#ifndef TA_DISPLAY_H
-#define TA_DISPLAY_H
-
-#include <tuxanci2/syscall.h>
-#include <tuxanci2/abi.h>
-#include <stdint.h>
-#include <stdbool.h>
-
-#define TA_DISPLAY_RGB(red, green, blue) ((((uint32_t)(red) & 255u) << 16) | (((uint32_t)(green) & 255u) << 8) | ((uint32_t)(blue) & 255u))
-
-static inline uint32_t ta_display_width(void) {
- return ta_syscall(TA_SYS_DISPLAY_WIDTH, 0, 0, 0, 0, 0, 0);
-}
-
-static inline uint32_t ta_display_height(void) {
- return ta_syscall(TA_SYS_DISPLAY_HEIGHT, 0, 0, 0, 0, 0, 0);
-}
-
-static inline bool ta_display_sprite_mode(void) {
- return ta_syscall(TA_SYS_DISPLAY_SPRITE_MODE, 0, 0, 0, 0, 0, 0) != 0;
-}
-
-#endif // TA_DISPLAY_H
diff --git a/sdk/include/tuxanci2/fixed.h b/sdk/include/tuxanci2/fixed.h
@@ -1,10 +0,0 @@
-#ifndef TA_FIXED_H
-#define TA_FIXED_H
-
-#include <stdint.h>
-
-typedef uint32_t ta_fixed;
-
-#define TA_FIXED(value) ((ta_fixed)((value) * 65536.0 + 0.5))
-
-#endif // TA_FIXED_H
diff --git a/sdk/include/tuxanci2/image.h b/sdk/include/tuxanci2/image.h
@@ -1,23 +0,0 @@
-#ifndef TA_IMAGE_H
-#define TA_IMAGE_H
-
-#include <tuxanci2/syscall.h>
-#include <tuxanci2/abi.h>
-#include <tuxanci2/fixed.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <stddef.h>
-
-static inline bool ta_image_init(uint32_t asset) {
- return ta_syscall(TA_SYS_IMAGE_INIT, asset, 0, 0, 0, 0, 0) != 0;
-}
-
-static inline bool ta_image_draw(uint32_t asset, ta_fixed x, ta_fixed y, ta_fixed width, ta_fixed height, uint32_t frame) {
- return ta_syscall(TA_SYS_IMAGE_DRAW, asset, x, y, width, height, frame) != 0;
-}
-
-static inline bool ta_image_get_size(uint32_t asset, uint32_t *width, uint32_t *height) {
- return ta_syscall(TA_SYS_IMAGE_GET_SIZE, asset, (uint32_t)(size_t)width, (uint32_t)(size_t)height, 0, 0, 0) != 0;
-}
-
-#endif // TA_IMAGE_H
diff --git a/sdk/include/tuxanci2/keyboard.h b/sdk/include/tuxanci2/keyboard.h
@@ -1,144 +0,0 @@
-#ifndef TA_KEYBOARD_H
-#define TA_KEYBOARD_H
-
-#include <tuxanci2/display.h>
-#include <tuxanci2/abi.h>
-#include <stdint.h>
-#include <stdbool.h>
-
-typedef enum {
- KEY_NONE = 0,
- KEY_BACKSPACE = 8,
- KEY_TAB = 9,
- KEY_ENTER = 13,
- KEY_ESCAPE = 27,
- KEY_SPACE = 32,
- KEY_EXCLAMATION_MARK = 33,
- KEY_QUOTATION_MARK = 34,
- KEY_HASH = 35,
- KEY_DOLLAR_SIGN = 36,
- KEY_PERCENT_SIGN = 37,
- KEY_AMPERSAND = 38,
- KEY_APOSTROPHE = 39,
- KEY_LEFT_PARENTHESIS = 40,
- KEY_RIGHT_PARENTHESIS = 41,
- KEY_ASTERISK = 42,
- KEY_PLUS = 43,
- KEY_COMMA = 44,
- KEY_MINUS = 45,
- KEY_PERIOD = 46,
- KEY_SLASH = 47,
- KEY_0 = 48,
- KEY_1 = 49,
- KEY_2 = 50,
- KEY_3 = 51,
- KEY_4 = 52,
- KEY_5 = 53,
- KEY_6 = 54,
- KEY_7 = 55,
- KEY_8 = 56,
- KEY_9 = 57,
- KEY_COLON = 58,
- KEY_SEMICOLON = 59,
- KEY_LESS_THAN = 60,
- KEY_EQUALS = 61,
- KEY_GREATER_THAN = 62,
- KEY_QUESTION_MARK = 63,
- KEY_AT_SIGN = 64,
- KEY_A = 97,
- KEY_B = 98,
- KEY_C = 99,
- KEY_D = 100,
- KEY_E = 101,
- KEY_F = 102,
- KEY_G = 103,
- KEY_H = 104,
- KEY_I = 105,
- KEY_J = 106,
- KEY_K = 107,
- KEY_L = 108,
- KEY_M = 109,
- KEY_N = 110,
- KEY_O = 111,
- KEY_P = 112,
- KEY_Q = 113,
- KEY_R = 114,
- KEY_S = 115,
- KEY_T = 116,
- KEY_U = 117,
- KEY_V = 118,
- KEY_W = 119,
- KEY_X = 120,
- KEY_Y = 121,
- KEY_Z = 122,
- KEY_LEFT_BRACKET = 91,
- KEY_BACKSLASH = 92,
- KEY_RIGHT_BRACKET = 93,
- KEY_CARET = 94,
- KEY_UNDERSCORE = 95,
- KEY_GRAVE_ACCENT = 96,
- KEY_LEFT_BRACE = 123,
- KEY_PIPE = 124,
- KEY_RIGHT_BRACE = 125,
- KEY_TILDE = 126,
- KEY_DELETE = 127,
- KEY_UP = 128,
- KEY_DOWN = 129,
- KEY_LEFT = 130,
- KEY_RIGHT = 131,
- KEY_F1 = 132,
- KEY_F2 = 133,
- KEY_F3 = 134,
- KEY_F4 = 135,
- KEY_F5 = 136,
- KEY_F6 = 137,
- KEY_F7 = 138,
- KEY_F8 = 139,
- KEY_F9 = 140,
- KEY_F10 = 141,
- KEY_F11 = 142,
- KEY_F12 = 143,
- KEY_HOME = 144,
- KEY_END = 145,
- KEY_PAGE_UP = 146,
- KEY_PAGE_DOWN = 147,
- KEY_INSERT = 148,
- KEY_CAPS_LOCK = 149,
- KEY_NUM_LOCK = 150,
- KEY_SCROLL_LOCK = 151,
- KEY_PRINT_SCREEN = 152,
- KEY_PAUSE = 153,
- KEY_MENU = 154,
- KEY_LEFT_SHIFT = 155,
- KEY_RIGHT_SHIFT = 156,
- KEY_LEFT_CTRL = 157,
- KEY_RIGHT_CTRL = 158,
- KEY_LEFT_ALT = 159,
- KEY_RIGHT_ALT = 160,
- KEY_LEFT_SUPER = 161,
- KEY_RIGHT_SUPER = 162,
- KEY_KP_0 = 163,
- KEY_KP_1 = 164,
- KEY_KP_2 = 165,
- KEY_KP_3 = 166,
- KEY_KP_4 = 167,
- KEY_KP_5 = 168,
- KEY_KP_6 = 169,
- KEY_KP_7 = 170,
- KEY_KP_8 = 171,
- KEY_KP_9 = 172,
- KEY_KP_DECIMAL = 173,
- KEY_KP_DIVIDE = 174,
- KEY_KP_MULTIPLY = 175,
- KEY_KP_SUBTRACT = 176,
- KEY_KP_ADD = 177,
- KEY_KP_ENTER = 178,
- KEY_KP_EQUALS = 179
-} ta_keyboard_keys;
-
-static inline bool ta_keyboard_is_down(ta_keyboard_keys key) {
- return ta_syscall(TA_SYS_KEYBOARD_IS_DOWN, (uint32_t)key, 0, 0, 0, 0, 0) != 0;
-}
-
-
-#endif // TA_KEYBOARD_H
diff --git a/sdk/include/tuxanci2/screen.h b/sdk/include/tuxanci2/screen.h
@@ -1,22 +0,0 @@
-#ifndef TA_SCREEN_H
-#define TA_SCREEN_H
-
-#include <tuxanci2/syscall.h>
-#include <tuxanci2/abi.h>
-#include <stdint.h>
-#include <stddef.h>
-#include <stdbool.h>
-
-typedef void (*ta_screen_init_function)(void);
-typedef void (*ta_screen_update_function)(void);
-typedef void (*ta_screen_destroy_function)(void);
-
-static inline bool ta_screen_register(uint32_t id, ta_screen_init_function init, ta_screen_update_function update, ta_screen_destroy_function destroy) {
- return ta_syscall(TA_SYS_SCREEN_REGISTER, id, (uint32_t)(size_t)init, (uint32_t)(size_t)update, (uint32_t)(size_t)destroy, 0, 0) != 0;
-}
-
-static inline bool ta_screen_switch(uint32_t id) {
- return ta_syscall(TA_SYS_SCREEN_SWITCH, id, 0, 0, 0, 0, 0) != 0;
-}
-
-#endif // TA_SCREEN_H
diff --git a/sdk/include/tuxanci2/syscall.h b/sdk/include/tuxanci2/syscall.h
@@ -1,20 +0,0 @@
-#ifndef TA_SYSCALL_H
-#define TA_SYSCALL_H
-
-#include <stdint.h>
-
-static inline uint32_t ta_syscall(uint32_t number, uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4, uint32_t arg5) {
- register uint32_t reg0 __asm__("a0") = arg0;
- register uint32_t reg1 __asm__("a1") = arg1;
- register uint32_t reg2 __asm__("a2") = arg2;
- register uint32_t reg3 __asm__("a3") = arg3;
- register uint32_t reg4 __asm__("a4") = arg4;
- register uint32_t reg5 __asm__("a5") = arg5;
- register uint32_t reg7 __asm__("a7") = number;
-
- __asm__ volatile("ecall" : "+r"(reg0) : "r"(reg1), "r"(reg2), "r"(reg3), "r"(reg4), "r"(reg5), "r"(reg7) : "memory");
-
- return reg0;
-}
-
-#endif // TA_SYSCALL_H
diff --git a/sdk/include/tuxanci2/text.h b/sdk/include/tuxanci2/text.h
@@ -1,31 +0,0 @@
-#ifndef TA_TEXT_H
-#define TA_TEXT_H
-
-#include <tuxanci2/syscall.h>
-#include <tuxanci2/abi.h>
-#include <stdint.h>
-#include <stddef.h>
-
-typedef uint32_t ta_text;
-
-static inline ta_text ta_text_create(const char *text, uint32_t size, uint32_t color, uint32_t border_width, uint32_t border_color) {
- return ta_syscall(TA_SYS_TEXT_CREATE, (uint32_t)(size_t)text, size, color, border_width, border_color, 0);
-}
-
-static inline uint32_t ta_text_width(ta_text text) {
- return ta_syscall(TA_SYS_TEXT_WIDTH, text, 0, 0, 0, 0, 0);
-}
-
-static inline uint32_t ta_text_height(ta_text text) {
- return ta_syscall(TA_SYS_TEXT_HEIGHT, text, 0, 0, 0, 0, 0);
-}
-
-static inline void ta_text_draw(ta_text text, uint32_t x, uint32_t y) {
- ta_syscall(TA_SYS_TEXT_DRAW, text, x, y, 0, 0, 0);
-}
-
-static inline void ta_text_destroy(ta_text text) {
- ta_syscall(TA_SYS_TEXT_DESTROY, text, 0, 0, 0, 0, 0);
-}
-
-#endif // TA_TEXT_H
diff --git a/sdk/linker.ld b/sdk/linker.ld
@@ -1,43 +0,0 @@
-OUTPUT_ARCH(riscv)
-ENTRY(_start)
-
-PROVIDE(__ram_size = 0x10000);
-PROVIDE(__stack_size = 0x2000);
-__heap_end = __ram_size - __stack_size;
-
-SECTIONS {
- . = 0;
-
- .magic_number : {
- BYTE(0x54) /* T */
- BYTE(0x41) /* A */
- BYTE(0x42) /* B */
- BYTE(0x43) /* C */
- }
-
- .text : {
- KEEP(*(.text.start))
- *(.text .text.*)
- }
-
- .rodata : {
- *(.rodata .rodata.* .srodata .srodata.*)
- }
-
- .data : {
- *(.data .data.* .sdata .sdata.*)
- }
-
- .bss : {
- *(.bss .bss.* .sbss .sbss.* COMMON)
- }
-
- . = ALIGN(8);
- __heap_start = .;
-
- /DISCARD/ : {
- *
- }
-
- ASSERT(__heap_start + 64 <= __heap_end, "no room left for heap")
-}
diff --git a/sdk/sdk.mk b/sdk/sdk.mk
@@ -1,63 +0,0 @@
-
-CROSS ?= riscv32-unknown-elf-
-
-CC := $(CROSS)gcc
-OBJCOPY := $(CROSS)objcopy
-
-BUILD := build
-SDK_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
-
-OPT := 2
-MARCH := rv32im
-MABI := ilp32
-
-LINKER_SCRIPT := linker.ld
-
-CFLAGS := -O$(OPT) -march=$(MARCH) -mabi=$(MABI) -ffreestanding -nostdinc -fno-builtin -fno-pic -fno-stack-protector -fno-tree-loop-distribute-patterns -Wall -Wextra -I$(SDK_DIR)include -I$(SDK_DIR)../include
-ASFLAGS := -march=$(MARCH) -mabi=$(MABI) -I$(SDK_DIR)include -I$(SDK_DIR)../include
-LDFLAGS := -march=$(MARCH) -mabi=$(MABI) -nostdlib -static -T $(SDK_DIR)$(LINKER_SCRIPT) -Wl,--gc-sections
-
-SDK_SRCS := $(shell find $(SDK_DIR)src -type f \( -name '*.c' -o -name '*.S' \))
-GAME_SRCS := $(shell find src -type f \( -name '*.c' -o -name '*.S' \))
-
-SDK_OBJS := $(patsubst $(SDK_DIR)%, $(BUILD)/sdk/%, $(SDK_SRCS))
-GAME_OBJS := $(patsubst %, $(BUILD)/game/%, $(GAME_SRCS))
-
-OBJS := $(SDK_OBJS:.c=.o)
-OBJS := $(OBJS:.S=.o)
-GAME_OBJS := $(GAME_OBJS:.c=.o)
-GAME_OBJS := $(GAME_OBJS:.S=.o)
-OBJS += $(GAME_OBJS)
-
-DEPS := $(OBJS:.o=.d)
-
-all: $(BUILD)/$(TARGET).tab
-
-$(BUILD)/$(TARGET).tab: $(BUILD)/$(TARGET).elf
- $(OBJCOPY) -O binary $< $@
-
-$(BUILD)/$(TARGET).elf: $(OBJS)
- $(CC) $(LDFLAGS) $^ -o $@
-
-$(BUILD)/sdk/%.o: $(SDK_DIR)%.c
- @mkdir -p $(@D)
- $(CC) $(CFLAGS) -MMD -MP -c $< -o $@
-
-$(BUILD)/sdk/%.o: $(SDK_DIR)%.S
- @mkdir -p $(@D)
- $(CC) $(ASFLAGS) -MMD -MP -c $< -o $@
-
-$(BUILD)/game/%.o: %.c
- @mkdir -p $(@D)
- $(CC) $(CFLAGS) -MMD -MP -c $< -o $@
-
-$(BUILD)/game/%.o: %.S
- @mkdir -p $(@D)
- $(CC) $(ASFLAGS) -MMD -MP -c $< -o $@
-
-clean:
- rm -rf $(BUILD)
-
--include $(DEPS)
-
-.PHONY: all clean
diff --git a/sdk/src/crt0.c b/sdk/src/crt0.c
@@ -1,21 +0,0 @@
-#include <stdint.h>
-#include <stddef.h>
-#include <tuxanci2/abi.h>
-#include <tuxanci2/syscall.h>
-
-extern int main(void);
-
-static inline void ta_ready(void (*stub)(uint32_t)) {
- ta_syscall(TA_SYS_READY, (uint32_t)(size_t)stub, 0, 0, 0, 0, 0);
-}
-
-static inline void ta_return(uint32_t value) {
- ta_syscall(TA_SYS_RETURN, value, 0, 0, 0, 0, 0);
-
- while (1) {}
-}
-
-__attribute__((section(".text.start"))) void _start(void) {
- main();
- ta_ready(ta_return);
-}
diff --git a/sdk/src/stdlib.c b/sdk/src/stdlib.c
@@ -1,259 +0,0 @@
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include <stddef.h>
-
-#define HEAP_ALIGNMENT 8u
-#define HEADER_SIZE 8u
-#define MIN_BLOCK 16u
-#define MAX_REQUEST 0x7FFFFFF0u
-#define USED_MAGIC 0xA110C8EDu
-
-typedef struct free_block free_block;
-
-struct free_block {
- uint32_t size;
- uint32_t used;
- free_block *next;
-};
-
-extern uint8_t __heap_start[];
-extern uint8_t __heap_end[];
-
-static free_block *free_list;
-static uint8_t *heap_low;
-static uint8_t *heap_high;
-static uint32_t heap_ready;
-
-static size_t align_up(size_t value) {
- return (value + (HEAP_ALIGNMENT - 1)) & ~(size_t)(HEAP_ALIGNMENT - 1);
-}
-
-static uint32_t request_to_block(size_t size) {
- uint32_t block = (uint32_t)align_up(size) + HEADER_SIZE;
-
- return block < MIN_BLOCK ? MIN_BLOCK : block;
-}
-
-static void heap_init(void) {
- size_t start = align_up((size_t)__heap_start);
- size_t end = (size_t)__heap_end & ~(size_t)(HEAP_ALIGNMENT - 1);
-
- heap_ready = 1;
- free_list = NULL;
- heap_low = (uint8_t *)start;
- heap_high = (uint8_t *)end;
-
- if (end < start + MIN_BLOCK) {
- return;
- }
-
- free_block *block = (free_block *)start;
-
- block->size = (uint32_t)(end - start);
- block->used = 0;
- block->next = NULL;
- free_list = block;
-}
-
-static void release(free_block *block) {
- free_block *previous = NULL;
- free_block *current = free_list;
-
- block->used = 0;
-
- while (current != NULL && current < block) {
- previous = current;
- current = current->next;
- }
-
- block->next = current;
-
- if (previous != NULL) {
- previous->next = block;
- } else {
- free_list = block;
- }
-
- if (current != NULL && (uint8_t *)block + block->size == (uint8_t *)current) {
- block->size += current->size;
- block->next = current->next;
- }
-
- if (previous != NULL && (uint8_t *)previous + previous->size == (uint8_t *)block) {
- previous->size += block->size;
- previous->next = block->next;
- }
-}
-
-static void unlink_block(free_block *target) {
- free_block **link = &free_list;
-
- while (*link != NULL) {
- if (*link == target) {
- *link = target->next;
-
- return;
- }
-
- link = &(*link)->next;
- }
-}
-
-static void trim(free_block *block, uint32_t need) {
- if (block->size - need < MIN_BLOCK) {
- return;
- }
-
- free_block *tail = (free_block *)((uint8_t *)block + need);
-
- tail->size = block->size - need;
- block->size = need;
-
- release(tail);
-}
-
-static free_block *block_from_pointer(void *pointer) {
- if (!heap_ready) {
- return NULL;
- }
-
- uint8_t *address = (uint8_t *)pointer;
-
- if (address < heap_low + HEADER_SIZE || address >= heap_high) {
- return NULL;
- }
-
- if (((size_t)address & (HEAP_ALIGNMENT - 1)) != 0) {
- return NULL;
- }
-
- free_block *block = (free_block *)(address - HEADER_SIZE);
-
- if (block->used != USED_MAGIC) {
- return NULL;
- }
-
- return block;
-}
-
-void *malloc(size_t size) {
- if (!heap_ready) {
- heap_init();
- }
-
- if (size == 0 || size > MAX_REQUEST) {
- return NULL;
- }
-
- uint32_t need = request_to_block(size);
- free_block *best = NULL;
-
- for (free_block *current = free_list; current != NULL; current = current->next) {
- if (current->size < need) {
- continue;
- }
-
- if (best == NULL || current->size < best->size) {
- best = current;
-
- if (current->size == need) {
- break;
- }
- }
- }
-
- if (best == NULL) {
- return NULL;
- }
-
- unlink_block(best);
- trim(best, need);
- best->used = USED_MAGIC;
-
- return (uint8_t *)best + HEADER_SIZE;
-}
-
-void free(void *pointer) {
- if (pointer == NULL) {
- return;
- }
-
- free_block *block = block_from_pointer(pointer);
-
- if (block == NULL) {
- return;
- }
-
- release(block);
-}
-
-void *calloc(size_t count, size_t size) {
- if (size != 0 && count > MAX_REQUEST / size) {
- return NULL;
- }
-
- size_t total = count * size;
- void *pointer = malloc(total);
-
- if (pointer != NULL) {
- memset(pointer, 0, total);
- }
-
- return pointer;
-}
-
-void *realloc(void *pointer, size_t size) {
- if (pointer == NULL) {
- return malloc(size);
- }
-
- free_block *block = block_from_pointer(pointer);
-
- if (block == NULL) {
- return NULL;
- }
-
- if (size == 0) {
- free(pointer);
-
- return NULL;
- }
-
- if (size > MAX_REQUEST) {
- return NULL;
- }
-
- uint32_t need = request_to_block(size);
-
- if (need <= block->size) {
- trim(block, need);
-
- return pointer;
- }
-
- free_block *neighbor = free_list;
-
- while (neighbor != NULL && (uint8_t *)neighbor < (uint8_t *)block + block->size) {
- neighbor = neighbor->next;
- }
-
- if (neighbor != NULL && (uint8_t *)neighbor == (uint8_t *)block + block->size && block->size + neighbor->size >= need) {
- unlink_block(neighbor);
- block->size += neighbor->size;
- trim(block, need);
-
- return pointer;
- }
-
- void *grown = malloc(size);
-
- if (grown == NULL) {
- return NULL;
- }
-
- memcpy(grown, pointer, block->size - HEADER_SIZE);
- free(pointer);
-
- return grown;
-}
diff --git a/sdk/src/string.c b/sdk/src/string.c
@@ -1,53 +0,0 @@
-#include <stdint.h>
-#include <stddef.h>
-
-void *memcpy(void *destination, const void *source, size_t count) {
- uint8_t *destination_bytes = (uint8_t *)destination;
- const uint8_t *source_bytes = (const uint8_t *)source;
-
- for (size_t i = 0; i < count; i++) {
- destination_bytes[i] = source_bytes[i];
- }
-
- return destination;
-}
-
-void *memmove(void *destination, const void *source, size_t count) {
- uint8_t *destination_bytes = (uint8_t *)destination;
- const uint8_t *source_bytes = (const uint8_t *)source;
-
- if (destination_bytes < source_bytes) {
- for (size_t i = 0; i < count; i++) {
- destination_bytes[i] = source_bytes[i];
- }
- } else {
- for (size_t i = count; i > 0; i--) {
- destination_bytes[i - 1] = source_bytes[i - 1];
- }
- }
-
- return destination;
-}
-
-void *memset(void *destination, int value, size_t count) {
- uint8_t *destination_bytes = (uint8_t *)destination;
-
- for (size_t i = 0; i < count; i++) {
- destination_bytes[i] = (uint8_t)value;
- }
-
- return destination;
-}
-
-int memcmp(const void *first, const void *second, size_t count) {
- const uint8_t *first_bytes = (const uint8_t *)first;
- const uint8_t *second_bytes = (const uint8_t *)second;
-
- for (size_t i = 0; i < count; i++) {
- if (first_bytes[i] != second_bytes[i]) {
- return first_bytes[i] < second_bytes[i] ? -1 : 1;
- }
- }
-
- return 0;
-}