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:
D.gitignore | 1-
D.gitmodules | 12------------
DMakefile | 466-------------------------------------------------------------------------------
MREADME.md | 30++----------------------------
Aengine.mk | 0
Dfiles/images/bg.tai | 0
Dfiles/images/loading_logo.tai | 0
Rfiles/fonts/LICENSE -> font/LICENSE | 0
Rfiles/fonts/dejavu_sans.ttf -> font/dejavu_sans.ttf | 0
Dgame/.gitignore | 1-
Dgame/Makefile | 5-----
Dgame/src/main.c | 13-------------
Dgame/src/screens/ta_screen_loading.c | 44--------------------------------------------
Dgame/src/screens/ta_screen_loading.h | 8--------
Dgame/src/screens/ta_screen_main_menu.c | 29-----------------------------
Dgame/src/screens/ta_screen_main_menu.h | 8--------
Dgame/src/ta_button.c | 163-------------------------------------------------------------------------------
Dgame/src/ta_button.h | 36------------------------------------
Dgame/src/ta_screens.h | 9---------
Dplatforms/cocoa/cocoa.m | 461-------------------------------------------------------------------------------
Dplatforms/dos/dos.c | 270-------------------------------------------------------------------------------
Dplatforms/dreamcast/KallistiOS | 1-
Dplatforms/dreamcast/dreamcast.c | 251-------------------------------------------------------------------------------
Dplatforms/n64/n64.c | 131-------------------------------------------------------------------------------
Dplatforms/ps1/logo.tmd | 0
Dplatforms/ps1/nugget | 1-
Dplatforms/ps1/ps1.c | 469-------------------------------------------------------------------------------
Dplatforms/saturn/jo.mk | 27---------------------------
Dplatforms/saturn/joengine | 1-
Dplatforms/saturn/saturn.c | 240-------------------------------------------------------------------------------
Dplatforms/wayland/wayland.c | 629-------------------------------------------------------------------------------
Dplatforms/win32/header_banner.bmp | 0
Dplatforms/win32/installer.ico | 0
Dplatforms/win32/installer.nsi | 67-------------------------------------------------------------------
Dplatforms/win32/win32.c | 270-------------------------------------------------------------------------------
Dplatforms/x11/x11.c | 268-------------------------------------------------------------------------------
Dplatforms/xbox/nxdk | 1-
Dplatforms/xbox/xbox.c | 182-------------------------------------------------------------------------------
Dsdk/LICENSE | 18------------------
Dsdk/include/stdbool.h | 10----------
Dsdk/include/stddef.h | 8--------
Dsdk/include/stdint.h | 12------------
Dsdk/include/stdlib.h | 20--------------------
Dsdk/include/string.h | 11-----------
Dsdk/include/tuxanci2/abi.h | 25-------------------------
Dsdk/include/tuxanci2/display.h | 23-----------------------
Dsdk/include/tuxanci2/fixed.h | 10----------
Dsdk/include/tuxanci2/image.h | 23-----------------------
Dsdk/include/tuxanci2/keyboard.h | 144-------------------------------------------------------------------------------
Dsdk/include/tuxanci2/screen.h | 22----------------------
Dsdk/include/tuxanci2/syscall.h | 20--------------------
Dsdk/include/tuxanci2/text.h | 31-------------------------------
Dsdk/linker.ld | 43-------------------------------------------
Dsdk/sdk.mk | 63---------------------------------------------------------------
Dsdk/src/crt0.c | 21---------------------
Dsdk/src/stdlib.c | 259-------------------------------------------------------------------------------
Dsdk/src/string.c | 53-----------------------------------------------------
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(&regs, 0, sizeof(regs)); - regs.x.ax = 0x0013; - __dpmi_int(0x10, &regs); -} - -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(&regs, 0, sizeof(regs)); - regs.x.ax = 0x0003; - __dpmi_int(0x10, &regs); - - 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(&regs, 0, sizeof(regs)); - regs.x.ax = 0x0100; - regs.x.cx = 0x0607; - __dpmi_int(0x10, &regs); - - memset(&regs, 0, sizeof(regs)); - regs.x.ax = 0x0600; - regs.x.bx = 0x0700; - regs.x.cx = 0; - regs.x.dx = 0x184F; - __dpmi_int(0x10, &regs); - - memset(&regs, 0, sizeof(regs)); - regs.x.ax = 0x0200; - regs.x.bx = 0; - regs.x.dx = 0; - __dpmi_int(0x10, &regs); -} - -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, &parameters); - } - 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, &registry_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; -}