Latest compatible version of Classicube from the original GitHub repository (https://github.com/ClassiCube/ClassiCube) that can be compiled on Classicube for PowerMac PPC running Mac OS X 10.4.
2
.gitattributes
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*.c linguist-language=C
|
||||
*.h linguist-language=C
|
||||
235
.gitignore
vendored
Normal file
@@ -0,0 +1,235 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# Visual studio User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.sln.docstates
|
||||
|
||||
# Visual studio files
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Android build results
|
||||
android/.cxx/
|
||||
android/.idea/
|
||||
android/.gradle/
|
||||
android/build/
|
||||
android/app/build/
|
||||
android/app/.externalNativeBuild/
|
||||
android/local.properties
|
||||
*.iml
|
||||
|
||||
#XCode stuff
|
||||
project.xcworkspace/
|
||||
xcuserdata/
|
||||
|
||||
# Nintendo Console build results
|
||||
build-3ds/
|
||||
build-nds/
|
||||
build-dsi/
|
||||
build-n64/
|
||||
build-gc/
|
||||
build-wii/
|
||||
build-wiiu/
|
||||
build-switch/
|
||||
classicube.nds
|
||||
|
||||
# SEGA console build results
|
||||
build-32x/
|
||||
build-saturn/
|
||||
build-dc/
|
||||
IP.BIN
|
||||
ISO_FILES/
|
||||
third_party/gldc/libGLdc.a
|
||||
cd/
|
||||
|
||||
# Microsoft console build results
|
||||
build-360/
|
||||
main.exe
|
||||
main.lib
|
||||
misc/xbox/ps_coloured.inl
|
||||
misc/xbox/ps_textured.inl
|
||||
misc/xbox/vs_coloured.inl
|
||||
misc/xbox/vs_textured.inl
|
||||
|
||||
# Sony console build results
|
||||
build-ps2/
|
||||
build-ps3/
|
||||
build-ps4/
|
||||
build-psp/
|
||||
build-vita/
|
||||
EBOOT.PBP
|
||||
PARAM.SFO
|
||||
param.sfo
|
||||
eboot.bin
|
||||
pkg.gp4
|
||||
|
||||
# Desktop build results
|
||||
build-amiga-68k/
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Rr]elease/
|
||||
x64/
|
||||
x86/
|
||||
build/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Oo]utput/
|
||||
[Pp]rofilingSessions/
|
||||
src/.vs/
|
||||
|
||||
# ClassiCube game files
|
||||
src/audio
|
||||
src/texpacks
|
||||
src/maps
|
||||
src/texturecache
|
||||
src/logs
|
||||
src/options.txt
|
||||
src/ClassiCube*
|
||||
src/screenshots
|
||||
src/fontscache.txt
|
||||
|
||||
# ClassiCube game files
|
||||
audio
|
||||
texpacks
|
||||
maps
|
||||
texturecache
|
||||
logs
|
||||
options.txt
|
||||
ClassiCube*
|
||||
screenshots
|
||||
fontscache.txt
|
||||
|
||||
# DOS files
|
||||
CWSDPMI.EXE
|
||||
CWSDPMI.SWP
|
||||
OPTIONS.TXT
|
||||
|
||||
# Android source files need to be included
|
||||
!android/app/src/main/java/com/classicube
|
||||
|
||||
# Flatpak wrapper which needs to be included
|
||||
!misc/flatpak/ClassiCubeLauncher
|
||||
|
||||
# CMake files
|
||||
CMakeFiles/
|
||||
CMakeCache.txt
|
||||
|
||||
#GCC object files
|
||||
*.o
|
||||
# Build dependency files
|
||||
*.d
|
||||
|
||||
# Roslyn cache directories
|
||||
*.ide/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
#NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Mac classic
|
||||
retro68scripts/
|
||||
|
||||
# PS2
|
||||
openvcl/
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
*.map
|
||||
|
||||
# Binary files
|
||||
*.bin
|
||||
*.elf
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# If using the old MSBuild-Integrated Package Restore, uncomment this:
|
||||
#!**/packages/repositories.config
|
||||
|
||||
# Windows Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Windows Store app package directory
|
||||
AppPackages/
|
||||
|
||||
# Others
|
||||
sql/
|
||||
*.Cache
|
||||
ClientBin/
|
||||
[Ss]tyle[Cc]op.*
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.pfx
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# Eclipse
|
||||
.cproject
|
||||
.project
|
||||
350
Makefile
Normal file
@@ -0,0 +1,350 @@
|
||||
SOURCE_DIR = src
|
||||
BUILD_DIR = build
|
||||
C_SOURCES = $(wildcard $(SOURCE_DIR)/*.c)
|
||||
OBJECTS = $(patsubst %.c, $(BUILD_DIR)/%.o, $(C_SOURCES))
|
||||
BUILD_DIRS = $(BUILD_DIR) $(BUILD_DIR)/src
|
||||
|
||||
##############################
|
||||
# Configurable flags and names
|
||||
##############################
|
||||
# Flags passed to the C compiler
|
||||
CFLAGS = -pipe -fno-math-errno -Werror -Wno-error=missing-braces -Wno-error=strict-aliasing
|
||||
# Flags passed to the linker
|
||||
LDFLAGS = -g -rdynamic
|
||||
# Name of the main executable
|
||||
ENAME = ClassiCube
|
||||
# Name of the final target file
|
||||
# (usually this is the executable, but e.g. is the app bundle on macOS)
|
||||
TARGET := $(ENAME)
|
||||
|
||||
# Enables dependency tracking (https://make.mad-scientist.net/papers/advanced-auto-dependency-generation/)
|
||||
# This ensures that changing a .h file automatically results in the .c files using it being auto recompiled when next running make
|
||||
# On older systems the required GCC options may not be supported - in which case just change TRACK_DEPENDENCIES to 0
|
||||
TRACK_DEPENDENCIES=1
|
||||
# link using C Compiler by default
|
||||
LINK = $(CC)
|
||||
|
||||
|
||||
#################################################################
|
||||
# Determine shell command used to remove files (for "make clean")
|
||||
#################################################################
|
||||
ifndef RM
|
||||
# No prefined RM variable, try to guess OS default
|
||||
ifeq ($(OS),Windows_NT)
|
||||
RM = del
|
||||
else
|
||||
RM = rm -f
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
###########################################################
|
||||
# If target platform isn't specified, default to current OS
|
||||
###########################################################
|
||||
ifndef $(PLAT)
|
||||
ifeq ($(OS),Windows_NT)
|
||||
PLAT = mingw
|
||||
else
|
||||
PLAT = $(shell uname -s | tr '[:upper:]' '[:lower:]')
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
#########################################################
|
||||
# Setup environment appropriate for the specific platform
|
||||
#########################################################
|
||||
ifeq ($(PLAT),web)
|
||||
CC = emcc
|
||||
OEXT = .html
|
||||
CFLAGS = -g
|
||||
LDFLAGS = -g -s WASM=1 -s NO_EXIT_RUNTIME=1 -s ABORTING_MALLOC=0 -s ALLOW_MEMORY_GROWTH=1 -s TOTAL_STACK=256Kb --js-library $(SOURCE_DIR)/interop_web.js
|
||||
BUILD_DIR = build/web
|
||||
endif
|
||||
|
||||
ifeq ($(PLAT),mingw)
|
||||
CC = gcc
|
||||
OEXT = .exe
|
||||
CFLAGS += -DUNICODE
|
||||
LDFLAGS = -g
|
||||
LIBS = -mwindows -lwinmm
|
||||
BUILD_DIR = build/win
|
||||
endif
|
||||
|
||||
ifeq ($(PLAT),linux)
|
||||
LIBS = -lX11 -lXi -lpthread -lGL -ldl
|
||||
BUILD_DIR = build/linux
|
||||
BEARSSL = 1
|
||||
endif
|
||||
|
||||
ifeq ($(PLAT),sunos)
|
||||
LIBS = -lsocket -lX11 -lXi -lGL
|
||||
BUILD_DIR = build/solaris
|
||||
BEARSSL = 1
|
||||
endif
|
||||
|
||||
ifeq ($(PLAT),hp-ux)
|
||||
CC = gcc
|
||||
LDFLAGS =
|
||||
LIBS = -lm -lX11 -lXi -lXext -L/opt/graphics/OpenGL/lib -lGL -lpthread
|
||||
BUILD_DIR = build/hpux
|
||||
BEARSSL = 1
|
||||
endif
|
||||
|
||||
ifeq ($(PLAT),darwin)
|
||||
OBJECTS += $(BUILD_DIR)/src/Window_cocoa.o
|
||||
LIBS =
|
||||
LDFLAGS = -rdynamic -framework Cocoa -framework OpenGL -framework IOKit -lobjc
|
||||
BUILD_DIR = build/macos
|
||||
TARGET = $(ENAME).app
|
||||
endif
|
||||
|
||||
ifeq ($(PLAT),freebsd)
|
||||
CFLAGS += -I /usr/local/include
|
||||
LDFLAGS = -L /usr/local/lib -rdynamic
|
||||
LIBS = -lexecinfo -lGL -lX11 -lXi -lpthread
|
||||
BUILD_DIR = build/freebsd
|
||||
BEARSSL = 1
|
||||
endif
|
||||
|
||||
ifeq ($(PLAT),openbsd)
|
||||
CFLAGS += -I /usr/X11R6/include -I /usr/local/include
|
||||
LDFLAGS = -L /usr/X11R6/lib -L /usr/local/lib -rdynamic
|
||||
LIBS = -lexecinfo -lGL -lX11 -lXi -lpthread
|
||||
BUILD_DIR = build/openbsd
|
||||
BEARSSL = 1
|
||||
endif
|
||||
|
||||
ifeq ($(PLAT),netbsd)
|
||||
CFLAGS += -I /usr/X11R7/include -I /usr/pkg/include
|
||||
LDFLAGS = -L /usr/X11R7/lib -L /usr/pkg/lib -rdynamic -Wl,-R/usr/X11R7/lib
|
||||
LIBS = -lexecinfo -lGL -lX11 -lXi -lpthread
|
||||
BUILD_DIR = build/netbsd
|
||||
BEARSSL = 1
|
||||
endif
|
||||
|
||||
ifeq ($(PLAT),dragonfly)
|
||||
CFLAGS += -I /usr/local/include
|
||||
LDFLAGS = -L /usr/local/lib -rdynamic
|
||||
LIBS = -lexecinfo -lGL -lX11 -lXi -lpthread
|
||||
BUILD_DIR = build/flybsd
|
||||
BEARSSL = 1
|
||||
endif
|
||||
|
||||
ifeq ($(PLAT),haiku)
|
||||
OBJECTS += $(BUILD_DIR)/src/Platform_BeOS.o $(BUILD_DIR)/src/Window_BeOS.o
|
||||
CFLAGS = -pipe -fno-math-errno
|
||||
LDFLAGS = -g
|
||||
LINK = $(CXX)
|
||||
LIBS = -lGL -lnetwork -lbe -lgame -ltracker
|
||||
BUILD_DIR = build/haiku
|
||||
BEARSSL = 1
|
||||
endif
|
||||
|
||||
ifeq ($(PLAT),beos)
|
||||
OBJECTS += $(BUILD_DIR)/src/Platform_BeOS.o $(BUILD_DIR)/src/Window_BeOS.o
|
||||
CFLAGS = -pipe
|
||||
LDFLAGS = -g
|
||||
LINK = $(CXX)
|
||||
LIBS = -lGL -lnetwork -lbe -lgame -ltracker
|
||||
BUILD_DIR = build/beos
|
||||
TRACK_DEPENDENCIES=0
|
||||
endif
|
||||
|
||||
ifeq ($(PLAT),serenityos)
|
||||
LIBS = -lgl -lSDL2
|
||||
BUILD_DIR = build/serenity
|
||||
BEARSSL = 1
|
||||
endif
|
||||
|
||||
ifeq ($(PLAT),irix)
|
||||
CC = gcc
|
||||
LIBS = -lGL -lX11 -lXi -lpthread -ldl
|
||||
BUILD_DIR = build/irix
|
||||
BEARSSL = 1
|
||||
endif
|
||||
|
||||
ifeq ($(PLAT),dos)
|
||||
CC = i586-pc-msdosdjgpp-gcc
|
||||
LIBS =
|
||||
LDFLAGS = -g
|
||||
OEXT = .exe
|
||||
BUILD_DIR = build/dos
|
||||
endif
|
||||
|
||||
|
||||
ifdef SDL2
|
||||
CFLAGS += -DCC_WIN_BACKEND=CC_WIN_BACKEND_SDL2
|
||||
LIBS += -lSDL2
|
||||
endif
|
||||
ifdef SDL3
|
||||
CFLAGS += -DCC_WIN_BACKEND=CC_WIN_BACKEND_SDL3
|
||||
LIBS += -lSDL3
|
||||
endif
|
||||
ifdef TERMINAL
|
||||
CFLAGS += -DCC_WIN_BACKEND=CC_WIN_BACKEND_TERMINAL -DCC_GFX_BACKEND=CC_GFX_BACKEND_SOFTGPU
|
||||
LIBS := $(subst mwindows,mconsole,$(LIBS))
|
||||
endif
|
||||
|
||||
ifdef BEARSSL
|
||||
BUILD_DIRS += $(BUILD_DIR)/third_party/bearssl/src
|
||||
BEARSSL_SOURCES = $(wildcard third_party/bearssl/src/*.c)
|
||||
BEARSSL_OBJECTS = $(patsubst %.c, $(BUILD_DIR)/%.o, $(BEARSSL_SOURCES))
|
||||
OBJECTS += $(BEARSSL_OBJECTS)
|
||||
CFLAGS += -Ithird_party/bearssl/inc -DCC_SSL_BACKEND=CC_SSL_BACKEND_BEARSSL -DCC_NET_BACKEND=CC_NET_BACKEND_BUILTIN
|
||||
endif
|
||||
|
||||
ifdef RELEASE
|
||||
CFLAGS += -O1
|
||||
else
|
||||
CFLAGS += -g
|
||||
endif
|
||||
|
||||
default: $(PLAT)
|
||||
|
||||
# Build for the specified platform
|
||||
web:
|
||||
$(MAKE) $(TARGET) PLAT=web
|
||||
linux:
|
||||
$(MAKE) $(TARGET) PLAT=linux
|
||||
mingw:
|
||||
$(MAKE) $(TARGET) PLAT=mingw
|
||||
sunos:
|
||||
$(MAKE) $(TARGET) PLAT=sunos
|
||||
hp-ux:
|
||||
$(MAKE) $(TARGET) PLAT=hp-ux
|
||||
darwin:
|
||||
$(MAKE) $(TARGET) PLAT=darwin
|
||||
freebsd:
|
||||
$(MAKE) $(TARGET) PLAT=freebsd
|
||||
openbsd:
|
||||
$(MAKE) $(TARGET) PLAT=openbsd
|
||||
netbsd:
|
||||
$(MAKE) $(TARGET) PLAT=netbsd
|
||||
dragonfly:
|
||||
$(MAKE) $(TARGET) PLAT=dragonfly
|
||||
haiku:
|
||||
$(MAKE) $(TARGET) PLAT=haiku
|
||||
beos:
|
||||
$(MAKE) $(TARGET) PLAT=beos
|
||||
serenityos:
|
||||
$(MAKE) $(TARGET) PLAT=serenityos
|
||||
irix:
|
||||
$(MAKE) $(TARGET) PLAT=irix
|
||||
dos:
|
||||
$(MAKE) $(TARGET) PLAT=dos
|
||||
# Default overrides
|
||||
sdl2:
|
||||
$(MAKE) $(TARGET) SDL2=1
|
||||
sdl3:
|
||||
$(MAKE) $(TARGET) SDL3=1
|
||||
terminal:
|
||||
$(MAKE) $(TARGET) TERMINAL=1
|
||||
release:
|
||||
$(MAKE) $(TARGET) RELEASE=1
|
||||
|
||||
# Some builds require more complex handling, so are moved to
|
||||
# separate makefiles to avoid having one giant messy makefile
|
||||
32x:
|
||||
$(MAKE) -f misc/32x/Makefile
|
||||
saturn:
|
||||
$(MAKE) -f misc/saturn/Makefile
|
||||
dreamcast:
|
||||
$(MAKE) -f misc/dreamcast/Makefile
|
||||
psp:
|
||||
$(MAKE) -f misc/psp/Makefile
|
||||
vita:
|
||||
$(MAKE) -f misc/vita/Makefile
|
||||
ps1:
|
||||
$(MAKE) -f misc/ps1/Makefile
|
||||
ps2:
|
||||
$(MAKE) -f misc/ps2/Makefile
|
||||
ps3:
|
||||
$(MAKE) -f misc/ps3/Makefile
|
||||
ps4:
|
||||
$(MAKE) -f misc/ps4/Makefile
|
||||
xbox:
|
||||
$(MAKE) -f misc/xbox/Makefile
|
||||
xbox360:
|
||||
$(MAKE) -f misc/xbox360/Makefile
|
||||
n64:
|
||||
$(MAKE) -f misc/n64/Makefile
|
||||
gba:
|
||||
$(MAKE) -f misc/gba/Makefile
|
||||
ds:
|
||||
$(MAKE) -f misc/ds/Makefile
|
||||
3ds:
|
||||
$(MAKE) -f misc/3ds/Makefile
|
||||
gamecube:
|
||||
$(MAKE) -f misc/gc/Makefile
|
||||
wii:
|
||||
$(MAKE) -f misc/wii/Makefile
|
||||
wiiu:
|
||||
$(MAKE) -f misc/wiiu/Makefile
|
||||
switch:
|
||||
$(MAKE) -f misc/switch/Makefile
|
||||
os/2:
|
||||
$(MAKE) -f misc/os2/Makefile
|
||||
macclassic_68k:
|
||||
$(MAKE) -f misc/macclassic/Makefile_68k
|
||||
macclassic_ppc:
|
||||
$(MAKE) -f misc/macclassic/Makefile_ppc
|
||||
amiga_68k:
|
||||
$(MAKE) -f misc/amiga/Makefile_68k
|
||||
amiga_ppc:
|
||||
$(MAKE) -f misc/amiga/Makefile_ppc
|
||||
|
||||
# Cleans up all build .o files
|
||||
clean:
|
||||
$(RM) $(OBJECTS)
|
||||
|
||||
|
||||
#################################################
|
||||
# Source files and executable compilation section
|
||||
#################################################
|
||||
# Auto creates directories for build files (.o and .d files)
|
||||
$(BUILD_DIRS):
|
||||
mkdir -p $@
|
||||
|
||||
# Main executable (typically just 'ClassiCube' or 'ClassiCube.exe')
|
||||
$(ENAME): $(BUILD_DIRS) $(OBJECTS)
|
||||
$(LINK) $(LDFLAGS) -o $@$(OEXT) $(OBJECTS) $(EXTRA_LIBS) $(LIBS)
|
||||
@echo "----------------------------------------------------"
|
||||
@echo "Successfully compiled executable file: $(ENAME)"
|
||||
@echo "----------------------------------------------------"
|
||||
|
||||
# macOS app bundle
|
||||
$(ENAME).app : $(ENAME)
|
||||
mkdir -p $(TARGET)/Contents/MacOS
|
||||
mkdir -p $(TARGET)/Contents/Resources
|
||||
cp $(ENAME) $(TARGET)/Contents/MacOS/$(ENAME)
|
||||
cp misc/macOS/Info.plist $(TARGET)/Contents/Info.plist
|
||||
cp misc/macOS/appicon.icns $(TARGET)/Contents/Resources/appicon.icns
|
||||
|
||||
|
||||
# === Compiling with dependency tracking ===
|
||||
# NOTE: Tracking dependencies might not work on older systems - disable this if so
|
||||
ifeq ($(TRACK_DEPENDENCIES), 1)
|
||||
|
||||
DEPFLAGS = -MT $@ -MMD -MP -MF $(BUILD_DIR)/$*.d
|
||||
DEPFILES := $(patsubst %.o, %.d, $(OBJECTS))
|
||||
$(DEPFILES):
|
||||
|
||||
$(BUILD_DIR)/%.o : %.c $(BUILD_DIR)/%.d
|
||||
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(DEPFLAGS) -c $< -o $@
|
||||
$(BUILD_DIR)/%.o : %.cpp $(BUILD_DIR)/%.d
|
||||
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(DEPFLAGS) -c $< -o $@
|
||||
$(BUILD_DIR)/%.o : %.m $(BUILD_DIR)/%.d
|
||||
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(DEPFLAGS) -c $< -o $@
|
||||
|
||||
include $(wildcard $(DEPFILES))
|
||||
# === Compiling WITHOUT dependency tracking ===
|
||||
else
|
||||
|
||||
$(BUILD_DIR)/%.o : %.c
|
||||
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@
|
||||
$(BUILD_DIR)/%.o : %.cpp
|
||||
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@
|
||||
endif
|
||||
|
||||
# EXTRA_CFLAGS and EXTRA_LIBS are not defined in the makefile intentionally -
|
||||
# define them on the command line as a simple way of adding CFLAGS/LIBS
|
||||
119
android/app/CMakeLists.txt
Normal file
@@ -0,0 +1,119 @@
|
||||
#
|
||||
# Copyright (C) The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.4.1)
|
||||
|
||||
# build native_app_glue as a static lib
|
||||
set(${CMAKE_C_FLAGS}, "${CMAKE_C_FLAGS}")
|
||||
# now build app's shared lib
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11 -Wall -Werror")
|
||||
|
||||
add_library(classicube SHARED
|
||||
../../src/main.c
|
||||
../../src/IsometricDrawer.c
|
||||
../../src/Builder.c
|
||||
../../src/ExtMath.c
|
||||
../../src/_ftbitmap.c
|
||||
../../src/Utils.c
|
||||
../../src/Camera.c
|
||||
../../src/Game.c
|
||||
../../src/GameVersion.c
|
||||
../../src/Window_Android.c
|
||||
../../src/_ftbase.c
|
||||
../../src/Graphics_GL2.c
|
||||
../../src/Deflate.c
|
||||
../../src/_cff.c
|
||||
../../src/_ftsynth.c
|
||||
../../src/String.c
|
||||
../../src/LWidgets.c
|
||||
../../src/Options.c
|
||||
../../src/Drawer2D.c
|
||||
../../src/Server.c
|
||||
../../src/Entity.c
|
||||
../../src/Drawer.c
|
||||
../../src/Vorbis.c
|
||||
../../src/Protocol.c
|
||||
../../src/World.c
|
||||
../../src/SelOutlineRenderer.c
|
||||
../../src/Platform_Posix.c
|
||||
../../src/Platform_Android.c
|
||||
../../src/LScreens.c
|
||||
../../src/_truetype.c
|
||||
../../src/_ftglyph.c
|
||||
../../src/Model.c
|
||||
../../src/_autofit.c
|
||||
../../src/Vectors.c
|
||||
../../src/HeldBlockRenderer.c
|
||||
../../src/Inventory.c
|
||||
../../src/Launcher.c
|
||||
../../src/Block.c
|
||||
../../src/LWeb.c
|
||||
../../src/Stream.c
|
||||
../../src/Lighting.c
|
||||
../../src/Resources.c
|
||||
../../src/PackedCol.c
|
||||
../../src/Screens.c
|
||||
../../src/Formats.c
|
||||
../../src/_sfnt.c
|
||||
../../src/Bitmap.c
|
||||
../../src/EntityComponents.c
|
||||
../../src/_pshinter.c
|
||||
../../src/Http_Worker.c
|
||||
../../src/MapRenderer.c
|
||||
../../src/Audio.c
|
||||
../../src/_ftinit.c
|
||||
../../src/Event.c
|
||||
../../src/Logger.c
|
||||
../../src/Widgets.c
|
||||
../../src/TexturePack.c
|
||||
../../src/Menus.c
|
||||
../../src/BlockPhysics.c
|
||||
../../src/_psmodule.c
|
||||
../../src/Chat.c
|
||||
../../src/Gui.c
|
||||
../../src/AxisLinesRenderer.c
|
||||
../../src/Picking.c
|
||||
../../src/_type1.c
|
||||
../../src/_smooth.c
|
||||
../../src/_psaux.c
|
||||
../../src/Generator.c
|
||||
../../src/Input.c
|
||||
../../src/Particle.c
|
||||
../../src/Physics.c
|
||||
../../src/SelectionBox.c
|
||||
../../src/EnvRenderer.c
|
||||
../../src/Animations.c
|
||||
../../src/LBackend.c
|
||||
../../src/SystemFonts.c
|
||||
../../src/Commands.c
|
||||
../../src/EntityRenderers.c
|
||||
../../src/Audio_SLES.c
|
||||
../../src/TouchUI.c
|
||||
../../src/LBackend_Android.c
|
||||
../../src/InputHandler.c
|
||||
../../src/MenuOptions.c
|
||||
../../src/FancyLighting.c
|
||||
../../src/Queue.c
|
||||
)
|
||||
|
||||
# add lib dependencies
|
||||
target_link_libraries(classicube
|
||||
android
|
||||
EGL
|
||||
GLESv2
|
||||
log
|
||||
OpenSLES
|
||||
jnigraphics)
|
||||
29
android/app/build.gradle
Normal file
@@ -0,0 +1,29 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
|
||||
defaultConfig {
|
||||
applicationId = 'com.classicube.android.client'
|
||||
minSdkVersion 13
|
||||
targetSdkVersion 26
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments '-DANDROID_STL=c++_static'
|
||||
}
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'),
|
||||
'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
version '3.10.2'
|
||||
path 'CMakeLists.txt'
|
||||
}
|
||||
}
|
||||
}
|
||||
32
android/app/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- BEGIN_INCLUDE(manifest) -->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.classicube.android.client"
|
||||
android:versionCode="1370"
|
||||
android:versionName="1.3.7">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="18" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18" />
|
||||
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="26"/>
|
||||
|
||||
<application android:icon="@mipmap/ccicon" android:label="ClassiCube">
|
||||
<provider
|
||||
android:name="com.classicube.CCFileProvider"
|
||||
android:authorities="com.classicube.android.client.provider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true" >
|
||||
</provider>
|
||||
|
||||
<activity android:name="com.classicube.MainActivity" android:label="ClassiCube"
|
||||
android:configChanges="orientation|screenSize|keyboard|keyboardHidden">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
<!-- END_INCLUDE(manifest) -->
|
||||
115
android/app/src/main/java/com/classicube/CCFileProvider.java
Normal file
@@ -0,0 +1,115 @@
|
||||
package com.classicube;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ProviderInfo;
|
||||
import android.database.Cursor;
|
||||
import android.database.MatrixCursor;
|
||||
import android.net.Uri;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.provider.MediaStore;
|
||||
import android.provider.OpenableColumns;
|
||||
|
||||
public class CCFileProvider extends ContentProvider
|
||||
{
|
||||
final static String[] DEFAULT_COLUMNS = { OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE, MediaStore.MediaColumns.DATA };
|
||||
File root;
|
||||
|
||||
@Override
|
||||
public boolean onCreate() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attachInfo(Context context, ProviderInfo info) {
|
||||
super.attachInfo(context, info);
|
||||
root = context.getExternalFilesDir(null); // getGameDataDirectory
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
|
||||
File file = getFileForUri(uri);
|
||||
// can be null when caller is requesting all columns
|
||||
if (projection == null) projection = DEFAULT_COLUMNS;
|
||||
|
||||
ArrayList<String> cols = new ArrayList<String>(3);
|
||||
ArrayList<Object> vals = new ArrayList<Object>(3);
|
||||
|
||||
for (String column : projection) {
|
||||
if (column.equals(OpenableColumns.DISPLAY_NAME)) {
|
||||
cols.add(OpenableColumns.DISPLAY_NAME);
|
||||
vals.add(file.getName());
|
||||
} else if (column.equals(OpenableColumns.SIZE)) {
|
||||
cols.add(OpenableColumns.SIZE);
|
||||
vals.add(file.length());
|
||||
} else if (column.equals(MediaStore.MediaColumns.DATA)) {
|
||||
cols.add(MediaStore.MediaColumns.DATA);
|
||||
vals.add(file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/4042434/converting-arrayliststring-to-string-in-java
|
||||
MatrixCursor cursor = new MatrixCursor(cols.toArray(new String[0]), 1);
|
||||
cursor.addRow(vals.toArray());
|
||||
return cursor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType(Uri uri) {
|
||||
String path = uri.getEncodedPath();
|
||||
int sepExt = path.lastIndexOf('.');
|
||||
|
||||
if (sepExt >= 0) {
|
||||
String fileExt = path.substring(sepExt);
|
||||
if (fileExt.equals(".png")) return "image/png";
|
||||
}
|
||||
return "application/octet-stream";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri insert(Uri uri, ContentValues values) {
|
||||
throw new UnsupportedOperationException("Readonly access");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
|
||||
throw new UnsupportedOperationException("Readonly access");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int delete(Uri uri, String selection, String[] selectionArgs) {
|
||||
throw new UnsupportedOperationException("Readonly access");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
|
||||
File file = getFileForUri(uri);
|
||||
return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
|
||||
}
|
||||
|
||||
public static Uri getUriForFile(String path) {
|
||||
// See AndroidManifest.xml for authority
|
||||
return new Uri.Builder()
|
||||
.scheme("content")
|
||||
.authority("com.classicube.android.client.provider")
|
||||
.encodedPath(Uri.encode(path, "/"))
|
||||
.build();
|
||||
}
|
||||
|
||||
File getFileForUri(Uri uri) {
|
||||
String path = uri.getPath();
|
||||
File file = new File(root, path);
|
||||
|
||||
file = file.getAbsoluteFile();
|
||||
// security validation check
|
||||
if (!file.getPath().startsWith(root.getPath())) {
|
||||
throw new SecurityException("Resolved path lies outside app directory:" + path);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.classicube;
|
||||
import android.view.InputDevice;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
public class CCMotionListener implements View.OnGenericMotionListener {
|
||||
MainActivity activity;
|
||||
|
||||
public CCMotionListener(MainActivity activity) {
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
// https://developer.android.com/develop/ui/views/touch-and-input/game-controllers/controller-input#java
|
||||
@Override
|
||||
public boolean onGenericMotion(View view, MotionEvent event) {
|
||||
if (event.getAction() != MotionEvent.ACTION_MOVE) return false;
|
||||
boolean source_joystick = (event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK;
|
||||
boolean source_gamepad = (event.getSource() & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD;
|
||||
|
||||
if (source_joystick || source_gamepad) {
|
||||
int historySize = event.getHistorySize();
|
||||
for (int i = 0; i < historySize; i++) {
|
||||
processJoystickInput(event, i);
|
||||
}
|
||||
|
||||
processJoystickInput(event, -1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void processJoystickInput(MotionEvent event, int historyPos) {
|
||||
float x1 = getAxisValue(event, MotionEvent.AXIS_X, historyPos);
|
||||
float y1 = getAxisValue(event, MotionEvent.AXIS_Y, historyPos);
|
||||
|
||||
float x2 = getAxisValue(event, MotionEvent.AXIS_Z, historyPos);
|
||||
float y2 = getAxisValue(event, MotionEvent.AXIS_RZ, historyPos);
|
||||
|
||||
if (x1 != 0 || y1 != 0)
|
||||
pushAxisMovement(MainActivity.CMD_GPAD_AXISL, x1, y1);
|
||||
if (x2 != 0 || y2 != 0)
|
||||
pushAxisMovement(MainActivity.CMD_GPAD_AXISR, x2, y2);
|
||||
}
|
||||
|
||||
float getAxisValue(MotionEvent event, int axis, int historyPos) {
|
||||
float value = historyPos < 0 ? event.getAxisValue(axis) :
|
||||
event.getHistoricalAxisValue(axis, historyPos);
|
||||
|
||||
// Deadzone detection
|
||||
if (value >= -0.25f && value <= 0.25f) value = 0;
|
||||
return value;
|
||||
}
|
||||
|
||||
void pushAxisMovement(int axis, float x, float y) {
|
||||
activity.pushCmd(axis, (int)(x * 4096), (int)(y * 4096));
|
||||
}
|
||||
}
|
||||
108
android/app/src/main/java/com/classicube/CCView.java
Normal file
@@ -0,0 +1,108 @@
|
||||
package com.classicube;
|
||||
import android.text.Editable;
|
||||
import android.text.Selection;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.inputmethod.BaseInputConnection;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputConnection;
|
||||
|
||||
public class CCView extends SurfaceView {
|
||||
SpannableStringBuilder kbText;
|
||||
MainActivity activity;
|
||||
|
||||
public CCView(MainActivity activity) {
|
||||
// setFocusable, setFocusableInTouchMode - API level 1
|
||||
super(activity);
|
||||
this.activity = activity;
|
||||
setFocusable(true);
|
||||
setFocusableInTouchMode(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchTouchEvent(MotionEvent ev) {
|
||||
return activity.handleTouchEvent(ev) || super.dispatchTouchEvent(ev);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputConnection onCreateInputConnection(EditorInfo attrs) {
|
||||
// BaseInputConnection, IME_ACTION_GO, IME_FLAG_NO_EXTRACT_UI - API level 3
|
||||
attrs.actionLabel = null;
|
||||
attrs.inputType = MainActivity.calcKeyboardType(activity.keyboardType);
|
||||
attrs.imeOptions = MainActivity.calcKeyboardOptions(activity.keyboardType);
|
||||
|
||||
kbText = new SpannableStringBuilder(activity.keyboardText);
|
||||
|
||||
InputConnection ic = new BaseInputConnection(this, true) {
|
||||
boolean inited;
|
||||
|
||||
void updateText() {
|
||||
activity.pushCmd(MainActivity.CMD_KEY_TEXT, kbText.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Editable getEditable() {
|
||||
if (!inited) {
|
||||
// needed to set selection, otherwise random crashes later with backspacing
|
||||
// set selection to end, so backspacing after opening keyboard with text still works
|
||||
Selection.setSelection(kbText, kbText.toString().length());
|
||||
inited = true;
|
||||
}
|
||||
return kbText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setComposingText(CharSequence text, int newCursorPosition) {
|
||||
boolean success = super.setComposingText(text, newCursorPosition);
|
||||
updateText();
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteSurroundingText(int beforeLength, int afterLength) {
|
||||
boolean success = super.deleteSurroundingText(beforeLength, afterLength);
|
||||
updateText();
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean commitText(CharSequence text, int newCursorPosition) {
|
||||
boolean success = super.commitText(text, newCursorPosition);
|
||||
updateText();
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean sendKeyEvent(KeyEvent ev) {
|
||||
// getSelectionStart - API level 1
|
||||
if (ev.getAction() != KeyEvent.ACTION_DOWN) return super.sendKeyEvent(ev);
|
||||
int code = ev.getKeyCode();
|
||||
int uni = ev.getUnicodeChar();
|
||||
|
||||
// start is -1 sometimes, and trying to insert/delete there crashes
|
||||
int start = Selection.getSelectionStart(kbText);
|
||||
if (start == -1) start = kbText.toString().length();
|
||||
|
||||
if (code == KeyEvent.KEYCODE_ENTER) {
|
||||
// enter maps to \n but that should not be intercepted
|
||||
} else if (code == KeyEvent.KEYCODE_DEL) {
|
||||
if (start <= 0) return false;
|
||||
kbText.delete(start - 1, start);
|
||||
updateText();
|
||||
return false;
|
||||
} else if (uni != 0) {
|
||||
kbText.insert(start, String.valueOf((char) uni));
|
||||
updateText();
|
||||
return false;
|
||||
}
|
||||
return super.sendKeyEvent(ev);
|
||||
}
|
||||
|
||||
};
|
||||
//String text = MainActivity.this.keyboardText;
|
||||
//if (text != null) ic.setComposingText(text, 0);
|
||||
return ic;
|
||||
}
|
||||
}
|
||||
1019
android/app/src/main/java/com/classicube/MainActivity.java
Normal file
BIN
android/app/src/main/res/mipmap-hdpi/ccicon.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
android/app/src/main/res/mipmap-mdpi/ccicon.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
android/app/src/main/res/mipmap-xhdpi/ccicon.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
android/app/src/main/res/mipmap-xxhdpi/ccicon.png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
3
android/app/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
</resources>
|
||||
21
android/build.gradle
Normal file
@@ -0,0 +1,21 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.6.4'
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
20
android/gradle.properties
Normal file
@@ -0,0 +1,20 @@
|
||||
# Project-wide Gradle settings.
|
||||
|
||||
# IDE (e.g. Android Studio) users:
|
||||
# Gradle settings configured through the IDE *will override*
|
||||
# any settings specified in this file.
|
||||
|
||||
# For more details on how to configure your build environment visit
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
android.enableJetifier=true
|
||||
android.useAndroidX=true
|
||||
org.gradle.jvmargs=-Xmx1536m
|
||||
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
|
||||
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
6
android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
#Fri May 06 22:33:57 AEST 2022
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-bin.zip
|
||||
distributionPath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
164
android/gradlew
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched.
|
||||
if $cygwin ; then
|
||||
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
fi
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >&-
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >&-
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
90
android/gradlew.bat
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windowz variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
2
android/settings.gradle
Normal file
@@ -0,0 +1,2 @@
|
||||
include ':app'
|
||||
|
||||
22
credits.txt
Normal file
@@ -0,0 +1,22 @@
|
||||
* Goodlyay - many suggestions, and being a great second pairs of eyes for issues and
|
||||
improvements with character modelling, animating, and view bobbing. Also designed the icons.
|
||||
Also designed all the textures in the web client. Big thanks!
|
||||
* AndrewPH - Advice on how to improve ui of both client and launcher, multiple
|
||||
suggestions, and hosting the automatic build bot for ClassiCube.
|
||||
* 123DMWM - many suggestions, and assistance in identifying bugs and their causes.
|
||||
* video_error - Allowing remote use of an macOS machine, pointing out many flaws in the plugin API.
|
||||
The macOS port would not have been possible without you, thanks!
|
||||
* Jerralish - reverse engineering and documenting the original classic map generation algorithm.
|
||||
* Cybertoon - Adding water animation, better metal step/dig sounds, identifying multiple flaws
|
||||
* Cheesse - multiple suggestions, testing ClassicalSharp on AMD graphics cards.
|
||||
* Hemsindor - testing ClassicalSharp on macOS.
|
||||
* headshotnoby - developing the Switch port.
|
||||
* Beyond_5D - identifying many differences from original Classic
|
||||
|
||||
And a big thanks to everyone else in the ClassiCube community (who I didn't mention here),
|
||||
who in the past have provided many suggestions and assisted in identifying bugs.
|
||||
|
||||
* Portions of the FreeType project (https://www.freetype.org/) are used for text rendering
|
||||
Some functionality has been removed compared to original FreeType source code.
|
||||
Additionally, the base .c files have an #ifdef to disable compiling for emscripten
|
||||
The source code of FreeType is otherwise unmodified.
|
||||
37
doc/compile-fixes.md
Normal file
@@ -0,0 +1,37 @@
|
||||
Visual studio unsupported platform toolset
|
||||
---------------------
|
||||
To fix the ```Error MSB8036 The Windows SDK version 5.1 was not found. Install the required version of Windows SDK or change the SDK version in the project property pages or by right-clicking the solution and selecting "Retarget solution"```
|
||||
* Right click **ClassiCube** project (it's under the *Solution 'ClassiCube'* in the *Solution Explorer* pane)
|
||||
* Click **Properties**
|
||||
* Make sure you are in **General** tab under **Configuration Properties**
|
||||
* You should see a dropdown named **Platform Toolset**. Click on it.
|
||||
* Change it to one of the toolsets in the list that pops up.
|
||||
* Click **OK**. You should be able to compile now
|
||||
|
||||

|
||||
|
||||
Common compilation errors
|
||||
---------------------
|
||||
#### Undefined reference to 'clock_gettime'
|
||||
Add ```-lrt``` when compiling. Occurs when using glibc versions before 2.17.
|
||||
|
||||
#### fatal error: execinfo.h: No such file or directory
|
||||
Define `CC_BACKTRACE_BUILTIN` when compiling. Usually occurs when using musl.
|
||||
|
||||
#### Undefined reference to 'backtrace'
|
||||
Define `CC_BACKTRACE_BUILTIN` when compiling. Usually occurs when using musl.
|
||||
|
||||
Webclient patches
|
||||
---------------------
|
||||
#### Mouse scrolling not properly prevented
|
||||
With recent chrome/firefox versions, page is still scrolled and console is spammed with\
|
||||
```"[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive."```
|
||||
|
||||
You need to to register events as a passive handler. Look for something like:
|
||||
```
|
||||
eventHandler.target.addEventListener(eventHandler.eventTypeString, jsEventHandler, eventHandler.useCapture);
|
||||
```
|
||||
and change to
|
||||
```
|
||||
eventHandler.target.addEventListener(eventHandler.eventTypeString, jsEventHandler, { useCapture: eventHandler.useCapture, passive: false });
|
||||
```
|
||||
186
doc/hosting-flask.md
Normal file
@@ -0,0 +1,186 @@
|
||||
The page provides a complete example for how to integrate the webclient into a simple website
|
||||
|
||||
The example website will be structured like so:
|
||||
|
||||
```
|
||||
websrv.py
|
||||
templates/play.html
|
||||
static/classisphere.js
|
||||
static/default.zip
|
||||
static/style.css
|
||||
static/jquery.js
|
||||
```
|
||||
|
||||
## Content
|
||||
#### websrv.py
|
||||
```Python
|
||||
from flask import Flask, render_template, request
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route("/")
|
||||
def index():
|
||||
return '<html><h1>Welcome!</h1>Click <a href="/play">here</a> to play</h1></html>'
|
||||
|
||||
@app.route("/play")
|
||||
@app.route("/play/")
|
||||
def play():
|
||||
user = request.args.get('user') or 'Singleplayer'
|
||||
ver = request.args.get('mppass') or ''
|
||||
addr = request.args.get('ip')
|
||||
port = request.args.get('port') or '25565'
|
||||
|
||||
if addr:
|
||||
args = "['%s', '%s', '%s', '%s']" % (user, ver, addr, port)
|
||||
else:
|
||||
args = "['%s']" % user
|
||||
return render_template('play.html', game_args=args)
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run()
|
||||
```
|
||||
|
||||
#### templates/play.html
|
||||
```HTML
|
||||
{% set mobile_mode = request.user_agent.platform in ('android', 'iphone', 'ipad') %}
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<link href="/static/style.css" rel="stylesheet">
|
||||
<script src="/static/jquery.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
{% if mobile_mode %}
|
||||
<style>
|
||||
#body {min-height: 0px;}
|
||||
.sec {padding: 0px;}
|
||||
.row {padding: 0px;}
|
||||
</style>
|
||||
{% else %}
|
||||
<div id="header">
|
||||
<div class="row">
|
||||
<a href="/"><h1 class="columns">Home</h1></a>
|
||||
<a href="/play"><h1 class="columns">Play</h1></a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div id="body">
|
||||
<div class="sec">
|
||||
<div class="row">
|
||||
<canvas id="canvas" style="display:block; box-sizing:border-box; border-width:0px; padding:0; margin:0 auto; background-color: black; width:100%; height:auto;"
|
||||
oncontextmenu="event.preventDefault()" tabindex=-1 width="1000" height="562"></canvas>
|
||||
<span id="logmsg" style="font-size:18px;color:#F67;"></span>
|
||||
</div>
|
||||
</div>
|
||||
<script type='text/javascript'>
|
||||
function resizeGameCanvas() {
|
||||
var cc_canv = $('canvas#canvas');
|
||||
var dpi = window.devicePixelRatio;
|
||||
var aspect_ratio = 16/9;
|
||||
|
||||
var viewport_w = cc_canv.parent().width();
|
||||
var viewport_h = viewport_w / aspect_ratio;
|
||||
|
||||
var canv_w = Math.round(viewport_w);
|
||||
var canv_h = Math.round(viewport_h);
|
||||
|
||||
if (canv_h % 2) { canv_h = canv_h - 1; }
|
||||
if (canv_w % 2) { canv_w = canv_w - 1; }
|
||||
|
||||
{% if mobile_mode %}
|
||||
var screen_h = Math.min(window.innerHeight, window.outerHeight || window.innerHeight);
|
||||
canv_h = screen_h;
|
||||
{% endif %}
|
||||
cc_canv[0].width = canv_w * dpi;
|
||||
cc_canv[0].height = canv_h * dpi;
|
||||
}
|
||||
|
||||
var Module = {
|
||||
preRun: [ resizeGameCanvas ],
|
||||
postRun: [],
|
||||
arguments: {{game_args|safe}},
|
||||
print: function(text) {
|
||||
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
|
||||
console.log(text);
|
||||
},
|
||||
printErr: function(text) {
|
||||
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
|
||||
console.error(text);
|
||||
},
|
||||
canvas: (function() { return document.getElementById('canvas'); })(),
|
||||
setStatus: function(text) {
|
||||
console.log(text);
|
||||
document.getElementById('logmsg').innerHTML = text;
|
||||
},
|
||||
totalDependencies: 0,
|
||||
monitorRunDependencies: function(left) {
|
||||
this.totalDependencies = Math.max(this.totalDependencies, left);
|
||||
Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.');
|
||||
}
|
||||
};
|
||||
Module.setStatus('Downloading...');
|
||||
window.onerror = function(msg) {
|
||||
// TODO: do not warn on ok events like simulating an infinite loop or exitStatus
|
||||
Module.setStatus('Exception thrown, see JavaScript console (' + msg + ')');
|
||||
Module.setStatus = function(text) {
|
||||
if (text) Module.printErr('[post-exception status] ' + text);
|
||||
};
|
||||
};
|
||||
</script>
|
||||
<script async type="text/javascript" src="/static/classisphere.js"></script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
#### static/classisphere.js
|
||||
Download `cs.classicube.net/client/latest/ClassiCube.js` for this
|
||||
|
||||
#### static/default.zip
|
||||
Download `classicube.net/static/default.zip` for this
|
||||
|
||||
#### static/style.css
|
||||
```CSS
|
||||
body { margin: 0; }
|
||||
|
||||
.row {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
max-width: 62.5em;
|
||||
}
|
||||
|
||||
a { text-decoration: none; }
|
||||
|
||||
.columns { display: inline-block; }
|
||||
|
||||
.sec {
|
||||
background:#f1ecfa;
|
||||
padding:10px 0 5px;
|
||||
}
|
||||
|
||||
#header { background-color:#5870b0; }
|
||||
|
||||
#header h1 {
|
||||
color:#fff;
|
||||
margin:0px 10px 0px 10px;
|
||||
width: 200px;
|
||||
}
|
||||
```
|
||||
|
||||
#### static/jquery.js
|
||||
Download some version of jQuery for this. Version 2.1.1 is known to work.
|
||||
|
||||
## Notes
|
||||
|
||||
* If you don't want the game to resize to fit different resolutions, remove the `resizeGameCanvas` code.
|
||||
|
||||
* mobile_mode is used to deliver a minified page for mobile/tablet devices
|
||||
|
||||
## Results
|
||||
|
||||
After all this setup, you need to install the flask package for python.
|
||||
|
||||
Then in command prompt/terminal enter: `python websrv.py`
|
||||
|
||||
Then navigate to `http://127.0.0.1:5000/play` in your web browser. If all goes well you should see the web client start in singleplayer.
|
||||
|
||||
To start in multiplayer instead, navigate to `http://127.0.0.1:5000/play?user=test&ip=127.0.0.1&port=25565`
|
||||
97
doc/hosting-webclient.md
Normal file
@@ -0,0 +1,97 @@
|
||||
Hosting your own version of the ClassiCube webclient is relatively straightforward
|
||||
|
||||
Only the following 3 files are required:
|
||||
1) A web page to initialise the game .js and display the game
|
||||
2) The game .js file
|
||||
3) The default texture pack
|
||||
|
||||
TODO: more advanced sample (authentication, custom game.js, skin server)
|
||||
|
||||
### Example setup
|
||||
|
||||
For example, let's assume your website is setup like this:
|
||||
* `example.com/play.html`
|
||||
* `example.com/static/classisphere.js`
|
||||
* `example.com/static/default.zip`
|
||||
|
||||
For simplicitly,
|
||||
1) Download `cs.classicube.net/client/latest/ClassiCube.js`, then upload it to `static/classisphere.js` on the webserver
|
||||
2) Download `classicube.net/static/default.zip`, then upload it to `static/default.zip` on the webserver
|
||||
|
||||
The play.html page is the trickiest part, because how to implement this is website-specific. (depends on how the website is styled, what webserver is used, what programming language is used to generate the html, etc)
|
||||
|
||||
#### Changing where the game downloads the texture pack from
|
||||
|
||||
There should be this piece of code somewhere in the .JS file: `function _interop_AsyncDownloadTexturePack(rawPath) {`
|
||||
|
||||
A bit below that, there should be `var url = '/static/default.zip';` - change that to the desired URL.
|
||||
|
||||
#### Embedding the game in play.html
|
||||
|
||||
The following HTML code is required to be somewhere in the webpage:
|
||||
```HTML
|
||||
<!-- the canvas *must not* have any border or padding, or mouse coords will be wrong -->
|
||||
<canvas id="canvas" style="display:block; border:0; padding:0; background-color: black;"
|
||||
oncontextmenu="event.preventDefault()" tabindex=-1></canvas>
|
||||
<span id="logmsg"></span>
|
||||
|
||||
<script type='text/javascript'>
|
||||
var Module = {
|
||||
preRun: [],
|
||||
postRun: [],
|
||||
arguments: [ {username}, {mppass}, {server ip}, {server port} ],
|
||||
print: function(text) {
|
||||
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
|
||||
console.log(text);
|
||||
},
|
||||
printErr: function(text) {
|
||||
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
|
||||
console.error(text);
|
||||
},
|
||||
canvas: (function() { return document.getElementById('canvas'); })(),
|
||||
setStatus: function(text) {
|
||||
console.log(text);
|
||||
document.getElementById('logmsg').innerHTML = text;
|
||||
},
|
||||
totalDependencies: 0,
|
||||
monitorRunDependencies: function(left) {
|
||||
this.totalDependencies = Math.max(this.totalDependencies, left);
|
||||
Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.');
|
||||
}
|
||||
};
|
||||
Module.setStatus('Downloading...');
|
||||
window.onerror = function(msg) {
|
||||
// TODO: do not warn on ok events like simulating an infinite loop or exitStatus
|
||||
Module.setStatus('Exception thrown, see JavaScript console (' + msg + ')');
|
||||
Module.setStatus = function(text) {
|
||||
if (text) Module.printErr('[post-exception status] ' + text);
|
||||
};
|
||||
};
|
||||
</script>
|
||||
<script async type="text/javascript" src="/static/classisphere.js"></script>
|
||||
```
|
||||
**To start in singleplayer instead, just use `arguments: [ {username} ],` instead**
|
||||
|
||||
##### Variables
|
||||
* {username} - the player's username
|
||||
* {mppass} - if server verifies names, [mppass](https://wiki.vg/Classic_Protocol#User_Authentication). Otherwise leave as `''`.
|
||||
* {server ip} - the IP address of the server to connect to
|
||||
* {server port} - the port on the server to connect on (usually `'25565'`)
|
||||
|
||||
### Complete example
|
||||
|
||||
The links below show how to integrate the webclient into a simple website
|
||||
* [Flask (python webserver)](hosting-flask.md)
|
||||
|
||||
### iOS / Android support
|
||||
|
||||
The webclient is compatible with Android / iOS devices and will show a touch based UI to these devices.
|
||||
|
||||
However, due to the limited screen size available on such devices, you should consider serving a webpage consisting of just the `<canvas>` to these devices - no header, footer or anything else.
|
||||
|
||||
Additionally, you will likely want to ensure zooming is disabled, viewport width is same as the device's width, and that 'add to device homescreen' is fully supported. You can accomplish that by adding these three HTML tags to the page:
|
||||
```HTML
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||
```
|
||||
177
doc/menu-architecture.md
Normal file
@@ -0,0 +1,177 @@
|
||||
## Introduction
|
||||
|
||||
The 2D GUI works by showing multiple 'screens' or 'layers' on top of each other. Each 'screen' usually contains one or more widgets. (e.g. a 'ButtonWidget' for a 'Close' button)
|
||||
|
||||
Here's an example of multiple screens:
|
||||
|
||||

|
||||
|
||||
The example above consists of three screens:
|
||||
1. `PauseScreen` - Top layer which consists of button widgets. Also draws a background to darken the screens/layers underneath it.
|
||||
2. `ChatScreen` - Text widgets in the bottom left area (Only one is currently used though)
|
||||
3. `HUDScreen` - Text in the top left and hotbar at the bottom
|
||||
|
||||
TODO: Explain event processing architecture
|
||||
|
||||
TODO: Explain pointer IDs. maybe a separate input-architecture.md file?
|
||||
|
||||
TODO: Explain dynamic vertex buffer
|
||||
|
||||
## Screen interface
|
||||
|
||||
#### `void Init(void* screen)`
|
||||
|
||||
Where you initialise state and objects that lasts for the entire duration the screen is open
|
||||
|
||||
E.g. Hooking into events
|
||||
|
||||
#### `void Free(void* screen)`
|
||||
|
||||
Where you undo the allocating/event hooking you did in `Init`.
|
||||
|
||||
#### `void ContextRecreated(void* screen)`
|
||||
|
||||
Where you allocate resources used for rendering, such as fonts, textures of widgets, and the screen's dynamic vertex buffer.
|
||||
|
||||
E.g. where you should call `ButtonWidget_SetConst`, `TextWidget_SetConst`, etc.
|
||||
|
||||
#### `void ContextLost(void* screen)`
|
||||
|
||||
Where you destroy/release all that resources that were allocated in `ContextRecreated`.
|
||||
|
||||
Note: You **MUST** destroy all the textures/vertex buffers that you allocated, as otherwise you will get an error later with 'recreating context failed' with the Direct3D9 backend when you next try to resize the window or go fullscreen. TODO: rewrite this note
|
||||
|
||||
#### `void Layout(void* screen)`
|
||||
|
||||
Where you reposition all the elements (i.e. widgets + anything else) of this screen.
|
||||
|
||||
Note: This is called when initially showing this screen, and whenever the window is resized
|
||||
|
||||
#### `int HandlesInputDown(void* screen, int button)`
|
||||
|
||||
Called whenever a input button (keyboard/mouse/gamepad) is pressed.
|
||||
|
||||
#### `void OnInputUp(void* screen, int button)`
|
||||
|
||||
Called whenever a input button (keyboard/mouse/gamepad) is released.
|
||||
|
||||
#### `int HandlesKeyPress(void* screen, char keyChar)`
|
||||
|
||||
Called when a key character is entered on the keyboard.
|
||||
|
||||
E.g. you'd get '$' here if user pressed 4 while holding shift)
|
||||
|
||||
#### `int HandlesTextChanged(void* screen, const cc_string* str)`
|
||||
|
||||
Called when the text changes in the on-screen keyboard. (i.e. KeyPress but for mobile text input)
|
||||
|
||||
#### `int HandlesMouseScroll(void* screen, float wheelDelta)`
|
||||
|
||||
Called when the wheel is scrolled on the mouse.
|
||||
|
||||
#### `int HandlesPointerDown(void* screen, int pointerID, int x, int y)`
|
||||
|
||||
Called whenever the left mouse or a touch finger is pressed.
|
||||
|
||||
#### `void OnPointerUp(void* screen, int pointerID, int x, int y)`
|
||||
|
||||
Called whenever the left mouse or a touch finger is released.
|
||||
|
||||
#### `int HandlesPointerMove(void* screen, int pointerID, int x, int y)`
|
||||
|
||||
Called whenever the left mouse or a touch finger is moved.
|
||||
|
||||
#### `void BuildMesh(void* screen)`
|
||||
|
||||
Where you fill out the screen's dynamic vertex buffer with the vertices of all the widgets.
|
||||
|
||||
Note: This gets called just before `Render()` whenever the `dirty` field is set to `true`.
|
||||
|
||||
Note: Pointer/Input events automatically set the `dirty` field to `true` for the next frame
|
||||
|
||||
#### `void Update(void* screen, double delta)`
|
||||
|
||||
Called just before `Render()` every frame and also provides the elapsed time since last render.
|
||||
|
||||
Typically you'd use this to update simple stuff that depends on accumulated time.
|
||||
(E.g. whether the flashing caret should appear or not for input widgets)
|
||||
|
||||
#### `void Render(void* screen)`
|
||||
|
||||
Called every frame and is where you actually draw the widgets and other stuff on-screen.
|
||||
|
||||
## Screen members
|
||||
|
||||
#### `struct ScreenVTABLE* VTABLE`
|
||||
|
||||
Set to a `ScreenVTABLE` instance which implements all of the `Screen interface` functions
|
||||
|
||||
#### `cc_bool grabsInput`
|
||||
|
||||
Whether this screen grabs all input.
|
||||
|
||||
Note: If any screen grabs all input, then the mouse cursor becomes visible, W/A/S/D stops causing player movement, etc.
|
||||
|
||||
#### `cc_bool blocksWorld`
|
||||
|
||||
Whether this screen completely and opaquely covers the game world behind it.
|
||||
|
||||
E.g. loading screen and disconnect screen
|
||||
|
||||
#### `cc_bool closable`
|
||||
|
||||
Whether this screen is automatically closed when pressing Escape.
|
||||
|
||||
Note: Usually should be true for screens that are menus (e.g. pause screen)
|
||||
|
||||
#### `cc_bool dirty`
|
||||
|
||||
Whether this screen will have `BuildMesh()` called on the next frame
|
||||
|
||||
Note: This should be set to `true` whenever any event/actions that might alter the screen's appearance occurs TODO explain when automatically called?
|
||||
|
||||
#### `int maxVertices`
|
||||
|
||||
The maximum number of vertices that this screen's dynamic vertex buffer may use
|
||||
|
||||
#### `GfxResourceID vb`
|
||||
|
||||
This screen's dynamic vertex buffer
|
||||
|
||||
#### `struct Widget** widgets;`
|
||||
|
||||
Pointer to the array of pointers to widgets that are contained in this screen
|
||||
|
||||
#### `int numWidgets;`
|
||||
|
||||
The number of widgets that are contained in this screen
|
||||
|
||||
|
||||
## Screen notes
|
||||
|
||||
* When the screen is shown via `Gui_Add`, the following functions are called
|
||||
1) Init
|
||||
2) ContextRecreated
|
||||
3) Layout
|
||||
4) HandlesPointerMove
|
||||
|
||||
* When the screen is removed via `Gui_Remove`, the following functions are called
|
||||
1) ContextLost
|
||||
2) Free
|
||||
|
||||
* When the screen is refreshed via `Gui_Refresh`, the following functions are called
|
||||
1) ContextLost
|
||||
2) ContextRecreated
|
||||
3) Layout
|
||||
|
||||
Note: Whenever `default.png` (font texture) changes, `Gui_Refresh` is called for all screens. Therefore, fonts should usually be allocated/freed in `ContextRecreated/ContextLost` instead of `Init/Free` to ensure that the screen still looks correct after the texture pack changes.
|
||||
|
||||
TODO: Move this note earlier?
|
||||
|
||||
# Putting it altogether
|
||||
|
||||
TODO Add example of screen
|
||||
|
||||
Simple menu example that grabs all input
|
||||
|
||||
More complicated example too
|
||||
124
doc/modules.md
Normal file
@@ -0,0 +1,124 @@
|
||||
The overall source code is structured where each .c represents a particular module. These modules are:
|
||||
|
||||
TODO: explain multiple backends for some Modules
|
||||
|
||||
## 2D modules
|
||||
|Module|Functionality|
|
||||
|--------|-------|
|
||||
|Bitmap|Represents a 2D array of pixels (and encoding/decoding to PNG)
|
||||
|Drawer2D|Contains a variety of drawing operations on bitmaps (including text and fonts)
|
||||
|PackedCol|32 bit RGBA color in a format suitable for using as color component of a vertex
|
||||
|SystemFonts|Drawing, measuring, and retrieving the list of platform/system specific fonts
|
||||
|
||||
## Audio modules
|
||||
|Module|Functionality|
|
||||
|--------|-------|
|
||||
|Audio|Playing music and dig/place/step sounds, and abstracts a PCM audio playing API
|
||||
|Vorbis| Decodes [ogg vorbis](https://xiph.org/vorbis/) audio into PCM audio samples
|
||||
|
||||
## Entity modules
|
||||
|Module|Functionality|
|
||||
|--------|-------|
|
||||
|Entity|Represents an in-game entity, and manages updating and rendering all entities
|
||||
|EntityComponents|Various components that can be used by entities (e.g. tilt, animation, hacks state)
|
||||
|Model|Contains the list of entity models, and provides relevant methods for entity models
|
||||
|Particle|Represents particle effects, and manages rendering and spawning particles
|
||||
|
||||
## Game modules
|
||||
|File|Functionality|
|
||||
|--------|-------|
|
||||
|Block|Stores properties and data for blocks (e.g. collide type, draw type, sound type)
|
||||
|BlockPhysics|Implements simple block physics for singleplayer
|
||||
|Camera|Represents a camera (can be first or third person)
|
||||
|Chat|Manages sending, adding, logging and handling chat
|
||||
|Game|Manages the overall game loop, state, and variables (e.g. renders a frame, runs scheduled tasks)
|
||||
|Input|Manages keyboard, mouse, and touch state and events, and implements base handlers for them
|
||||
|Inventory|Manages inventory hotbar, and ordering of blocks in the inventory menu
|
||||
|
||||
## Game gui modules
|
||||
|File|Functionality|
|
||||
|--------|-------|
|
||||
|Gui|Describes and manages the 2D GUI elements on screen
|
||||
|IsometricDrawer|Draws 2D isometric blocks for the hotbar and inventory UIs
|
||||
|Menus|Contains all 2D non-menu screens (e.g. inventory, HUD, loading, chat)
|
||||
|Screens|Contains all 2D menu screens (e.g. pause menu, keys list menu, font list menu)
|
||||
|Widgets|Contains individual GUI widgets (e.g. button, label)
|
||||
|
||||
## Graphics modules
|
||||
|Module|Functionality|
|
||||
|--------|-------|
|
||||
|Builder|Converts a 16x16x16 chunk into a mesh of vertices
|
||||
|Drawer|Draws the vertices for a cuboid region
|
||||
|Graphics|Abstracts a 3D graphics rendering API
|
||||
|
||||
## I/O modules
|
||||
|Module|Functionality|
|
||||
|--------|-------|
|
||||
|Deflate|Decodes and encodes data compressed using DEFLATE (in addition to GZIP/ZLIB headers)
|
||||
|Stream|Abstract reading and writing data to/from various sources in a streaming manner
|
||||
|
||||
## Launcher modules
|
||||
|Module|Functionality|
|
||||
|--------|-------|
|
||||
|Launcher|Manages the overall launcher loop, state, and variables (e.g. resets pixels in areas, marks areas as needing to be redrawn)
|
||||
|LBackend|Handles the rendering of widgets and forwarding input events to screens/menus
|
||||
|LScreens|Contains all the menus in the launcher (e.g. servers list, updates menu, main menu)
|
||||
|LWeb|Responsible for launcher related web requests (e.g. signing in, fetching servers list)
|
||||
|LWidgets|Contains individual launcher GUI widgets (e.g. button, label, input textbox)
|
||||
|Resources|Responsible for checking, downloading, and creating the default assets (e.g. default.zip, sounds)
|
||||
|
||||
## Map modules
|
||||
|Module|Description|
|
||||
|--------|-------|
|
||||
|Formats|Imports/exports a world from/to several map file formats (e.g. .cw, .dat, .lvl)
|
||||
|Generator|Generates a new world in either a flatgrass or Minecraft Classic style
|
||||
|Lighting|Gets lighting colors at coordinates in the world
|
||||
|World|Manages fixed size 3D array of blocks and associated environment metadata
|
||||
|
||||
## Math/Physics modules
|
||||
|Module|Description|
|
||||
|--------|-------|
|
||||
|ExtMath|Math functions, math constants, and a Random Number Generator
|
||||
|Physics|AABBs and geometry intersection
|
||||
|Picking|Performs raytracing to e.g. determine the picked/selected block in the world
|
||||
|Vectors|Contains vector,matrix,and frustum culling
|
||||
|
||||
## Network modules
|
||||
|Module|Description|
|
||||
|--------|-------|
|
||||
|Http|Performs GET and POST requests in the background
|
||||
|Protocol|Implements Minecraft Classic, CPE, and WoM environment protocols
|
||||
|Server|Manages a connection to a singleplayer or multiplayer server
|
||||
|SSL|Performs SSL/TLS encryption and decryption
|
||||
|
||||
## Platform modules
|
||||
|Module|Description|
|
||||
|--------|-------|
|
||||
|Logger|Manages logging to client.log, and dumping state in both intentional and unhandled crashes
|
||||
|Platform|Abstracts platform specific functionality. (e.g. opening a file, allocating memory, starting a thread)
|
||||
|Program|Parses command line arguments, and then starts either the Game or Launcher
|
||||
|Window|Abstracts creating and managing a window (e.g. setting titlebar text, entering fullscreen)
|
||||
|
||||
## Rendering modules
|
||||
|Module|Description|
|
||||
|--------|-------|
|
||||
|AxisLinesRenderer|Renders 3 lines showing direction of each axis
|
||||
|EnvRenderer|Renders environment of the world (clouds, sky, skybox, world sides/edges, etc)
|
||||
|HeldBlockRenderer|Renders the block currently being held in bottom right corner
|
||||
|MapRenderer|Renders the blocks of the world by diving it into chunks, and manages sorting/updating these chunks
|
||||
|SelOutlineRenderer|Renders an outline around the block currently being looked at
|
||||
|SelectionBox|Renders and stores selection boxes
|
||||
|
||||
## Texture pack modules
|
||||
|Module|Functionality|
|
||||
|--------|-------|
|
||||
|Animations|Everything relating to texture animations (including default water/lava ones)
|
||||
|TexturePack|Everything relating to texture packs (e.g. extracting .zip, terrain atlas, etc)
|
||||
|
||||
## Utility modules
|
||||
|Module|Functionality|
|
||||
|--------|-------|
|
||||
|Event|Contains all events and provies helper methods for using events
|
||||
|Options|Retrieves options from and sets options in options.txt
|
||||
|String|Implements operations for a string with a buffer, length, and capacity
|
||||
|Utils|Various general utility functions
|
||||
171
doc/options.md
Normal file
@@ -0,0 +1,171 @@
|
||||
Listed below are all of the options supported in options.txt
|
||||
|
||||
# Global options
|
||||
|
||||
### HTTP options
|
||||
|Name|Default|Description|
|
||||
|--|--|--|
|
||||
`http-no-https`|`false`|Whether `https://` support is disabled<br>**Disabling means your account password is transmitted in plaintext**
|
||||
`https-verify`|`false`|Whether to validate 'https://' certificates returned by webservers<br>**Disabling this is a bad idea, but is still less bad than `http-no-https`**
|
||||
|
||||
### Text drawing options
|
||||
|Name|Default|Description|
|
||||
|--|--|--|
|
||||
`gui-arialchatfont`|`false`|Whether system fonts are used instead of default.png for drawing most text
|
||||
`gui-blacktextshadows`|`false`|Whether text shadow color is pure black instead of faded
|
||||
`gui-fontname`||Name of preferred system font to use for text rendering
|
||||
|
||||
### Window options
|
||||
|Name|Default|Description|
|
||||
|--|--|--|
|
||||
`landscape-mode`|`false`|Whether to force landscape orientation<br>**Only supported on Android/iOS**
|
||||
|
||||
# Launcher options
|
||||
|
||||
### General options
|
||||
|Name|Default|Description|
|
||||
|--|--|--|
|
||||
`autocloselauncher`|`false`|Whether to automatically close the launcher after the game is started
|
||||
`launcher-cc-username`||Account username
|
||||
`launcher-cc-password`||Encrypted account password
|
||||
`nostalgia-classicbg`|false`|Whether to draw classic minecraft.net like background
|
||||
|
||||
### Web options
|
||||
|Name|Default|Description|
|
||||
|--|--|--|
|
||||
`server-services`|`https://www.classicube.net/api`|URL for account services (login and server list)
|
||||
`launcher-session`||Encrypted session cookie<br>Valid session cookies avoids MFA/2FA check
|
||||
|
||||
### Theme colors
|
||||
|Name|Description|
|
||||
|--|--|
|
||||
`launcher-back-col`|Background/base color
|
||||
`launcher-btn-border-col`|Color of border arround buttons
|
||||
`launcher-btn-fore-active-col`|Color of button when mouse is hovered over
|
||||
`launcher-btn-fore-inactive-col`|Normal color of buttons
|
||||
`launcher-btn-highlight-inactive-col`|Color of line at top of buttons
|
||||
|
||||
### Direct connect
|
||||
|Name|Description|
|
||||
|--|--|
|
||||
`launcher-dc-username`|Username to use when connecting
|
||||
`launcher-dc-ip`|IP address or hostname to connect to
|
||||
`launcher-dc-port`|Port to connect on
|
||||
`launcher-dc-mppass`|Encrypted mppass to use when connecting
|
||||
|
||||
### Resume
|
||||
|Name|Description|
|
||||
|--|--|
|
||||
`launcherserver`|Name of server to connect to<br>Hint for user, not actually used for connecting
|
||||
`launcher-username`|Username to use when connecting
|
||||
`launcher-ip`|IP address or hostname to connect to
|
||||
`launcher-port`|Port to connect on
|
||||
`launcher-mppass`|Encrypted mppass to use when connecting
|
||||
|
||||
# Game options
|
||||
|
||||
### Audio options
|
||||
|Name|Default|Description|
|
||||
|--|--|--|
|
||||
`soundsvolume`|`0` for webclient<br>`100` elsewhere|Volume of game sounds (e.g. break/walk sounds)<br>Volume must be between 0 and 100
|
||||
`musicvolume`|`0` for webclient<br>`100` elsewhere|Volume of game background music<br>Volume must be between 0 and 100
|
||||
`music-mindelay`|`120` (2 minutes)|Minimum delay before next music track is played <br>Delay must be between 0 and 3600
|
||||
`music-maxdelay`|`420` (7 minutes)|Maximum delay before next music track is played <br>Delay must be between 0 and 3600
|
||||
|
||||
### Block physics options
|
||||
|Name|Default|Description|
|
||||
|--|--|--|
|
||||
`singleplayerphysics`|`true`|Whether block physics are enabled in singleplayer
|
||||
|
||||
### Chat options
|
||||
|Name|Default|Description|
|
||||
|--|--|--|
|
||||
`chat-logging`|`false` for mobile/web<br>`true` elsewhere|Whether to log chat messages to disc
|
||||
|
||||
### HTTP options
|
||||
|Name|Default|Description|
|
||||
|--|--|--|
|
||||
`http-skinserver`|`http://classicube.s3.amazonaws.com/skin`|URL where player skins are downloaded from
|
||||
|
||||
### Map rendering options
|
||||
|Name|Default|Description|
|
||||
|--|--|--|
|
||||
`gfx-smoothlighting`|`false`|Whether smooth/advanced lighting is enabled
|
||||
`gfx-maxchunkupdates`|`30`|Max number of chunks built in one frame<br>Must be between 4 and 1024
|
||||
|
||||
### Camera options
|
||||
|Name|Default|Description|
|
||||
|--|--|--|
|
||||
`mousesensitivity`|`40` for Windows<br>`30` elsewhere|How sensitive camera rotation is to mouse movement<br>Sensitivity must be between 1 and 200
|
||||
`hacks-fov`|`70`|Field of view<br>Must be between 1 and 179
|
||||
`hacks-cameraclipping`|`true`|Whether third person camera is clipped to not go inside blocks
|
||||
`invertmouse`|`true`|Whether vertical mouse movement direction is inverted
|
||||
`camera-smooth`|`false`|Whether smooth camera mode is enabled
|
||||
`cameramass`|`20`|How smooth the smooth camera is<br>Value must be between 1 and 100
|
||||
|
||||
### Game options
|
||||
|Name|Default|Description|
|
||||
|--|--|--|
|
||||
./Game.c: Game_ClassicMode = Options_GetBool(OPT_CLASSIC_MODE, false);
|
||||
./Game.c: Game_ClassicHacks = Options_GetBool(OPT_CLASSIC_HACKS, false);
|
||||
./Game.c: Game_AllowCustomBlocks = Options_GetBool(OPT_CUSTOM_BLOCKS, true);
|
||||
./Game.c: Game_UseCPE = Options_GetBool(OPT_CPE, true);
|
||||
./Game.c: Game_SimpleArmsAnim = Options_GetBool(OPT_SIMPLE_ARMS_ANIM, false);
|
||||
./Game.c: Game_ViewBobbing = Options_GetBool(OPT_VIEW_BOBBING, true);
|
||||
./Game.c: Game_ViewDistance = Options_GetInt(OPT_VIEW_DISTANCE, 8, 4096, 512);
|
||||
./Game.c: Game_BreakableLiquids = !Game_ClassicMode && Options_GetBool(OPT_MODIFIABLE_LIQUIDS, false);
|
||||
./Game.c: Game_AllowServerTextures = Options_GetBool(OPT_SERVER_TEXTURES, true);
|
||||
|
||||
### Hacks options
|
||||
|Name|Default|Description|
|
||||
|--|--|--|
|
||||
`hacks-hacksenabled`|`true`|Whether hacks are enabled at all<br>Has no effect in 'classic only' game mode
|
||||
`hacks-speedmultiplier`|`10.0`|Speed multiplier/factor when speedhacks are active<br>Multiplier must be between 0.1 and 50.0
|
||||
`hacks-pushbackplacing`|`false`|Whether to enable pushback placing mode
|
||||
`hacks-noclipslide`|`false`|Whether to still slide for a bit after a movement button is released in noclip mode
|
||||
`hacks-womstylehacks`|`false`|Whether to enable WoM client style hacks (e.g. ludicrous triple jump)
|
||||
`hacks-fullblockstep`|`false`|Whether to automatically climb up 1.0 (default is only 0.5) tall blocks
|
||||
`hacks-jumpvelocity`|`0.42`|Initial vertical velocity when you start a jump<br>Velocity must be between 0.0 and 52.0
|
||||
`hacks-perm-msgs`|`true`|Whether to show a message in chat if you attempt to use a currently disabled hack
|
||||
|
||||
## General rendering options
|
||||
|Name|Default|Description|
|
||||
|--|--|--|
|
||||
`gfx-mipmaps`|`false`|Whether to use mipmaps to reduce faraway texture noise
|
||||
`fpslimit`|`LimitVSync`|Strategy used to limit FPS<br>Strategies: LimitVSync, Limit30FPS, Limit60FPS, Limit120FPS, Limit144FPS, LimitNone
|
||||
`normal`|`normal`|Environmental effects render mode<br>Modes: normal, normalfast, legacy, legacyfast<br>- legacy improves appearance on some older GPUs<br>- fast disables clouds, fog and overhead sky
|
||||
|
||||
## Other rendering options
|
||||
|Name|Default|Description|
|
||||
|--|--|--|
|
||||
`nostalgia-classicarm`|Classic mode|Whether to render your own arm in classic or modern minecraft style
|
||||
`gui-blockinhand`|`true`|Whether to show block currently being held in bottom right corner
|
||||
`namesmode`|`Hovered`|Entity nametag rendering mode<br>None, Hovered, All, AllHovered, AllUnscaled
|
||||
`entityshadow`|`None`|Entity shadow rendering mode<br>None, SnapToBlock, Circle, CircleAll
|
||||
|
||||
### Texture pack options
|
||||
|Name|Default|Description|
|
||||
|--|--|--|
|
||||
`defaulttexpack`|`default.zip`|Filename of default texture pack
|
||||
|
||||
### Window options
|
||||
|Name|Default|Description|
|
||||
|--|--|--|
|
||||
`window-width`|`854`|Width of game window<br>Width must be between 0 and display width
|
||||
`window-height`|`480`|Height of game window<br>Height must be between 0 and display height
|
||||
`win-grab-cursor`|`false`|Whether to grab exclusive control over the cursor<br>**Only supported on Linux/BSD**
|
||||
|
||||
./Gui.c: Gui.Chatlines = Options_GetInt(OPT_CHATLINES, 0, 30, Gui.DefaultLines);
|
||||
./Gui.c: Gui.ClickableChat = !Game_ClassicMode && Options_GetBool(OPT_CLICKABLE_CHAT, !Input_TouchMode);
|
||||
./Gui.c: Gui.TabAutocomplete = !Game_ClassicMode && Options_GetBool(OPT_TAB_AUTOCOMPLETE, true);
|
||||
./Gui.c: Gui.ClassicTexture = Options_GetBool(OPT_CLASSIC_GUI, true) || Game_ClassicMode;
|
||||
./Gui.c: Gui.ClassicTabList = Options_GetBool(OPT_CLASSIC_TABLIST, false) || Game_ClassicMode;
|
||||
./Gui.c: Gui.ClassicMenu = Options_GetBool(OPT_CLASSIC_OPTIONS, false) || Game_ClassicMode;
|
||||
./Gui.c: Gui.ClassicChat = Options_GetBool(OPT_CLASSIC_CHAT, false) || Game_PureClassic;
|
||||
./Gui.c: Gui.ShowFPS = Options_GetBool(OPT_SHOW_FPS, true);
|
||||
./Gui.c: Gui.RawInventoryScale = Options_GetFloat(OPT_INVENTORY_SCALE, 0.25f, 5.0f, 1.0f);
|
||||
./Gui.c: Gui.RawHotbarScale = Options_GetFloat(OPT_HOTBAR_SCALE, 0.25f, 5.0f, 1.0f);
|
||||
./Gui.c: Gui.RawChatScale = Options_GetFloat(OPT_CHAT_SCALE, 0.25f, 5.0f, 1.0f);
|
||||
./Gui.c: Gui.RawTouchScale = Options_GetFloat(OPT_TOUCH_SCALE, 0.25f, 5.0f, 1.0f);
|
||||
./Gui.c: Gui._onscreenButtons = Options_GetInt(OPT_TOUCH_BUTTONS, 0, Int32_MaxValue,
|
||||
./Input.c: mapping = Options_GetEnum(name.buffer, KeyBind_Defaults[i], Input_Names, INPUT_COUNT);
|
||||
72
doc/overriding-defaults.md
Normal file
@@ -0,0 +1,72 @@
|
||||
Although ClassiCube strives to be as platform independent as possible, in some cases it will need to use system specific code
|
||||
|
||||
For instance:
|
||||
* Texture creation for 3D graphics rendering
|
||||
* Buffer allocation for audio output
|
||||
* High resolution time measurement
|
||||
* Window creation
|
||||
|
||||
For simplicity, related system specific code is grouped together as a Module (e.g. `Audio`), which can then be implemented using a backend (e.g. `WinMM`, `OpenAL`, `OpenSL ES`, etc)
|
||||
|
||||
#### Note: By default, ClassiCube automatically selects the recommended backends for the system. <br> It is recommended that you do *NOT* change the backends unless you know exactly what you are doing.
|
||||
|
||||
Some systems may provide multiple potential backends for a Module. For example on Windows:
|
||||
* OpenGL could be used instead of Direct3D 9 for the 3D rendering backend
|
||||
* SDL could be used instead of the native WinAPI for the window backend
|
||||
|
||||
TODO finish this
|
||||
|
||||
TODO introduction (explaining platform specific modules, and how classicube has to integrate with one of them)
|
||||
|
||||
There are two ways of changing the backend that gets used for the system:
|
||||
1) Changing the default defines in `Core.h`
|
||||
2) Using additional compilation flags to override default module backend(s)
|
||||
3) Adding `-DCC_BUILD_MANUAL` to compilation flags and then manually defining all module backends via additional compilation flags
|
||||
|
||||
When manually compiling the source code, 1) is usually the easiest. <br>
|
||||
For automated scripts compiling every single commit, 2) is the recommended approach
|
||||
TODO: Move this into table
|
||||
|
||||
|
||||
### 3D Graphics backends (`CC_GFX_BACKEND`)
|
||||
* CC_GFX_BACKEND_SOFTGPU - Software rasteriser
|
||||
* CC_GFX_BACKEND_D3D9 - Direct3D 9
|
||||
* CC_GFX_BACKEND_D3D11 - Direct3D 11
|
||||
* CC_GFX_BACKEND_GL1 - OpenGL 1.2/1.5
|
||||
* CC_GFX_BACKEND_GL2 - OpenGL 2 (shaders)
|
||||
|
||||
The OpenGL backend can be further customised:
|
||||
* CC_BUILD_GL11 (must be using CC_GFX_BACKEND_GL1)
|
||||
* CC_BUILD_GLES (must be using CC_GFX_BACKEND_GL2)
|
||||
|
||||
### OpenGL context backends
|
||||
* CC_BUILD_EGL
|
||||
* CC_BUILD_WGL
|
||||
|
||||
### HTTP backends (`CC_NET_BACKEND`)
|
||||
* CC_NET_BACKEND_BUILTIN - custom HTTP client
|
||||
* CC_NET_BACKEND_LIBCURL
|
||||
* CC_BUILD_CFNETWORK
|
||||
|
||||
### SSL backends (`CC_SSL_BACKEND`)
|
||||
* CC_SSL_BACKEND_NONE
|
||||
* CC_SSL_BACKEND_BEARSSL
|
||||
* CC_SSL_BACKEND_SCHANNEL
|
||||
|
||||
### Window backends (`CC_WIN_BACKEND`)
|
||||
* CC_WIN_BACKEND_TERMINAL
|
||||
* CC_WIN_BACKEND_SDL2
|
||||
* CC_WIN_BACKEND_SDL3
|
||||
* CC_WIN_BACKEND_X11
|
||||
* CC_WIN_BACKEND_WIN32
|
||||
|
||||
### Audio backends (`CC_AUD_BACKEND`)
|
||||
* CC_AUD_BACKEND_OPENAL
|
||||
* CC_AUD_BACKEND_WINMM
|
||||
* CC_AUD_BACKEND_OPENSLES
|
||||
|
||||
### Platform backends
|
||||
* CC_BUILD_POSIX
|
||||
* CC_BUILD_WIN
|
||||
|
||||
TODO fill in rest
|
||||
253
doc/plugin-dev.md
Normal file
@@ -0,0 +1,253 @@
|
||||
This document details how to compile a basic plugin in Visual Studio, MinGW, or GCC/Clang.
|
||||
|
||||
To find the functions and variables available for use in plugins, look for `CC_API`/`CC_VAR` in the .h files.
|
||||
|
||||
[Source code of some actual plugins](https://github.com/ClassiCube/ClassiCube-Plugins/)
|
||||
|
||||
### Setup
|
||||
|
||||
You need to download and install either Visual Studio, MinGW, or GCC/Clang.
|
||||
|
||||
*Note: MinGW/GCC/Clang are relatively small, while Visual Studio is gigabytes in size.
|
||||
If you're just trying to compile a plugin on Windows you might want to use MinGW. See main readme.*
|
||||
|
||||
I assume your directory is structured like this:
|
||||
```
|
||||
src/...
|
||||
TestPlugin.c
|
||||
```
|
||||
Or in other words, in a directory somewhere, you have a file named `TestPlugin.c`, and then a sub-directory named `src` which contains the game's source code.
|
||||
|
||||
### Basic plugin
|
||||
```C
|
||||
#include "src/Chat.h"
|
||||
#include "src/Game.h"
|
||||
#include "src/String.h"
|
||||
|
||||
static void TestPlugin_Init(void) {
|
||||
cc_string msg = String_FromConst("Hello world!");
|
||||
Chat_Add(&msg);
|
||||
}
|
||||
|
||||
int Plugin_ApiVersion = 1;
|
||||
struct IGameComponent Plugin_Component = { TestPlugin_Init };
|
||||
```
|
||||
Here's the idea for a basic plugin that shows "Hello world" in chat when the game starts. Alas, this won't compile...
|
||||
|
||||
### Basic plugin boilerplate
|
||||
```C
|
||||
#ifdef _WIN32
|
||||
#define CC_API __declspec(dllimport)
|
||||
#define CC_VAR __declspec(dllimport)
|
||||
#define EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define CC_API
|
||||
#define CC_VAR
|
||||
#define EXPORT __attribute__((visibility("default")))
|
||||
#endif
|
||||
|
||||
#include "src/Chat.h"
|
||||
#include "src/Game.h"
|
||||
#include "src/String.h"
|
||||
|
||||
static void TestPlugin_Init(void) {
|
||||
cc_string msg = String_FromConst("Hello world!");
|
||||
Chat_Add(&msg);
|
||||
}
|
||||
|
||||
EXPORT int Plugin_ApiVersion = 1;
|
||||
EXPORT struct IGameComponent Plugin_Component = { TestPlugin_Init };
|
||||
```
|
||||
With this boilerplate, we're ready to compile the plugin.
|
||||
All plugins require this boilerplate, so feel free to copy and paste it.
|
||||
|
||||
---
|
||||
|
||||
### Writing plugins in C++
|
||||
|
||||
Exported plugin functions **must** be surrounded with `extern "C"`, i.e.
|
||||
```C
|
||||
extern "C" {
|
||||
EXPORT int Plugin_ApiVersion = 1;
|
||||
EXPORT struct IGameComponent Plugin_Component = { TestPlugin_Init };
|
||||
}
|
||||
```
|
||||
Otherwise your plugin will not load. (you'll see `error getting plugin version` in-game)
|
||||
|
||||
---
|
||||
|
||||
## Compiling
|
||||
|
||||
Plugin compilation instructions differs depending on the compiler and operating system
|
||||
|
||||
### Linux
|
||||
|
||||
[Compiling using gcc or clang](plugin-dev.md#using-gcc-or-clang)
|
||||
|
||||
[Cross compiling for Windows 32-bit](plugin-dev.md#cross-compiling-for-windows-32-bit-using-mingw-w64)
|
||||
|
||||
[Cross compiling for Windows 64-bit](plugin-dev.md#cross-compiling-for-windows-64-bit-using-mingw-w64)
|
||||
|
||||
### macOS
|
||||
|
||||
[Compiling using gcc or clang](plugin-dev.md#using-gcc-or-clang-1)
|
||||
|
||||
### Windows
|
||||
|
||||
[Compiling using Visual Studio](plugin-dev.md#using-visual-studio)
|
||||
|
||||
[Compiling using mingw-w64](plugin-dev.md#using-mingw-w64)
|
||||
|
||||
---
|
||||
|
||||
## Compiling - Linux
|
||||
|
||||
### Using gcc or clang
|
||||
|
||||
#### Compiling
|
||||
|
||||
`cc TestPlugin.c -o TestPlugin.so -shared -fPIC`
|
||||
|
||||
Then put `TestPlugin.so` into your game's `plugins` folder. Done.
|
||||
|
||||
### Cross compiling for Windows 32 bit using mingw-w64
|
||||
|
||||
#### Setup
|
||||
|
||||
1) Create `ClassiCube.exe` by either:
|
||||
1) Compiling the game, see `Cross compiling for windows (32 bit)` in [main readme](/readme.md#cross-compiling-for-windows-32-bit)
|
||||
2) Downloading 32 bit ClassiCube from https://www.classicube.net/download/#dl-win
|
||||
2) Install the `mingw-w64-tools` package (if it isn't already)
|
||||
3) Generate the list of exported symbols from `ClassiCube.exe` by running:
|
||||
* `gendef ClassiCube.exe`
|
||||
4) Create a linkable library from the exported symbols list by running:
|
||||
* `i686-w64-mingw32-dlltool -d ClassiCube.def -l libClassiCube.a -D ClassiCube.exe`
|
||||
|
||||
TODO: also document alternate method of compiling the game using --out-implib
|
||||
|
||||
#### Compiling
|
||||
|
||||
`i686-w64-mingw32-gcc TestPlugin.c -o TestPlugin.dll -s -shared -L . -lClassiCube`
|
||||
|
||||
Then put `TestPlugin.dll` into your game's `plugins` folder. Done.
|
||||
|
||||
### Cross compiling for Windows 64 bit using mingw-w64
|
||||
|
||||
#### Setup
|
||||
|
||||
1) Create `ClassiCube.exe` by either:
|
||||
1) Compiling the game, see `Cross compiling for windows (64 bit)` in [main readme](/readme.md#cross-compiling-for-windows-64-bit)
|
||||
2) Downloading 64 bit ClassiCube from https://www.classicube.net/download/#dl-win
|
||||
2) Install the `mingw-w64-tools` package (if it isn't already)
|
||||
3) Generate the list of exported symbols from `ClassiCube.exe` by running:
|
||||
* `gendef ClassiCube.exe`
|
||||
4) Create a linkable library from the exported symbols list by running:
|
||||
* `x86_64-w64-mingw32-dlltool -d ClassiCube.def -l libClassiCube.a -D ClassiCube.exe`
|
||||
|
||||
TODO: also document alternate method of compiling the game using --out-implib
|
||||
|
||||
#### Compiling
|
||||
|
||||
`x86_64-w64-mingw32-gcc TestPlugin.c -o TestPlugin.dll -s -shared -L . -lClassiCube`
|
||||
|
||||
Then put `TestPlugin.dll` into your game's `plugins` folder. Done.
|
||||
|
||||
## Compiling - macOS
|
||||
|
||||
### Using gcc or clang
|
||||
|
||||
#### Compiling
|
||||
|
||||
`cc TestPlugin.c -o TestPlugin.dylib -undefined dynamic_lookup`
|
||||
|
||||
Then put `TestPlugin.dylib` into your game's `plugins` folder. Done.
|
||||
|
||||
## Compiling - Windows
|
||||
|
||||
### Using Visual Studio
|
||||
TODO more detailed when I have some more time...
|
||||
|
||||
#### Setup
|
||||
|
||||
1) Compile the game, see `Compiling - Windows > using Visual Studio` in main readme
|
||||
2) Find the `ClassiCube.lib` that was generated when compiling the game. Usually it is in either `src\x64\Debug` or `src\x86\Debug`.
|
||||
3) Add a new `Empty Project` to the ClassiCube solution, then add the plugin .c files to it
|
||||
|
||||
Note: If the plugin provides a .vcxproj file, you can skip step 2 and just open that project file instead.
|
||||
|
||||
#### Configuration - alternative #1
|
||||
|
||||
The simplest way of linking to the `.lib` file is simply adding the following code to one of the plugin's `.c` files
|
||||
|
||||
```C
|
||||
#ifdef _MSC_VER
|
||||
#ifdef _WIN64
|
||||
#pragma comment(lib, "[GAME SRC FOLDER]/x64/Debug/ClassiCube.lib")
|
||||
#else
|
||||
#pragma comment(lib, "[GAME SRC FOLDER]/x86/Debug/ClassiCube.lib")
|
||||
#endif
|
||||
#endif
|
||||
```
|
||||
|
||||
replacing `[GAME SRC FOLDER]` with the full path of `src` folder (e.g. `C:/Dev/ClassiCube/src`)
|
||||
|
||||
#### Configuration - alternative #2
|
||||
|
||||
The more complicated way of linking to the `.lib` file is to add it to the plugin's project configuration file
|
||||
|
||||
Right click the plugin project in the `Solution Explorer` pane, then click `Properties`
|
||||
|
||||
TODO: add screenshots here
|
||||
|
||||
TODO: may need to configure include directories
|
||||
|
||||
1) In `Configuration properties` -> `General`, make sure `Configuration type` is set to `Dynamic library (.DLL)`
|
||||
|
||||
2) In `Configuration properties` -> `Linker` -> `Input`, click the dropdown button for `Additional Dependencies`, then click `Edit`. Add the full path to `ClassiCube.lib`, then click `OK`
|
||||
|
||||
#### Compiling
|
||||
|
||||
Build the project. There should be a line in the build output that tells you where you can find the .dll file like this:
|
||||
`
|
||||
Project1.vcxproj -> C:\classicube-dev\testplugin\src\x64\Debug\TestPlugin.dll
|
||||
`
|
||||
|
||||
Then put `TestPlugin.dll` into your game's `plugins` folder. Done.
|
||||
|
||||
### Using mingw-w64
|
||||
|
||||
#### Setup
|
||||
|
||||
1) Create `ClassiCube.exe` by either:
|
||||
1) Compiling the game, see `Compiling for windows (MinGW-w64)` in [main readme](/readme.md#using-mingw-w64)
|
||||
2) Downloading ClassiCube from https://www.classicube.net/download/#dl-win
|
||||
2) Generate the list of exported symbols in `ClassiCube.exe` by running:
|
||||
* `gendef ClassiCube.exe`
|
||||
3) Create a linkable library from the exported symbols list by running:
|
||||
* `dlltool -d ClassiCube.def -l libClassiCube.a -D ClassiCube.exe`
|
||||
|
||||
#### Compiling
|
||||
|
||||
`gcc TestPlugin.c -o TestPlugin.dll -s -shared -L . -lClassiCube`
|
||||
|
||||
Then put `TestPlugin.dll` into your game's `plugins` folder. Done.
|
||||
|
||||
## Notes for compiling for Windows
|
||||
|
||||
### Ensuring your plugin works when the ClassiCube exe isn't named ClassiCube.exe
|
||||
|
||||
If you follow the prior compilation instructions, the compiled DLL will have a runtime dependancy on `ClassiCube.exe`
|
||||
|
||||
However, this means that if the executable is e.g. named `ClassiCube (2).exe` instead. the plugin DLL will fail to load
|
||||
|
||||
To avoid this problem, you must
|
||||
1) Stop linking to `ClassiCube` (e.g. for `MinGW`, remove the ` -L . -lClassiCube`)
|
||||
2) Load all functions and variables exported from ClassiCube via `GetProcAddress` instead
|
||||
|
||||
This is somewhat tedious to do - see [here](https://github.com/ClassiCube/ClassiCube-Plugins/) for some examples of plugins which do this
|
||||
|
||||
#### Compiling ultra small plugin DLLs - MinGW
|
||||
If you **ONLY** use code from the game (no external libraries and no C standard library functions):
|
||||
* You can add `-nostartfiles -Wl,--entry=0` to the compile flags to reduce the DLL size (e.g from 11 to 4 kb)
|
||||
|
||||
This isn't necessary to do though, and plugin DLLs work completely fine without doing this.
|
||||
93
doc/portability.md
Normal file
@@ -0,0 +1,93 @@
|
||||
Although most of the code is platform-independent, some per-platform functionality is required.
|
||||
|
||||
By default `Core.h` tries to automatically define appropriate backends for your system. Define ```CC_BUILD_MANUAL``` to disable this.
|
||||
|
||||
Note: Updating doesn't work properly in Windows 95 or Windows 98
|
||||
|
||||
## Before you start
|
||||
* IEEE floating-point support is required. (Can be emulated in software, but will affect performance)
|
||||
* The `int` data type must be 32-bits.
|
||||
* 32-bit addressing (or more) is required.
|
||||
* Support for 8/16/32/64 integer types is required. (your compiler must support 64-bit arithmetic)
|
||||
* At least around 2 MB of RAM is required at a minimum
|
||||
* At least 128 kb for main thread stack size
|
||||
|
||||
In summary, the codebase can theroetically be ported to any modern-ish hardware, but not stuff like a UNIVAC machine, the SuperFX chip on the SNES, or an 8-bit microcontroller.
|
||||
|
||||
## Porting
|
||||
|
||||
Listed below are the requirements for implementing each platform-dependent file.<br>
|
||||
When porting to other platforms, you should try to leverage existing backends when possible.<br>
|
||||
Only cross platform backends are listed below.
|
||||
|
||||
### Platform
|
||||
General platform specific functionality.
|
||||
|
||||
- Get exe path, start/exit process, open url in browser
|
||||
- Dynamic library management
|
||||
- Allocate, free, copy, set memory
|
||||
- Current system time, stopwatch time
|
||||
- File I/O, Directory I/O, Socket I/O
|
||||
- Threading, signalable wait, mutex
|
||||
- Drawing/measuring native font
|
||||
- Native font text drawing and measuring
|
||||
- Encrypt/decrypt data, getting command line args
|
||||
|
||||
Define:
|
||||
- ```CC_BUILD_POSIX``` - Use posix API
|
||||
|
||||
posix note: Some functions are not covered. (stopwatch, getting exe path, open url in browser)
|
||||
These must still be implemented for each operating system
|
||||
|
||||
### Window
|
||||
Create a window, show a dialog window, set window contents, keyboard/mouse input
|
||||
|
||||
Also monitor size, clipboard, cursor, raw relative mouse movement (optional)
|
||||
|
||||
Define:
|
||||
- ```DEFAULT_WIN_BACKEND CC_WIN_BACKEND_X11 ``` - Use X11/XLib (unix-ish) (glX)
|
||||
- ```DEFAULT_WIN_BACKEND CC_WIN_BACKEND_SDL2``` - Use SDL2 library (SDL2)
|
||||
|
||||
If using OpenGL, also OpenGL context management
|
||||
|
||||
### Logger
|
||||
Dump registers and backtrace, log unhandled errors (e.g. invalid memory read)
|
||||
|
||||
Define:
|
||||
- ```CC_BUILD_POSIX``` - use POSIX api
|
||||
|
||||
posix note: Register access is highly dependent on OS and architecture.
|
||||
|
||||
(e.g. Linux uses &r.gregs[REG_EAX] while FreeBSD uses &r.mc_eax)
|
||||
|
||||
### Audio
|
||||
Play multiple audio streams with varying sample rates
|
||||
|
||||
Define:
|
||||
- ```DEFAULT_AUD_BACKEND CC_AUD_BACKEND_OPENAL``` - use OpenAL
|
||||
- ```CC_BUILD_NOAUDIO``` - stub audio implementation (silent)
|
||||
|
||||
### 3D Graphics
|
||||
Texturing, depth buffer, alpha, etc (See Graphics.h for full list)
|
||||
|
||||
Define:
|
||||
- ```DEFAULT_GFX_BACKEND CC_GFX_BACKEND_GL1``` - Use legacy OpenGL (1.5/1.2 + ARB_VERTEX_BUFFER_OBJECT)
|
||||
- ```CC_BUILD_GL11``` - Use OpenGL 1.1 features only
|
||||
- ```DEFAULT_GFX_BACKEND CC_GFX_BACKEND_GL2``` - Use modern OpenGL shaders
|
||||
- ```CC_BUILD_GLES``` - Makes these shaders compatible with OpenGL ES
|
||||
- ```DEFAULT_GFX_BACKEND CC_GFX_BACKEND_SOFTGPU``` - Use built in software rasteriser
|
||||
|
||||
### HTTP
|
||||
HTTP, HTTPS, and setting request/getting response headers
|
||||
|
||||
Define:
|
||||
- ```DEFAULT_NET_BACKEND CC_NET_BACKEND_BUILTIN``` - use built in simple HTTP backend
|
||||
- ```DEFAULT_NET_BACKEND CC_NET_BACKEND_LIBCURL``` - use libcurl for HTTP
|
||||
|
||||
Supporting connection reuse is highly recommended. (but not required)
|
||||
|
||||
### SSL
|
||||
SSL and TLS support, plus basic certificate validation
|
||||
|
||||
Define:
|
||||
- ```DEFAULT_SSL_BACKEND CC_SSL_BACKEND_BEARSSL``` - use BearSSL for SSL/TLS
|
||||
12
doc/readme.md
Normal file
@@ -0,0 +1,12 @@
|
||||
This folder contains general information relating to the game's source code.
|
||||
|
||||
|File|Description|
|
||||
|--------|-------|
|
||||
|compile-fixes.md | Steps on how to fix some common compilation errors |
|
||||
|hosting-flask.md | Example website that hosts the web client using [Flask](https://flask.palletsprojects.com/)|
|
||||
|hosting-webclient.md | Explains how to integrate the web client into your own website |
|
||||
|modules.md | Provides a summary about the modules that constitute the game's code|
|
||||
|plugin-dev.md | Explains how to compile a simple plugin for the game |
|
||||
|portability.md | Provides information about porting this game to other platforms |
|
||||
|style.md | Explains the style guidelines that the source code generally follows |
|
||||
|strings.md | Provides details about the custom string type used by this game |
|
||||
42
doc/sound-credits.md
Normal file
@@ -0,0 +1,42 @@
|
||||
## Sources
|
||||
|
||||
https://old.reddit.com/r/Minecraft/comments/3zxucv/where_did_the_sound_in_minecraft_come_from/
|
||||
https://web.archive.org/web/20100830062601/http://minecraft.net/credits.jsp
|
||||
https://web.archive.org/web/20100124101348/http://www.freesound.org/usersAttribution.php?id=1045860&format=html
|
||||
https://web.archive.org/web/20100613143900/http://www.freesound.org/usersAttribution.php?id=584268
|
||||
https://freesound.org/people/C418/downloaded_sounds/?page=7#sound
|
||||
|
||||
## Sounds
|
||||
|
||||
**dig/step_grass1** - grass1.wav by Snoman
|
||||
* https://freesound.org/people/Snoman/sounds/9904/
|
||||
|
||||
**dig/step_grass2** - grass2.wav by Snoman
|
||||
* https://freesound.org/people/Snoman/sounds/9905/
|
||||
|
||||
**dig/step_grass3** - grass3.wav by Snoman
|
||||
* https://freesound.org/people/Snoman/sounds/9906/
|
||||
|
||||
**dig/step_grass4** - grass4.wav by Snoman
|
||||
* https://freesound.org/people/Snoman/sounds/9907/
|
||||
|
||||
**dig_glass1** - glass shatter.wav by datasoundsample
|
||||
* https://freesound.org/people/datasoundsample/sounds/41348/
|
||||
|
||||
**dig_glass2** - gb12.aif by lsprice
|
||||
* http://www.freesound.org/samplesViewSingle.php?id=88808/
|
||||
|
||||
**dig_glass3** - bm_Glass_Break.wav by cmusounddesign
|
||||
* https://freesound.org/people/cmusounddesign/sounds/71947/
|
||||
|
||||
**dig/step_gravel1** - gravel walking.aif by tigersound
|
||||
* https://freesound.org/people/tigersound/sounds/15562/
|
||||
|
||||
**dig/step_gravel2** - gravel walking.aif by tigersound
|
||||
* https://freesound.org/people/tigersound/sounds/15562/
|
||||
|
||||
**dig/step_gravel3** - gravel walking.aif by tigersound
|
||||
* https://freesound.org/people/tigersound/sounds/15562/
|
||||
|
||||
**dig/step_gravel4** - gravel walking.aif by tigersound
|
||||
* https://freesound.org/people/tigersound/sounds/15562/
|
||||
329
doc/strings.md
Normal file
@@ -0,0 +1,329 @@
|
||||
## Introduction
|
||||
|
||||
ClassiCube uses a custom string type rather than the standard C `char*` string in most places
|
||||
|
||||
ClassiCube strings (`cc_string`) are a struct with the following fields:
|
||||
- `buffer` -> Pointer to 8 bit characters (unsigned [code page 437 indices](https://en.wikipedia.org/wiki/Code_page_437#Character_set))
|
||||
- `length` -> Number of characters currently used
|
||||
- `capacity` -> Maximum number of characters (i.e buffer size)
|
||||
|
||||
Note: This means **STRINGS MAY NOT BE NULL TERMINATED** (and are not in most cases)
|
||||
|
||||
You should also read the **Strings** section in the [style guide](/doc/style.md)
|
||||
|
||||
## Memory management
|
||||
Some general guidelines to keep in mind when it comes to `cc_string` strings:
|
||||
- String buffers can be allocated on either the stack or heap<br>
|
||||
(i.e. make sure you don't return strings that are using stack allocated buffers)
|
||||
- Strings are fixed capacity (strings do not grow when length reaches capcity)<br>
|
||||
(i.e. make sure you allocate a large enough buffer upfront)
|
||||
- Strings are not garbage collected or reference counted<br>
|
||||
(i.e. you are responsible for managing the lifetime of strings)
|
||||
|
||||
## Usage examples
|
||||
|
||||
Initialisating a string from readonly text:
|
||||
```C
|
||||
cc_string str = String_FromConst("ABC");
|
||||
```
|
||||
|
||||
Initialising a string from temporary memory on the stack:
|
||||
```C
|
||||
// str will be able to store at most 200 characters in it
|
||||
char strBuffer[200];
|
||||
cc_string str = String_FromArray(strBuffer);
|
||||
```
|
||||
|
||||
Initialising a string from persistent memory on the heap:
|
||||
```C
|
||||
// str will be able to store at most 200 characters in it
|
||||
char* str = Mem_Alloc(1, 200, "String buffer");
|
||||
cc_string str = String_Init(str, 0, 200);
|
||||
```
|
||||
|
||||
# Converting to/from other string representations
|
||||
|
||||
## C String conversion
|
||||
|
||||
### C string -> cc_string
|
||||
|
||||
Creating a `cc_string` string from a C string is straightforward:
|
||||
|
||||
#### From a constant C string
|
||||
```C
|
||||
void Example(void) {
|
||||
cc_string str = String_FromConst("test");
|
||||
}
|
||||
```
|
||||
|
||||
#### From a C string
|
||||
```C
|
||||
void Example(const char* c_str) {
|
||||
cc_string str = String_FromReadonly(c_str);
|
||||
}
|
||||
```
|
||||
Note: `String_FromReadonly` can also be used with constant C strings, it's just a bit slower
|
||||
|
||||
#### From a C fixed size string
|
||||
```C
|
||||
struct Something { int value; char name[50]; };
|
||||
|
||||
void Example(struct Something* some) {
|
||||
cc_string str = String_FromRawArray(some->name);
|
||||
}
|
||||
```
|
||||
|
||||
### cc_string -> C string
|
||||
|
||||
The `buffer` field **should not** be treated as a C string, because `cc_string` strings **MAY NOT BE NULL TERMINATED**
|
||||
|
||||
The general way to achieve this is to
|
||||
1. Initialise `capacity` with 1 less than actual buffer size (e.g. use `String_InitArray_NT` instead of `String_InitArray`)
|
||||
2. Perform various operations on the `cc_string` string
|
||||
3. Add null terminator to end (i.e. `buffer[length]` = '\0';
|
||||
4. Use `buffer` as a C string now
|
||||
|
||||
For example:
|
||||
```C
|
||||
void PrintInt(int value) {
|
||||
cc_string str; char strBuffer[128];
|
||||
String_InitArray_NT(str, strBuffer);
|
||||
String_AppendInt(&str, value);
|
||||
str.buffer[str.length] = '\0';
|
||||
puts(str.buffer);
|
||||
}
|
||||
```
|
||||
|
||||
## OS String conversion
|
||||
|
||||
`cc_string` strings cannot be directly used as arguments for operating system functions and must be converted first.
|
||||
|
||||
The following functions are provided to convert `cc_string` strings into operating system specific encoded strings:
|
||||
|
||||
### cc_string -> Windows string
|
||||
|
||||
`Platform_EncodeString` converts a `cc_string` into a null terminated `WCHAR` and `CHAR` string
|
||||
|
||||
#### Example
|
||||
```C
|
||||
void SetWorkingDir(cc_string* title) {
|
||||
cc_winstring str;
|
||||
Platform_EncodeUtf16(&str, title);
|
||||
SetCurrentDirectoryW(str.uni);
|
||||
|
||||
// it's recommended that you DON'T use the ansi format whenever possible
|
||||
//SetCurrentDirectoryA(str.ansi);
|
||||
}
|
||||
```
|
||||
|
||||
### cc_string -> UTF8 string
|
||||
|
||||
`String_EncodeUtf8` converts a `cc_string` into a null terminated UTF8-encoded `char*` string
|
||||
|
||||
#### Example
|
||||
```C
|
||||
void SetWorkingDir(cc_string* title) {
|
||||
char buffer[NATIVE_STR_LEN];
|
||||
String_EncodeUtf8(buffer, title);
|
||||
chdir(buffer);
|
||||
}
|
||||
```
|
||||
|
||||
# API
|
||||
|
||||
I'm lazy so I will just link to [String.h](/src/String.h)
|
||||
|
||||
If you'd rather I provided a more detailed reference here, please let me know.
|
||||
|
||||
TODO
|
||||
|
||||
# Comparisons to other string implementations
|
||||
|
||||
## C comparison
|
||||
|
||||
A rough mapping of C string API to ClassiCube's string API:
|
||||
```
|
||||
atof -> Convert_ParseFloat
|
||||
strtof -> Convert_ParseFloat
|
||||
atoi -> Convert_ParseInt
|
||||
strtoi -> Convert_ParseInt
|
||||
|
||||
strcat -> String_AppendConst/String_AppendString
|
||||
strcpy -> String_Copy
|
||||
strtok -> String_UNSAFE_Split
|
||||
|
||||
strlen -> str.length
|
||||
strcmp -> String_Equals/String_Compare
|
||||
strchr -> String_IndexOf
|
||||
strrchr -> String_LastIndexOf
|
||||
strstr -> String_IndexOfConst
|
||||
|
||||
sprintf -> String_Format1/2/3/4
|
||||
%d -> %i
|
||||
%04d -> %p4
|
||||
%i -> %i
|
||||
%c -> %r
|
||||
%.4f -> %f4
|
||||
%s -> %s (cc_string)
|
||||
%s -> %c (char*)
|
||||
%x -> %h
|
||||
```
|
||||
|
||||
## C# comparison
|
||||
|
||||
A rough mapping of C# string API to ClassiCube's string API:
|
||||
```
|
||||
byte.Parse -> Convert_ParseUInt8
|
||||
ushort.Parse -> Convert_ParseUInt16
|
||||
float.Parse -> Convert_ParseFloat
|
||||
int.Parse -> Convert_ParseInt
|
||||
ulong.Parse -> Convert_ParseUInt64
|
||||
bool.Parse -> Convert_ParseBool
|
||||
|
||||
a += "X"; -> String_AppendString
|
||||
b = a; -> String_Copy
|
||||
string.Insert -> String_InsertAt
|
||||
string.Remove -> String_DeleteAt
|
||||
|
||||
string.Substring -> String_UNSAFE_Substring/String_UNSAFE_SubstringAt
|
||||
string.Split -> String_UNSAFE_Split/String_UNSAFE_SplitBy
|
||||
string.TrimStart -> String_UNSAFE_TrimStart
|
||||
string.TrimEnd -> String_UNSAFE_TrimEnd
|
||||
|
||||
a.Length -> str.length
|
||||
a == b -> String_Equals
|
||||
string.Equals -> String_CaslessEquals (StringComparison.OrdinalIgnoreCase)
|
||||
string.IndexOf -> String_IndexOf/String_IndexOfConst
|
||||
string.LastIndexOf -> String_LastIndexOf
|
||||
string.StartsWith -> String_CaselessStarts (StringComparison.OrdinalIgnoreCase)
|
||||
string.EndsWith -> String_CaselessEnds (StringComparison.OrdinalIgnoreCase)
|
||||
string.CompareTo -> String_Compare
|
||||
|
||||
string.Format -> String_Format1/2/3/4
|
||||
```
|
||||
*Note: I modelled cc_string after C# strings, hence the similar function names*
|
||||
|
||||
## C++ comparison
|
||||
|
||||
A rough mapping of C++ std::string API to ClassiCube's string API:
|
||||
```
|
||||
std::stof -> Convert_ParseFloat
|
||||
std::stoi -> Convert_ParseInt
|
||||
std::stoul -> Convert_ParseUInt64
|
||||
|
||||
string::append -> String_AppendString/String_AppendConst
|
||||
b = a; -> String_Copy
|
||||
string::insert -> String_InsertAt
|
||||
string::erase -> String_DeleteAt
|
||||
|
||||
string::substr -> String_UNSAFE_Substring/String_UNSAFE_SubstringAt
|
||||
|
||||
string::length -> str.length
|
||||
a == b -> String_Equals
|
||||
string::find -> String_IndexOf/String_IndexOfConst
|
||||
string::rfind -> String_LastIndexOf
|
||||
string::compare -> String_Compare
|
||||
|
||||
std::sprintf -> String_Format1/2/3/4
|
||||
```
|
||||
|
||||
# Detailed lifetime examples
|
||||
|
||||
Managing the lifetime of strings is important, as not properly managing them can cause issues.
|
||||
|
||||
For example, consider the following function:
|
||||
```C
|
||||
const cc_string* GetString(void);
|
||||
|
||||
void PrintSomething(void) {
|
||||
cc_string* str = GetString();
|
||||
// .. other code ..
|
||||
Chat_Add(str);
|
||||
}
|
||||
```
|
||||
|
||||
Without knowing the lifetime of the string returned from `GetString`, using it might either:
|
||||
* Work just fine
|
||||
* Sometimes work fine
|
||||
* Cause a subtle issue
|
||||
* Cause a major problem
|
||||
ptodo rearrange
|
||||
|
||||
### Constant string return example
|
||||
```C
|
||||
const cc_string* GetString(void) {
|
||||
static cc_string str = String_FromConst("ABC");
|
||||
return &str;
|
||||
}
|
||||
```
|
||||
|
||||
This will work fine - as long as the caller does not modify the returned string at all
|
||||
|
||||
### Stack allocated string return example
|
||||
|
||||
```C
|
||||
const cc_string* GetString(void) {
|
||||
char strBuffer[1024];
|
||||
cc_string str = String_FromArray(strBuffer);
|
||||
|
||||
String_AppendConst(&str, "ABC");
|
||||
return &str;
|
||||
}
|
||||
```
|
||||
|
||||
This will **almost certainly cause problems** - after `GetString` returns, the contents of both `str` and `strBuffer` may be changed to arbitary values (as once `GetString` returns, their contents are then eligible to be overwritten by other stack allocated variables)
|
||||
|
||||
As a general rule, you should **NEVER** return a string allocated on the stack
|
||||
|
||||
### Dynamically allocated string return example
|
||||
|
||||
```C
|
||||
const cc_string* GetString(void) {
|
||||
char* buffer = Mem_Alloc(1024, 1, "string buffer");
|
||||
cc_string* str = Mem_Alloc(1, sizeof(cc_string), "string");
|
||||
|
||||
*str = String_Init(buffer, 0, 1024);
|
||||
String_AppendConst(str, "ABC");
|
||||
return str;
|
||||
}
|
||||
```
|
||||
|
||||
This will work fine - however, now you also need to remember to `Mem_Free` both the string and its buffer to avoid a memory leak
|
||||
|
||||
As a general rule, you should avoid returning a dynamically allocated string
|
||||
|
||||
### UNSAFE mutable string return example
|
||||
|
||||
```C
|
||||
char global_buffer[1024];
|
||||
cc_string global_str = String_FromArray(global_buffer);
|
||||
|
||||
const cc_string* GetString(void) {
|
||||
return &global_str;
|
||||
}
|
||||
```
|
||||
|
||||
Depending on what functions are called in-between `GetString` and `Chat_Add`, `global_str` or its contents may be modified - which can result in an unexpected value being displayed in chat
|
||||
|
||||
This potential issue is not just theoretical - it has actually resulted in several real bugs in ClassiCube itself
|
||||
|
||||
As a general rule, for unsafe functions returning a string that may be mutated behind your back, you should try to maintain a reference to the string for as short of time as possible
|
||||
|
||||
### Reducing string lifetime issues
|
||||
|
||||
In general, for functions that produce strings, you should try to leave the responsibility of managing the string's lifetime up to the calling function to avoid these pitfalls
|
||||
|
||||
The example from before could instead be rewritten like so:
|
||||
|
||||
```C
|
||||
void GetString(cc_string* str);
|
||||
|
||||
void PrintSomething(void) {
|
||||
char strBuffer[256];
|
||||
cc_string str = String_InitArray(strBuffer);
|
||||
GetString(&str);
|
||||
|
||||
// .. other code ..
|
||||
Chat_Add(&str);
|
||||
}
|
||||
```
|
||||
34
doc/style.md
Normal file
@@ -0,0 +1,34 @@
|
||||
### Guidelines
|
||||
* Code should be C89 compatible and compilable as C++.
|
||||
* Each .c file should represent a module. (see architecture.md for more details)
|
||||
* Public functions and variables should be prefixed by module to avoid name collisions. (e.g. `Game_Reset`)
|
||||
* Private functions should be named using pascal case. Prefixing module is optional - do it when it makes sense.
|
||||
* Private variables don't really have a consistent style.
|
||||
|
||||
### Types
|
||||
* Explicit integer size typedefs are provided in `Core.h` for when needed. Otherwise just use int.
|
||||
* A few common simple structs are typedef-ed, but are rarely otherwise.
|
||||
* `cc_bool` is an alias for 8 bit unsigned integer
|
||||
* `PackedCol` field order differs depending on the underlying 3D graphics API
|
||||
|
||||
Note: The explicit integer size typedefs may not have been defined if you aren't compiling using GCC/Clang/MSVC, so for other compilers you may need to add them into `Core.h`
|
||||
|
||||
### Strings
|
||||
|
||||
A custom string type (`cc_string`) is used rather than `char*` strings in most places (see [strings](strings.md) page for more details)
|
||||
|
||||
*Note: Several functions will take raw `char*` for performance, but this is not encouraged*
|
||||
|
||||
#### String arguments
|
||||
String arguments are annotated to indicate storage and readonly requirements. These are:
|
||||
- `const cc_string*` - String is not modified at all
|
||||
- `cc_string*` - Characters in string may be modified
|
||||
- `STRING_REF` - Macro annotation indicating a **reference is kept to the characters**
|
||||
|
||||
To make it extra clear, functions with `STRING_REF` arguments usually also have `_UNSAFE_` as part of their name.
|
||||
|
||||
For example, consider the function `cc_string Substring_UNSAFE(STRING_REF const cc_string* str, length)`
|
||||
|
||||
The *input string* is not modified at all. However, the characters of the *returned string* points to the characters of the *input string*, so modifying the characters in the *input string* also modifies the *returned string*.
|
||||
|
||||
In general, use of `const cc_string*` is preferred when possible, and `STRING_REF` as little as possible.
|
||||
350
license.txt
Normal file
@@ -0,0 +1,350 @@
|
||||
Copyright (c) 2014 - 2024, UnknownShadow200
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
3. Neither the name of ClassiCube nor the names of its contributors may be
|
||||
used to endorse or promote products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
Other function licenses
|
||||
=======================
|
||||
|
||||
Ray-box intersection algorithm comes from:
|
||||
"An efficient and robust ray-box intersection algorithm", Williams, Barrus, Morley & Shirley, Journal of Graphics Tools, 2005"
|
||||
C++ source at http://www.cs.utah.edu/~awilliam/box/ does not appear to have an attached license.
|
||||
|
||||
|
||||
Cell traversal of rays based on code I found that was in turn from http://www.xnawiki.com/index.php/Voxel_traversal
|
||||
The archived about page (http://web.archive.org/web/20090412065116/http://www.xnawiki.com/index.php/XNAWiki:About) states
|
||||
that "All code found on the wiki is considered public domain".
|
||||
|
||||
|
||||
Frustum culling was based on the code from http://www.crownandcutlass.com/features/technicaldetails/frustum.html,
|
||||
which is in turn archived from (now defunct) http://www.markmorley.com/
|
||||
"This page and its contents are Copyright 2000 by Mark Morley
|
||||
Unless otherwise noted, you may use any and all code examples provided herein in any way you want."
|
||||
|
||||
|
||||
OpenTK license
|
||||
===============
|
||||
Copyright (c) 2006 - 2010 The Open Toolkit library.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
OpenTK.Platform.Windows and OpenTK.Platform.X11 include portions of the Mono class library.
|
||||
These portions are covered by the following license:
|
||||
|
||||
Copyright (c) 2004 Novell, Inc.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
Emscripten license
|
||||
==============================================================================
|
||||
|
||||
Copyright (c) 2010-2014 Emscripten authors, see AUTHORS file.
|
||||
|
||||
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.
|
||||
|
||||
==============================================================================
|
||||
|
||||
Copyright (c) 2010-2014 Emscripten authors, see AUTHORS file.
|
||||
All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal with 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:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimers.
|
||||
|
||||
Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimers
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
Neither the names of Mozilla,
|
||||
nor the names of its contributors may be used to endorse
|
||||
or promote products derived from this Software without specific prior
|
||||
written permission.
|
||||
|
||||
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 CONTRIBUTORS 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 WITH THE SOFTWARE.
|
||||
|
||||
==============================================================================
|
||||
|
||||
|
||||
BearSSL license
|
||||
==============================================================================
|
||||
Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
|
||||
|
||||
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.
|
||||
==============================================================================
|
||||
|
||||
|
||||
|
||||
FreeType license
|
||||
==================
|
||||
The FreeType Project LICENSE
|
||||
----------------------------
|
||||
|
||||
2006-Jan-27
|
||||
|
||||
Copyright 1996-2002, 2006 by
|
||||
David Turner, Robert Wilhelm, and Werner Lemberg
|
||||
|
||||
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
The FreeType Project is distributed in several archive packages;
|
||||
some of them may contain, in addition to the FreeType font engine,
|
||||
various tools and contributions which rely on, or relate to, the
|
||||
FreeType Project.
|
||||
|
||||
This license applies to all files found in such packages, and
|
||||
which do not fall under their own explicit license. The license
|
||||
affects thus the FreeType font engine, the test programs,
|
||||
documentation and makefiles, at the very least.
|
||||
|
||||
This license was inspired by the BSD, Artistic, and IJG
|
||||
(Independent JPEG Group) licenses, which all encourage inclusion
|
||||
and use of free software in commercial and freeware products
|
||||
alike. As a consequence, its main points are that:
|
||||
|
||||
o We don't promise that this software works. However, we will be
|
||||
interested in any kind of bug reports. (`as is' distribution)
|
||||
|
||||
o You can use this software for whatever you want, in parts or
|
||||
full form, without having to pay us. (`royalty-free' usage)
|
||||
|
||||
o You may not pretend that you wrote this software. If you use
|
||||
it, or only parts of it, in a program, you must acknowledge
|
||||
somewhere in your documentation that you have used the
|
||||
FreeType code. (`credits')
|
||||
|
||||
We specifically permit and encourage the inclusion of this
|
||||
software, with or without modifications, in commercial products.
|
||||
We disclaim all warranties covering The FreeType Project and
|
||||
assume no liability related to The FreeType Project.
|
||||
|
||||
|
||||
Finally, many people asked us for a preferred form for a
|
||||
credit/disclaimer to use in compliance with this license. We thus
|
||||
encourage you to use the following text:
|
||||
|
||||
"""
|
||||
Portions of this software are copyright © <year> The FreeType
|
||||
Project (www.freetype.org). All rights reserved.
|
||||
"""
|
||||
|
||||
Please replace <year> with the value from the FreeType version you
|
||||
actually use.
|
||||
|
||||
|
||||
Legal Terms
|
||||
===========
|
||||
|
||||
0. Definitions
|
||||
--------------
|
||||
|
||||
Throughout this license, the terms `package', `FreeType Project',
|
||||
and `FreeType archive' refer to the set of files originally
|
||||
distributed by the authors (David Turner, Robert Wilhelm, and
|
||||
Werner Lemberg) as the `FreeType Project', be they named as alpha,
|
||||
beta or final release.
|
||||
|
||||
`You' refers to the licensee, or person using the project, where
|
||||
`using' is a generic term including compiling the project's source
|
||||
code as well as linking it to form a `program' or `executable'.
|
||||
This program is referred to as `a program using the FreeType
|
||||
engine'.
|
||||
|
||||
This license applies to all files distributed in the original
|
||||
FreeType Project, including all source code, binaries and
|
||||
documentation, unless otherwise stated in the file in its
|
||||
original, unmodified form as distributed in the original archive.
|
||||
If you are unsure whether or not a particular file is covered by
|
||||
this license, you must contact us to verify this.
|
||||
|
||||
The FreeType Project is copyright (C) 1996-2000 by David Turner,
|
||||
Robert Wilhelm, and Werner Lemberg. All rights reserved except as
|
||||
specified below.
|
||||
|
||||
1. No Warranty
|
||||
--------------
|
||||
|
||||
THE FREETYPE PROJECT IS PROVIDED `AS IS' WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY DAMAGES CAUSED BY THE USE OR THE INABILITY TO
|
||||
USE, OF THE FREETYPE PROJECT.
|
||||
|
||||
2. Redistribution
|
||||
-----------------
|
||||
|
||||
This license grants a worldwide, royalty-free, perpetual and
|
||||
irrevocable right and license to use, execute, perform, compile,
|
||||
display, copy, create derivative works of, distribute and
|
||||
sublicense the FreeType Project (in both source and object code
|
||||
forms) and derivative works thereof for any purpose; and to
|
||||
authorize others to exercise some or all of the rights granted
|
||||
herein, subject to the following conditions:
|
||||
|
||||
o Redistribution of source code must retain this license file
|
||||
(`FTL.TXT') unaltered; any additions, deletions or changes to
|
||||
the original files must be clearly indicated in accompanying
|
||||
documentation. The copyright notices of the unaltered,
|
||||
original files must be preserved in all copies of source
|
||||
files.
|
||||
|
||||
o Redistribution in binary form must provide a disclaimer that
|
||||
states that the software is based in part of the work of the
|
||||
FreeType Team, in the distribution documentation. We also
|
||||
encourage you to put an URL to the FreeType web page in your
|
||||
documentation, though this isn't mandatory.
|
||||
|
||||
These conditions apply to any software derived from or based on
|
||||
the FreeType Project, not just the unmodified files. If you use
|
||||
our work, you must acknowledge us. However, no fee need be paid
|
||||
to us.
|
||||
|
||||
3. Advertising
|
||||
--------------
|
||||
|
||||
Neither the FreeType authors and contributors nor you shall use
|
||||
the name of the other for commercial, advertising, or promotional
|
||||
purposes without specific prior written permission.
|
||||
|
||||
We suggest, but do not require, that you use one or more of the
|
||||
following phrases to refer to this software in your documentation
|
||||
or advertising materials: `FreeType Project', `FreeType Engine',
|
||||
`FreeType library', or `FreeType Distribution'.
|
||||
|
||||
As you have not signed this license, you are not required to
|
||||
accept it. However, as the FreeType Project is copyrighted
|
||||
material, only this license, or another one contracted with the
|
||||
authors, grants you the right to use, distribute, and modify it.
|
||||
Therefore, by using, distributing, or modifying the FreeType
|
||||
Project, you indicate that you understand and accept all the terms
|
||||
of this license.
|
||||
|
||||
4. Contacts
|
||||
-----------
|
||||
|
||||
There are two mailing lists related to FreeType:
|
||||
|
||||
o freetype@nongnu.org
|
||||
|
||||
Discusses general use and applications of FreeType, as well as
|
||||
future and wanted additions to the library and distribution.
|
||||
If you are looking for support, start in this list if you
|
||||
haven't found anything to help you in the documentation.
|
||||
|
||||
o freetype-devel@nongnu.org
|
||||
|
||||
Discusses bugs, as well as engine internals, design issues,
|
||||
specific licenses, porting, etc.
|
||||
|
||||
Our home page can be found at
|
||||
|
||||
https://www.freetype.org
|
||||
|
||||
|
||||
--- end of FTL.TXT ---
|
||||
131
misc/32x/32x.h
Normal file
@@ -0,0 +1,131 @@
|
||||
#ifndef __32X_H__
|
||||
#define __32X_H__
|
||||
|
||||
/* Create a 5:5:5 RGB color */
|
||||
#define COLOR(r,g,b) (((r)&0x1F)|((g)&0x1F)<<5|((b)&0x1F)<<10)
|
||||
|
||||
#define MARS_CRAM (*(volatile unsigned short *)0x20004200)
|
||||
#define MARS_FRAMEBUFFER (*(volatile unsigned short *)0x24000000)
|
||||
#define MARS_OVERWRITE_IMG (*(volatile unsigned short *)0x24020000)
|
||||
#define MARS_SDRAM (*(volatile unsigned short *)0x26000000)
|
||||
|
||||
#define MARS_SYS_INTMSK (*(volatile unsigned short *)0x20004000)
|
||||
#define MARS_SYS_DMACTR (*(volatile unsigned short *)0x20004006)
|
||||
#define MARS_SYS_DMASAR (*(volatile unsigned long *)0x20004008)
|
||||
#define MARS_SYS_DMADAR (*(volatile unsigned long *)0x2000400C)
|
||||
#define MARS_SYS_DMALEN (*(volatile unsigned short *)0x20004010)
|
||||
#define MARS_SYS_DMAFIFO (*(volatile unsigned short *)0x20004012)
|
||||
#define MARS_SYS_VRESI_CLR (*(volatile unsigned short *)0x20004014)
|
||||
#define MARS_SYS_VINT_CLR (*(volatile unsigned short *)0x20004016)
|
||||
#define MARS_SYS_HINT_CLR (*(volatile unsigned short *)0x20004018)
|
||||
#define MARS_SYS_CMDI_CLR (*(volatile unsigned short *)0x2000401A)
|
||||
#define MARS_SYS_PWMI_CLR (*(volatile unsigned short *)0x2000401C)
|
||||
#define MARS_SYS_COMM0 (*(volatile unsigned short *)0x20004020) /* Master SH2 communication */
|
||||
#define MARS_SYS_COMM2 (*(volatile unsigned short *)0x20004022)
|
||||
#define MARS_SYS_COMM4 (*(volatile unsigned short *)0x20004024) /* Slave SH2 communication */
|
||||
#define MARS_SYS_COMM6 (*(volatile unsigned short *)0x20004026)
|
||||
#define MARS_SYS_COMM8 (*(volatile unsigned short *)0x20004028) /* controller 1 current value */
|
||||
#define MARS_SYS_COMM10 (*(volatile unsigned short *)0x2000402A) /* controller 2 current value */
|
||||
#define MARS_SYS_COMM12 (*(volatile unsigned long *)0x2000402C) /* vcount current value */
|
||||
|
||||
#define MARS_PWM_CTRL (*(volatile unsigned short *)0x20004030)
|
||||
#define MARS_PWM_CYCLE (*(volatile unsigned short *)0x20004032)
|
||||
#define MARS_PWM_LEFT (*(volatile unsigned short *)0x20004034)
|
||||
#define MARS_PWM_RIGHT (*(volatile unsigned short *)0x20004036)
|
||||
#define MARS_PWM_MONO (*(volatile unsigned short *)0x20004038)
|
||||
|
||||
#define MARS_VDP_DISPMODE (*(volatile unsigned short *)0x20004100)
|
||||
#define MARS_VDP_FILLEN (*(volatile unsigned short *)0x20004104)
|
||||
#define MARS_VDP_FILADR (*(volatile unsigned short *)0x20004106)
|
||||
#define MARS_VDP_FILDAT (*(volatile unsigned short *)0x20004108)
|
||||
#define MARS_VDP_FBCTL (*(volatile unsigned short *)0x2000410A)
|
||||
|
||||
#define MARS_SH2_ACCESS_VDP 0x8000
|
||||
#define MARS_68K_ACCESS_VDP 0x0000
|
||||
|
||||
#define MARS_PAL_FORMAT 0x0000
|
||||
#define MARS_NTSC_FORMAT 0x8000
|
||||
|
||||
#define MARS_VDP_PRIO_68K 0x0000
|
||||
#define MARS_VDP_PRIO_32X 0x0080
|
||||
|
||||
#define MARS_224_LINES 0x0000
|
||||
#define MARS_240_LINES 0x0040
|
||||
|
||||
#define MARS_VDP_MODE_OFF 0x0000
|
||||
#define MARS_VDP_MODE_256 0x0001
|
||||
#define MARS_VDP_MODE_32K 0x0002
|
||||
#define MARS_VDP_MODE_RLE 0x0003
|
||||
|
||||
#define MARS_VDP_VBLK 0x8000
|
||||
#define MARS_VDP_HBLK 0x4000
|
||||
#define MARS_VDP_PEN 0x2000
|
||||
#define MARS_VDP_FEN 0x0002
|
||||
#define MARS_VDP_FS 0x0001
|
||||
|
||||
#define SH2_CCTL_CP 0x10
|
||||
#define SH2_CCTL_TW 0x08
|
||||
#define SH2_CCTL_CE 0x01
|
||||
|
||||
#define SH2_FRT_TIER (*(volatile unsigned char *)0xFFFFFE10)
|
||||
#define SH2_FRT_FTCSR (*(volatile unsigned char *)0xFFFFFE11)
|
||||
#define SH2_FRT_FRCH (*(volatile unsigned char *)0xFFFFFE12)
|
||||
#define SH2_FRT_FRCL (*(volatile unsigned char *)0xFFFFFE13)
|
||||
#define SH2_FRT_OCRH (*(volatile unsigned char *)0xFFFFFE14)
|
||||
#define SH2_FRT_OCRL (*(volatile unsigned char *)0xFFFFFE15)
|
||||
#define SH2_FRT_TCR (*(volatile unsigned char *)0xFFFFFE16)
|
||||
#define SH2_FRT_TOCR (*(volatile unsigned char *)0xFFFFFE17)
|
||||
#define SH2_FRT_ICRH (*(volatile unsigned char *)0xFFFFFE18)
|
||||
#define SH2_FRT_ICRL (*(volatile unsigned char *)0xFFFFFE19)
|
||||
|
||||
#define SH2_DMA_SAR0 (*(volatile unsigned long *)0xFFFFFF80)
|
||||
#define SH2_DMA_DAR0 (*(volatile unsigned long *)0xFFFFFF84)
|
||||
#define SH2_DMA_TCR0 (*(volatile unsigned long *)0xFFFFFF88)
|
||||
#define SH2_DMA_CHCR0 (*(volatile unsigned long *)0xFFFFFF8C)
|
||||
#define SH2_DMA_VCR0 (*(volatile unsigned long *)0xFFFFFFA0)
|
||||
#define SH2_DMA_DRCR0 (*(volatile unsigned char *)0xFFFFFE71)
|
||||
|
||||
#define SH2_DMA_SAR1 (*(volatile unsigned long *)0xFFFFFF90)
|
||||
#define SH2_DMA_DAR1 (*(volatile unsigned long *)0xFFFFFF94)
|
||||
#define SH2_DMA_TCR1 (*(volatile unsigned long *)0xFFFFFF98)
|
||||
#define SH2_DMA_CHCR1 (*(volatile unsigned long *)0xFFFFFF9C)
|
||||
#define SH2_DMA_VCR1 (*(volatile unsigned long *)0xFFFFFFA8)
|
||||
#define SH2_DMA_DRCR1 (*(volatile unsigned char *)0xFFFFFE72)
|
||||
|
||||
#define SH2_DMA_DMAOR (*(volatile unsigned long *)0xFFFFFFB0)
|
||||
|
||||
#define SH2_INT_IPRA (*(volatile unsigned short *)0xFFFFFEE2)
|
||||
|
||||
#define SEGA_CTRL_UP 0x0001
|
||||
#define SEGA_CTRL_DOWN 0x0002
|
||||
#define SEGA_CTRL_LEFT 0x0004
|
||||
#define SEGA_CTRL_RIGHT 0x0008
|
||||
#define SEGA_CTRL_B 0x0010
|
||||
#define SEGA_CTRL_C 0x0020
|
||||
#define SEGA_CTRL_A 0x0040
|
||||
#define SEGA_CTRL_START 0x0080
|
||||
#define SEGA_CTRL_Z 0x0100
|
||||
#define SEGA_CTRL_Y 0x0200
|
||||
#define SEGA_CTRL_X 0x0400
|
||||
#define SEGA_CTRL_MODE 0x0800
|
||||
|
||||
#define SEGA_CTRL_TYPE 0xF000
|
||||
#define SEGA_CTRL_THREE 0x0000
|
||||
#define SEGA_CTRL_SIX 0x1000
|
||||
#define SEGA_CTRL_NONE 0xF000
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* global functions in sh2_crt0.s */
|
||||
extern void fast_memcpy(void *dst, void *src, int len);
|
||||
extern void CacheControl(int mode);
|
||||
extern void CacheClearLine(void* ptr);
|
||||
extern void ScreenStretch(int src, int width, int height, int interp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
109
misc/32x/Makefile
Normal file
@@ -0,0 +1,109 @@
|
||||
ifdef $(GENDEV)
|
||||
ROOTDIR = $(GENDEV)
|
||||
else
|
||||
ROOTDIR = /opt/toolchains/sega
|
||||
endif
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Configurable options
|
||||
#---------------------------------------------------------------------------------
|
||||
TARGET = ClassiCube-32x
|
||||
BUILD_DIR = build/32x
|
||||
SOURCE_DIRS = src src/32x misc/32x
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
C_FILES = $(foreach dir,$(SOURCE_DIRS),$(wildcard $(dir)/*.c))
|
||||
S_FILES = misc/32x/sh2_crt0.s
|
||||
OBJS = $(addprefix $(BUILD_DIR)/, $(notdir $(C_FILES:%.c=%.o) $(S_FILES:%.s=%.o)))
|
||||
|
||||
LDSCRIPTSDIR = $(ROOTDIR)/ldscripts
|
||||
LIBS = $(LIBPATH) -lc -lgcc -lgcc-Os-4-200 -lnosys
|
||||
|
||||
LIBPATH = -L$(ROOTDIR)/sh-elf/lib -L$(ROOTDIR)/sh-elf/lib/gcc/sh-elf/4.6.2 -L$(ROOTDIR)/sh-elf/sh-elf/lib
|
||||
INCPATH = -I$(ROOTDIR)/sh-elf/include -I$(ROOTDIR)/sh-elf/sh-elf/include
|
||||
|
||||
SHCCFLAGS = -m2 -mb -Ofast -Wall -g -c -fomit-frame-pointer -DPLAT_32X -ffunction-sections -fdata-sections
|
||||
SHHWFLAGS = -m2 -mb -O1 -Wall -g -c -fomit-frame-pointer
|
||||
SHLDFLAGS = -T $(LDSCRIPTSDIR)/mars.ld -nostdlib -Wl,--gc-sections
|
||||
SHASFLAGS = --big
|
||||
|
||||
MDLDFLAGS = -T $(LDSCRIPTSDIR)/md.ld --oformat binary
|
||||
MDASFLAGS = -m68000 --register-prefix-optional
|
||||
|
||||
SHPREFIX = $(ROOTDIR)/sh-elf/bin/sh-elf-
|
||||
SHCC = $(SHPREFIX)gcc
|
||||
SHAS = $(SHPREFIX)as
|
||||
SHLD = $(SHPREFIX)ld
|
||||
SHOBJC = $(SHPREFIX)objcopy
|
||||
|
||||
MDPREFIX = $(ROOTDIR)/m68k-elf/bin/m68k-elf-
|
||||
MDAS = $(MDPREFIX)as
|
||||
MDLD = $(MDPREFIX)ld
|
||||
|
||||
# Dependency tracking
|
||||
DEPFLAGS = -MT $@ -MMD -MP -MF $(BUILD_DIR)/$*.d
|
||||
DEPFILES := $(OBJS:%.o=%.d)
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
all: $(BUILD_DIR) $(BUILD_DIR)/m68k_crt0.bin $(BUILD_DIR)/m68k_crt1.bin $(TARGET).bin
|
||||
|
||||
clean:
|
||||
rm -f $(BUILD_DIR)/*.o $(BUILD_DIR)/*.bin $(TARGET).bin $(TARGET).elf
|
||||
|
||||
$(BUILD_DIR):
|
||||
mkdir -p $(BUILD_DIR)
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# binary generation
|
||||
#---------------------------------------------------------------------------------
|
||||
$(TARGET).bin: $(TARGET).elf
|
||||
$(SHOBJC) -O binary $< $(BUILD_DIR)/temp.bin
|
||||
dd if=$(BUILD_DIR)/temp.bin of=$@ bs=64K conv=sync
|
||||
|
||||
$(TARGET).elf: $(OBJS)
|
||||
$(SHCC) $(SHLDFLAGS) $(OBJS) $(LIBS) -o $(TARGET).elf
|
||||
|
||||
|
||||
$(BUILD_DIR)/m68k_crt0.o: misc/32x/m68k_crt0.s
|
||||
$(MDAS) $(MDASFLAGS) $< -o $@
|
||||
|
||||
$(BUILD_DIR)/m68k_crt0.bin: $(BUILD_DIR)/m68k_crt0.o
|
||||
$(MDLD) $(MDLDFLAGS) $< -o $@
|
||||
|
||||
$(BUILD_DIR)/m68k_crt1.o: misc/32x/m68k_crt1.s
|
||||
$(MDAS) $(MDASFLAGS) $< -o $@
|
||||
|
||||
$(BUILD_DIR)/m68k_crt1.bin: $(BUILD_DIR)/m68k_crt1.o
|
||||
$(MDLD) $(MDLDFLAGS) $< -o $@
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# object generation
|
||||
#---------------------------------------------------------------------------------
|
||||
$(BUILD_DIR)/%.o: src/%.c
|
||||
$(SHCC) $(SHCCFLAGS) $(INCPATH) $(DEPFLAGS) $< -o $@
|
||||
|
||||
$(BUILD_DIR)/%.o: src/32x/%.c
|
||||
$(SHCC) $(SHCCFLAGS) $(INCPATH) $(DEPFLAGS) $< -o $@
|
||||
|
||||
$(BUILD_DIR)/%.o: misc/32x/%.c
|
||||
$(SHCC) $(SHCCFLAGS) $(INCPATH) $(DEPFLAGS) $< -o $@
|
||||
|
||||
$(BUILD_DIR)/%.o: misc/32x/%.s
|
||||
$(SHAS) $(SHASFLAGS) $(INCPATH) $< -o $@
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Dependency tracking
|
||||
#---------------------------------------------------------------------------------
|
||||
$(DEPFILES):
|
||||
|
||||
include $(wildcard $(DEPFILES))
|
||||
256
misc/32x/hw_32x.c
Normal file
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Licensed under the BSD license
|
||||
*
|
||||
* debug_32x.c - Debug screen functions.
|
||||
*
|
||||
* Copyright (c) 2005 Marcus R. Brown <mrbrown@ocgnet.org>
|
||||
* Copyright (c) 2005 James Forshaw <tyranid@gmail.com>
|
||||
* Copyright (c) 2005 John Kelley <ps2dev@kelley.ca>
|
||||
*
|
||||
* Altered for 32X by Chilly Willy
|
||||
*/
|
||||
|
||||
#include "32x.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static int init = 0;
|
||||
static unsigned short fgc = 0, bgc = 0;
|
||||
static unsigned char fgs = 0, bgs = 0;
|
||||
|
||||
static unsigned short currentFB = 0;
|
||||
|
||||
void Hw32xSetFGColor(int s, int r, int g, int b)
|
||||
{
|
||||
volatile unsigned short *palette = &MARS_CRAM;
|
||||
fgs = s;
|
||||
fgc = COLOR(r, g, b);
|
||||
palette[fgs] = fgc;
|
||||
}
|
||||
|
||||
void Hw32xSetBGColor(int s, int r, int g, int b)
|
||||
{
|
||||
volatile unsigned short *palette = &MARS_CRAM;
|
||||
bgs = s;
|
||||
bgc = COLOR(r, g, b);
|
||||
palette[bgs] = bgc;
|
||||
}
|
||||
|
||||
void Hw32xInit(int vmode, int lineskip)
|
||||
{
|
||||
volatile unsigned short *frameBuffer16 = &MARS_FRAMEBUFFER;
|
||||
int i;
|
||||
|
||||
// Wait for the SH2 to gain access to the VDP
|
||||
while ((MARS_SYS_INTMSK & MARS_SH2_ACCESS_VDP) == 0) ;
|
||||
|
||||
if (vmode == MARS_VDP_MODE_32K)
|
||||
{
|
||||
// Set 16-bit direct mode, 224 lines
|
||||
MARS_VDP_DISPMODE = MARS_224_LINES | MARS_VDP_MODE_32K;
|
||||
|
||||
// init both framebuffers
|
||||
|
||||
// Flip the framebuffer selection bit and wait for it to take effect
|
||||
MARS_VDP_FBCTL = currentFB ^ 1;
|
||||
while ((MARS_VDP_FBCTL & MARS_VDP_FS) == currentFB) ;
|
||||
currentFB ^= 1;
|
||||
// rewrite line table
|
||||
for (i=0; i<224/(lineskip+1); i++)
|
||||
{
|
||||
if (lineskip)
|
||||
{
|
||||
int j = lineskip + 1;
|
||||
while (j)
|
||||
{
|
||||
frameBuffer16[i*(lineskip+1) + (lineskip + 1 - j)] = i*320 + 0x100; /* word offset of line */
|
||||
j--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i<200)
|
||||
frameBuffer16[i] = i*320 + 0x100; /* word offset of line */
|
||||
else
|
||||
frameBuffer16[i] = 200*320 + 0x100; /* word offset of line */
|
||||
}
|
||||
}
|
||||
// clear screen
|
||||
for (i=0x100; i<0x10000; i++)
|
||||
frameBuffer16[i] = 0;
|
||||
|
||||
// Flip the framebuffer selection bit and wait for it to take effect
|
||||
MARS_VDP_FBCTL = currentFB ^ 1;
|
||||
while ((MARS_VDP_FBCTL & MARS_VDP_FS) == currentFB) ;
|
||||
currentFB ^= 1;
|
||||
// rewrite line table
|
||||
for (i=0; i<224/(lineskip+1); i++)
|
||||
{
|
||||
if (lineskip)
|
||||
{
|
||||
int j = lineskip + 1;
|
||||
while (j)
|
||||
{
|
||||
frameBuffer16[i*(lineskip+1) + (lineskip + 1 - j)] = i*320 + 0x100; /* word offset of line */
|
||||
j--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i<200)
|
||||
frameBuffer16[i] = i*320 + 0x100; /* word offset of line */
|
||||
else
|
||||
frameBuffer16[i] = 200*320 + 0x100; /* word offset of line */
|
||||
}
|
||||
}
|
||||
// clear screen
|
||||
for (i=0x100; i<0x10000; i++)
|
||||
frameBuffer16[i] = 0;
|
||||
}
|
||||
|
||||
Hw32xSetFGColor(255,31,31,31);
|
||||
Hw32xSetBGColor(0,0,0,0);
|
||||
init = vmode;
|
||||
}
|
||||
|
||||
void Hw32xScreenClear()
|
||||
{
|
||||
int i;
|
||||
int l = (init == MARS_VDP_MODE_256) ? 320*224/2 + 0x100 : 320*200 + 0x100;
|
||||
volatile unsigned short *frameBuffer16 = &MARS_FRAMEBUFFER;
|
||||
|
||||
// clear screen
|
||||
for (i=0x100; i<l; i++)
|
||||
frameBuffer16[i] = 0;
|
||||
|
||||
// Flip the framebuffer selection bit and wait for it to take effect
|
||||
MARS_VDP_FBCTL = currentFB ^ 1;
|
||||
while ((MARS_VDP_FBCTL & MARS_VDP_FS) == currentFB) ;
|
||||
currentFB ^= 1;
|
||||
|
||||
// clear screen
|
||||
for (i=0x100; i<l; i++)
|
||||
frameBuffer16[i] = 0;
|
||||
|
||||
Hw32xSetFGColor(255,31,31,31);
|
||||
Hw32xSetBGColor(0,0,0,0);
|
||||
}
|
||||
|
||||
void Hw32xDelay(int ticks)
|
||||
{
|
||||
unsigned long ct = MARS_SYS_COMM12 + ticks;
|
||||
while (MARS_SYS_COMM12 < ct) ;
|
||||
}
|
||||
|
||||
void Hw32xScreenFlip(int wait)
|
||||
{
|
||||
// Flip the framebuffer selection bit
|
||||
MARS_VDP_FBCTL = currentFB ^ 1;
|
||||
if (wait)
|
||||
{
|
||||
while ((MARS_VDP_FBCTL & MARS_VDP_FS) == currentFB) ;
|
||||
currentFB ^= 1;
|
||||
}
|
||||
}
|
||||
|
||||
void Hw32xFlipWait()
|
||||
{
|
||||
while ((MARS_VDP_FBCTL & MARS_VDP_FS) == currentFB) ;
|
||||
currentFB ^= 1;
|
||||
}
|
||||
|
||||
|
||||
// MD Command support code ---------------------------------------------
|
||||
|
||||
unsigned short HwMdReadPad(int port)
|
||||
{
|
||||
if (port == 0)
|
||||
return MARS_SYS_COMM8;
|
||||
else if (port == 1)
|
||||
return MARS_SYS_COMM10;
|
||||
else
|
||||
return SEGA_CTRL_NONE;
|
||||
}
|
||||
|
||||
unsigned char HwMdReadSram(unsigned short offset)
|
||||
{
|
||||
while (MARS_SYS_COMM0) ; // wait until 68000 has responded to any earlier requests
|
||||
MARS_SYS_COMM2 = offset;
|
||||
MARS_SYS_COMM0 = 0x0100; // Read SRAM
|
||||
while (MARS_SYS_COMM0) ;
|
||||
return MARS_SYS_COMM2 & 0x00FF;
|
||||
}
|
||||
|
||||
void HwMdWriteSram(unsigned char byte, unsigned short offset)
|
||||
{
|
||||
while (MARS_SYS_COMM0) ; // wait until 68000 has responded to any earlier requests
|
||||
MARS_SYS_COMM2 = offset;
|
||||
MARS_SYS_COMM0 = 0x0200 | byte; // Write SRAM
|
||||
while (MARS_SYS_COMM0) ;
|
||||
}
|
||||
|
||||
int HwMdReadMouse(int port)
|
||||
{
|
||||
unsigned int mouse1, mouse2;
|
||||
while (MARS_SYS_COMM0) ; // wait until 68000 has responded to any earlier requests
|
||||
MARS_SYS_COMM0 = 0x0300|port; // tells 68000 to read mouse
|
||||
while (MARS_SYS_COMM0 == (0x0300|port)) ; // wait for mouse value
|
||||
mouse1 = MARS_SYS_COMM0;
|
||||
mouse2 = MARS_SYS_COMM2;
|
||||
MARS_SYS_COMM0 = 0; // tells 68000 we got the mouse value
|
||||
return (int)((mouse1 << 16) | mouse2);
|
||||
}
|
||||
|
||||
void HwMdClearScreen(void)
|
||||
{
|
||||
while (MARS_SYS_COMM0) ; // wait until 68000 has responded to any earlier requests
|
||||
MARS_SYS_COMM0 = 0x0400; // Clear Screen (Name Table B)
|
||||
while (MARS_SYS_COMM0) ;
|
||||
}
|
||||
|
||||
void HwMdSetOffset(unsigned short offset)
|
||||
{
|
||||
while (MARS_SYS_COMM0) ; // wait until 68000 has responded to any earlier requests
|
||||
MARS_SYS_COMM2 = offset;
|
||||
MARS_SYS_COMM0 = 0x0500; // Set offset (into either Name Table B or VRAM)
|
||||
while (MARS_SYS_COMM0) ;
|
||||
}
|
||||
|
||||
void HwMdSetNTable(unsigned short word)
|
||||
{
|
||||
while (MARS_SYS_COMM0) ; // wait until 68000 has responded to any earlier requests
|
||||
MARS_SYS_COMM2 = word;
|
||||
MARS_SYS_COMM0 = 0x0600; // Set word at offset in Name Table B
|
||||
while (MARS_SYS_COMM0) ;
|
||||
}
|
||||
|
||||
void HwMdSetVram(unsigned short word)
|
||||
{
|
||||
while (MARS_SYS_COMM0) ; // wait until 68000 has responded to any earlier requests
|
||||
MARS_SYS_COMM2 = word;
|
||||
MARS_SYS_COMM0 = 0x0700; // Set word at offset in VRAM
|
||||
while (MARS_SYS_COMM0) ;
|
||||
}
|
||||
|
||||
void HwMdPuts(char *str, int color, int x, int y)
|
||||
{
|
||||
HwMdSetOffset(((y<<6) | x) << 1);
|
||||
while (*str)
|
||||
HwMdSetNTable(((*str++ - 0x20) & 0xFF) | color);
|
||||
}
|
||||
|
||||
void HwMdPutc(char chr, int color, int x, int y)
|
||||
{
|
||||
HwMdSetOffset(((y<<6) | x) << 1);
|
||||
HwMdSetNTable(((chr - 0x20) & 0xFF) | color);
|
||||
}
|
||||
|
||||
|
||||
// Slave SH2 support code ----------------------------------------------
|
||||
|
||||
void slave(void)
|
||||
{
|
||||
while (1) ;
|
||||
}
|
||||
30
misc/32x/hw_32x.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef HW_32X_H
|
||||
#define HW_32X_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
extern void Hw32xSetFGColor(int s, int r, int g, int b);
|
||||
extern void Hw32xSetBGColor(int s, int r, int g, int b);
|
||||
extern void Hw32xInit(int vmode, int lineskip);
|
||||
extern int Hw32xScreenGetX();
|
||||
extern int Hw32xScreenGetY();
|
||||
extern void Hw32xScreenSetXY(int x, int y);
|
||||
extern void Hw32xScreenClear();
|
||||
extern void Hw32xDelay(int ticks);
|
||||
extern void Hw32xScreenFlip(int wait);
|
||||
extern void Hw32xFlipWait();
|
||||
|
||||
extern unsigned short HwMdReadPad(int port);
|
||||
extern unsigned char HwMdReadSram(unsigned short offset);
|
||||
extern void HwMdWriteSram(unsigned char byte, unsigned short offset);
|
||||
extern int HwMdReadMouse(int port);
|
||||
extern void HwMdClearScreen(void);
|
||||
extern void HwMdSetOffset(unsigned short offset);
|
||||
extern void HwMdSetNTable(unsigned short word);
|
||||
extern void HwMdSetVram(unsigned short word);
|
||||
extern void HwMdPuts(char *str, int color, int x, int y);
|
||||
extern void HwMdPutc(char chr, int color, int x, int y);
|
||||
|
||||
#endif
|
||||
98
misc/32x/m68k_crt0.s
Normal file
@@ -0,0 +1,98 @@
|
||||
| SEGA 32X support code for the 68000
|
||||
| by Chilly Willy
|
||||
| First part of rom header
|
||||
|
||||
.text
|
||||
|
||||
| Initial exception vectors. When the console is first turned on, it is
|
||||
| in MegaDrive mode. All vectors just point to the code to start up the
|
||||
| Mars adapter. After the adapter is enabled, none of these vectors will
|
||||
| appear as the adapter uses its own vector table to route exceptions to
|
||||
| the jump table. 0x3F0 is where the 68000 starts at for the 32X.
|
||||
|
||||
.long 0x01000000,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0
|
||||
.long 0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0
|
||||
.long 0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0
|
||||
.long 0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0
|
||||
.long 0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0
|
||||
.long 0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0
|
||||
.long 0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0
|
||||
.long 0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0
|
||||
|
||||
| Standard MegaDrive ROM header at 0x100
|
||||
|
||||
.ascii "SEGA 32X Example" /* SEGA must be the first four chars for TMSS */
|
||||
.ascii "(C)2024 "
|
||||
.ascii "ClassiCube 32X " /* export name */
|
||||
.ascii " "
|
||||
.ascii " "
|
||||
.ascii "ClassiCube 32X " /* domestic (Japanese) name */
|
||||
.ascii " "
|
||||
.ascii " "
|
||||
.ascii "GM MK-0000 -00"
|
||||
.word 0x0000 /* checksum - not needed */
|
||||
.ascii "J6 "
|
||||
.long 0x00000000,0x0007FFFF /* ROM start, end */
|
||||
.long 0x00FF0000,0x00FFFFFF /* RAM start, end */
|
||||
|
||||
.ifdef HAS_SAVE_RAM
|
||||
.ascii "RA" /* External RAM */
|
||||
.byte 0xF8 /* don't clear + odd bytes */
|
||||
.byte 0x20 /* SRAM */
|
||||
.long 0x00200001,0x0020FFFF /* SRAM start, end */
|
||||
.else
|
||||
.ascii " " /* no SRAM */
|
||||
.endif
|
||||
|
||||
.ascii " "
|
||||
.ascii " "
|
||||
|
||||
.ifdef MYTH_HOMEBREW
|
||||
.ascii "MYTH3900" /* memo indicates Myth native executable */
|
||||
.else
|
||||
.ascii " " /* memo */
|
||||
.endif
|
||||
|
||||
.ascii " "
|
||||
.ascii " "
|
||||
.ascii "F " /* enable any hardware configuration */
|
||||
|
||||
| Mars exception vector jump table at 0x200
|
||||
|
||||
jmp 0x880800.l /* reset = hot start */
|
||||
jsr 0x880806.l /* EX_BusError */
|
||||
jsr 0x880806.l /* EX_AddrError */
|
||||
jsr 0x880806.l /* EX_IllInstr */
|
||||
jsr 0x880806.l /* EX_DivByZero */
|
||||
jsr 0x880806.l /* EX_CHK */
|
||||
jsr 0x880806.l /* EX_TrapV */
|
||||
jsr 0x880806.l /* EX_Priviledge */
|
||||
jsr 0x880806.l /* EX_Trace */
|
||||
jsr 0x880806.l /* EX_LineA */
|
||||
jsr 0x880806.l /* EX_LineF */
|
||||
.space 72 /* reserved */
|
||||
jsr 0x880806.l /* EX_Spurious */
|
||||
jsr 0x880806.l /* EX_Level1 */
|
||||
jsr 0x880806.l /* EX_Level2 */
|
||||
jsr 0x880806.l /* EX_Level3 */
|
||||
jmp 0x88080C.l /* EX_Level4 HBlank */
|
||||
jsr 0x880806.l /* EX_Level5 */
|
||||
jmp 0x880812.l /* EX_Level6 VBlank */
|
||||
jsr 0x880806.l /* EX_Level7 */
|
||||
jsr 0x880806.l /* EX_Trap0 */
|
||||
jsr 0x880806.l /* EX_Trap1 */
|
||||
jsr 0x880806.l /* EX_Trap2 */
|
||||
jsr 0x880806.l /* EX_Trap3 */
|
||||
jsr 0x880806.l /* EX_Trap4 */
|
||||
jsr 0x880806.l /* EX_Trap5 */
|
||||
jsr 0x880806.l /* EX_Trap6 */
|
||||
jsr 0x880806.l /* EX_Trap7 */
|
||||
jsr 0x880806.l /* EX_Trap8 */
|
||||
jsr 0x880806.l /* EX_Trap9 */
|
||||
jsr 0x880806.l /* EX_TrapA */
|
||||
jsr 0x880806.l /* EX_TrapB */
|
||||
jsr 0x880806.l /* EX_TrapC */
|
||||
jsr 0x880806.l /* EX_TrapD */
|
||||
jsr 0x880806.l /* EX_TrapE */
|
||||
jsr 0x880806.l /* EX_TrapF */
|
||||
.space 166 /* reserved */
|
||||
1846
misc/32x/m68k_crt1.s
Normal file
802
misc/32x/sh2_crt0.s
Normal file
@@ -0,0 +1,802 @@
|
||||
! SEGA 32X support code for SH2
|
||||
! by Chilly Willy
|
||||
! Rom header and SH2 init/exception code - must be first in object list
|
||||
|
||||
.text
|
||||
|
||||
! Standard MD Header at 0x000
|
||||
|
||||
.incbin "build/32x/m68k_crt0.bin", 0, 0x3C0
|
||||
|
||||
! Standard Mars Header at 0x3C0
|
||||
|
||||
.ascii "ClassiCube 32X " /* module name (16 chars) */
|
||||
.long 0x00000000 /* version */
|
||||
.long __text_end-0x02000000 /* Source (in ROM) */
|
||||
.long 0x00000000 /* Destination (in SDRAM) */
|
||||
.long __data_size /* Size */
|
||||
.long 0x06000240 /* Master SH2 Jump */
|
||||
.long 0x06000244 /* Slave SH2 Jump */
|
||||
.long 0x06000000 /* Master SH2 VBR */
|
||||
.long 0x06000120 /* Slave SH2 VBR */
|
||||
|
||||
! Standard MD startup code at 0x3F0
|
||||
|
||||
.incbin "build/32x/m68k_crt1.bin"
|
||||
|
||||
|
||||
.data
|
||||
|
||||
! Master Vector Base Table at 0x06000000
|
||||
|
||||
.long mstart /* Cold Start PC */
|
||||
.long 0x0603FC00 /* Cold Start SP */
|
||||
.long mstart /* Manual Reset PC */
|
||||
.long 0x0603FC00 /* Manual Reset SP */
|
||||
.long main_err /* Illegal instruction */
|
||||
.long 0x00000000 /* reserved */
|
||||
.long main_err /* Invalid slot instruction */
|
||||
.long 0x20100400 /* reserved */
|
||||
.long 0x20100420 /* reserved */
|
||||
.long main_err /* CPU address error */
|
||||
.long main_err /* DMA address error */
|
||||
.long main_err /* NMI vector */
|
||||
.long main_err /* User break vector */
|
||||
.space 76 /* reserved */
|
||||
.long main_err /* TRAPA #32 */
|
||||
.long main_err /* TRAPA #33 */
|
||||
.long main_err /* TRAPA #34 */
|
||||
.long main_err /* TRAPA #35 */
|
||||
.long main_err /* TRAPA #36 */
|
||||
.long main_err /* TRAPA #37 */
|
||||
.long main_err /* TRAPA #38 */
|
||||
.long main_err /* TRAPA #39 */
|
||||
.long main_err /* TRAPA #40 */
|
||||
.long main_err /* TRAPA #41 */
|
||||
.long main_err /* TRAPA #42 */
|
||||
.long main_err /* TRAPA #43 */
|
||||
.long main_err /* TRAPA #44 */
|
||||
.long main_err /* TRAPA #45 */
|
||||
.long main_err /* TRAPA #46 */
|
||||
.long main_err /* TRAPA #47 */
|
||||
.long main_err /* TRAPA #48 */
|
||||
.long main_err /* TRAPA #49 */
|
||||
.long main_err /* TRAPA #50 */
|
||||
.long main_err /* TRAPA #51 */
|
||||
.long main_err /* TRAPA #52 */
|
||||
.long main_err /* TRAPA #53 */
|
||||
.long main_err /* TRAPA #54 */
|
||||
.long main_err /* TRAPA #55 */
|
||||
.long main_err /* TRAPA #56 */
|
||||
.long main_err /* TRAPA #57 */
|
||||
.long main_err /* TRAPA #58 */
|
||||
.long main_err /* TRAPA #59 */
|
||||
.long main_err /* TRAPA #60 */
|
||||
.long main_err /* TRAPA #61 */
|
||||
.long main_err /* TRAPA #62 */
|
||||
.long main_err /* TRAPA #63 */
|
||||
.long main_irq /* Level 1 IRQ */
|
||||
.long main_irq /* Level 2 & 3 IRQ's */
|
||||
.long main_irq /* Level 4 & 5 IRQ's */
|
||||
.long main_irq /* PWM interupt */
|
||||
.long main_irq /* Command interupt */
|
||||
.long main_irq /* H Blank interupt */
|
||||
.long main_irq /* V Blank interupt */
|
||||
.long main_irq /* Reset Button */
|
||||
|
||||
! Slave Vector Base Table at 0x06000120
|
||||
|
||||
.long sstart /* Cold Start PC */
|
||||
.long 0x06040000 /* Cold Start SP */
|
||||
.long sstart /* Manual Reset PC */
|
||||
.long 0x06040000 /* Manual Reset SP */
|
||||
.long slav_err /* Illegal instruction */
|
||||
.long 0x00000000 /* reserved */
|
||||
.long slav_err /* Invalid slot instruction */
|
||||
.long 0x20100400 /* reserved */
|
||||
.long 0x20100420 /* reserved */
|
||||
.long slav_err /* CPU address error */
|
||||
.long slav_err /* DMA address error */
|
||||
.long slav_err /* NMI vector */
|
||||
.long slav_err /* User break vector */
|
||||
.space 76 /* reserved */
|
||||
.long slav_err /* TRAPA #32 */
|
||||
.long slav_err /* TRAPA #33 */
|
||||
.long slav_err /* TRAPA #34 */
|
||||
.long slav_err /* TRAPA #35 */
|
||||
.long slav_err /* TRAPA #36 */
|
||||
.long slav_err /* TRAPA #37 */
|
||||
.long slav_err /* TRAPA #38 */
|
||||
.long slav_err /* TRAPA #39 */
|
||||
.long slav_err /* TRAPA #40 */
|
||||
.long slav_err /* TRAPA #41 */
|
||||
.long slav_err /* TRAPA #42 */
|
||||
.long slav_err /* TRAPA #43 */
|
||||
.long slav_err /* TRAPA #44 */
|
||||
.long slav_err /* TRAPA #45 */
|
||||
.long slav_err /* TRAPA #46 */
|
||||
.long slav_err /* TRAPA #47 */
|
||||
.long slav_err /* TRAPA #48 */
|
||||
.long slav_err /* TRAPA #49 */
|
||||
.long slav_err /* TRAPA #50 */
|
||||
.long slav_err /* TRAPA #51 */
|
||||
.long slav_err /* TRAPA #52 */
|
||||
.long slav_err /* TRAPA #53 */
|
||||
.long slav_err /* TRAPA #54 */
|
||||
.long slav_err /* TRAPA #55 */
|
||||
.long slav_err /* TRAPA #56 */
|
||||
.long slav_err /* TRAPA #57 */
|
||||
.long slav_err /* TRAPA #58 */
|
||||
.long slav_err /* TRAPA #59 */
|
||||
.long slav_err /* TRAPA #60 */
|
||||
.long slav_err /* TRAPA #61 */
|
||||
.long slav_err /* TRAPA #62 */
|
||||
.long slav_err /* TRAPA #63 */
|
||||
.long slav_irq /* Level 1 IRQ */
|
||||
.long slav_irq /* Level 2 & 3 IRQ's */
|
||||
.long slav_irq /* Level 4 & 5 IRQ's */
|
||||
.long slav_irq /* PWM interupt */
|
||||
.long slav_irq /* Command interupt */
|
||||
.long slav_irq /* H Blank interupt */
|
||||
.long slav_irq /* V Blank interupt */
|
||||
.long slav_irq /* Reset Button */
|
||||
|
||||
! The main SH2 starts here at 0x06000240
|
||||
|
||||
mstart:
|
||||
bra mcont
|
||||
nop
|
||||
|
||||
! The slave SH2 starts here at 0x06000244
|
||||
|
||||
sstart:
|
||||
bra scont
|
||||
nop
|
||||
|
||||
! Each section of code below has its own data table so that the code
|
||||
! can be extended without worrying about the offsets becoming too big.
|
||||
! This results in duplicate entries, but not so many that we care. :)
|
||||
|
||||
mcont:
|
||||
! clear interrupt flags
|
||||
mov.l _master_int_clr,r1
|
||||
mov.w r0,@-r1 /* PWM INT clear */
|
||||
mov.w r0,@r1
|
||||
mov.w r0,@-r1 /* CMD INT clear */
|
||||
mov.w r0,@r1
|
||||
mov.w r0,@-r1 /* H INT clear */
|
||||
mov.w r0,@r1
|
||||
mov.w r0,@-r1 /* V INT clear */
|
||||
mov.w r0,@r1
|
||||
mov.w r0,@-r1 /* VRES INT clear */
|
||||
mov.w r0,@r1
|
||||
|
||||
mov.l _master_stk,r15
|
||||
! purge cache and turn it off
|
||||
mov.l _master_cctl,r0
|
||||
mov #0x10,r1
|
||||
mov.b r1,@r0
|
||||
|
||||
! clear bss
|
||||
mov #0,r0
|
||||
mov.l _master_bss_start,r1
|
||||
mov.l _master_bss_end,r2
|
||||
0:
|
||||
mov.l r0,@r1
|
||||
cmp/eq r1,r2
|
||||
bf/s 0b
|
||||
add #4,r1
|
||||
|
||||
! wait for 68000 to finish init
|
||||
mov.l _master_sts,r0
|
||||
mov.l _master_ok,r1
|
||||
1:
|
||||
mov.l @r0,r2
|
||||
nop
|
||||
nop
|
||||
cmp/eq r1,r2
|
||||
bt 1b
|
||||
|
||||
! do all initializers
|
||||
mov.l _master_do_init,r0
|
||||
jsr @r0
|
||||
nop
|
||||
|
||||
! let Slave SH2 run
|
||||
mov #0,r1
|
||||
mov.l r1,@(4,r0) /* clear slave status */
|
||||
|
||||
mov #0x80,r0
|
||||
mov.l _master_adapter,r1
|
||||
mov.b r0,@r1 /* set FM */
|
||||
mov #0x00,r0
|
||||
mov.b r0,@(1,r1) /* set int enables */
|
||||
mov #0x20,r0
|
||||
ldc r0,sr /* allow ints */
|
||||
|
||||
! purge cache, turn it on, and run main()
|
||||
mov.l _master_cctl,r0
|
||||
mov #0x11,r1
|
||||
mov.b r1,@r0
|
||||
mov.l _master_go,r0
|
||||
jsr @r0
|
||||
nop
|
||||
|
||||
! do all finishers
|
||||
mov.l _master_do_fini,r0
|
||||
jsr @r0
|
||||
nop
|
||||
2:
|
||||
bra 2b
|
||||
nop
|
||||
|
||||
.align 2
|
||||
_master_int_clr:
|
||||
.long 0x2000401E /* one word passed last int clr reg */
|
||||
_master_stk:
|
||||
.long 0x0603FC00 /* Cold Start SP */
|
||||
_master_sts:
|
||||
.long 0x20004020
|
||||
_master_ok:
|
||||
.ascii "M_OK"
|
||||
_master_adapter:
|
||||
.long 0x20004000
|
||||
_master_cctl:
|
||||
.long 0xFFFFFE92
|
||||
_master_go:
|
||||
.long _main
|
||||
|
||||
_master_bss_start:
|
||||
.long __bss_start
|
||||
_master_bss_end:
|
||||
.long __bss_end
|
||||
_master_do_init:
|
||||
.long __INIT_SECTION__
|
||||
_master_do_fini:
|
||||
.long __FINI_SECTION__
|
||||
|
||||
scont:
|
||||
! clear interrupt flags
|
||||
mov.l _slave_int_clr,r1
|
||||
mov.w r0,@-r1 /* PWM INT clear */
|
||||
mov.w r0,@r1
|
||||
mov.w r0,@-r1 /* CMD INT clear */
|
||||
mov.w r0,@r1
|
||||
mov.w r0,@-r1 /* H INT clear */
|
||||
mov.w r0,@r1
|
||||
mov.w r0,@-r1 /* V INT clear */
|
||||
mov.w r0,@r1
|
||||
mov.w r0,@-r1 /* VRES INT clear */
|
||||
mov.w r0,@r1
|
||||
|
||||
mov.l _slave_stk,r15
|
||||
! wait for Master SH2 and 68000 to finish init
|
||||
mov.l _slave_sts,r0
|
||||
mov.l _slave_ok,r1
|
||||
1:
|
||||
mov.l @r0,r2
|
||||
nop
|
||||
nop
|
||||
cmp/eq r1,r2
|
||||
bt 1b
|
||||
|
||||
mov.l _slave_adapter,r1
|
||||
mov #0x00,r0
|
||||
mov.b r0,@(1,r1) /* set int enables (different from master despite same address!) */
|
||||
mov #0x20,r0
|
||||
ldc r0,sr /* allow ints */
|
||||
|
||||
! purge cache, turn it on, and run slave()
|
||||
mov.l _slave_cctl,r0
|
||||
mov #0x11,r1
|
||||
mov.b r1,@r0
|
||||
mov.l _slave_go,r0
|
||||
jmp @r0
|
||||
nop
|
||||
|
||||
.align 2
|
||||
_slave_int_clr:
|
||||
.long 0x2000401E /* one word passed last int clr reg */
|
||||
_slave_stk:
|
||||
.long 0x06040000 /* Cold Start SP */
|
||||
_slave_sts:
|
||||
.long 0x20004024
|
||||
_slave_ok:
|
||||
.ascii "S_OK"
|
||||
_slave_adapter:
|
||||
.long 0x20004000
|
||||
_slave_cctl:
|
||||
.long 0xFFFFFE92
|
||||
_slave_go:
|
||||
.long _slave
|
||||
|
||||
! Master exception handler
|
||||
|
||||
main_err:
|
||||
rte
|
||||
nop
|
||||
|
||||
! Master IRQ handler
|
||||
|
||||
main_irq:
|
||||
mov.l r0,@-r15
|
||||
|
||||
stc sr,r0 /* SR holds IRQ level in I3-I0 */
|
||||
shlr2 r0
|
||||
and #0x38,r0
|
||||
cmp/eq #0x28,r0
|
||||
bt main_h_irq
|
||||
cmp/eq #0x18,r0
|
||||
bt main_pwm_irq
|
||||
cmp/eq #0x30,r0
|
||||
bt main_v_irq
|
||||
cmp/eq #0x20,r0
|
||||
bt main_cmd_irq
|
||||
cmp/eq #0x38,r0
|
||||
bt main_vres_irq
|
||||
|
||||
mov.l @r15+,r0
|
||||
rte
|
||||
nop
|
||||
|
||||
main_v_irq:
|
||||
mov.l r1,@-r15
|
||||
|
||||
mov.l mvi_mars_adapter,r1
|
||||
mov.w r0,@(0x16,r1) /* clear V IRQ */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
! handle V IRQ
|
||||
|
||||
mov.l @r15+,r1
|
||||
mov.l @r15+,r0
|
||||
rte
|
||||
nop
|
||||
|
||||
.align 2
|
||||
mvi_mars_adapter:
|
||||
.long 0x20004000
|
||||
|
||||
main_h_irq:
|
||||
mov.l r1,@-r15
|
||||
|
||||
mov.l mhi_mars_adapter,r1
|
||||
mov.w r0,@(0x18,r1) /* clear H IRQ */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
! handle H IRQ
|
||||
|
||||
mov.l @r15+,r1
|
||||
mov.l @r15+,r0
|
||||
rte
|
||||
nop
|
||||
|
||||
.align 2
|
||||
mhi_mars_adapter:
|
||||
.long 0x20004000
|
||||
|
||||
main_cmd_irq:
|
||||
mov.l r1,@-r15
|
||||
|
||||
mov.l mci_mars_adapter,r1
|
||||
mov.w r0,@(0x1A,r1) /* clear CMD IRQ */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
! handle CMD IRQ
|
||||
|
||||
mov.l @r15+,r1
|
||||
mov.l @r15+,r0
|
||||
rte
|
||||
nop
|
||||
|
||||
.align 2
|
||||
mci_mars_adapter:
|
||||
.long 0x20004000
|
||||
|
||||
main_pwm_irq:
|
||||
mov.l r1,@-r15
|
||||
|
||||
mov.l mpi_mars_adapter,r1
|
||||
mov.w r0,@(0x1C,r1) /* clear PWM IRQ */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
! handle PWM IRQ
|
||||
|
||||
mov.l @r15+,r1
|
||||
mov.l @r15+,r0
|
||||
rte
|
||||
nop
|
||||
|
||||
.align 2
|
||||
mpi_mars_adapter:
|
||||
.long 0x20004000
|
||||
|
||||
main_vres_irq:
|
||||
mov.l mvri_mars_adapter,r1
|
||||
mov.w r0,@(0x14,r1) /* clear VRES IRQ */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
mov #0x0F,r0
|
||||
shll2 r0
|
||||
shll2 r0
|
||||
ldc r0,sr /* disallow ints */
|
||||
|
||||
mov.l mvri_master_stk,r15
|
||||
mov.l mvri_master_vres,r0
|
||||
jmp @r0
|
||||
nop
|
||||
|
||||
.align 2
|
||||
mvri_mars_adapter:
|
||||
.long 0x20004000
|
||||
mvri_master_stk:
|
||||
.long 0x0603FC00 /* Cold Start SP */
|
||||
mvri_master_vres:
|
||||
.long main_reset
|
||||
|
||||
! Slave exception handler
|
||||
|
||||
slav_err:
|
||||
rte
|
||||
nop
|
||||
|
||||
! Slave IRQ handler
|
||||
|
||||
slav_irq:
|
||||
mov.l r0,@-r15
|
||||
|
||||
stc sr,r0 /* SR holds IRQ level I3-I0 */
|
||||
shlr2 r0
|
||||
and #0x38,r0
|
||||
cmp/eq #0x28,r0
|
||||
bt slav_h_irq
|
||||
cmp/eq #0x18,r0
|
||||
bt slav_pwm_irq
|
||||
cmp/eq #0x30,r0
|
||||
bt slav_v_irq
|
||||
cmp/eq #0x20,r0
|
||||
bt slav_cmd_irq
|
||||
cmp/eq #0x38,r0
|
||||
bt slav_vres_irq
|
||||
|
||||
mov.l @r15+,r0
|
||||
rte
|
||||
nop
|
||||
|
||||
slav_v_irq:
|
||||
mov.l r1,@-r15
|
||||
|
||||
mov.l svi_mars_adapter,r1
|
||||
mov.w r0,@(0x16,r1) /* clear V IRQ */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
! handle V IRQ
|
||||
|
||||
mov.l @r15+,r1
|
||||
mov.l @r15+,r0
|
||||
rte
|
||||
nop
|
||||
|
||||
.align 2
|
||||
svi_mars_adapter:
|
||||
.long 0x20004000
|
||||
|
||||
slav_h_irq:
|
||||
mov.l r1,@-r15
|
||||
|
||||
mov.l shi_mars_adapter,r1
|
||||
mov.w r0,@(0x18,r1) /* clear H IRQ */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
! handle H IRQ
|
||||
|
||||
mov.l @r15+,r1
|
||||
mov.l @r15+,r0
|
||||
rte
|
||||
nop
|
||||
|
||||
.align 2
|
||||
shi_mars_adapter:
|
||||
.long 0x20004000
|
||||
|
||||
slav_cmd_irq:
|
||||
mov.l r1,@-r15
|
||||
|
||||
mov.l sci_mars_adapter,r1
|
||||
mov.w r0,@(0x1A,r1) /* clear CMD IRQ */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
! handle CMD IRQ
|
||||
|
||||
mov.l @r15+,r1
|
||||
mov.l @r15+,r0
|
||||
rte
|
||||
nop
|
||||
|
||||
.align 2
|
||||
sci_mars_adapter:
|
||||
.long 0x20004000
|
||||
|
||||
slav_pwm_irq:
|
||||
mov.l r1,@-r15
|
||||
|
||||
mov.l spi_mars_adapter,r1
|
||||
mov.w r0,@(0x1C,r1) /* clear PWM IRQ */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
! handle PWM IRQ
|
||||
|
||||
mov.l @r15+,r1
|
||||
mov.l @r15+,r0
|
||||
rte
|
||||
nop
|
||||
|
||||
.align 2
|
||||
spi_mars_adapter:
|
||||
.long 0x20004000
|
||||
|
||||
slav_vres_irq:
|
||||
mov.l svri_mars_adapter,r1
|
||||
mov.w r0,@(0x14,r1) /* clear VRES IRQ */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
mov #0x0F,r0
|
||||
shll2 r0
|
||||
shll2 r0
|
||||
ldc r0,sr /* disallow ints */
|
||||
|
||||
mov.l svri_slave_stk,r15
|
||||
mov.l svri_slave_vres,r0
|
||||
jmp @r0
|
||||
nop
|
||||
|
||||
.align 2
|
||||
svri_mars_adapter:
|
||||
.long 0x20004000
|
||||
svri_slave_stk:
|
||||
.long 0x06040000 /* Cold Start SP */
|
||||
svri_slave_vres:
|
||||
.long slav_reset
|
||||
|
||||
|
||||
! Fast memcpy function - copies longs, runs from sdram for speed
|
||||
! On entry: r4 = dst, r5 = src, r6 = len (in longs)
|
||||
|
||||
.align 4
|
||||
.global _fast_memcpy
|
||||
_fast_memcpy:
|
||||
mov.l @r5+,r3
|
||||
mov.l r3,@r4
|
||||
dt r6
|
||||
bf/s _fast_memcpy
|
||||
add #4,r4
|
||||
rts
|
||||
nop
|
||||
|
||||
! Cache clear line function
|
||||
! On entry: r4 = ptr - should be 16 byte aligned
|
||||
|
||||
.align 4
|
||||
.global _CacheClearLine
|
||||
_CacheClearLine:
|
||||
mov.l _cache_flush,r0
|
||||
or r0,r4
|
||||
mov #0,r0
|
||||
mov.l r0,@r4
|
||||
rts
|
||||
nop
|
||||
|
||||
.align 2
|
||||
|
||||
_cache_flush:
|
||||
.long 0x40000000
|
||||
|
||||
! Cache control function
|
||||
! On entry: r4 = cache mode => 0x10 = CP, 0x08 = TW, 0x01 = CE
|
||||
|
||||
.align 4
|
||||
.global _CacheControl
|
||||
_CacheControl:
|
||||
mov.l _sh2_cctl,r0
|
||||
mov.b r4,@r0
|
||||
rts
|
||||
nop
|
||||
|
||||
.align 2
|
||||
|
||||
_sh2_cctl:
|
||||
.long 0xFFFFFE92
|
||||
|
||||
! void ScreenStretch(int src, int width, int height, int interp);
|
||||
! On entry: r4 = src pointer, r5 = width, r6 = height, r7 = interpolate
|
||||
|
||||
.align 4
|
||||
.global _ScreenStretch
|
||||
_ScreenStretch:
|
||||
cmp/pl r7
|
||||
bt ss_interp
|
||||
|
||||
! stretch screen without interpolation
|
||||
|
||||
0:
|
||||
mov r5,r3
|
||||
shll r3
|
||||
mov r3,r2
|
||||
shll r2
|
||||
add r4,r3
|
||||
add r4,r2
|
||||
1:
|
||||
add #-2,r3
|
||||
mov.w @r3,r0
|
||||
extu.w r0,r1
|
||||
shll16 r0
|
||||
or r1,r0
|
||||
mov.l r0,@-r2
|
||||
cmp/eq r3,r4
|
||||
bf 1b
|
||||
|
||||
/* next line */
|
||||
mov.w ss_pitch,r0
|
||||
dt r6
|
||||
bf/s 0b
|
||||
add r0,r4
|
||||
rts
|
||||
nop
|
||||
|
||||
ss_interp:
|
||||
|
||||
! stretch screen with interpolation
|
||||
|
||||
0:
|
||||
mov r5,r3
|
||||
shll r3
|
||||
mov r3,r2
|
||||
shll r2
|
||||
add r4,r3
|
||||
add r4,r2
|
||||
mov #0,r7
|
||||
1:
|
||||
add #-2,r3
|
||||
mov.w @r3,r0
|
||||
mov.w ss_mask,r1
|
||||
and r0,r1 /* masked curr pixel */
|
||||
shll16 r0
|
||||
add r1,r7 /* add to masked prev pixel */
|
||||
shlr r7 /* blended pixel */
|
||||
or r7,r0 /* curr pixel << 16 | blended pixel */
|
||||
mov r1,r7 /* masked prev pixel = masked curr pixel */
|
||||
mov.l r0,@-r2
|
||||
cmp/eq r3,r4
|
||||
bf 1b
|
||||
|
||||
/* next line */
|
||||
mov.w ss_pitch,r0
|
||||
dt r6
|
||||
bf/s 0b
|
||||
add r0,r4
|
||||
rts
|
||||
nop
|
||||
|
||||
ss_mask:
|
||||
.word 0x7BDE
|
||||
ss_pitch:
|
||||
.word 640
|
||||
|
||||
.align 2
|
||||
|
||||
.text
|
||||
|
||||
main_reset:
|
||||
! do any master SH2 specific reset code here
|
||||
|
||||
mov.l slav_st,r0
|
||||
mov.l slav_ok,r1
|
||||
0:
|
||||
mov.l @r0,r2
|
||||
nop
|
||||
nop
|
||||
cmp/eq r1,r2
|
||||
bf 0b /* wait for slave */
|
||||
|
||||
! recopy rom data to sdram
|
||||
|
||||
mov.l rom_header,r1
|
||||
mov.l @r1,r2 /* src relative to start of rom */
|
||||
mov.l @(4,r1),r3 /* dst relative to start of sdram */
|
||||
mov.l @(8,r1),r4 /* size (longword aligned) */
|
||||
mov.l rom_start,r1
|
||||
add r1,r2
|
||||
mov.l sdram_start,r1
|
||||
add r1,r3
|
||||
shlr2 r4 /* number of longs */
|
||||
add #-1,r4
|
||||
1:
|
||||
mov.l @r2+,r0
|
||||
mov.l r0,@r3
|
||||
add #4,r3
|
||||
dt r4
|
||||
bf 1b
|
||||
|
||||
mov.l main_st,r0
|
||||
mov.l main_ok,r1
|
||||
mov.l r1,@r0 /* tell everyone reset complete */
|
||||
|
||||
mov.l main_go,r0
|
||||
jmp @r0
|
||||
nop
|
||||
|
||||
slav_reset:
|
||||
! do any slave SH2 specific reset code here
|
||||
|
||||
mov.l slav_st,r0
|
||||
mov.l slav_ok,r1
|
||||
mov.l r1,@r0 /* tell master to start reset */
|
||||
|
||||
mov.l main_st,r0
|
||||
mov.l main_ok,r1
|
||||
0:
|
||||
mov.l @r0,r2
|
||||
nop
|
||||
nop
|
||||
cmp/eq r1,r2
|
||||
bf 0b /* wait for master to do the work */
|
||||
|
||||
mov.l slav_go,r0
|
||||
jmp @r0
|
||||
nop
|
||||
|
||||
.align 2
|
||||
main_st:
|
||||
.long 0x20004020
|
||||
main_ok:
|
||||
.ascii "M_OK"
|
||||
main_go:
|
||||
.long mstart
|
||||
rom_header:
|
||||
.long 0x220003D4
|
||||
rom_start:
|
||||
.long 0x22000000
|
||||
sdram_start:
|
||||
.long 0x26000000
|
||||
|
||||
slav_st:
|
||||
.long 0x20004024
|
||||
slav_ok:
|
||||
.ascii "S_OK"
|
||||
slav_go:
|
||||
.long sstart
|
||||
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
|
||||
127
misc/3ds/Makefile
Normal file
@@ -0,0 +1,127 @@
|
||||
ifeq ($(strip $(DEVKITPRO)),)
|
||||
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>devkitPro)
|
||||
endif
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Configurable options
|
||||
#---------------------------------------------------------------------------------
|
||||
# Name of the final output
|
||||
TARGET = ClassiCube-3ds
|
||||
# List of directories containing source code
|
||||
SOURCE_DIRS = src src/3ds third_party/bearssl/src
|
||||
# List of directories containing shader files
|
||||
SHDR_DIRS = misc/3ds
|
||||
# List of directories containing more header files
|
||||
INCLUDES = -Ithird_party/bearssl/inc
|
||||
# Directory where object files are placed
|
||||
BUILD_DIR = build/3ds
|
||||
|
||||
APP_ICON = misc/3ds/icon.png
|
||||
APP_TITLE = ClassiCube
|
||||
APP_DESCRIPTION = Simple block building sandbox
|
||||
APP_AUTHOR = ClassiCube team
|
||||
|
||||
CIA_BANNER_BIN = misc/3ds/banner.bin
|
||||
CIA_ICON_BIN = misc/3ds/icon.bin
|
||||
CIA_SPEC_RSF = misc/3ds/spec.rsf
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
S_FILES = $(foreach dir,$(SOURCE_DIRS),$(wildcard $(dir)/*.S))
|
||||
C_FILES = $(foreach dir,$(SOURCE_DIRS),$(wildcard $(dir)/*.c))
|
||||
OBJS = $(addprefix $(BUILD_DIR)/, $(notdir $(C_FILES:%.c=%.o) $(S_FILES:%.S=%.o)))
|
||||
|
||||
PICAFILES := $(foreach dir,$(SHDR_DIRS),$(notdir $(wildcard $(dir)/*.v.pica)))
|
||||
OBJS += $(addprefix $(BUILD_DIR)/, $(PICAFILES:.v.pica=.shbin.o))
|
||||
|
||||
ARCH = -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft
|
||||
CFLAGS = -g -Wall -O2 -mword-relocations -ffunction-sections $(ARCH) $(INCLUDE) -D__3DS__
|
||||
ASFLAGS = -g $(ARCH)
|
||||
|
||||
LDFLAGS = -specs=3dsx.specs -g $(ARCH)
|
||||
LIBS = -lctru -lm
|
||||
|
||||
CTRULIB = $(DEVKITPRO)/libctru
|
||||
INCLUDES += $(foreach dir, $(CTRULIB), -I$(dir)/include)
|
||||
LDFLAGS += $(foreach dir, $(CTRULIB), -L$(dir)/lib)
|
||||
|
||||
# Dependency tracking
|
||||
DEPFLAGS = -MT $@ -MMD -MP -MF $(BUILD_DIR)/$*.d
|
||||
DEPFILES := $(OBJS:%.o=%.d)
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Compiler tools
|
||||
#---------------------------------------------------------------------------------
|
||||
PREFIX := $(DEVKITPRO)/devkitARM/bin/arm-none-eabi-
|
||||
ARM_AS := $(PREFIX)as
|
||||
ARM_CC := $(PREFIX)gcc
|
||||
ARM_CXX := $(PREFIX)g++
|
||||
|
||||
_DSXTOOL := $(DEVKITPRO)/tools/bin/3dsxtool
|
||||
SMDHTOOL := $(DEVKITPRO)/tools/bin/smdhtool
|
||||
PICASSO := $(DEVKITPRO)/tools/bin/picasso
|
||||
BIN2S := $(DEVKITPRO)/tools/bin/bin2s
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
default: $(BUILD_DIR) $(TARGET).cia
|
||||
|
||||
clean:
|
||||
rm $(TARGET).cia $(TARGET).3dsx $(TARGET).elf $(OBJS)
|
||||
|
||||
$(BUILD_DIR):
|
||||
mkdir -p $(BUILD_DIR)
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Executable generation
|
||||
#---------------------------------------------------------------------------------
|
||||
$(TARGET).elf: $(OBJS)
|
||||
$(ARM_CC) $(LDFLAGS) $^ -o $@ $(LIBS)
|
||||
|
||||
$(BUILD_DIR).smdh: $(APP_ICON)
|
||||
$(SMDHTOOL) --create "$(APP_TITLE)" "$(APP_DESCRIPTION)" "$(APP_AUTHOR)" $(APP_ICON) $@
|
||||
|
||||
$(TARGET).3dsx: $(TARGET).elf $(BUILD_DIR).smdh
|
||||
$(_DSXTOOL) $< $@ --smdh=$(BUILD_DIR).smdh
|
||||
|
||||
$(BUILD_DIR)/makerom:
|
||||
wget https://github.com/3DSGuy/Project_CTR/releases/download/makerom-v0.18.3/makerom-v0.18.3-ubuntu_x86_64.zip -O $(BUILD_DIR)/makerom.zip
|
||||
unzip $(BUILD_DIR)/makerom.zip -d $(BUILD_DIR)
|
||||
chmod +x $(BUILD_DIR)/makerom
|
||||
|
||||
$(TARGET).cia : $(TARGET).3dsx $(BUILD_DIR)/makerom
|
||||
$(BUILD_DIR)/makerom -f cia -o $(TARGET).cia -elf $(TARGET).elf -rsf $(CIA_SPEC_RSF) -icon $(CIA_ICON_BIN) -banner $(CIA_BANNER_BIN) -exefslogo -target t
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Object generation
|
||||
#---------------------------------------------------------------------------------
|
||||
$(BUILD_DIR)/%.o: src/%.c
|
||||
$(ARM_CC) $(CFLAGS) $(INCLUDES) $(DEPFLAGS) -c $< -o $@
|
||||
|
||||
$(BUILD_DIR)/%.o: src/3ds/%.c
|
||||
$(ARM_CC) $(CFLAGS) $(INCLUDES) $(DEPFLAGS) -c $< -o $@
|
||||
|
||||
$(BUILD_DIR)/%.o: third_party/bearssl/src/%.c
|
||||
$(ARM_CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
|
||||
|
||||
$(BUILD_DIR)/%.shbin: misc/3ds/%.v.pica
|
||||
$(PICASSO) $< -o $@
|
||||
|
||||
$(BUILD_DIR)/%.shbin.o: $(BUILD_DIR)/%.shbin
|
||||
$(BIN2S) $< | $(ARM_AS) -o $@
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Dependency tracking
|
||||
#---------------------------------------------------------------------------------
|
||||
$(DEPFILES):
|
||||
|
||||
include $(wildcard $(DEPFILES))
|
||||
BIN
misc/3ds/audio.wav
Normal file
BIN
misc/3ds/banner.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
33
misc/3ds/coloured.v.pica
Normal file
@@ -0,0 +1,33 @@
|
||||
; Vertex shader for rendering coloured vertices for PICA200 GPU on the Nintendo 3DS
|
||||
; ==================================================================================
|
||||
|
||||
; Uniforms
|
||||
.fvec MVP[4];
|
||||
|
||||
; Constants
|
||||
.constf ONE_DIV_255(0.003921568627, 0.003921568627, 0.003921568627, 0.003921568627)
|
||||
|
||||
; Outputs
|
||||
.out out_pos position
|
||||
.out out_col color
|
||||
|
||||
; Inputs (defined as aliases for convenience)
|
||||
.alias in_pos v0
|
||||
.alias in_col v1
|
||||
|
||||
.proc main
|
||||
; r0 = in_pos
|
||||
mov r0, in_pos
|
||||
|
||||
; out_pos = MVP * r0
|
||||
dp4 out_pos.x, MVP[0], r0
|
||||
dp4 out_pos.y, MVP[1], r0
|
||||
dp4 out_pos.z, MVP[2], r0
|
||||
dp4 out_pos.w, MVP[3], r0
|
||||
|
||||
; out_col = in_col * ONE_DIV_255
|
||||
mul out_col, ONE_DIV_255, in_col
|
||||
|
||||
end
|
||||
.end
|
||||
|
||||
BIN
misc/3ds/icon.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
38
misc/3ds/offset.v.pica
Normal file
@@ -0,0 +1,38 @@
|
||||
; Vertex shader for rendering textured vertices with an offset for PICA200 GPU on the Nintendo 3DS
|
||||
; ==================================================================================
|
||||
|
||||
; Uniforms
|
||||
.fvec MVP[4];
|
||||
.fvec tex_offset;
|
||||
|
||||
; Constants
|
||||
.constf ONE_DIV_255(0.003921568627, 0.003921568627, 0.003921568627, 0.003921568627)
|
||||
|
||||
; Outputs
|
||||
.out out_pos position
|
||||
.out out_col color
|
||||
.out out_tex texcoord0
|
||||
|
||||
; Inputs (defined as aliases for convenience)
|
||||
.alias in_pos v0
|
||||
.alias in_col v1
|
||||
.alias in_tex v2
|
||||
|
||||
.proc main
|
||||
; r0 = in_pos
|
||||
mov r0, in_pos
|
||||
|
||||
; out_pos = MVP * r0
|
||||
dp4 out_pos.x, MVP[0], r0
|
||||
dp4 out_pos.y, MVP[1], r0
|
||||
dp4 out_pos.z, MVP[2], r0
|
||||
dp4 out_pos.w, MVP[3], r0
|
||||
|
||||
; out_col = in_col * ONE_DIV_255
|
||||
mul out_col, ONE_DIV_255, in_col
|
||||
; out_tex = in_tex + tex_offset
|
||||
add out_tex, tex_offset, in_tex
|
||||
|
||||
end
|
||||
.end
|
||||
|
||||
5
misc/3ds/readme.md
Normal file
@@ -0,0 +1,5 @@
|
||||
Commands used to generate the .bin files:
|
||||
|
||||
`bannertool makebanner -i banner.png -a audio.wav -o banner.bin`
|
||||
|
||||
`bannertool makesmdh -s ClassiCube -l ClassiCube -p UnknownShadow200 -i icon.png -o icon.bin`
|
||||
204
misc/3ds/spec.rsf
Normal file
@@ -0,0 +1,204 @@
|
||||
# https://github.com/msikma/3ds-tpl
|
||||
# https://gist.github.com/jakcron/9f9f02ffd94d98a72632
|
||||
|
||||
BasicInfo:
|
||||
Title : ClassiCube
|
||||
CompanyCode : "00"
|
||||
ProductCode : CCBE
|
||||
ContentType : Application
|
||||
Logo : Nintendo
|
||||
|
||||
TitleInfo:
|
||||
UniqueId : 0x00CCBE
|
||||
Category : Application
|
||||
|
||||
CardInfo:
|
||||
MediaSize : 128MB # 128MB / 256MB / 512MB / 1GB / 2GB / 4GB
|
||||
MediaType : Card1 # Card1 / Card2
|
||||
CardDevice : NorFlash # NorFlash(Pick this if you use savedata) / None
|
||||
|
||||
|
||||
Option:
|
||||
UseOnSD : true # true if App is to be installed to SD
|
||||
FreeProductCode : true # Removes limitations on ProductCode
|
||||
MediaFootPadding : false # If true CCI files are created with padding
|
||||
EnableCrypt : false # Enables encryption for NCCH and CIA
|
||||
EnableCompress : true # Compresses exefs code
|
||||
|
||||
AccessControlInfo:
|
||||
#UseExtSaveData : true
|
||||
#ExtSaveDataId: 0xff3ff
|
||||
#UseExtendedSaveDataAccessControl: true
|
||||
#AccessibleSaveDataIds: [0x101, 0x202, 0x303, 0x404, 0x505, 0x606]
|
||||
|
||||
SystemControlInfo:
|
||||
SaveDataSize: 128KB
|
||||
RemasterVersion: 0
|
||||
StackSize: 0x40000
|
||||
|
||||
AccessControlInfo:
|
||||
FileSystemAccess:
|
||||
- Debug
|
||||
- DirectSdmc
|
||||
- DirectSdmcWrite
|
||||
|
||||
IdealProcessor : 0
|
||||
AffinityMask : 1
|
||||
|
||||
Priority : 16
|
||||
SystemMode : 80MB
|
||||
MaxCpu : 0x9E # Default
|
||||
DisableDebug : false
|
||||
EnableForceDebug : false
|
||||
CanWriteSharedPage : false
|
||||
CanUsePrivilegedPriority : false
|
||||
CanUseNonAlphabetAndNumber : false
|
||||
PermitMainFunctionArgument : false
|
||||
CanShareDeviceMemory : false
|
||||
RunnableOnSleep : false
|
||||
SpecialMemoryArrange : false
|
||||
CoreVersion : 2
|
||||
DescVersion : 2
|
||||
|
||||
ReleaseKernelMajor : "02"
|
||||
ReleaseKernelMinor : "33"
|
||||
MemoryType : Application
|
||||
HandleTableSize: 512
|
||||
|
||||
# New3DS Exclusive Process Settings
|
||||
SystemModeExt : 124MB # Legacy(Default)/124MB/178MB Legacy:Use Old3DS SystemMode
|
||||
CpuSpeed : 804MHz # 268MHz(Default)/804MHz
|
||||
EnableL2Cache : true # false(default)/true
|
||||
CanAccessCore2 : true
|
||||
|
||||
# Virtual Address Mappings
|
||||
IORegisterMapping:
|
||||
- 1ff50000-1ff57fff # DSP memory
|
||||
- 1ff70000-1ff77fff
|
||||
MemoryMapping:
|
||||
- 1f000000-1f5fffff:r # VRAM
|
||||
|
||||
SystemCallAccess:
|
||||
ArbitrateAddress: 34
|
||||
Break: 60
|
||||
CancelTimer: 28
|
||||
ClearEvent: 25
|
||||
ClearTimer: 29
|
||||
CloseHandle: 35
|
||||
ConnectToPort: 45
|
||||
ControlMemory: 1
|
||||
CreateAddressArbiter: 33
|
||||
CreateEvent: 23
|
||||
CreateMemoryBlock: 30
|
||||
CreateMutex: 19
|
||||
CreateSemaphore: 21
|
||||
CreateThread: 8
|
||||
CreateTimer: 26
|
||||
DuplicateHandle: 39
|
||||
ExitProcess: 3
|
||||
ExitThread: 9
|
||||
GetCurrentProcessorNumber: 17
|
||||
GetHandleInfo: 41
|
||||
GetProcessId: 53
|
||||
GetProcessIdOfThread: 54
|
||||
GetProcessIdealProcessor: 6
|
||||
GetProcessInfo: 43
|
||||
GetResourceLimit: 56
|
||||
GetResourceLimitCurrentValues: 58
|
||||
GetResourceLimitLimitValues: 57
|
||||
GetSystemInfo: 42
|
||||
GetSystemTick: 40
|
||||
GetThreadContext: 59
|
||||
GetThreadId: 55
|
||||
GetThreadIdealProcessor: 15
|
||||
GetThreadInfo: 44
|
||||
GetThreadPriority: 11
|
||||
MapMemoryBlock: 31
|
||||
OutputDebugString: 61
|
||||
QueryMemory: 2
|
||||
ReleaseMutex: 20
|
||||
ReleaseSemaphore: 22
|
||||
SendSyncRequest1: 46
|
||||
SendSyncRequest2: 47
|
||||
SendSyncRequest3: 48
|
||||
SendSyncRequest4: 49
|
||||
SendSyncRequest: 50
|
||||
SetThreadPriority: 12
|
||||
SetTimer: 27
|
||||
SignalEvent: 24
|
||||
SleepThread: 10
|
||||
UnmapMemoryBlock: 32
|
||||
WaitSynchronization1: 36
|
||||
WaitSynchronizationN: 37
|
||||
InterruptNumbers:
|
||||
|
||||
# Service List
|
||||
# Maximum 34 services (32 if firmware is prior to 9.3.0)
|
||||
ServiceAccessControl:
|
||||
- APT:U
|
||||
- $hioFIO
|
||||
- $hostio0
|
||||
- $hostio1
|
||||
- ac:u
|
||||
- boss:U
|
||||
- cam:u
|
||||
- cecd:u
|
||||
- cfg:u
|
||||
- dlp:FKCL
|
||||
- dlp:SRVR
|
||||
- dsp::DSP
|
||||
- frd:u
|
||||
- fs:USER
|
||||
- gsp::Gpu
|
||||
- hid:USER
|
||||
- mic:u
|
||||
- ndm:u
|
||||
- news:s
|
||||
- nwm::UDS
|
||||
- ptm:u
|
||||
- pxi:dev
|
||||
- soc:U
|
||||
- gsp::Lcd
|
||||
- y2r:u
|
||||
- ldr:ro
|
||||
- ir:USER
|
||||
- ir:u
|
||||
- csnd:SND
|
||||
- am:u
|
||||
- ns:s
|
||||
|
||||
SystemControlInfo:
|
||||
# Modules that run services listed above should be included below
|
||||
# Maximum 48 dependencies
|
||||
# If a module is listed that isn't present on the 3DS, the title will get stuck at the logo (3ds waves)
|
||||
# So act, nfc and qtm are commented for 4.x support. Uncomment if you need these.
|
||||
# <module name>:<module titleid>
|
||||
Dependency:
|
||||
ac: 0x0004013000002402L
|
||||
am: 0x0004013000001502L
|
||||
boss: 0x0004013000003402L
|
||||
camera: 0x0004013000001602L
|
||||
cecd: 0x0004013000002602L
|
||||
cfg: 0x0004013000001702L
|
||||
codec: 0x0004013000001802L
|
||||
csnd: 0x0004013000002702L
|
||||
dlp: 0x0004013000002802L
|
||||
dsp: 0x0004013000001a02L
|
||||
friends: 0x0004013000003202L
|
||||
gpio: 0x0004013000001b02L
|
||||
gsp: 0x0004013000001c02L
|
||||
hid: 0x0004013000001d02L
|
||||
i2c: 0x0004013000001e02L
|
||||
ir: 0x0004013000003302L
|
||||
mcu: 0x0004013000001f02L
|
||||
mic: 0x0004013000002002L
|
||||
ndm: 0x0004013000002b02L
|
||||
news: 0x0004013000003502L
|
||||
nim: 0x0004013000002c02L
|
||||
nwm: 0x0004013000002d02L
|
||||
pdn: 0x0004013000002102L
|
||||
ps: 0x0004013000003102L
|
||||
ptm: 0x0004013000002202L
|
||||
ro: 0x0004013000003702L
|
||||
socket: 0x0004013000002e02L
|
||||
spi: 0x0004013000002302L
|
||||
37
misc/3ds/textured.v.pica
Normal file
@@ -0,0 +1,37 @@
|
||||
; Vertex shader for rendering textured vertices for PICA200 GPU on the Nintendo 3DS
|
||||
; ==================================================================================
|
||||
|
||||
; Uniforms
|
||||
.fvec MVP[4];
|
||||
|
||||
; Constants
|
||||
.constf ONE_DIV_255(0.003921568627, 0.003921568627, 0.003921568627, 0.003921568627)
|
||||
|
||||
; Outputs
|
||||
.out out_pos position
|
||||
.out out_col color
|
||||
.out out_tex texcoord0
|
||||
|
||||
; Inputs (defined as aliases for convenience)
|
||||
.alias in_pos v0
|
||||
.alias in_col v1
|
||||
.alias in_tex v2
|
||||
|
||||
.proc main
|
||||
; r0 = in_pos
|
||||
mov r0, in_pos
|
||||
|
||||
; out_pos = MVP * r0
|
||||
dp4 out_pos.x, MVP[0], r0
|
||||
dp4 out_pos.y, MVP[1], r0
|
||||
dp4 out_pos.z, MVP[2], r0
|
||||
dp4 out_pos.w, MVP[3], r0
|
||||
|
||||
; out_col = in_col * ONE_DIV_255
|
||||
mul out_col, ONE_DIV_255, in_col
|
||||
; out_tex = in_tex
|
||||
mov out_tex, in_tex
|
||||
|
||||
end
|
||||
.end
|
||||
|
||||
BIN
misc/CCicon.ico
Normal file
|
After Width: | Height: | Size: 107 KiB |
BIN
misc/CCicon.png
Normal file
|
After Width: | Height: | Size: 7.0 KiB |
50
misc/UWP/Package.appxmanifest
Normal file
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<Package
|
||||
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
||||
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
|
||||
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
||||
IgnorableNamespaces="uap mp">
|
||||
|
||||
<Identity
|
||||
Name="64f1d536-965b-4190-90d3-47d861786f88"
|
||||
Publisher="CN=ClassiCube"
|
||||
Version="1.0.0.0" />
|
||||
|
||||
<mp:PhoneIdentity PhoneProductId="64f1d536-965b-4190-90d3-47d861786f88" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
|
||||
|
||||
<Properties>
|
||||
<DisplayName>ClassiCube-UWP</DisplayName>
|
||||
<PublisherDisplayName>ClassiCube</PublisherDisplayName>
|
||||
<Logo>Assets\StoreLogo.png</Logo>
|
||||
</Properties>
|
||||
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
|
||||
</Dependencies>
|
||||
|
||||
<Resources>
|
||||
<Resource Language="x-generate"/>
|
||||
</Resources>
|
||||
|
||||
<Applications>
|
||||
<Application Id="App"
|
||||
Executable="$targetnametoken$.exe"
|
||||
EntryPoint="ClassiCube_UWP.App">
|
||||
<uap:VisualElements
|
||||
DisplayName="ClassiCube-UWP"
|
||||
Description="ClassiCube-UWP"
|
||||
BackgroundColor="transparent" Square44x44Logo="Assets\Square44x44Logo.png" Square150x150Logo="Assets\Square150x150Logo.png">
|
||||
<uap:DefaultTile>
|
||||
<uap:ShowNameOnTiles>
|
||||
<uap:ShowOn Tile="square150x150Logo"/>
|
||||
</uap:ShowNameOnTiles>
|
||||
</uap:DefaultTile>
|
||||
</uap:VisualElements>
|
||||
</Application>
|
||||
</Applications>
|
||||
|
||||
<Capabilities>
|
||||
<Capability Name="internetClient" />
|
||||
</Capabilities>
|
||||
</Package>
|
||||
809
misc/UWP/Platform_UWP.cpp
Normal file
@@ -0,0 +1,809 @@
|
||||
#include "../../src/Core.h"
|
||||
#include "../../src/_PlatformBase.h"
|
||||
#include "../../src/Stream.h"
|
||||
#include "../../src/SystemFonts.h"
|
||||
#include "../../src/Funcs.h"
|
||||
#include "../../src/Utils.h"
|
||||
#include "../../src/Errors.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define NOSERVICE
|
||||
#define NOMCX
|
||||
#define NOIME
|
||||
#ifndef UNICODE
|
||||
#define UNICODE
|
||||
#define _UNICODE
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <shellapi.h>
|
||||
#include <wincrypt.h>
|
||||
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/Windows.System.h>
|
||||
|
||||
using namespace winrt;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Windows::System;
|
||||
|
||||
static HANDLE heap;
|
||||
const cc_result ReturnCode_FileShareViolation = ERROR_SHARING_VIOLATION;
|
||||
const cc_result ReturnCode_FileNotFound = ERROR_FILE_NOT_FOUND;
|
||||
const cc_result ReturnCode_DirectoryExists = ERROR_ALREADY_EXISTS;
|
||||
const cc_result ReturnCode_SocketInProgess = WSAEINPROGRESS;
|
||||
const cc_result ReturnCode_SocketWouldBlock = WSAEWOULDBLOCK;
|
||||
const cc_result ReturnCode_SocketDropped = WSAECONNRESET;
|
||||
|
||||
const char* Platform_AppNameSuffix = "";
|
||||
cc_bool Platform_ReadonlyFilesystem;
|
||||
cc_uint8 Platform_Flags = PLAT_FLAG_SINGLE_PROCESS;
|
||||
#define UWP_STRING(str) ((wchar_t*)(str)->uni)
|
||||
|
||||
/*########################################################################################################################*
|
||||
*---------------------------------------------------------Memory----------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
void* Mem_Set(void* dst, cc_uint8 value, unsigned numBytes) { return memset( dst, value, numBytes); }
|
||||
void* Mem_Copy(void* dst, const void* src, unsigned numBytes) { return memcpy( dst, src, numBytes); }
|
||||
void* Mem_Move(void* dst, const void* src, unsigned numBytes) { return memmove(dst, src, numBytes); }
|
||||
|
||||
void* Mem_TryAlloc(cc_uint32 numElems, cc_uint32 elemsSize) {
|
||||
cc_uint32 size = CalcMemSize(numElems, elemsSize);
|
||||
return size ? HeapAlloc(heap, 0, size) : NULL;
|
||||
}
|
||||
|
||||
void* Mem_TryAllocCleared(cc_uint32 numElems, cc_uint32 elemsSize) {
|
||||
cc_uint32 size = CalcMemSize(numElems, elemsSize);
|
||||
return size ? HeapAlloc(heap, HEAP_ZERO_MEMORY, size) : NULL;
|
||||
}
|
||||
|
||||
void* Mem_TryRealloc(void* mem, cc_uint32 numElems, cc_uint32 elemsSize) {
|
||||
cc_uint32 size = CalcMemSize(numElems, elemsSize);
|
||||
return size ? HeapReAlloc(heap, 0, mem, size) : NULL;
|
||||
}
|
||||
|
||||
void Mem_Free(void* mem) {
|
||||
if (mem) HeapFree(heap, 0, mem);
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*------------------------------------------------------Logging/Time-------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
/* TODO: check this is actually accurate */
|
||||
static cc_uint64 sw_freqMul = 1, sw_freqDiv = 1;
|
||||
cc_uint64 Stopwatch_ElapsedMicroseconds(cc_uint64 beg, cc_uint64 end) {
|
||||
if (end < beg) return 0;
|
||||
return ((end - beg) * sw_freqMul) / sw_freqDiv;
|
||||
}
|
||||
|
||||
static HANDLE conHandle;
|
||||
static BOOL hasDebugger;
|
||||
|
||||
void Platform_Log(const char* msg, int len) {
|
||||
char tmp[2048 + 1];
|
||||
DWORD wrote;
|
||||
|
||||
if (conHandle) {
|
||||
WriteFile(conHandle, msg, len, &wrote, NULL);
|
||||
WriteFile(conHandle, "\n", 1, &wrote, NULL);
|
||||
}
|
||||
|
||||
if (!hasDebugger) return;
|
||||
len = min(len, 2048);
|
||||
Mem_Copy(tmp, msg, len); tmp[len] = '\0';
|
||||
|
||||
OutputDebugStringA(tmp);
|
||||
OutputDebugStringA("\n");
|
||||
}
|
||||
|
||||
#define FILETIME_EPOCH 50491123200ULL
|
||||
#define FILETIME_UNIX_EPOCH 11644473600ULL
|
||||
#define FileTime_TotalSecs(time) ((time / 10000000) + FILETIME_EPOCH)
|
||||
#define FileTime_UnixTime(time) ((time / 10000000) - FILETIME_UNIX_EPOCH)
|
||||
|
||||
TimeMS DateTime_CurrentUTC(void) {
|
||||
FILETIME ft;
|
||||
cc_uint64 raw;
|
||||
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
/* in 100 nanosecond units, since Jan 1 1601 */
|
||||
raw = ft.dwLowDateTime | ((cc_uint64)ft.dwHighDateTime << 32);
|
||||
return FileTime_TotalSecs(raw);
|
||||
}
|
||||
|
||||
void DateTime_CurrentLocal(struct cc_datetime* t) {
|
||||
SYSTEMTIME localTime;
|
||||
GetLocalTime(&localTime);
|
||||
|
||||
t->year = localTime.wYear;
|
||||
t->month = localTime.wMonth;
|
||||
t->day = localTime.wDay;
|
||||
t->hour = localTime.wHour;
|
||||
t->minute = localTime.wMinute;
|
||||
t->second = localTime.wSecond;
|
||||
}
|
||||
|
||||
static cc_bool sw_highRes;
|
||||
cc_uint64 Stopwatch_Measure(void) {
|
||||
LARGE_INTEGER t;
|
||||
FILETIME ft;
|
||||
|
||||
if (sw_highRes) {
|
||||
QueryPerformanceCounter(&t);
|
||||
return (cc_uint64)t.QuadPart;
|
||||
} else {
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
return (cc_uint64)ft.dwLowDateTime | ((cc_uint64)ft.dwHighDateTime << 32);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*-------------------------------------------------------Crash handling----------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
static const char* ExceptionDescribe(cc_uint32 code) {
|
||||
switch (code) {
|
||||
case EXCEPTION_ACCESS_VIOLATION: return "ACCESS_VIOLATION";
|
||||
case EXCEPTION_ILLEGAL_INSTRUCTION: return "ILLEGAL_INSTRUCTION";
|
||||
case EXCEPTION_INT_DIVIDE_BY_ZERO: return "DIVIDE_BY_ZERO";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static LONG WINAPI UnhandledFilter(struct _EXCEPTION_POINTERS* info) {
|
||||
cc_string msg; char msgBuffer[128 + 1];
|
||||
const char* desc;
|
||||
cc_uint32 code;
|
||||
cc_uintptr addr;
|
||||
|
||||
code = (cc_uint32)info->ExceptionRecord->ExceptionCode;
|
||||
addr = (cc_uintptr)info->ExceptionRecord->ExceptionAddress;
|
||||
desc = ExceptionDescribe(code);
|
||||
|
||||
String_InitArray_NT(msg, msgBuffer);
|
||||
if (desc) {
|
||||
String_Format2(&msg, "Unhandled %c error at %x", desc, &addr);
|
||||
} else {
|
||||
String_Format2(&msg, "Unhandled exception 0x%h at %x", &code, &addr);
|
||||
}
|
||||
|
||||
DWORD numArgs = info->ExceptionRecord->NumberParameters;
|
||||
if (numArgs) {
|
||||
numArgs = min(numArgs, EXCEPTION_MAXIMUM_PARAMETERS);
|
||||
String_AppendConst(&msg, " [");
|
||||
|
||||
for (DWORD i = 0; i < numArgs; i++)
|
||||
{
|
||||
String_Format1(&msg, "0x%x,", &info->ExceptionRecord->ExceptionInformation[i]);
|
||||
}
|
||||
String_Append(&msg, ']');
|
||||
}
|
||||
|
||||
msg.buffer[msg.length] = '\0';
|
||||
Logger_DoAbort(0, msg.buffer, info->ContextRecord);
|
||||
return EXCEPTION_EXECUTE_HANDLER; /* TODO: different flag */
|
||||
}
|
||||
|
||||
void CrashHandler_Install(void) {
|
||||
SetUnhandledExceptionFilter(UnhandledFilter);
|
||||
}
|
||||
|
||||
void Process_Abort2(cc_result result, const char* raw_msg) {
|
||||
Logger_DoAbort(result, raw_msg, NULL);
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*-----------------------------------------------------Directory/File------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
void Directory_GetCachePath(cc_string* path) { }
|
||||
|
||||
void Platform_EncodePath(cc_filepath* dst, const cc_string* src) {
|
||||
Platform_EncodeString(dst, src);
|
||||
}
|
||||
|
||||
cc_result Directory_Create(const cc_filepath* path) {
|
||||
if (CreateDirectoryW(UWP_STRING(path), NULL)) return 0;
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
int File_Exists(const cc_filepath* path) {
|
||||
DWORD attribs = GetFileAttributesW(UWP_STRING(path));
|
||||
|
||||
return attribs != INVALID_FILE_ATTRIBUTES && !(attribs & FILE_ATTRIBUTE_DIRECTORY);
|
||||
}
|
||||
|
||||
static cc_result Directory_EnumCore(const cc_string* dirPath, const cc_string* file, DWORD attribs,
|
||||
void* obj, Directory_EnumCallback callback) {
|
||||
cc_string path; char pathBuffer[MAX_PATH + 10];
|
||||
int is_dir;
|
||||
|
||||
/* ignore . and .. entry */
|
||||
if (file->length == 1 && file->buffer[0] == '.') return 0;
|
||||
if (file->length == 2 && file->buffer[0] == '.' && file->buffer[1] == '.') return 0;
|
||||
|
||||
String_InitArray(path, pathBuffer);
|
||||
String_Format2(&path, "%s/%s", dirPath, file);
|
||||
|
||||
is_dir = attribs & FILE_ATTRIBUTE_DIRECTORY;
|
||||
callback(&path, obj, is_dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cc_result Directory_Enum(const cc_string* dirPath, void* obj, Directory_EnumCallback callback) {
|
||||
cc_string path; char pathBuffer[MAX_PATH + 10];
|
||||
WIN32_FIND_DATAW eW;
|
||||
int i, ansi = false;
|
||||
cc_filepath str;
|
||||
HANDLE find;
|
||||
cc_result res;
|
||||
|
||||
/* Need to append \* to search for files in directory */
|
||||
String_InitArray(path, pathBuffer);
|
||||
String_Format1(&path, "%s\\*", dirPath);
|
||||
Platform_EncodePath(&str, &path);
|
||||
|
||||
find = FindFirstFileW(UWP_STRING(&str), &eW);
|
||||
if (!find || find == INVALID_HANDLE_VALUE)
|
||||
return GetLastError();
|
||||
|
||||
do {
|
||||
path.length = 0;
|
||||
for (i = 0; i < MAX_PATH && eW.cFileName[i]; i++) {
|
||||
/* TODO: UTF16 to codepoint conversion */
|
||||
String_Append(&path, Convert_CodepointToCP437(eW.cFileName[i]));
|
||||
}
|
||||
if ((res = Directory_EnumCore(dirPath, &path, eW.dwFileAttributes, obj, callback))) return res;
|
||||
} while (FindNextFileW(find, &eW));
|
||||
|
||||
res = GetLastError(); /* return code from FindNextFile */
|
||||
FindClose(find);
|
||||
return res == ERROR_NO_MORE_FILES ? 0 : res;
|
||||
}
|
||||
|
||||
static cc_result DoFile(cc_file* file, const cc_filepath* path, DWORD access, DWORD createMode) {
|
||||
*file = CreateFile2(UWP_STRING(path), access, FILE_SHARE_READ, createMode, NULL);
|
||||
if (*file && *file != INVALID_HANDLE_VALUE) return 0;
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
cc_result File_Open(cc_file* file, const cc_filepath* path) {
|
||||
return DoFile(file, path, GENERIC_READ, OPEN_EXISTING);
|
||||
}
|
||||
cc_result File_Create(cc_file* file, const cc_filepath* path) {
|
||||
return DoFile(file, path, GENERIC_WRITE | GENERIC_READ, CREATE_ALWAYS);
|
||||
}
|
||||
cc_result File_OpenOrCreate(cc_file* file, const cc_filepath* path) {
|
||||
return DoFile(file, path, GENERIC_WRITE | GENERIC_READ, OPEN_ALWAYS);
|
||||
}
|
||||
|
||||
cc_result File_Read(cc_file file, void* data, cc_uint32 count, cc_uint32* bytesRead) {
|
||||
/* NOTE: the (DWORD*) cast assumes that sizeof(long) is 4 */
|
||||
BOOL success = ReadFile(file, data, count, (DWORD*)bytesRead, NULL);
|
||||
return success ? 0 : GetLastError();
|
||||
}
|
||||
|
||||
cc_result File_Write(cc_file file, const void* data, cc_uint32 count, cc_uint32* bytesWrote) {
|
||||
/* NOTE: the (DWORD*) cast assumes that sizeof(long) is 4 */
|
||||
BOOL success = WriteFile(file, data, count, (DWORD*)bytesWrote, NULL);
|
||||
return success ? 0 : GetLastError();
|
||||
}
|
||||
|
||||
cc_result File_Close(cc_file file) {
|
||||
return CloseHandle(file) ? 0 : GetLastError();
|
||||
}
|
||||
|
||||
cc_result File_Seek(cc_file file, int offset, int seekType) {
|
||||
static cc_uint8 modes[] = { FILE_BEGIN, FILE_CURRENT, FILE_END };
|
||||
DWORD pos = SetFilePointer(file, offset, NULL, modes[seekType]);
|
||||
return pos != INVALID_SET_FILE_POINTER ? 0 : GetLastError();
|
||||
}
|
||||
|
||||
cc_result File_Position(cc_file file, cc_uint32* pos) {
|
||||
*pos = SetFilePointer(file, 0, NULL, FILE_CURRENT);
|
||||
return *pos != INVALID_SET_FILE_POINTER ? 0 : GetLastError();
|
||||
}
|
||||
|
||||
cc_result File_Length(cc_file file, cc_uint32* len) {
|
||||
LARGE_INTEGER raw;
|
||||
if (!GetFileSizeEx(file, &raw)) return GetLastError();
|
||||
|
||||
*len = raw.QuadPart;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*--------------------------------------------------------Threading--------------------------------------------------------*
|
||||
*#############################################################################################################p############*/
|
||||
void Thread_Sleep(cc_uint32 milliseconds) { Sleep(milliseconds); }
|
||||
static DWORD WINAPI ExecThread(void* param) {
|
||||
Thread_StartFunc func = (Thread_StartFunc)param;
|
||||
func();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Thread_Run(void** handle, Thread_StartFunc func, int stackSize, const char* name) {
|
||||
DWORD threadID;
|
||||
HANDLE thread = CreateThread(NULL, 0, ExecThread, (void*)func, CREATE_SUSPENDED, &threadID);
|
||||
if (!thread) Process_Abort2(GetLastError(), "Creating thread");
|
||||
|
||||
*handle = thread;
|
||||
ResumeThread(thread);
|
||||
}
|
||||
|
||||
void Thread_Detach(void* handle) {
|
||||
if (!CloseHandle((HANDLE)handle)) {
|
||||
Process_Abort2(GetLastError(), "Freeing thread handle");
|
||||
}
|
||||
}
|
||||
|
||||
void Thread_Join(void* handle) {
|
||||
WaitForSingleObject((HANDLE)handle, INFINITE);
|
||||
Thread_Detach(handle);
|
||||
}
|
||||
|
||||
void* Mutex_Create(const char* name) {
|
||||
CRITICAL_SECTION* ptr = (CRITICAL_SECTION*)Mem_Alloc(1, sizeof(CRITICAL_SECTION), "mutex");
|
||||
InitializeCriticalSection(ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void Mutex_Free(void* handle) {
|
||||
DeleteCriticalSection((CRITICAL_SECTION*)handle);
|
||||
Mem_Free(handle);
|
||||
}
|
||||
void Mutex_Lock(void* handle) { EnterCriticalSection((CRITICAL_SECTION*)handle); }
|
||||
void Mutex_Unlock(void* handle) { LeaveCriticalSection((CRITICAL_SECTION*)handle); }
|
||||
|
||||
void* Waitable_Create(const char* name) {
|
||||
void* handle = CreateEventA(NULL, false, false, NULL);
|
||||
if (!handle) {
|
||||
Process_Abort2(GetLastError(), "Creating waitable");
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
|
||||
void Waitable_Free(void* handle) {
|
||||
if (!CloseHandle((HANDLE)handle)) {
|
||||
Process_Abort2(GetLastError(), "Freeing waitable");
|
||||
}
|
||||
}
|
||||
|
||||
void Waitable_Signal(void* handle) { SetEvent((HANDLE)handle); }
|
||||
void Waitable_Wait(void* handle) {
|
||||
WaitForSingleObject((HANDLE)handle, INFINITE);
|
||||
}
|
||||
|
||||
void Waitable_WaitFor(void* handle, cc_uint32 milliseconds) {
|
||||
WaitForSingleObject((HANDLE)handle, milliseconds);
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*---------------------------------------------------------Socket----------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
/* Sanity check to ensure cc_sockaddr struct is large enough to contain all socket addresses supported by this platform */
|
||||
static char sockaddr_size_check[sizeof(SOCKADDR_STORAGE) < CC_SOCKETADDR_MAXSIZE ? 1 : -1];
|
||||
|
||||
static cc_result ParseHostNew(char* host, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
char portRaw[32]; cc_string portStr;
|
||||
struct addrinfo hints = { 0 };
|
||||
struct addrinfo* result;
|
||||
struct addrinfo* cur;
|
||||
int i = 0;
|
||||
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
|
||||
String_InitArray(portStr, portRaw);
|
||||
String_AppendInt(&portStr, port);
|
||||
portRaw[portStr.length] = '\0';
|
||||
|
||||
int res = getaddrinfo(host, portRaw, &hints, &result);
|
||||
if (res == WSAHOST_NOT_FOUND) return SOCK_ERR_UNKNOWN_HOST;
|
||||
if (res) return res;
|
||||
|
||||
/* Prefer IPv4 addresses first */
|
||||
for (cur = result; cur && i < SOCKET_MAX_ADDRS; cur = cur->ai_next)
|
||||
{
|
||||
if (cur->ai_family != AF_INET) continue;
|
||||
SocketAddr_Set(&addrs[i], cur->ai_addr, cur->ai_addrlen); i++;
|
||||
}
|
||||
|
||||
for (cur = result; cur && i < SOCKET_MAX_ADDRS; cur = cur->ai_next)
|
||||
{
|
||||
if (cur->ai_family == AF_INET) continue;
|
||||
SocketAddr_Set(&addrs[i], cur->ai_addr, cur->ai_addrlen); i++;
|
||||
}
|
||||
|
||||
freeaddrinfo(result);
|
||||
*numValidAddrs = i;
|
||||
return i == 0 ? ERR_INVALID_ARGUMENT : 0;
|
||||
}
|
||||
|
||||
cc_result Socket_ParseAddress(const cc_string* address, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
SOCKADDR_IN* addr4 = (SOCKADDR_IN* )addrs[0].data;
|
||||
SOCKADDR_IN6* addr6 = (SOCKADDR_IN6*)addrs[0].data;
|
||||
cc_winstring str;
|
||||
INT size;
|
||||
|
||||
*numValidAddrs = 0;
|
||||
Platform_EncodeString(&str, address);
|
||||
|
||||
size = sizeof(*addr4);
|
||||
if (!WSAStringToAddressW(UWP_STRING(&str), AF_INET, NULL, (SOCKADDR*)addr4, &size)) {
|
||||
addr4->sin_port = htons(port);
|
||||
|
||||
addrs[0].size = size;
|
||||
*numValidAddrs = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
size = sizeof(*addr6);
|
||||
if (!WSAStringToAddressW(UWP_STRING(&str), AF_INET6, NULL, (SOCKADDR*)addr6, &size)) {
|
||||
addr6->sin6_port = htons(port);
|
||||
|
||||
addrs[0].size = size;
|
||||
*numValidAddrs = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ParseHostNew(str.ansi, port, addrs, numValidAddrs);
|
||||
}
|
||||
|
||||
cc_result Socket_Create(cc_socket* s, cc_sockaddr* addr, cc_bool nonblocking) {
|
||||
SOCKADDR* raw_addr = (SOCKADDR*)addr->data;
|
||||
|
||||
*s = socket(raw_addr->sa_family, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (*s == -1) return WSAGetLastError();
|
||||
|
||||
if (nonblocking) {
|
||||
u_long blockingMode = -1; /* non-blocking mode */
|
||||
ioctlsocket(*s, FIONBIO, &blockingMode);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
cc_result Socket_Connect(cc_socket s, cc_sockaddr* addr) {
|
||||
SOCKADDR* raw_addr = (SOCKADDR*)addr->data;
|
||||
|
||||
int res = connect(s, raw_addr, addr->size);
|
||||
return res == -1 ? WSAGetLastError() : 0;
|
||||
}
|
||||
|
||||
cc_result Socket_Read(cc_socket s, cc_uint8* data, cc_uint32 count, cc_uint32* modified) {
|
||||
int recvCount = recv(s, (char*)data, count, 0);
|
||||
if (recvCount != -1) { *modified = recvCount; return 0; }
|
||||
*modified = 0; return WSAGetLastError();
|
||||
}
|
||||
|
||||
cc_result Socket_Write(cc_socket s, const cc_uint8* data, cc_uint32 count, cc_uint32* modified) {
|
||||
int sentCount = send(s, (const char*)data, count, 0);
|
||||
if (sentCount != -1) { *modified = sentCount; return 0; }
|
||||
*modified = 0; return WSAGetLastError();
|
||||
}
|
||||
|
||||
void Socket_Close(cc_socket s) {
|
||||
shutdown(s, SD_BOTH);
|
||||
closesocket(s);
|
||||
}
|
||||
|
||||
static cc_result Socket_Poll(cc_socket s, int mode, cc_bool* success) {
|
||||
fd_set set;
|
||||
struct timeval time = { 0 };
|
||||
int selectCount;
|
||||
|
||||
set.fd_count = 1;
|
||||
set.fd_array[0] = s;
|
||||
|
||||
if (mode == SOCKET_POLL_READ) {
|
||||
selectCount = select(1, &set, NULL, NULL, &time);
|
||||
} else {
|
||||
selectCount = select(1, NULL, &set, NULL, &time);
|
||||
}
|
||||
|
||||
if (selectCount == -1) { *success = false; return WSAGetLastError(); }
|
||||
|
||||
*success = set.fd_count != 0; return 0;
|
||||
}
|
||||
|
||||
cc_result Socket_CheckReadable(cc_socket s, cc_bool* readable) {
|
||||
return Socket_Poll(s, SOCKET_POLL_READ, readable);
|
||||
}
|
||||
|
||||
cc_result Socket_CheckWritable(cc_socket s, cc_bool* writable) {
|
||||
int resultSize = sizeof(cc_result);
|
||||
cc_result res = Socket_Poll(s, SOCKET_POLL_WRITE, writable);
|
||||
if (res || *writable) return res;
|
||||
|
||||
/* https://stackoverflow.com/questions/29479953/so-error-value-after-successful-socket-operation */
|
||||
getsockopt(s, SOL_SOCKET, SO_ERROR, (char*)&res, &resultSize);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*-----------------------------------------------------Process/Module------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
cc_bool Process_OpenSupported = true;
|
||||
|
||||
static cc_result Process_RawGetExePath(cc_winstring* path, int* len) {
|
||||
*len = GetModuleFileNameW(NULL, UWP_STRING(path), NATIVE_STR_LEN);
|
||||
path->uni[*len] = '\0';
|
||||
if (*len) return 0;
|
||||
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
cc_result Process_StartGame2(const cc_string* args, int numArgs) {
|
||||
union STARTUPINFO_union {
|
||||
STARTUPINFOW wide;
|
||||
STARTUPINFOA ansi;
|
||||
} si = { 0 }; // less compiler warnings this way
|
||||
|
||||
cc_winstring path;
|
||||
cc_string argv; char argvBuffer[NATIVE_STR_LEN];
|
||||
PROCESS_INFORMATION pi = { 0 };
|
||||
cc_winstring raw;
|
||||
cc_result res;
|
||||
int len, i;
|
||||
|
||||
if (Platform_IsSingleProcess()) return SetGameArgs(args, numArgs);
|
||||
|
||||
if ((res = Process_RawGetExePath(&path, &len))) return res;
|
||||
si.wide.cb = sizeof(STARTUPINFOW);
|
||||
|
||||
String_InitArray(argv, argvBuffer);
|
||||
/* Game doesn't actually care about argv[0] */
|
||||
String_AppendConst(&argv, "cc");
|
||||
for (i = 0; i < numArgs; i++)
|
||||
{
|
||||
if (String_IndexOf(&args[i], ' ') >= 0) {
|
||||
String_Format1(&argv, " \"%s\"", &args[i]);
|
||||
} else {
|
||||
String_Format1(&argv, " %s", &args[i]);
|
||||
}
|
||||
}
|
||||
Platform_EncodeString(&raw, &argv);
|
||||
|
||||
if (!CreateProcessW(UWP_STRING(&path), UWP_STRING(&raw), NULL, NULL,
|
||||
false, 0, NULL, NULL, &si.wide, &pi)) return GetLastError();
|
||||
|
||||
/* Don't leak memory for process return code */
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Process_Exit(cc_result code) { ExitProcess(code); }
|
||||
cc_result Process_StartOpen(const cc_string* args) {
|
||||
cc_winstring raw;
|
||||
Platform_EncodeString(&raw, args);
|
||||
|
||||
auto str = hstring(UWP_STRING(&raw));
|
||||
auto uri = Uri(str);
|
||||
|
||||
auto options = Windows::System::LauncherOptions();
|
||||
options.TreatAsUntrusted(true);
|
||||
Windows::System::Launcher::LaunchUriAsync(uri, options);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*--------------------------------------------------------Updater----------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
#define UPDATE_TMP TEXT("CC_prev.exe")
|
||||
#define UPDATE_SRC TEXT(UPDATE_FILE)
|
||||
cc_bool Updater_Supported = true;
|
||||
|
||||
#if defined _M_IX86
|
||||
const struct UpdaterInfo Updater_Info = {
|
||||
"&eDirect3D 9 is recommended", 2,
|
||||
{
|
||||
{ "Direct3D9", "ClassiCube.exe" },
|
||||
{ "OpenGL", "ClassiCube.opengl.exe" }
|
||||
}
|
||||
};
|
||||
#elif defined _M_X64
|
||||
const struct UpdaterInfo Updater_Info = {
|
||||
"&eDirect3D 9 is recommended", 2,
|
||||
{
|
||||
{ "Direct3D9", "ClassiCube.64.exe" },
|
||||
{ "OpenGL", "ClassiCube.64-opengl.exe" }
|
||||
}
|
||||
};
|
||||
#elif defined _M_ARM64
|
||||
const struct UpdaterInfo Updater_Info = { "", 1, { { "Direct3D11", "cc-arm64-d3d11.exe" } } };
|
||||
#elif defined _M_ARM
|
||||
const struct UpdaterInfo Updater_Info = { "", 1, { { "Direct3D11", "cc-arm32-d3d11.exe" } } };
|
||||
#else
|
||||
const struct UpdaterInfo Updater_Info = { "&eCompile latest source code to update", 0 };
|
||||
#endif
|
||||
|
||||
cc_bool Updater_Clean(void) {
|
||||
return DeleteFile(UPDATE_TMP) || GetLastError() == ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
cc_result Updater_Start(const char** action) {
|
||||
cc_winstring path;
|
||||
cc_result res;
|
||||
int len;
|
||||
|
||||
*action = "Getting executable path";
|
||||
if ((res = Process_RawGetExePath(&path, &len))) return res;
|
||||
|
||||
*action = "Moving executable to CC_prev.exe";
|
||||
if (!path.uni[0]) return ERR_NOT_SUPPORTED; /* MoveFileA returns ERROR_ACCESS_DENIED on Win 9x anyways */
|
||||
if (!MoveFileExW(UWP_STRING(&path), UPDATE_TMP, MOVEFILE_REPLACE_EXISTING)) return GetLastError();
|
||||
|
||||
*action = "Replacing executable";
|
||||
if (!MoveFileExW(UPDATE_SRC, UWP_STRING(&path), MOVEFILE_REPLACE_EXISTING)) return GetLastError();
|
||||
|
||||
*action = "Restarting game";
|
||||
return Process_StartGame2(NULL, 0);
|
||||
}
|
||||
|
||||
cc_result Updater_GetBuildTime(cc_uint64* timestamp) {
|
||||
cc_winstring path;
|
||||
cc_file file;
|
||||
FILETIME ft;
|
||||
cc_uint64 raw;
|
||||
cc_result res;
|
||||
int len;
|
||||
|
||||
if ((res = Process_RawGetExePath(&path, &len))) return res;
|
||||
if ((res = File_Open(&file, &path))) return res;
|
||||
|
||||
if (GetFileTime(file, NULL, NULL, &ft)) {
|
||||
raw = ft.dwLowDateTime | ((cc_uint64)ft.dwHighDateTime << 32);
|
||||
*timestamp = FileTime_UnixTime(raw);
|
||||
} else {
|
||||
res = GetLastError();
|
||||
}
|
||||
|
||||
File_Close(file);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Don't need special execute permission on windows */
|
||||
cc_result Updater_MarkExecutable(void) { return 0; }
|
||||
cc_result Updater_SetNewBuildTime(cc_uint64 timestamp) {
|
||||
static const cc_string path = String_FromConst(UPDATE_FILE);
|
||||
cc_filepath str;
|
||||
cc_file file;
|
||||
FILETIME ft;
|
||||
cc_uint64 raw;
|
||||
cc_result res;
|
||||
|
||||
Platform_EncodePath(&str, &path);
|
||||
res = File_OpenOrCreate(&file, &str);
|
||||
if (res) return res;
|
||||
|
||||
raw = 10000000 * (timestamp + FILETIME_UNIX_EPOCH);
|
||||
ft.dwLowDateTime = (cc_uint32)raw;
|
||||
ft.dwHighDateTime = (cc_uint32)(raw >> 32);
|
||||
|
||||
if (!SetFileTime(file, NULL, NULL, &ft)) res = GetLastError();
|
||||
File_Close(file);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*-------------------------------------------------------Dynamic lib-------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
const cc_string DynamicLib_Ext = String_FromConst(".dll");
|
||||
static cc_result dynamicErr;
|
||||
static cc_bool loadingPlugin;
|
||||
|
||||
void* DynamicLib_Load2(const cc_string* path) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* DynamicLib_Get2(void* lib, const char* name) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cc_bool DynamicLib_DescribeError(cc_string* dst) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*--------------------------------------------------------Platform---------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
void Platform_EncodeString(cc_winstring* dst, const cc_string* src) {
|
||||
cc_unichar* uni;
|
||||
char* ansi;
|
||||
int i;
|
||||
if (src->length > FILENAME_SIZE) Process_Abort("String too long to expand");
|
||||
|
||||
uni = dst->uni;
|
||||
for (i = 0; i < src->length; i++)
|
||||
{
|
||||
*uni++ = Convert_CP437ToUnicode(src->buffer[i]);
|
||||
}
|
||||
*uni = '\0';
|
||||
|
||||
ansi = dst->ansi;
|
||||
for (i = 0; i < src->length; i++)
|
||||
{
|
||||
*ansi++ = (char)dst->uni[i];
|
||||
}
|
||||
*ansi = '\0';
|
||||
}
|
||||
|
||||
static void Platform_InitStopwatch(void) {
|
||||
LARGE_INTEGER freq;
|
||||
sw_highRes = QueryPerformanceFrequency(&freq);
|
||||
|
||||
if (sw_highRes) {
|
||||
sw_freqMul = 1000 * 1000;
|
||||
sw_freqDiv = freq.QuadPart;
|
||||
} else { sw_freqDiv = 10; }
|
||||
}
|
||||
|
||||
void Platform_Init(void) {
|
||||
WSADATA wsaData;
|
||||
cc_result res;
|
||||
|
||||
Platform_InitStopwatch();
|
||||
heap = GetProcessHeap();
|
||||
|
||||
hasDebugger = IsDebuggerPresent();
|
||||
AttachConsole(-1); /* ATTACH_PARENT_PROCESS */
|
||||
|
||||
conHandle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
if (conHandle == INVALID_HANDLE_VALUE) conHandle = NULL;
|
||||
|
||||
res = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
if (res) Logger_SysWarn(res, "starting WSA");
|
||||
}
|
||||
|
||||
void Platform_Free(void) {
|
||||
WSACleanup();
|
||||
HeapDestroy(heap);
|
||||
}
|
||||
|
||||
cc_bool Platform_DescribeError(cc_result res, cc_string* dst) {
|
||||
WCHAR chars[NATIVE_STR_LEN];
|
||||
DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
|
||||
|
||||
res = FormatMessageW(flags, NULL, res, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
chars, NATIVE_STR_LEN, NULL);
|
||||
if (!res) return false;
|
||||
|
||||
String_AppendUtf16(dst, chars, res * 2);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*-------------------------------------------------------Encryption--------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
cc_result Platform_Encrypt(const void* data, int len, cc_string* dst) {
|
||||
return 200;
|
||||
}
|
||||
|
||||
cc_result Platform_Decrypt(const void* data, int len, cc_string* dst) {
|
||||
return 200;
|
||||
}
|
||||
|
||||
cc_result Platform_GetEntropy(void* data, int len) {
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*-----------------------------------------------------Configuration-------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
int Platform_GetCommandLineArgs(int argc, STRING_REF char** argv, cc_string* args) {
|
||||
return GetGameArgs(args);
|
||||
}
|
||||
|
||||
cc_result Platform_SetDefaultCurrentDirectory(int argc, char** argv) {
|
||||
return 0;
|
||||
}
|
||||
327
misc/UWP/Window_UWP.cpp
Normal file
@@ -0,0 +1,327 @@
|
||||
#include "../../src/Core.h"
|
||||
|
||||
#include <winrt/Windows.ApplicationModel.DataTransfer.h>
|
||||
#include <winrt/Windows.ApplicationModel.h>
|
||||
#include <winrt/Windows.ApplicationModel.Core.h>
|
||||
#include <winrt/Windows.ApplicationModel.Activation.h>
|
||||
#include <winrt/Windows.Devices.Input.h>
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/Windows.Graphics.Display.h>
|
||||
#include <winrt/Windows.Storage.Pickers.h>
|
||||
#include <winrt/Windows.System.h>
|
||||
#include <winrt/Windows.UI.Core.h>
|
||||
|
||||
using namespace winrt;
|
||||
using namespace Windows::ApplicationModel;
|
||||
using namespace Windows::ApplicationModel::Core;
|
||||
using namespace Windows::ApplicationModel::DataTransfer;
|
||||
using namespace Windows::ApplicationModel::Activation;
|
||||
using namespace Windows::Devices::Input;
|
||||
using namespace Windows::Graphics::Display;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Windows::System;
|
||||
using namespace Windows::UI::Core;
|
||||
using namespace Windows::UI::Input;
|
||||
|
||||
#include "../../src/_WindowBase.h"
|
||||
#include "../../src/String.h"
|
||||
#include "../../src/Funcs.h"
|
||||
#include "../../src/Bitmap.h"
|
||||
#include "../../src/Options.h"
|
||||
#include "../../src/Errors.h"
|
||||
#include "../../src/Graphics.h"
|
||||
#include "../../src/Game.h"
|
||||
#define UWP_STRING(str) ((wchar_t*)(str)->uni)
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*--------------------------------------------------Public implementation--------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
void Window_PreInit(void) {
|
||||
DisplayInfo.CursorVisible = true;
|
||||
}
|
||||
|
||||
void Window_Init(void) {
|
||||
CoreWindow& window = CoreWindow::GetForCurrentThread();
|
||||
Input.Sources = INPUT_SOURCE_NORMAL;
|
||||
|
||||
DisplayInfo.Width = 640;
|
||||
DisplayInfo.Height = 480;
|
||||
DisplayInfo.Depth = 32;
|
||||
DisplayInfo.ScaleX = 1.0f;
|
||||
DisplayInfo.ScaleY = 1.0f;
|
||||
|
||||
Rect bounds = window.Bounds();
|
||||
|
||||
WindowInfo.UIScaleX = DEFAULT_UI_SCALE_X;
|
||||
WindowInfo.UIScaleY = DEFAULT_UI_SCALE_Y;
|
||||
WindowInfo.Width = bounds.Width;
|
||||
WindowInfo.Height = bounds.Height;
|
||||
WindowInfo.Exists = true;
|
||||
}
|
||||
|
||||
void Window_Free(void) { }
|
||||
|
||||
void Window_Create2D(int width, int height) { }
|
||||
void Window_Create3D(int width, int height) { }
|
||||
|
||||
void Window_Destroy(void) {
|
||||
}
|
||||
|
||||
void Window_SetTitle(const cc_string* title) {
|
||||
}
|
||||
|
||||
void Clipboard_GetText(cc_string* value) {
|
||||
DataPackageView content = Clipboard::GetContent();
|
||||
hstring str = content.GetTextAsync().get();
|
||||
}
|
||||
|
||||
void Clipboard_SetText(const cc_string* value) {
|
||||
cc_winstring raw;
|
||||
Platform_EncodeString(&raw, value);
|
||||
auto str = hstring(UWP_STRING(&raw));
|
||||
|
||||
DataPackage package = DataPackage();
|
||||
package.SetText(str);
|
||||
Clipboard::SetContent(package);
|
||||
}
|
||||
|
||||
int Window_GetWindowState(void) {
|
||||
return WINDOW_STATE_NORMAL;
|
||||
}
|
||||
|
||||
cc_result Window_EnterFullscreen(void) {
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
cc_result Window_ExitFullscreen(void) {
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
int Window_IsObscured(void) { return 0; }
|
||||
|
||||
void Window_Show(void) {
|
||||
}
|
||||
|
||||
void Window_SetSize(int width, int height) {
|
||||
}
|
||||
|
||||
void Window_RequestClose(void) {
|
||||
Event_RaiseVoid(&WindowEvents.Closing);
|
||||
}
|
||||
|
||||
void Window_ProcessEvents(float delta) {
|
||||
CoreWindow& window = CoreWindow::GetForCurrentThread();
|
||||
|
||||
CoreDispatcher& dispatcher = window.Dispatcher();
|
||||
dispatcher.ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
|
||||
}
|
||||
|
||||
void Gamepads_Init(void) {
|
||||
|
||||
}
|
||||
|
||||
void Gamepads_Process(float delta) { }
|
||||
|
||||
static void Cursor_GetRawPos(int* x, int* y) {
|
||||
CoreWindow& window = CoreWindow::GetForCurrentThread();
|
||||
|
||||
Point point = window.PointerPosition();
|
||||
*x = point.X;
|
||||
*y = point.Y;
|
||||
}
|
||||
|
||||
void Cursor_SetPosition(int x, int y) {
|
||||
CoreWindow& window = CoreWindow::GetForCurrentThread();
|
||||
|
||||
Point point = Point(x, y);
|
||||
window.PointerPosition(point);
|
||||
}
|
||||
|
||||
static void Cursor_DoSetVisible(cc_bool visible) {
|
||||
}
|
||||
|
||||
static void ShowDialogCore(const char* title, const char* msg) {
|
||||
}
|
||||
|
||||
static cc_result OpenSaveFileDialog(const cc_string* filters, FileDialogCallback callback, cc_bool load,
|
||||
const char* const* fileExts, const cc_string* defaultName) {
|
||||
return ERR_NOT_SUPPORTED;
|
||||
//auto picker = Windows::Storage::Pickers::FileOpenPicker();
|
||||
//picker.FileTypeFilter().Append(hstring(L".jpg"));
|
||||
|
||||
//Windows::Storage::StorageFile file = picker->PickSingleFileAsync();
|
||||
}
|
||||
|
||||
cc_result Window_OpenFileDialog(const struct OpenFileDialogArgs* args) {
|
||||
const char* const* fileExts = args->filters;
|
||||
cc_string filters; char buffer[NATIVE_STR_LEN];
|
||||
int i;
|
||||
|
||||
/* Filter tokens are \0 separated - e.g. "Maps (*.cw;*.dat)\0*.cw;*.dat\0 */
|
||||
String_InitArray(filters, buffer);
|
||||
String_Format1(&filters, "%c (", args->description);
|
||||
for (i = 0; fileExts[i]; i++)
|
||||
{
|
||||
if (i) String_Append(&filters, ';');
|
||||
String_Format1(&filters, "*%c", fileExts[i]);
|
||||
}
|
||||
String_Append(&filters, ')');
|
||||
String_Append(&filters, '\0');
|
||||
|
||||
for (i = 0; fileExts[i]; i++)
|
||||
{
|
||||
if (i) String_Append(&filters, ';');
|
||||
String_Format1(&filters, "*%c", fileExts[i]);
|
||||
}
|
||||
String_Append(&filters, '\0');
|
||||
|
||||
return OpenSaveFileDialog(&filters, args->Callback, true, fileExts, &String_Empty);
|
||||
}
|
||||
|
||||
cc_result Window_SaveFileDialog(const struct SaveFileDialogArgs* args) {
|
||||
const char* const* titles = args->titles;
|
||||
const char* const* fileExts = args->filters;
|
||||
cc_string filters; char buffer[NATIVE_STR_LEN];
|
||||
int i;
|
||||
|
||||
/* Filter tokens are \0 separated - e.g. "Map (*.cw)\0*.cw\0 */
|
||||
String_InitArray(filters, buffer);
|
||||
for (i = 0; fileExts[i]; i++)
|
||||
{
|
||||
String_Format2(&filters, "%c (*%c)", titles[i], fileExts[i]);
|
||||
String_Append(&filters, '\0');
|
||||
String_Format1(&filters, "*%c", fileExts[i]);
|
||||
String_Append(&filters, '\0');
|
||||
}
|
||||
return OpenSaveFileDialog(&filters, args->Callback, false, fileExts, &args->defaultName);
|
||||
}
|
||||
|
||||
static GfxResourceID fb_tex, fb_vb;
|
||||
static void AllocateVB(void) {
|
||||
struct VertexTextured* data = (struct VertexTextured*)Gfx_RecreateAndLockVb(&fb_vb,
|
||||
VERTEX_FORMAT_TEXTURED, 4);
|
||||
data[0].x = -1.0f; data[0].y = -1.0f; data[0].z = 0.0f; data[0].Col = PACKEDCOL_WHITE; data[0].U = 0.0f; data[0].V = 1.0f;
|
||||
data[1].x = 1.0f; data[1].y = -1.0f; data[1].z = 0.0f; data[1].Col = PACKEDCOL_WHITE; data[1].U = 1.0f; data[1].V = 1.0f;
|
||||
data[2].x = 1.0f; data[2].y = 1.0f; data[2].z = 0.0f; data[2].Col = PACKEDCOL_WHITE; data[2].U = 1.0f; data[2].V = 0.0f;
|
||||
data[3].x = -1.0f; data[3].y = 1.0f; data[3].z = 0.0f; data[3].Col = PACKEDCOL_WHITE; data[3].U = 0.0f; data[2].V = 0.0f;
|
||||
|
||||
Gfx_UnlockVb(fb_vb);
|
||||
}
|
||||
|
||||
void Window_AllocFramebuffer(struct Bitmap* bmp, int width, int height) {
|
||||
bmp->scan0 = (BitmapCol*)Mem_Alloc(width * height, BITMAPCOLOR_SIZE, "bitmap");
|
||||
bmp->width = width;
|
||||
bmp->height = height;
|
||||
|
||||
if (!Gfx.Created) Gfx_Create();
|
||||
fb_tex = Gfx_AllocTexture(bmp, bmp->width, TEXTURE_FLAG_NONPOW2, false);
|
||||
AllocateVB();
|
||||
|
||||
Game.Width = Window_Main.Width;
|
||||
Game.Height = Window_Main.Height;
|
||||
Gfx_OnWindowResize();
|
||||
}
|
||||
|
||||
void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) {
|
||||
struct Bitmap part;
|
||||
part.scan0 = Bitmap_GetRow(bmp, r.y) + r.x;
|
||||
part.width = r.width;
|
||||
part.height = r.height;
|
||||
|
||||
Gfx_BeginFrame();
|
||||
Gfx_BindIb(Gfx.DefaultIb);
|
||||
Gfx_UpdateTexture(fb_tex, r.x, r.y, &part, bmp->width, false);
|
||||
|
||||
Gfx_LoadMatrix(MATRIX_VIEW, &Matrix_Identity);
|
||||
Gfx_LoadMatrix(MATRIX_PROJ, &Matrix_Identity);
|
||||
Gfx_SetDepthTest(false);
|
||||
Gfx_SetAlphaTest(false);
|
||||
Gfx_SetAlphaBlending(false);
|
||||
|
||||
Gfx_SetVertexFormat(VERTEX_FORMAT_COLOURED);
|
||||
Gfx_SetVertexFormat(VERTEX_FORMAT_TEXTURED);
|
||||
Gfx_BindTexture(fb_tex);
|
||||
Gfx_BindVb(fb_vb);
|
||||
Gfx_DrawVb_IndexedTris(4);
|
||||
Gfx_EndFrame();
|
||||
}
|
||||
|
||||
void Window_FreeFramebuffer(struct Bitmap* bmp) {
|
||||
Mem_Free(bmp->scan0);
|
||||
Gfx_DeleteTexture(&fb_tex);
|
||||
Gfx_DeleteVb(&fb_vb);
|
||||
}
|
||||
|
||||
static cc_bool rawMouseInited, rawMouseSupported;
|
||||
static void InitRawMouse(void) {
|
||||
|
||||
}
|
||||
|
||||
void OnscreenKeyboard_Open(struct OpenKeyboardArgs* args) { }
|
||||
void OnscreenKeyboard_SetText(const cc_string* text) { }
|
||||
void OnscreenKeyboard_Close(void) { }
|
||||
|
||||
void Window_EnableRawMouse(void) {
|
||||
DefaultEnableRawMouse();
|
||||
if (!rawMouseInited) InitRawMouse();
|
||||
|
||||
rawMouseInited = true;
|
||||
}
|
||||
|
||||
void Window_UpdateRawMouse(void) {
|
||||
if (rawMouseSupported) {
|
||||
/* handled in WM_INPUT messages */
|
||||
CentreMousePosition();
|
||||
} else {
|
||||
DefaultUpdateRawMouse();
|
||||
}
|
||||
}
|
||||
|
||||
void Window_DisableRawMouse(void) {
|
||||
DefaultDisableRawMouse();
|
||||
}
|
||||
|
||||
|
||||
struct CCApp : implements<CCApp, IFrameworkViewSource, IFrameworkView>
|
||||
{
|
||||
|
||||
// IFrameworkViewSource interface
|
||||
IFrameworkView CreateView()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
// IFrameworkView interface
|
||||
void Initialize(CoreApplicationView const& view)
|
||||
{
|
||||
}
|
||||
|
||||
void Load(hstring const& entryPoint)
|
||||
{
|
||||
}
|
||||
|
||||
void Uninitialize()
|
||||
{
|
||||
}
|
||||
|
||||
void Run()
|
||||
{
|
||||
CoreWindow& window = CoreWindow::GetForCurrentThread();
|
||||
window.Activate();
|
||||
Window_Main.Handle.ptr = get_abi(window);
|
||||
|
||||
extern int main(int argc, char** argv);
|
||||
main(0, NULL);
|
||||
}
|
||||
|
||||
void SetWindow(CoreWindow const& win)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
int __stdcall wWinMain(void*, void*, wchar_t** argv, int argc)
|
||||
{
|
||||
auto app = make<CCApp>();
|
||||
CoreApplication::Run(app);
|
||||
}
|
||||
BIN
misc/UWP/assets/LockScreenLogo.scale-200.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
misc/UWP/assets/SplashScreen.scale-200.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
misc/UWP/assets/Square150x150Logo.scale-200.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
misc/UWP/assets/Square44x44Logo.scale-200.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
BIN
misc/UWP/assets/StoreLogo.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
misc/UWP/assets/Wide310x150Logo.scale-200.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
44
misc/amiga/Makefile_68k
Normal file
@@ -0,0 +1,44 @@
|
||||
AS=m68k-amigaos-as
|
||||
CC=m68k-amigaos-gcc
|
||||
CXX=m68k-amigaos-g++
|
||||
|
||||
CFLAGS :=-O1 -fno-math-errno -DPLAT_AMIGA -DCC_BUILD_NOFPU
|
||||
TARGET := ClassiCube-68k
|
||||
BUILD_DIR := build-amiga-68k
|
||||
SOURCE_DIR := src
|
||||
LDFLAGS :=
|
||||
|
||||
C_SOURCES := $(wildcard $(SOURCE_DIR)/*.c)
|
||||
C_ASSEMS := $(patsubst $(SOURCE_DIR)/%.c, $(BUILD_DIR)/%.S, $(C_SOURCES))
|
||||
C_OBJECTS := $(patsubst $(SOURCE_DIR)/%.c, $(BUILD_DIR)/%.o, $(C_SOURCES))
|
||||
|
||||
# Dependency tracking
|
||||
DEPFLAGS = -MT $@ -MMD -MP -MF $(BUILD_DIR)/$*.d
|
||||
DEPFILES := $(C_OBJECTS:%.o=%.d)
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
default: $(BUILD_DIR) $(TARGET).exe
|
||||
|
||||
$(BUILD_DIR):
|
||||
mkdir -p $(BUILD_DIR)
|
||||
|
||||
$(TARGET).exe: $(C_OBJECTS)
|
||||
$(CC) $(LDFLAGS) -o $(TARGET).exe $(C_OBJECTS)
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# object generation
|
||||
#---------------------------------------------------------------------------------
|
||||
$(C_OBJECTS): $(BUILD_DIR)/%.o : $(BUILD_DIR)/%.S
|
||||
$(AS) $< -o $@
|
||||
|
||||
$(C_ASSEMS): $(BUILD_DIR)/%.S : $(SOURCE_DIR)/%.c
|
||||
$(CC) $(CFLAGS) $(DEPFLAGS) -S -c $< -o $@
|
||||
|
||||
# Dependency tracking
|
||||
$(DEPFILES):
|
||||
|
||||
include $(wildcard $(DEPFILES))
|
||||
41
misc/bitmap_font_gen.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
void Main()
|
||||
{
|
||||
Console.WriteLine("static cc_uint8 font_bitmap[][8] = {");
|
||||
using (Bitmap bmp = new Bitmap(@"C:\classicube-dev\default.png"))
|
||||
{
|
||||
for (int CY = 0; CY < 16; CY++)
|
||||
for (int CX = 0; CX < 16; CX++)
|
||||
DecodeTile(bmp, CX, CY);
|
||||
}
|
||||
Console.WriteLine("}");
|
||||
}
|
||||
|
||||
static void DecodeTile(Bitmap bmp, int cx, int cy) {
|
||||
int c = (cy << 4) | cx;
|
||||
if (c <= 32 || c >= 127) return;
|
||||
|
||||
int X = cx * 8, Y = cy * 8;
|
||||
|
||||
Console.Write("\t{ ");
|
||||
|
||||
for (int y = Y; y < Y + 8; y++) {
|
||||
uint mask = 0;
|
||||
int shift = 0;
|
||||
|
||||
for (int x = X; x < X + 8; x++, shift++) {
|
||||
Color P = bmp.GetPixel(x, y);
|
||||
|
||||
if (P.A == 0) {
|
||||
mask |= 0u << shift;
|
||||
} else if (P.R == 255 && P.G == 255 && P.B == 255 && P.A == 255) {
|
||||
mask |= 1u << shift;
|
||||
} else {
|
||||
throw new InvalidOperationException("unsupported colour" + P);
|
||||
}
|
||||
}
|
||||
|
||||
string suffix = y == Y + 7 ? " " : ",";
|
||||
Console.Write("0x" + mask.ToString("X2") + suffix);
|
||||
}
|
||||
Console.WriteLine("}, /* " + (char)c + " */");
|
||||
}
|
||||
65
misc/build_scripts/buildbot_plugin.sh
Normal file
@@ -0,0 +1,65 @@
|
||||
#!/bin/bash
|
||||
# This is similar to buildbot.sh but builds plugins for the game instead
|
||||
# Some variables must be set before invoking this script. See buildtestplugin.sh
|
||||
cd $ROOT
|
||||
echo $(pwd)
|
||||
FILES=$(find . -type f -name "*.c" | tr '\n' ' ')
|
||||
FLAGS="-shared -fPIC -O1 -s -std=c99"
|
||||
echo $FILES
|
||||
|
||||
# ----------------------------- compile linux
|
||||
NIX32_CC="gcc -m32"
|
||||
NIX64_CC="gcc -m64"
|
||||
NIX_FLAGS="-nostartfiles -Wl,--entry=0"
|
||||
|
||||
echo "Compiling linux32.."
|
||||
$NIX32_CC $FILES -I ~/client/src/ -I ./src/ -o ${PLUGIN}_nix32.so $FLAGS $NIX_FLAGS
|
||||
|
||||
echo "Compiling linux64.."
|
||||
$NIX64_CC $FILES -I ~/client/src/ -I ./src/ -o ${PLUGIN}_nix64.so $FLAGS $NIX_FLAGS
|
||||
|
||||
# ----------------------------- compile macOS
|
||||
MAC32_CC=~/osx/target/bin/o32-clang
|
||||
MAC64_CC=~/osx/target/bin/o64-clang
|
||||
MAC_FLAGS="-undefined dynamic_lookup"
|
||||
|
||||
echo "Compiling mac32.."
|
||||
$MAC32_CC $FILES -I ~/client/src/ -I ./src/ -o ${PLUGIN}_mac32.dylib $FLAGS $MAC_FLAGS
|
||||
|
||||
echo "Compiling mac64.."
|
||||
$MAC64_CC $FILES -I ~/client/src/ -I ./src/ -o ${PLUGIN}_mac64.dylib $FLAGS $MAC_FLAGS
|
||||
|
||||
# ----------------------------- compile Windows
|
||||
WIN32_CC=i686-w64-mingw32-gcc
|
||||
WIN64_CC=x86_64-w64-mingw32-gcc
|
||||
# TODO: Figure out why we sometimes need this with mingw
|
||||
# If we don't include nostart files for some plugins, get a
|
||||
# ertr000001.o:(.rdata+0x0): undefined reference to `_pei386_runtime_relocator'
|
||||
# Seems to happen if you use exported variables from the game
|
||||
if [ -z "$LITE_MODE" ]; then
|
||||
WIN_FLAGS=""
|
||||
else
|
||||
WIN_FLAGS="-nostartfiles -Wl,--entry=0"
|
||||
fi
|
||||
# NOTE: You also need to install 'mingw-w64-tools' package for gendef
|
||||
|
||||
echo "Compiling win32"
|
||||
rm ClassiCube.exe ClassiCube.def
|
||||
cp ~/client/src/cc-w32-d3d.exe ClassiCube.exe
|
||||
gendef ClassiCube.exe
|
||||
i686-w64-mingw32-dlltool -d ClassiCube.def -l libClassiCube.a -D ClassiCube.exe
|
||||
$WIN32_CC $FILES -I ~/client/src/ -I ./src/ -o ${PLUGIN}_win32.dll $FLAGS $WIN_FLAGS -L . -lClassiCube
|
||||
|
||||
echo "Compiling win64"
|
||||
rm ClassiCube.exe ClassiCube.def
|
||||
cp ~/client/src/cc-w64-d3d.exe ClassiCube.exe
|
||||
gendef ClassiCube.exe
|
||||
x86_64-w64-mingw32-dlltool -d ClassiCube.def -l libClassiCube.a -D ClassiCube.exe
|
||||
$WIN64_CC $FILES -I ~/client/src/ -I ./src/ -o ${PLUGIN}_win64.dll $FLAGS $WIN_FLAGS -L . -lClassiCube
|
||||
|
||||
# ----------------------------- compile raspberry pi
|
||||
RPI_CC=~/rpi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-gcc-4.8.3
|
||||
RPI_FLAGS="-nostartfiles -Wl,--entry=0"
|
||||
|
||||
echo "Compiling rpi"
|
||||
$RPI_CC $FILES -I ~/client/src/ -I ./src/ -o ${PLUGIN}_rpi.so $FLAGS $RPI_FLAGS
|
||||
4
misc/build_scripts/buildtestplugin.sh
Normal file
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
ROOT=~/plugins/test/
|
||||
PLUGIN=test
|
||||
source ./buildbot_plugin.sh
|
||||
6
misc/build_scripts/readme.md
Normal file
@@ -0,0 +1,6 @@
|
||||
This folder contains build scripts for automatically compiling ClassiCube
|
||||
|
||||
|File|Description|
|
||||
|--------|-------|
|
||||
|buildbot_plugin.sh | Compiles specified plugin for various platforms |
|
||||
|buildtestplugin.sh | Example script for how to use buildbot_plugin.sh |
|
||||
BIN
misc/certs/BaltimoreCyberTrustRoot.crt
Normal file
BIN
misc/certs/DigiCertGlobalRootCA.crt
Normal file
BIN
misc/certs/DigiCertGlobalRootG2.crt
Normal file
34
misc/certs/USERTrustRSACertificationAuthority.crt
Normal file
@@ -0,0 +1,34 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB
|
||||
iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl
|
||||
cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV
|
||||
BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw
|
||||
MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV
|
||||
BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
|
||||
aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy
|
||||
dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
|
||||
AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B
|
||||
3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY
|
||||
tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/
|
||||
Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2
|
||||
VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT
|
||||
79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6
|
||||
c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT
|
||||
Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l
|
||||
c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee
|
||||
UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE
|
||||
Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd
|
||||
BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G
|
||||
A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF
|
||||
Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO
|
||||
VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3
|
||||
ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs
|
||||
8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR
|
||||
iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze
|
||||
Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ
|
||||
XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/
|
||||
qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB
|
||||
VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB
|
||||
L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG
|
||||
jjxDah2nGN59PRbxYvnKkKj9
|
||||
-----END CERTIFICATE-----
|
||||
397
misc/certs/certs.h
Normal file
@@ -0,0 +1,397 @@
|
||||
// This file includes the following root certificates:
|
||||
// - DigiCert Global Root (dropbox.com)
|
||||
// - DigiCert Global Root G2 (resources.download.minecraft.net)
|
||||
// - ISRG Root X1 (catbox.moe)
|
||||
// - ISRG Root X2 (123dmwm.com, garbage.loan)
|
||||
// - Baltimore CyberTrust Root (old classicube.net)
|
||||
// - USERTrust RSA (imgur.com)
|
||||
// - Google Trust Services Root R4 (classicube.net)
|
||||
// Generated using "brssl -ta [cert 1] [cert 2].." from BearSSL
|
||||
|
||||
static const unsigned char TA0_DN[] = {
|
||||
0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
|
||||
0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A,
|
||||
0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49,
|
||||
0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13,
|
||||
0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72,
|
||||
0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55,
|
||||
0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74,
|
||||
0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74,
|
||||
0x20, 0x43, 0x41
|
||||
};
|
||||
|
||||
static const unsigned char TA0_RSA_N[] = {
|
||||
0xE2, 0x3B, 0xE1, 0x11, 0x72, 0xDE, 0xA8, 0xA4, 0xD3, 0xA3, 0x57, 0xAA,
|
||||
0x50, 0xA2, 0x8F, 0x0B, 0x77, 0x90, 0xC9, 0xA2, 0xA5, 0xEE, 0x12, 0xCE,
|
||||
0x96, 0x5B, 0x01, 0x09, 0x20, 0xCC, 0x01, 0x93, 0xA7, 0x4E, 0x30, 0xB7,
|
||||
0x53, 0xF7, 0x43, 0xC4, 0x69, 0x00, 0x57, 0x9D, 0xE2, 0x8D, 0x22, 0xDD,
|
||||
0x87, 0x06, 0x40, 0x00, 0x81, 0x09, 0xCE, 0xCE, 0x1B, 0x83, 0xBF, 0xDF,
|
||||
0xCD, 0x3B, 0x71, 0x46, 0xE2, 0xD6, 0x66, 0xC7, 0x05, 0xB3, 0x76, 0x27,
|
||||
0x16, 0x8F, 0x7B, 0x9E, 0x1E, 0x95, 0x7D, 0xEE, 0xB7, 0x48, 0xA3, 0x08,
|
||||
0xDA, 0xD6, 0xAF, 0x7A, 0x0C, 0x39, 0x06, 0x65, 0x7F, 0x4A, 0x5D, 0x1F,
|
||||
0xBC, 0x17, 0xF8, 0xAB, 0xBE, 0xEE, 0x28, 0xD7, 0x74, 0x7F, 0x7A, 0x78,
|
||||
0x99, 0x59, 0x85, 0x68, 0x6E, 0x5C, 0x23, 0x32, 0x4B, 0xBF, 0x4E, 0xC0,
|
||||
0xE8, 0x5A, 0x6D, 0xE3, 0x70, 0xBF, 0x77, 0x10, 0xBF, 0xFC, 0x01, 0xF6,
|
||||
0x85, 0xD9, 0xA8, 0x44, 0x10, 0x58, 0x32, 0xA9, 0x75, 0x18, 0xD5, 0xD1,
|
||||
0xA2, 0xBE, 0x47, 0xE2, 0x27, 0x6A, 0xF4, 0x9A, 0x33, 0xF8, 0x49, 0x08,
|
||||
0x60, 0x8B, 0xD4, 0x5F, 0xB4, 0x3A, 0x84, 0xBF, 0xA1, 0xAA, 0x4A, 0x4C,
|
||||
0x7D, 0x3E, 0xCF, 0x4F, 0x5F, 0x6C, 0x76, 0x5E, 0xA0, 0x4B, 0x37, 0x91,
|
||||
0x9E, 0xDC, 0x22, 0xE6, 0x6D, 0xCE, 0x14, 0x1A, 0x8E, 0x6A, 0xCB, 0xFE,
|
||||
0xCD, 0xB3, 0x14, 0x64, 0x17, 0xC7, 0x5B, 0x29, 0x9E, 0x32, 0xBF, 0xF2,
|
||||
0xEE, 0xFA, 0xD3, 0x0B, 0x42, 0xD4, 0xAB, 0xB7, 0x41, 0x32, 0xDA, 0x0C,
|
||||
0xD4, 0xEF, 0xF8, 0x81, 0xD5, 0xBB, 0x8D, 0x58, 0x3F, 0xB5, 0x1B, 0xE8,
|
||||
0x49, 0x28, 0xA2, 0x70, 0xDA, 0x31, 0x04, 0xDD, 0xF7, 0xB2, 0x16, 0xF2,
|
||||
0x4C, 0x0A, 0x4E, 0x07, 0xA8, 0xED, 0x4A, 0x3D, 0x5E, 0xB5, 0x7F, 0xA3,
|
||||
0x90, 0xC3, 0xAF, 0x27
|
||||
};
|
||||
|
||||
static const unsigned char TA0_RSA_E[] = {
|
||||
0x01, 0x00, 0x01
|
||||
};
|
||||
|
||||
static const unsigned char TA1_DN[] = {
|
||||
0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
|
||||
0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A,
|
||||
0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49,
|
||||
0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13,
|
||||
0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72,
|
||||
0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55,
|
||||
0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74,
|
||||
0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74,
|
||||
0x20, 0x47, 0x32
|
||||
};
|
||||
|
||||
static const unsigned char TA1_RSA_N[] = {
|
||||
0xBB, 0x37, 0xCD, 0x34, 0xDC, 0x7B, 0x6B, 0xC9, 0xB2, 0x68, 0x90, 0xAD,
|
||||
0x4A, 0x75, 0xFF, 0x46, 0xBA, 0x21, 0x0A, 0x08, 0x8D, 0xF5, 0x19, 0x54,
|
||||
0xC9, 0xFB, 0x88, 0xDB, 0xF3, 0xAE, 0xF2, 0x3A, 0x89, 0x91, 0x3C, 0x7A,
|
||||
0xE6, 0xAB, 0x06, 0x1A, 0x6B, 0xCF, 0xAC, 0x2D, 0xE8, 0x5E, 0x09, 0x24,
|
||||
0x44, 0xBA, 0x62, 0x9A, 0x7E, 0xD6, 0xA3, 0xA8, 0x7E, 0xE0, 0x54, 0x75,
|
||||
0x20, 0x05, 0xAC, 0x50, 0xB7, 0x9C, 0x63, 0x1A, 0x6C, 0x30, 0xDC, 0xDA,
|
||||
0x1F, 0x19, 0xB1, 0xD7, 0x1E, 0xDE, 0xFD, 0xD7, 0xE0, 0xCB, 0x94, 0x83,
|
||||
0x37, 0xAE, 0xEC, 0x1F, 0x43, 0x4E, 0xDD, 0x7B, 0x2C, 0xD2, 0xBD, 0x2E,
|
||||
0xA5, 0x2F, 0xE4, 0xA9, 0xB8, 0xAD, 0x3A, 0xD4, 0x99, 0xA4, 0xB6, 0x25,
|
||||
0xE9, 0x9B, 0x6B, 0x00, 0x60, 0x92, 0x60, 0xFF, 0x4F, 0x21, 0x49, 0x18,
|
||||
0xF7, 0x67, 0x90, 0xAB, 0x61, 0x06, 0x9C, 0x8F, 0xF2, 0xBA, 0xE9, 0xB4,
|
||||
0xE9, 0x92, 0x32, 0x6B, 0xB5, 0xF3, 0x57, 0xE8, 0x5D, 0x1B, 0xCD, 0x8C,
|
||||
0x1D, 0xAB, 0x95, 0x04, 0x95, 0x49, 0xF3, 0x35, 0x2D, 0x96, 0xE3, 0x49,
|
||||
0x6D, 0xDD, 0x77, 0xE3, 0xFB, 0x49, 0x4B, 0xB4, 0xAC, 0x55, 0x07, 0xA9,
|
||||
0x8F, 0x95, 0xB3, 0xB4, 0x23, 0xBB, 0x4C, 0x6D, 0x45, 0xF0, 0xF6, 0xA9,
|
||||
0xB2, 0x95, 0x30, 0xB4, 0xFD, 0x4C, 0x55, 0x8C, 0x27, 0x4A, 0x57, 0x14,
|
||||
0x7C, 0x82, 0x9D, 0xCD, 0x73, 0x92, 0xD3, 0x16, 0x4A, 0x06, 0x0C, 0x8C,
|
||||
0x50, 0xD1, 0x8F, 0x1E, 0x09, 0xBE, 0x17, 0xA1, 0xE6, 0x21, 0xCA, 0xFD,
|
||||
0x83, 0xE5, 0x10, 0xBC, 0x83, 0xA5, 0x0A, 0xC4, 0x67, 0x28, 0xF6, 0x73,
|
||||
0x14, 0x14, 0x3D, 0x46, 0x76, 0xC3, 0x87, 0x14, 0x89, 0x21, 0x34, 0x4D,
|
||||
0xAF, 0x0F, 0x45, 0x0C, 0xA6, 0x49, 0xA1, 0xBA, 0xBB, 0x9C, 0xC5, 0xB1,
|
||||
0x33, 0x83, 0x29, 0x85
|
||||
};
|
||||
|
||||
static const unsigned char TA1_RSA_E[] = {
|
||||
0x01, 0x00, 0x01
|
||||
};
|
||||
|
||||
static const unsigned char TA2_DN[] = {
|
||||
0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
|
||||
0x02, 0x55, 0x53, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x0A,
|
||||
0x13, 0x20, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, 0x74, 0x20, 0x53,
|
||||
0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x65, 0x73, 0x65,
|
||||
0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x31, 0x15,
|
||||
0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0C, 0x49, 0x53, 0x52,
|
||||
0x47, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x58, 0x31
|
||||
};
|
||||
|
||||
static const unsigned char TA2_RSA_N[] = {
|
||||
0xAD, 0xE8, 0x24, 0x73, 0xF4, 0x14, 0x37, 0xF3, 0x9B, 0x9E, 0x2B, 0x57,
|
||||
0x28, 0x1C, 0x87, 0xBE, 0xDC, 0xB7, 0xDF, 0x38, 0x90, 0x8C, 0x6E, 0x3C,
|
||||
0xE6, 0x57, 0xA0, 0x78, 0xF7, 0x75, 0xC2, 0xA2, 0xFE, 0xF5, 0x6A, 0x6E,
|
||||
0xF6, 0x00, 0x4F, 0x28, 0xDB, 0xDE, 0x68, 0x86, 0x6C, 0x44, 0x93, 0xB6,
|
||||
0xB1, 0x63, 0xFD, 0x14, 0x12, 0x6B, 0xBF, 0x1F, 0xD2, 0xEA, 0x31, 0x9B,
|
||||
0x21, 0x7E, 0xD1, 0x33, 0x3C, 0xBA, 0x48, 0xF5, 0xDD, 0x79, 0xDF, 0xB3,
|
||||
0xB8, 0xFF, 0x12, 0xF1, 0x21, 0x9A, 0x4B, 0xC1, 0x8A, 0x86, 0x71, 0x69,
|
||||
0x4A, 0x66, 0x66, 0x6C, 0x8F, 0x7E, 0x3C, 0x70, 0xBF, 0xAD, 0x29, 0x22,
|
||||
0x06, 0xF3, 0xE4, 0xC0, 0xE6, 0x80, 0xAE, 0xE2, 0x4B, 0x8F, 0xB7, 0x99,
|
||||
0x7E, 0x94, 0x03, 0x9F, 0xD3, 0x47, 0x97, 0x7C, 0x99, 0x48, 0x23, 0x53,
|
||||
0xE8, 0x38, 0xAE, 0x4F, 0x0A, 0x6F, 0x83, 0x2E, 0xD1, 0x49, 0x57, 0x8C,
|
||||
0x80, 0x74, 0xB6, 0xDA, 0x2F, 0xD0, 0x38, 0x8D, 0x7B, 0x03, 0x70, 0x21,
|
||||
0x1B, 0x75, 0xF2, 0x30, 0x3C, 0xFA, 0x8F, 0xAE, 0xDD, 0xDA, 0x63, 0xAB,
|
||||
0xEB, 0x16, 0x4F, 0xC2, 0x8E, 0x11, 0x4B, 0x7E, 0xCF, 0x0B, 0xE8, 0xFF,
|
||||
0xB5, 0x77, 0x2E, 0xF4, 0xB2, 0x7B, 0x4A, 0xE0, 0x4C, 0x12, 0x25, 0x0C,
|
||||
0x70, 0x8D, 0x03, 0x29, 0xA0, 0xE1, 0x53, 0x24, 0xEC, 0x13, 0xD9, 0xEE,
|
||||
0x19, 0xBF, 0x10, 0xB3, 0x4A, 0x8C, 0x3F, 0x89, 0xA3, 0x61, 0x51, 0xDE,
|
||||
0xAC, 0x87, 0x07, 0x94, 0xF4, 0x63, 0x71, 0xEC, 0x2E, 0xE2, 0x6F, 0x5B,
|
||||
0x98, 0x81, 0xE1, 0x89, 0x5C, 0x34, 0x79, 0x6C, 0x76, 0xEF, 0x3B, 0x90,
|
||||
0x62, 0x79, 0xE6, 0xDB, 0xA4, 0x9A, 0x2F, 0x26, 0xC5, 0xD0, 0x10, 0xE1,
|
||||
0x0E, 0xDE, 0xD9, 0x10, 0x8E, 0x16, 0xFB, 0xB7, 0xF7, 0xA8, 0xF7, 0xC7,
|
||||
0xE5, 0x02, 0x07, 0x98, 0x8F, 0x36, 0x08, 0x95, 0xE7, 0xE2, 0x37, 0x96,
|
||||
0x0D, 0x36, 0x75, 0x9E, 0xFB, 0x0E, 0x72, 0xB1, 0x1D, 0x9B, 0xBC, 0x03,
|
||||
0xF9, 0x49, 0x05, 0xD8, 0x81, 0xDD, 0x05, 0xB4, 0x2A, 0xD6, 0x41, 0xE9,
|
||||
0xAC, 0x01, 0x76, 0x95, 0x0A, 0x0F, 0xD8, 0xDF, 0xD5, 0xBD, 0x12, 0x1F,
|
||||
0x35, 0x2F, 0x28, 0x17, 0x6C, 0xD2, 0x98, 0xC1, 0xA8, 0x09, 0x64, 0x77,
|
||||
0x6E, 0x47, 0x37, 0xBA, 0xCE, 0xAC, 0x59, 0x5E, 0x68, 0x9D, 0x7F, 0x72,
|
||||
0xD6, 0x89, 0xC5, 0x06, 0x41, 0x29, 0x3E, 0x59, 0x3E, 0xDD, 0x26, 0xF5,
|
||||
0x24, 0xC9, 0x11, 0xA7, 0x5A, 0xA3, 0x4C, 0x40, 0x1F, 0x46, 0xA1, 0x99,
|
||||
0xB5, 0xA7, 0x3A, 0x51, 0x6E, 0x86, 0x3B, 0x9E, 0x7D, 0x72, 0xA7, 0x12,
|
||||
0x05, 0x78, 0x59, 0xED, 0x3E, 0x51, 0x78, 0x15, 0x0B, 0x03, 0x8F, 0x8D,
|
||||
0xD0, 0x2F, 0x05, 0xB2, 0x3E, 0x7B, 0x4A, 0x1C, 0x4B, 0x73, 0x05, 0x12,
|
||||
0xFC, 0xC6, 0xEA, 0xE0, 0x50, 0x13, 0x7C, 0x43, 0x93, 0x74, 0xB3, 0xCA,
|
||||
0x74, 0xE7, 0x8E, 0x1F, 0x01, 0x08, 0xD0, 0x30, 0xD4, 0x5B, 0x71, 0x36,
|
||||
0xB4, 0x07, 0xBA, 0xC1, 0x30, 0x30, 0x5C, 0x48, 0xB7, 0x82, 0x3B, 0x98,
|
||||
0xA6, 0x7D, 0x60, 0x8A, 0xA2, 0xA3, 0x29, 0x82, 0xCC, 0xBA, 0xBD, 0x83,
|
||||
0x04, 0x1B, 0xA2, 0x83, 0x03, 0x41, 0xA1, 0xD6, 0x05, 0xF1, 0x1B, 0xC2,
|
||||
0xB6, 0xF0, 0xA8, 0x7C, 0x86, 0x3B, 0x46, 0xA8, 0x48, 0x2A, 0x88, 0xDC,
|
||||
0x76, 0x9A, 0x76, 0xBF, 0x1F, 0x6A, 0xA5, 0x3D, 0x19, 0x8F, 0xEB, 0x38,
|
||||
0xF3, 0x64, 0xDE, 0xC8, 0x2B, 0x0D, 0x0A, 0x28, 0xFF, 0xF7, 0xDB, 0xE2,
|
||||
0x15, 0x42, 0xD4, 0x22, 0xD0, 0x27, 0x5D, 0xE1, 0x79, 0xFE, 0x18, 0xE7,
|
||||
0x70, 0x88, 0xAD, 0x4E, 0xE6, 0xD9, 0x8B, 0x3A, 0xC6, 0xDD, 0x27, 0x51,
|
||||
0x6E, 0xFF, 0xBC, 0x64, 0xF5, 0x33, 0x43, 0x4F
|
||||
};
|
||||
|
||||
static const unsigned char TA2_RSA_E[] = {
|
||||
0x01, 0x00, 0x01
|
||||
};
|
||||
|
||||
static const unsigned char TA3_DN[] = {
|
||||
0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
|
||||
0x02, 0x55, 0x53, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x0A,
|
||||
0x13, 0x20, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, 0x74, 0x20, 0x53,
|
||||
0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x65, 0x73, 0x65,
|
||||
0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x31, 0x15,
|
||||
0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0C, 0x49, 0x53, 0x52,
|
||||
0x47, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x58, 0x32
|
||||
};
|
||||
|
||||
static const unsigned char TA3_EC_Q[] = {
|
||||
0x04, 0xCD, 0x9B, 0xD5, 0x9F, 0x80, 0x83, 0x0A, 0xEC, 0x09, 0x4A, 0xF3,
|
||||
0x16, 0x4A, 0x3E, 0x5C, 0xCF, 0x77, 0xAC, 0xDE, 0x67, 0x05, 0x0D, 0x1D,
|
||||
0x07, 0xB6, 0xDC, 0x16, 0xFB, 0x5A, 0x8B, 0x14, 0xDB, 0xE2, 0x71, 0x60,
|
||||
0xC4, 0xBA, 0x45, 0x95, 0x11, 0x89, 0x8E, 0xEA, 0x06, 0xDF, 0xF7, 0x2A,
|
||||
0x16, 0x1C, 0xA4, 0xB9, 0xC5, 0xC5, 0x32, 0xE0, 0x03, 0xE0, 0x1E, 0x82,
|
||||
0x18, 0x38, 0x8B, 0xD7, 0x45, 0xD8, 0x0A, 0x6A, 0x6E, 0xE6, 0x00, 0x77,
|
||||
0xFB, 0x02, 0x51, 0x7D, 0x22, 0xD8, 0x0A, 0x6E, 0x9A, 0x5B, 0x77, 0xDF,
|
||||
0xF0, 0xFA, 0x41, 0xEC, 0x39, 0xDC, 0x75, 0xCA, 0x68, 0x07, 0x0C, 0x1F,
|
||||
0xEA
|
||||
};
|
||||
|
||||
static const unsigned char TA4_DN[] = {
|
||||
0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
|
||||
0x02, 0x49, 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A,
|
||||
0x13, 0x09, 0x42, 0x61, 0x6C, 0x74, 0x69, 0x6D, 0x6F, 0x72, 0x65, 0x31,
|
||||
0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x0A, 0x43, 0x79,
|
||||
0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20,
|
||||
0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6C, 0x74, 0x69,
|
||||
0x6D, 0x6F, 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72,
|
||||
0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74
|
||||
};
|
||||
|
||||
static const unsigned char TA4_RSA_N[] = {
|
||||
0xA3, 0x04, 0xBB, 0x22, 0xAB, 0x98, 0x3D, 0x57, 0xE8, 0x26, 0x72, 0x9A,
|
||||
0xB5, 0x79, 0xD4, 0x29, 0xE2, 0xE1, 0xE8, 0x95, 0x80, 0xB1, 0xB0, 0xE3,
|
||||
0x5B, 0x8E, 0x2B, 0x29, 0x9A, 0x64, 0xDF, 0xA1, 0x5D, 0xED, 0xB0, 0x09,
|
||||
0x05, 0x6D, 0xDB, 0x28, 0x2E, 0xCE, 0x62, 0xA2, 0x62, 0xFE, 0xB4, 0x88,
|
||||
0xDA, 0x12, 0xEB, 0x38, 0xEB, 0x21, 0x9D, 0xC0, 0x41, 0x2B, 0x01, 0x52,
|
||||
0x7B, 0x88, 0x77, 0xD3, 0x1C, 0x8F, 0xC7, 0xBA, 0xB9, 0x88, 0xB5, 0x6A,
|
||||
0x09, 0xE7, 0x73, 0xE8, 0x11, 0x40, 0xA7, 0xD1, 0xCC, 0xCA, 0x62, 0x8D,
|
||||
0x2D, 0xE5, 0x8F, 0x0B, 0xA6, 0x50, 0xD2, 0xA8, 0x50, 0xC3, 0x28, 0xEA,
|
||||
0xF5, 0xAB, 0x25, 0x87, 0x8A, 0x9A, 0x96, 0x1C, 0xA9, 0x67, 0xB8, 0x3F,
|
||||
0x0C, 0xD5, 0xF7, 0xF9, 0x52, 0x13, 0x2F, 0xC2, 0x1B, 0xD5, 0x70, 0x70,
|
||||
0xF0, 0x8F, 0xC0, 0x12, 0xCA, 0x06, 0xCB, 0x9A, 0xE1, 0xD9, 0xCA, 0x33,
|
||||
0x7A, 0x77, 0xD6, 0xF8, 0xEC, 0xB9, 0xF1, 0x68, 0x44, 0x42, 0x48, 0x13,
|
||||
0xD2, 0xC0, 0xC2, 0xA4, 0xAE, 0x5E, 0x60, 0xFE, 0xB6, 0xA6, 0x05, 0xFC,
|
||||
0xB4, 0xDD, 0x07, 0x59, 0x02, 0xD4, 0x59, 0x18, 0x98, 0x63, 0xF5, 0xA5,
|
||||
0x63, 0xE0, 0x90, 0x0C, 0x7D, 0x5D, 0xB2, 0x06, 0x7A, 0xF3, 0x85, 0xEA,
|
||||
0xEB, 0xD4, 0x03, 0xAE, 0x5E, 0x84, 0x3E, 0x5F, 0xFF, 0x15, 0xED, 0x69,
|
||||
0xBC, 0xF9, 0x39, 0x36, 0x72, 0x75, 0xCF, 0x77, 0x52, 0x4D, 0xF3, 0xC9,
|
||||
0x90, 0x2C, 0xB9, 0x3D, 0xE5, 0xC9, 0x23, 0x53, 0x3F, 0x1F, 0x24, 0x98,
|
||||
0x21, 0x5C, 0x07, 0x99, 0x29, 0xBD, 0xC6, 0x3A, 0xEC, 0xE7, 0x6E, 0x86,
|
||||
0x3A, 0x6B, 0x97, 0x74, 0x63, 0x33, 0xBD, 0x68, 0x18, 0x31, 0xF0, 0x78,
|
||||
0x8D, 0x76, 0xBF, 0xFC, 0x9E, 0x8E, 0x5D, 0x2A, 0x86, 0xA7, 0x4D, 0x90,
|
||||
0xDC, 0x27, 0x1A, 0x39
|
||||
};
|
||||
|
||||
static const unsigned char TA4_RSA_E[] = {
|
||||
0x01, 0x00, 0x01
|
||||
};
|
||||
|
||||
static const unsigned char TA5_DN[] = {
|
||||
0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
|
||||
0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
|
||||
0x08, 0x13, 0x0A, 0x4E, 0x65, 0x77, 0x20, 0x4A, 0x65, 0x72, 0x73, 0x65,
|
||||
0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0B,
|
||||
0x4A, 0x65, 0x72, 0x73, 0x65, 0x79, 0x20, 0x43, 0x69, 0x74, 0x79, 0x31,
|
||||
0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x54, 0x68,
|
||||
0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20,
|
||||
0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x31, 0x2E, 0x30, 0x2C, 0x06,
|
||||
0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x55, 0x53, 0x45, 0x52, 0x54, 0x72,
|
||||
0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74,
|
||||
0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75,
|
||||
0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79
|
||||
};
|
||||
|
||||
static const unsigned char TA5_RSA_N[] = {
|
||||
0x80, 0x12, 0x65, 0x17, 0x36, 0x0E, 0xC3, 0xDB, 0x08, 0xB3, 0xD0, 0xAC,
|
||||
0x57, 0x0D, 0x76, 0xED, 0xCD, 0x27, 0xD3, 0x4C, 0xAD, 0x50, 0x83, 0x61,
|
||||
0xE2, 0xAA, 0x20, 0x4D, 0x09, 0x2D, 0x64, 0x09, 0xDC, 0xCE, 0x89, 0x9F,
|
||||
0xCC, 0x3D, 0xA9, 0xEC, 0xF6, 0xCF, 0xC1, 0xDC, 0xF1, 0xD3, 0xB1, 0xD6,
|
||||
0x7B, 0x37, 0x28, 0x11, 0x2B, 0x47, 0xDA, 0x39, 0xC6, 0xBC, 0x3A, 0x19,
|
||||
0xB4, 0x5F, 0xA6, 0xBD, 0x7D, 0x9D, 0xA3, 0x63, 0x42, 0xB6, 0x76, 0xF2,
|
||||
0xA9, 0x3B, 0x2B, 0x91, 0xF8, 0xE2, 0x6F, 0xD0, 0xEC, 0x16, 0x20, 0x90,
|
||||
0x09, 0x3E, 0xE2, 0xE8, 0x74, 0xC9, 0x18, 0xB4, 0x91, 0xD4, 0x62, 0x64,
|
||||
0xDB, 0x7F, 0xA3, 0x06, 0xF1, 0x88, 0x18, 0x6A, 0x90, 0x22, 0x3C, 0xBC,
|
||||
0xFE, 0x13, 0xF0, 0x87, 0x14, 0x7B, 0xF6, 0xE4, 0x1F, 0x8E, 0xD4, 0xE4,
|
||||
0x51, 0xC6, 0x11, 0x67, 0x46, 0x08, 0x51, 0xCB, 0x86, 0x14, 0x54, 0x3F,
|
||||
0xBC, 0x33, 0xFE, 0x7E, 0x6C, 0x9C, 0xFF, 0x16, 0x9D, 0x18, 0xBD, 0x51,
|
||||
0x8E, 0x35, 0xA6, 0xA7, 0x66, 0xC8, 0x72, 0x67, 0xDB, 0x21, 0x66, 0xB1,
|
||||
0xD4, 0x9B, 0x78, 0x03, 0xC0, 0x50, 0x3A, 0xE8, 0xCC, 0xF0, 0xDC, 0xBC,
|
||||
0x9E, 0x4C, 0xFE, 0xAF, 0x05, 0x96, 0x35, 0x1F, 0x57, 0x5A, 0xB7, 0xFF,
|
||||
0xCE, 0xF9, 0x3D, 0xB7, 0x2C, 0xB6, 0xF6, 0x54, 0xDD, 0xC8, 0xE7, 0x12,
|
||||
0x3A, 0x4D, 0xAE, 0x4C, 0x8A, 0xB7, 0x5C, 0x9A, 0xB4, 0xB7, 0x20, 0x3D,
|
||||
0xCA, 0x7F, 0x22, 0x34, 0xAE, 0x7E, 0x3B, 0x68, 0x66, 0x01, 0x44, 0xE7,
|
||||
0x01, 0x4E, 0x46, 0x53, 0x9B, 0x33, 0x60, 0xF7, 0x94, 0xBE, 0x53, 0x37,
|
||||
0x90, 0x73, 0x43, 0xF3, 0x32, 0xC3, 0x53, 0xEF, 0xDB, 0xAA, 0xFE, 0x74,
|
||||
0x4E, 0x69, 0xC7, 0x6B, 0x8C, 0x60, 0x93, 0xDE, 0xC4, 0xC7, 0x0C, 0xDF,
|
||||
0xE1, 0x32, 0xAE, 0xCC, 0x93, 0x3B, 0x51, 0x78, 0x95, 0x67, 0x8B, 0xEE,
|
||||
0x3D, 0x56, 0xFE, 0x0C, 0xD0, 0x69, 0x0F, 0x1B, 0x0F, 0xF3, 0x25, 0x26,
|
||||
0x6B, 0x33, 0x6D, 0xF7, 0x6E, 0x47, 0xFA, 0x73, 0x43, 0xE5, 0x7E, 0x0E,
|
||||
0xA5, 0x66, 0xB1, 0x29, 0x7C, 0x32, 0x84, 0x63, 0x55, 0x89, 0xC4, 0x0D,
|
||||
0xC1, 0x93, 0x54, 0x30, 0x19, 0x13, 0xAC, 0xD3, 0x7D, 0x37, 0xA7, 0xEB,
|
||||
0x5D, 0x3A, 0x6C, 0x35, 0x5C, 0xDB, 0x41, 0xD7, 0x12, 0xDA, 0xA9, 0x49,
|
||||
0x0B, 0xDF, 0xD8, 0x80, 0x8A, 0x09, 0x93, 0x62, 0x8E, 0xB5, 0x66, 0xCF,
|
||||
0x25, 0x88, 0xCD, 0x84, 0xB8, 0xB1, 0x3F, 0xA4, 0x39, 0x0F, 0xD9, 0x02,
|
||||
0x9E, 0xEB, 0x12, 0x4C, 0x95, 0x7C, 0xF3, 0x6B, 0x05, 0xA9, 0x5E, 0x16,
|
||||
0x83, 0xCC, 0xB8, 0x67, 0xE2, 0xE8, 0x13, 0x9D, 0xCC, 0x5B, 0x82, 0xD3,
|
||||
0x4C, 0xB3, 0xED, 0x5B, 0xFF, 0xDE, 0xE5, 0x73, 0xAC, 0x23, 0x3B, 0x2D,
|
||||
0x00, 0xBF, 0x35, 0x55, 0x74, 0x09, 0x49, 0xD8, 0x49, 0x58, 0x1A, 0x7F,
|
||||
0x92, 0x36, 0xE6, 0x51, 0x92, 0x0E, 0xF3, 0x26, 0x7D, 0x1C, 0x4D, 0x17,
|
||||
0xBC, 0xC9, 0xEC, 0x43, 0x26, 0xD0, 0xBF, 0x41, 0x5F, 0x40, 0xA9, 0x44,
|
||||
0x44, 0xF4, 0x99, 0xE7, 0x57, 0x87, 0x9E, 0x50, 0x1F, 0x57, 0x54, 0xA8,
|
||||
0x3E, 0xFD, 0x74, 0x63, 0x2F, 0xB1, 0x50, 0x65, 0x09, 0xE6, 0x58, 0x42,
|
||||
0x2E, 0x43, 0x1A, 0x4C, 0xB4, 0xF0, 0x25, 0x47, 0x59, 0xFA, 0x04, 0x1E,
|
||||
0x93, 0xD4, 0x26, 0x46, 0x4A, 0x50, 0x81, 0xB2, 0xDE, 0xBE, 0x78, 0xB7,
|
||||
0xFC, 0x67, 0x15, 0xE1, 0xC9, 0x57, 0x84, 0x1E, 0x0F, 0x63, 0xD6, 0xE9,
|
||||
0x62, 0xBA, 0xD6, 0x5F, 0x55, 0x2E, 0xEA, 0x5C, 0xC6, 0x28, 0x08, 0x04,
|
||||
0x25, 0x39, 0xB8, 0x0E, 0x2B, 0xA9, 0xF2, 0x4C, 0x97, 0x1C, 0x07, 0x3F,
|
||||
0x0D, 0x52, 0xF5, 0xED, 0xEF, 0x2F, 0x82, 0x0F
|
||||
};
|
||||
|
||||
static const unsigned char TA5_RSA_E[] = {
|
||||
0x01, 0x00, 0x01
|
||||
};
|
||||
|
||||
static const unsigned char TA6_DN[] = {
|
||||
0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
|
||||
0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A,
|
||||
0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75,
|
||||
0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20,
|
||||
0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03,
|
||||
0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52,
|
||||
0x34
|
||||
};
|
||||
|
||||
static const unsigned char TA6_EC_Q[] = {
|
||||
0x04, 0xF3, 0x74, 0x73, 0xA7, 0x68, 0x8B, 0x60, 0xAE, 0x43, 0xB8, 0x35,
|
||||
0xC5, 0x81, 0x30, 0x7B, 0x4B, 0x49, 0x9D, 0xFB, 0xC1, 0x61, 0xCE, 0xE6,
|
||||
0xDE, 0x46, 0xBD, 0x6B, 0xD5, 0x61, 0x18, 0x35, 0xAE, 0x40, 0xDD, 0x73,
|
||||
0xF7, 0x89, 0x91, 0x30, 0x5A, 0xEB, 0x3C, 0xEE, 0x85, 0x7C, 0xA2, 0x40,
|
||||
0x76, 0x3B, 0xA9, 0xC6, 0xB8, 0x47, 0xD8, 0x2A, 0xE7, 0x92, 0x91, 0x6A,
|
||||
0x73, 0xE9, 0xB1, 0x72, 0x39, 0x9F, 0x29, 0x9F, 0xA2, 0x98, 0xD3, 0x5F,
|
||||
0x5E, 0x58, 0x86, 0x65, 0x0F, 0xA1, 0x84, 0x65, 0x06, 0xD1, 0xDC, 0x8B,
|
||||
0xC9, 0xC7, 0x73, 0xC8, 0x8C, 0x6A, 0x2F, 0xE5, 0xC4, 0xAB, 0xD1, 0x1D,
|
||||
0x8A
|
||||
};
|
||||
|
||||
static
|
||||
#ifndef CC_BUILD_SYMBIAN
|
||||
const
|
||||
#endif
|
||||
br_x509_trust_anchor TAs[7] = {
|
||||
{
|
||||
{ (unsigned char *)TA0_DN, sizeof TA0_DN },
|
||||
BR_X509_TA_CA,
|
||||
{
|
||||
BR_KEYTYPE_RSA,
|
||||
{ {
|
||||
(unsigned char *)TA0_RSA_N, sizeof TA0_RSA_N,
|
||||
(unsigned char *)TA0_RSA_E, sizeof TA0_RSA_E,
|
||||
} }
|
||||
}
|
||||
},
|
||||
{
|
||||
{ (unsigned char *)TA1_DN, sizeof TA1_DN },
|
||||
BR_X509_TA_CA,
|
||||
{
|
||||
BR_KEYTYPE_RSA,
|
||||
{ {
|
||||
(unsigned char *)TA1_RSA_N, sizeof TA1_RSA_N,
|
||||
(unsigned char *)TA1_RSA_E, sizeof TA1_RSA_E,
|
||||
} }
|
||||
}
|
||||
},
|
||||
{
|
||||
{ (unsigned char *)TA2_DN, sizeof TA2_DN },
|
||||
BR_X509_TA_CA,
|
||||
{
|
||||
BR_KEYTYPE_RSA,
|
||||
{ {
|
||||
(unsigned char *)TA2_RSA_N, sizeof TA2_RSA_N,
|
||||
(unsigned char *)TA2_RSA_E, sizeof TA2_RSA_E,
|
||||
} }
|
||||
}
|
||||
},
|
||||
{
|
||||
{ (unsigned char *)TA3_DN, sizeof TA3_DN },
|
||||
BR_X509_TA_CA,
|
||||
{
|
||||
|
||||
#if defined CC_BUILD_SYMBIAN
|
||||
BR_KEYTYPE_EC
|
||||
/* set in SSL.c */
|
||||
#else
|
||||
BR_KEYTYPE_EC,
|
||||
{ .ec = {
|
||||
BR_EC_secp384r1,
|
||||
(unsigned char *)TA3_EC_Q, sizeof TA3_EC_Q,
|
||||
} }
|
||||
#endif
|
||||
}
|
||||
},
|
||||
{
|
||||
{ (unsigned char *)TA4_DN, sizeof TA4_DN },
|
||||
BR_X509_TA_CA,
|
||||
{
|
||||
BR_KEYTYPE_RSA,
|
||||
{ {
|
||||
(unsigned char *)TA4_RSA_N, sizeof TA4_RSA_N,
|
||||
(unsigned char *)TA4_RSA_E, sizeof TA4_RSA_E,
|
||||
} }
|
||||
}
|
||||
},
|
||||
{
|
||||
{ (unsigned char *)TA5_DN, sizeof TA5_DN },
|
||||
BR_X509_TA_CA,
|
||||
{
|
||||
BR_KEYTYPE_RSA,
|
||||
{ {
|
||||
(unsigned char *)TA5_RSA_N, sizeof TA5_RSA_N,
|
||||
(unsigned char *)TA5_RSA_E, sizeof TA5_RSA_E,
|
||||
} }
|
||||
}
|
||||
},
|
||||
{
|
||||
{ (unsigned char *)TA6_DN, sizeof TA6_DN },
|
||||
BR_X509_TA_CA,
|
||||
{
|
||||
#if defined CC_BUILD_SYMBIAN
|
||||
BR_KEYTYPE_EC
|
||||
/* set in SSL.c */
|
||||
#else
|
||||
BR_KEYTYPE_EC,
|
||||
{ .ec = {
|
||||
BR_EC_secp384r1,
|
||||
(unsigned char *)TA6_EC_Q, sizeof TA6_EC_Q,
|
||||
} }
|
||||
#endif
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#define TAs_NUM 7
|
||||
BIN
misc/certs/isrg-root-x2.der
Normal file
BIN
misc/certs/isrgrootx1.der
Normal file
BIN
misc/certs/r4.crt
Normal file
96
misc/dreamcast/Makefile
Normal file
@@ -0,0 +1,96 @@
|
||||
ifeq ($(strip $(KOS_BASE)),)
|
||||
$(warning Please set KOS variables in your environment. For example:)
|
||||
$(warning source /opt/toolchains/dc/kos/environ.sh)
|
||||
$(error Failed to find KallistiOS installation)
|
||||
endif
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Configurable options
|
||||
#---------------------------------------------------------------------------------
|
||||
# Directory where object files are placed
|
||||
BUILD_DIR := build/dc
|
||||
# List of directories containing source code
|
||||
SOURCE_DIRS := src third_party/bearssl/src misc/dreamcast
|
||||
# Name of the final output
|
||||
TARGET := ClassiCube-dc
|
||||
# Additional libraries to link against
|
||||
LIBS = -lm -lppp -lkosfat
|
||||
# List of directories containing more header files
|
||||
INCLUDES = -Ithird_party/bearssl/inc
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
S_FILES := $(foreach dir,$(SOURCE_DIRS),$(wildcard $(dir)/*.S))
|
||||
C_FILES := $(foreach dir,$(SOURCE_DIRS),$(wildcard $(dir)/*.c))
|
||||
OBJS := $(addprefix $(BUILD_DIR)/, $(notdir $(C_FILES:%.c=%.o) $(S_FILES:%.S=%.o)))
|
||||
CFLAGS := -g -DNDEBUG -O3 -fipa-pta -fno-pie -flto=auto -fomit-frame-pointer -fbuiltin -ffast-math -ffp-contract=fast -mfsrra -mfsca -pipe -fno-math-errno
|
||||
LDFLAGS = -g
|
||||
|
||||
# Dependency tracking
|
||||
DEPFLAGS = -MT $@ -MMD -MP -MF $(BUILD_DIR)/$*.d
|
||||
DEPFILES := $(OBJS:%.o=%.d)
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
default: $(BUILD_DIR) $(TARGET).cdi
|
||||
|
||||
clean:
|
||||
rm $(TARGET).cdi $(TARGET).iso $(TARGET).elf $(TARGET)-scr.bin $(TARGET).bin $(OBJS)
|
||||
|
||||
$(BUILD_DIR):
|
||||
mkdir -p $(BUILD_DIR)
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Executable generation
|
||||
#---------------------------------------------------------------------------------
|
||||
$(TARGET).elf: $(OBJS)
|
||||
kos-cc $(LDFLAGS) $^ -o $@ $(LIBS)
|
||||
|
||||
$(TARGET).bin: $(TARGET).elf
|
||||
sh-elf-objcopy -R .stack -O binary $(TARGET).elf $(TARGET).bin
|
||||
|
||||
# https://dcemulation.org/phpBB/viewtopic.php?t=105269
|
||||
$(TARGET)-scr.bin: $(TARGET).bin
|
||||
$(KOS_BASE)/utils/scramble/scramble $(TARGET).bin $(TARGET)-scr.bin
|
||||
|
||||
$(TARGET).iso: $(TARGET)-scr.bin
|
||||
mkdir -p ISO_FILES
|
||||
cp $(TARGET)-scr.bin ISO_FILES/1ST_READ.BIN
|
||||
mkdir -p ISO_FILES/audio
|
||||
mkdir -p ISO_FILES/maps
|
||||
mkdir -p ISO_FILES/texpacks
|
||||
mkdir -p ISO_FILES/texturecache
|
||||
cp misc/dreamcast/classicube.zip ISO_FILES/texpacks/default.zip
|
||||
cp misc/dreamcast/IP.BIN IP.BIN
|
||||
mkisofs -G IP.BIN -C 0,11702 -J -l -r -quiet -o $(TARGET).iso ISO_FILES
|
||||
# genisoimage -V ClassiCube -G IP.BIN -joliet -rock -l -o $(TARGET).iso ISO_FILES
|
||||
|
||||
$(TARGET).cdi: $(TARGET).iso
|
||||
cdi4dc $(TARGET).iso $(TARGET).cdi
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Object generation
|
||||
#---------------------------------------------------------------------------------
|
||||
$(BUILD_DIR)/%.o: src/%.c
|
||||
kos-cc $(CFLAGS) $(INCLUDES) $(DEPFLAGS) -c $< -o $@
|
||||
|
||||
$(BUILD_DIR)/%.o: third_party/bearssl/src/%.c
|
||||
kos-cc $(CFLAGS) $(INCLUDES) -c $< -o $@
|
||||
|
||||
$(BUILD_DIR)/%.o: misc/dreamcast/%.S
|
||||
kos-cc $(DEPFLAGS) -c $< -o $@
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Dependency tracking
|
||||
#---------------------------------------------------------------------------------
|
||||
$(DEPFILES):
|
||||
|
||||
include $(wildcard $(DEPFILES))
|
||||
196
misc/dreamcast/VertexClip.S
Normal file
@@ -0,0 +1,196 @@
|
||||
! r1 = v1, CLOBBERS
|
||||
! r2 = v2, CLOBBERS
|
||||
! r3 = OUT, CLOBBERS
|
||||
! r4 = TMP 1, preserved
|
||||
! r5 = TMP 2, preserved
|
||||
! r0 = CL0, CLOBBERS
|
||||
|
||||
! FR0 = 0
|
||||
! FR1 = 0
|
||||
! FR2 = A.1
|
||||
! FR3 = B.1
|
||||
! FR4 = 0
|
||||
! FR5 = 0
|
||||
! FR6 = A.2
|
||||
! FR7 = B.2
|
||||
! FR8 = 0
|
||||
! FR9 = 0
|
||||
! FR10 = invT
|
||||
! FR11 = t
|
||||
|
||||
#define TM1 r0 // CLOBBERED, temp register 1
|
||||
#define TM2 r4 // PRESERVED, temp register 2
|
||||
#define CLO r5 // PRESERVED, output colour
|
||||
|
||||
#define IN1 r1 // CLOBBERED, input vertex 1
|
||||
#define IN2 r2 // CLOBBERED, input vertex 2
|
||||
#define OUT r3 // CLOBBERED, output vertex
|
||||
|
||||
#define CL1 r1 // CLOBBERED, input colour 1
|
||||
#define CL2 r2 // CLOBBERED, input colour 2
|
||||
|
||||
! Calculates the near plane intersection point between two points:
|
||||
! float t = fabsf(v1->z) / fabsf(v2->z - v1->z)
|
||||
! float invt = 1.0f - t;
|
||||
!
|
||||
! out->x = invt * v1->x + t * v2->x;
|
||||
! out->y = invt * v1->y + t * v2->y;
|
||||
! out->z = 0.0f; // clipped against near plane anyways (I.e Z/W = 0 --> Z = 0)
|
||||
!
|
||||
! out->u = invt * v1->u + t * v2->u;
|
||||
! out->v = invt * v1->v + t * v2->v;
|
||||
! out->w = invt * v1->w + t * v2->w;
|
||||
!
|
||||
! out->b = invt * v1->b + t * v2->b;
|
||||
! out->g = invt * v1->g + t * v2->g;
|
||||
! out->r = invt * v1->r + t * v2->r;
|
||||
! out->a = invt * v1->a + t * v2->a;
|
||||
! To optimise these calculations, FIPR is used:
|
||||
! FIPR = FVm.x*FVn.x + FVm.y*FVn.x + FVm.z*FVn.z + FVm.w*FVn.w --> FVn.w
|
||||
! FIPR can be used to accomplish "vout->Q = invt * v1->Q + t * v2->Q" by:
|
||||
! - assigning x/y components to 0 for both vectors
|
||||
! - assigning t and invT to z/w of FVm vector
|
||||
! - assigning v1 and v2 to z/w of FVn vector
|
||||
! FIPR = 0*0 + 0*0 + t*v1->Q + invT*v2->Q --> FVn.w
|
||||
! FIPR = t*v1->Q + invT*v2->Q --> FVn.w
|
||||
|
||||
.global _ClipLine
|
||||
.align 4
|
||||
_ClipLine:
|
||||
mov.l r4,@-r15 ! LS, push(r4)
|
||||
mov.l r5,@-r15 ! LS, push(r5)
|
||||
mov IN1, TM1 ! MT, tmp = &v1
|
||||
fldi0 fr4 ! LS, fr4 = 0
|
||||
add #12, TM1 ! EX, tmp = &v1->z
|
||||
fmov.s @TM1, fr2 ! LS, fr2 = v1->z
|
||||
mov IN2, TM1 ! MT, tmp = &v2
|
||||
fldi0 fr5 ! LS, fr5 = 0
|
||||
add #12, TM1 ! EX, tmp = &v2->z
|
||||
fmov.s @TM1,fr11 ! LS, fr11 = v2->z
|
||||
fsub fr2,fr11 ! FE, fr11 = v2->z - v1->z
|
||||
fldi0 fr8 ! LS, fr8 = 0
|
||||
fmul fr11,fr11 ! FE, fr11 = (v2->z - v1->z) * (v2->z * v1->z)
|
||||
fldi0 fr9 ! LS, fr9 = 0
|
||||
fldi0 fr0 ! LS, fr0 = 0
|
||||
fldi0 fr1 ! LS, fr1 = 0
|
||||
fsrra fr11 ! FE, fr11 = 1 / abs(v2->z - v1->z)
|
||||
fabs fr2 ! LS, fr2 = abs(v1->z)
|
||||
fmul fr2,fr11 ! FE, fr11 = abs(v1->Z) / abs(v2->z - v1->z) --> t
|
||||
add #4, IN1 ! EX, v1 += 4
|
||||
fldi1 fr10 ! LS, fr10 = 1
|
||||
add #4, IN2 ! EX, v2 += 4
|
||||
add #4, OUT ! EX, OUT += 4
|
||||
fsub fr11,fr10 ! FE, fr10 = 1.0 - t --> invT
|
||||
|
||||
fmov.s @IN1+, fr2 ! LS, A1 = v1->x, v1 += 4
|
||||
fmov.s @IN2+, fr3 ! LS, B1 = v2->x, v2 += 4
|
||||
fipr fv8, fv0 ! FE, LERP(A1, B1)
|
||||
fmov.s @IN1+, fr6 ! LS, A2 = v1->y, v1 += 4
|
||||
fmov.s @IN2+, fr7 ! LS, B2 = v2->y, v2 += 4
|
||||
|
||||
fmov.s fr3,@OUT ! LS, OUT->x = LERP
|
||||
add #4, OUT ! EX, OUT += 4
|
||||
fipr fv8, fv4 ! FE, LERP(A2, B2)
|
||||
add #4, IN1 ! EX, v1 += 4
|
||||
add #4, IN2 ! EX, v2 += 4
|
||||
|
||||
fmov.s fr7,@OUT ! LS, OUT->y = LERP
|
||||
add #4, OUT ! EX, OUT += 4
|
||||
fmov.s fr1,@OUT ! LS, OUT->z = 0
|
||||
add #4, OUT ! EX, OUT += 4
|
||||
|
||||
fmov.s @IN1+, fr2 ! LS, A1 = v1->u, v1 += 4
|
||||
fmov.s @IN2+, fr3 ! LS, B1 = v2->u, v2 += 4
|
||||
fipr fv8, fv0 ! FE, LERP(A1, B1)
|
||||
fmov.s @IN1+, fr6 ! LS, A2 = v1->v, v1 += 4
|
||||
fmov.s @IN2+, fr7 ! LS, B2 = v2->v, v2 += 4
|
||||
|
||||
fmov.s fr3,@OUT ! LS, OUT->u = LERP
|
||||
add #4, OUT ! EX, OUT += 4
|
||||
fipr fv8, fv4 ! FE, LERP(A2, B2)
|
||||
add #4, IN1 ! EX, v1 += 4
|
||||
add #4, IN2 ! EX, v2 += 4
|
||||
fmov.s @IN1,fr2 ! LS, A1 = v1->w
|
||||
fmov.s @IN2,fr3 ! LS, B1 = v2->w
|
||||
fmov.s fr7,@OUT ! LS, OUT->v = LERP
|
||||
add #8, OUT ! EX, OUT += 8
|
||||
|
||||
fipr fv8, fv0 ! FE, LERP(A1, B1)
|
||||
add #-4, IN1 ! EX, v1 -= 4
|
||||
add #-4, IN2 ! EX, v2 -= 4
|
||||
fmov.s fr3,@OUT ! LS, OUT->w = lerp
|
||||
add #-4, OUT ! EX, OUT -= 4
|
||||
|
||||
mov.l @IN1,CL1 ! LS, ACOLOR = v1->bgra
|
||||
mov.l @IN2,CL2 ! LS, BCOLOR = v2->bgra
|
||||
! Bypass interpolation if unnecessary
|
||||
cmp/eq CL1,CL2 ! MT, T = ACOLOR == BCOLOR
|
||||
bt.s 1f ! BR, if (T) goto 1;
|
||||
mov CL1,CLO ! MT, OUTCOLOR = ACOLOR (branch delay instruction)
|
||||
! Interpolate B
|
||||
extu.b CL1,TM1 ! EX, val = ACOLOR.b
|
||||
lds TM1,fpul ! CO, FPUL = val
|
||||
float fpul,fr2 ! EX, fr2 = float(FPUL)
|
||||
extu.b CL2,TM1 ! EX, val = BCOLOR.b
|
||||
lds TM1,fpul ! CO, FPUL = val
|
||||
float fpul,fr3 ! EX, fr3 = float(FPUL)
|
||||
fipr fv8, fv0 ! FE, LERP(A1, B1)
|
||||
shlr8 CL1 ! EX, ACOLOR >>= 8
|
||||
ftrc fr3,fpul ! FE, FPUL = int(lerp)
|
||||
shlr8 CL2 ! EX, BCOLOR >>= 8
|
||||
sts fpul,TM2 ! CO, tmp = FPUL
|
||||
! Interpolate G
|
||||
extu.b CL1,TM1 ! EX, val = ACOLOR.g
|
||||
lds TM1,fpul ! CO, FPUL = val
|
||||
float fpul,fr2 ! EX, fr2 = float(FPUL)
|
||||
extu.b CL2,TM1 ! EX, val = BCOLOR.g
|
||||
lds TM1,fpul ! CO, FPUL = val
|
||||
float fpul,fr3 ! EX, fr3 = float(FPUL)
|
||||
fipr fv8, fv0 ! FE, LERP(A1, B1)
|
||||
shlr8 CL1 ! EX, ACOLOR >>= 8
|
||||
ftrc fr3,fpul ! FE, FPUL = int(lerp)
|
||||
extu.b TM2,TM2 ! EX, tmp = (uint8)tmp
|
||||
mov TM2,CLO ! MT, OUTCOLOR.b = tmp
|
||||
shlr8 CL2 ! EX, BCOLOR >>= 8
|
||||
sts fpul,TM2 ! CO, tmp = FPUL
|
||||
! Interpolate R
|
||||
extu.b CL1,TM1 ! EX, val = ACOLOR.r
|
||||
lds TM1,fpul ! CO, FPUL = val
|
||||
float fpul,fr2 ! EX, fr2 = float(FPUL)
|
||||
extu.b CL2,TM1 ! EX, val = BCOLOR.r
|
||||
lds TM1,fpul ! CO, FPUL = val
|
||||
float fpul,fr3 ! EX, fr3 = float(FPUL)
|
||||
fipr fv8, fv0 ! FE, LERP(A1, B1)
|
||||
shlr8 CL1 ! EX, ACOLOR >>= 8
|
||||
ftrc fr3,fpul ! FE, FPUL = int(lerp)
|
||||
extu.b TM2,TM2 ! EX, tmp = (uint8)tmp
|
||||
shll8 TM2 ! EX, tmp <<= 8
|
||||
or TM2,CLO ! EX, OUTCOLOR.g |= tmp
|
||||
shlr8 CL2 ! EX, BCOLOR >>= 8
|
||||
sts fpul,TM2 ! CO, tmp = FPUL
|
||||
! Interpolate A
|
||||
extu.b CL1,TM1 ! EX, val = ACOLOR.a
|
||||
lds TM1,fpul ! CO, FPUL = val
|
||||
float fpul,fr2 ! EX, fr2 = float(FPUL)
|
||||
extu.b CL2,TM1 ! EX, val = BCOLOR.a
|
||||
lds TM1,fpul ! CO, FPUL = val
|
||||
float fpul,fr3 ! EX, fr3 = float(FPUL)
|
||||
fipr fv8, fv0 ! FE, LERP(A1, B1)
|
||||
ftrc fr3,fpul ! FE, FPUL = int(lerp)
|
||||
extu.b TM2,TM2 ! EX, tmp = (uint8)tmp
|
||||
shll16 TM2 ! EX, tmp <<= 16
|
||||
or TM2,CLO ! EX, OUTCOLOR.r |= tmp
|
||||
sts fpul,TM2 ! CO, tmp = FPUL
|
||||
extu.b TM2,TM2 ! EX, tmp = (uint8)tmp
|
||||
shll16 TM2 ! EX, tmp <<= 16
|
||||
shll8 TM2 ! EX, tmp <<= 8
|
||||
or TM2,CLO ! EX, OUTCOLOR.a |= tmp
|
||||
|
||||
1:
|
||||
mov.l CLO,@OUT ! LS, OUT->color = OUTCOLOR
|
||||
mov.l @r15+,r5 ! LS, pop(r5)
|
||||
rts ! CO, return after executing instruction in delay slot
|
||||
mov.l @r15+,r4 ! LS, pop(r4)
|
||||
|
||||
.size _ClipLine, .-_ClipLine
|
||||
.type _ClipLine,%function
|
||||
210
misc/dreamcast/VertexClip2.S
Normal file
@@ -0,0 +1,210 @@
|
||||
! Calculates vertex as the near plane intersection point between two points:
|
||||
! float t = fabsf(v1->z) / fabsf(v2->z - v1->z)
|
||||
! float w = (1 - t) * v1->w + t * v2->w;
|
||||
!
|
||||
! out->c = type << 24
|
||||
! out->x = ((1 - t) * v1->x + t * v2->x) * 1/w
|
||||
! out->y = ((1 - t) * v1->y + t * v2->y) * 1/w
|
||||
! out->w = 1/w
|
||||
!
|
||||
! out->u = (1 - t) * v1->u + t * v2->u;
|
||||
! out->v = (1 - t) * v1->v + t * v2->v;
|
||||
!
|
||||
! out->b = (1 - t) * v1->b + t * v2->b;
|
||||
! out->g = (1 - t) * v1->g + t * v2->g;
|
||||
! out->r = (1 - t) * v1->r + t * v2->r;
|
||||
! out->a = (1 - t) * v1->a + t * v2->a;
|
||||
|
||||
! Optimisations:
|
||||
! - w always ends up being zNear
|
||||
! - Calculations of (1 - t) * v1 + t * v2 can be rearranged to t * (v2 - v1) + v1
|
||||
! - These rearranges calculations can then take advantage of FMAC
|
||||
|
||||
! Final calculation:
|
||||
! out->c = type << 24
|
||||
! out->x = ((v2->x - v1->x) + v1->x) * 1/zNear
|
||||
! out->y = ((v2->y - v1->y) + v1->y) * 1/zNear
|
||||
! out->w = 1/zNear
|
||||
!
|
||||
! out->u = (v2->u - v1->u) + v1->u;
|
||||
! out->v = (v2->v - v1->v) + v1->v;
|
||||
!
|
||||
! out->b = (v2->b - v1->b) + v1->b;
|
||||
! out->g = (v2->g - v1->g) + v1->g;
|
||||
! out->r = (v2->r - v1->r) + v1->r;
|
||||
! out->a = (v2->a - v1->a) + v1->a;
|
||||
|
||||
! INPUT ARGUMENTS
|
||||
#define IN1 r4 // input vertex 1
|
||||
#define IN2 r5 // input vertex 2
|
||||
#define OUT r6 // output vertex
|
||||
#define TYP r7 // type/flags for output vertex
|
||||
|
||||
#define TM1 r1 // temp register 1
|
||||
#define TM2 r3 // temp register 2
|
||||
#define CL1 r4 // input colour 1
|
||||
#define CL2 r5 // input colour 2
|
||||
#define CLO r7 // output colour
|
||||
|
||||
#define F_T fr0
|
||||
#define F_W fr1
|
||||
#define F_X1 fr2
|
||||
#define F_X2 fr3
|
||||
#define F_Y1 fr4
|
||||
#define F_Y2 fr5
|
||||
#define F_U1 fr6
|
||||
#define F_U2 fr7
|
||||
#define F_V1 fr8
|
||||
#define F_V2 fr9
|
||||
#define F_Z1 fr10
|
||||
#define F_Z2 fr11
|
||||
#define Ftmp fr11
|
||||
|
||||
.global _ClipEdge
|
||||
.align 4
|
||||
_ClipEdge:
|
||||
fschg ! FE (swap to 32 bit FPU loads/stores)
|
||||
! Start calculating interpolation factor
|
||||
add #28, IN1 ! EX, IN1 = &v1->z
|
||||
mov.l _NEAR_CLIP_W,TM1 ! LS, tmp = invW (1/zNear)
|
||||
fmov.s @IN1, F_Z1 ! LS, Z1 = v1->z
|
||||
add #28, IN2 ! EX, IN = &v2->z
|
||||
fmov.s @IN2, F_Z2 ! LS, Z2 = v2->z
|
||||
shll16 TYP ! EX, TYP <<= 16
|
||||
fsub F_Z1, Ftmp ! FE, tmp = v2->z - v1->z
|
||||
! Load W
|
||||
lds TM1,fpul ! LS, FPUL = invW (1/zNear)
|
||||
add #-24, IN1 ! EX, IN1 = &v1->x
|
||||
fsts fpul,F_W ! LS, invW = FPUL
|
||||
add #-24, IN2 ! EX, IN2 = &v2->x
|
||||
! Finish calculating interpolation factor
|
||||
shll8 TYP ! EX, TYP <<= 8
|
||||
fmul Ftmp,Ftmp ! FE, tmp = (v2->z - v1->z) * (v2->z * v1->z)
|
||||
mov.l TYP,@OUT ! LS, dst->cmd = TYPE
|
||||
|
||||
! Load components
|
||||
fmov.s @IN1+, F_X1 ! LS, X1 = v1->x
|
||||
fmov.s @IN2+, F_X2 ! LS, X2 = v2->x
|
||||
fmov.s @IN1+, F_Y1 ! LS, Y1 = y1->x
|
||||
fmov.s @IN2+, F_Y2 ! LS, Y2 = y2->x
|
||||
fsrra Ftmp ! FE, tmp = 1 / abs(v2->z - v1->z)
|
||||
add #4, IN1 ! EX, skip over W
|
||||
fabs F_Z1 ! LS, z1 = abs(v1->z)
|
||||
add #4, IN2 ! EX, skip over W
|
||||
fmov.s @IN1+, F_U1 ! LS, U1 = v1->u
|
||||
fmov.s @IN2+, F_U2 ! LS, U2 = v2->u
|
||||
fmov.s @IN1+, F_V1 ! LS, V1 = v1->v
|
||||
fmul F_Z1,Ftmp ! FE, tmp = abs(v1->Z) / abs(v2->z - v1->z)
|
||||
fmov.s @IN2+, F_V2 ! LS, V2 = v2->v
|
||||
|
||||
! Interpolate vertices
|
||||
fsub F_X1, F_X2 ! FE, X2 = X2 - X1
|
||||
fsub F_Y1, F_Y2 ! FE, Y2 = Y2 - Y1
|
||||
fsub F_U1, F_U2 ! FE, U2 = U2 - U1
|
||||
fmov Ftmp, F_T ! LS, T = tmp
|
||||
fsub F_V1, F_V2 ! FE, V2 = V2 - V1
|
||||
|
||||
fmac F_T,F_X2,F_X1 ! FE, X = T * (X2 - X1) + X1
|
||||
fmac F_T,F_Y2,F_Y1 ! FE, Y = T * (Y2 - Y1) + Y1
|
||||
fmac F_T,F_U2,F_U1 ! FE, U = T * (U2 - U1) + U1
|
||||
fmac F_T,F_V2,F_V1 ! FE, V = T * (V2 - V1) + V1
|
||||
|
||||
! Adjust by w
|
||||
fmul F_W, F_X1 ! FE, x = invW * x
|
||||
fmul F_W, F_Y1 ! FE, x = invY * x
|
||||
|
||||
! Load colours and check if equal
|
||||
mov.l @IN1,CL1 ! LS, ACOLOR = v1->bgra
|
||||
mov.l @IN2,CL2 ! LS, BCOLOR = v2->bgra
|
||||
cmp/eq CL1,CL2 ! MT, T = ACOLOR == BCOLOR
|
||||
add #28, OUT ! EX, dst = &dst->padding
|
||||
|
||||
! Bypass RGBA interpolation if unnecessary
|
||||
bt.s 1f ! BR, if (T) goto 1;
|
||||
mov CL1,CLO ! MT, OUTCOLOR = ACOLOR (branch delay instruction)
|
||||
|
||||
! Interpolate B
|
||||
extu.b CL1,TM1 ! EX, val = ACOLOR.b
|
||||
lds TM1,fpul ! LS, FPUL = val
|
||||
float fpul,F_Z1 ! FE, C1 = float(val)
|
||||
extu.b CL2,TM1 ! EX, val = BCOLOR.b
|
||||
lds TM1,fpul ! LS, FPUL = val
|
||||
float fpul,F_Z2 ! FE, C2 = float(val)
|
||||
fsub F_Z1, F_Z2 ! FE, C2 = C2 - C1
|
||||
fmac F_T,F_Z2,F_Z1 ! FE, C = T * (C2 - C1) + C1
|
||||
shlr8 CL1 ! EX, ACOLOR >>= 8
|
||||
shlr8 CL2 ! EX, BCOLOR >>= 8
|
||||
ftrc F_Z1,fpul ! FE, FPUL = int(C)
|
||||
sts fpul,TM2 ! LS, tmp = FPUL
|
||||
|
||||
! Interpolate G
|
||||
extu.b CL1,TM1 ! EX, val = ACOLOR.g
|
||||
lds TM1,fpul ! LS, FPUL = val
|
||||
float fpul,F_Z1 ! FE, C1 = float(val)
|
||||
extu.b CL2,TM1 ! EX, val = BCOLOR.g
|
||||
lds TM1,fpul ! LS, FPUL = val
|
||||
float fpul,F_Z2 ! FE, C2 = float(val)
|
||||
fsub F_Z1, F_Z2 ! FE, C2 = C2 - C1
|
||||
fmac F_T,F_Z2,F_Z1 ! FE, C = T * (C2 - C1) + C1
|
||||
shlr8 CL1 ! EX, ACOLOR >>= 8
|
||||
extu.b TM2,TM2 ! EX, tmp = (uint8)tmp
|
||||
mov TM2,CLO ! MT, OUTCOLOR.b = tmp
|
||||
shlr8 CL2 ! EX, BCOLOR >>= 8
|
||||
ftrc F_Z1,fpul ! FE, FPUL = int(C)
|
||||
sts fpul,TM2 ! LS, tmp = FPUL
|
||||
|
||||
! Interpolate R
|
||||
extu.b CL1,TM1 ! EX, val = ACOLOR.r
|
||||
lds TM1,fpul ! LS, FPUL = val
|
||||
float fpul,F_Z1 ! FE, C1 = float(val)
|
||||
extu.b CL2,TM1 ! EX, val = BCOLOR.r
|
||||
lds TM1,fpul ! LS, FPUL = val
|
||||
float fpul,F_Z2 ! FE, C2 = float(val)
|
||||
fsub F_Z1, F_Z2 ! FE, C2 = C2 - C1
|
||||
fmac F_T,F_Z2,F_Z1 ! FE, C = T * (C2 - C1) + C1
|
||||
shlr8 CL1 ! EX, ACOLOR >>= 8
|
||||
extu.b TM2,TM2 ! EX, tmp = (uint8)tmp
|
||||
shll8 TM2 ! EX, tmp <<= 8
|
||||
or TM2,CLO ! EX, OUTCOLOR.g |= tmp
|
||||
shlr8 CL2 ! EX, BCOLOR >>= 8
|
||||
ftrc F_Z1,fpul ! FE, FPUL = int(C)
|
||||
sts fpul,TM2 ! LS, tmp = FPUL
|
||||
|
||||
! Interpolate A
|
||||
extu.b CL1,TM1 ! EX, val = ACOLOR.a
|
||||
lds TM1,fpul ! LS, FPUL = val
|
||||
float fpul,F_Z1 ! FE, C1 = float(val)
|
||||
extu.b CL2,TM1 ! EX, val = BCOLOR.a
|
||||
lds TM1,fpul ! LS, FPUL = val
|
||||
float fpul,F_Z2 ! FE, C2 = float(val)
|
||||
fsub F_Z1, F_Z2 ! FE, C2 = C2 - C1
|
||||
fmac F_T,F_Z2,F_Z1 ! FE, C = T * (C2 - C1) + C1
|
||||
extu.b TM2,TM2 ! EX, tmp = (uint8)tmp
|
||||
shll16 TM2 ! EX, tmp <<= 16
|
||||
or TM2,CLO ! EX, OUTCOLOR.r |= tmp
|
||||
ftrc F_Z1,fpul ! FE, FPUL = int(C)
|
||||
sts fpul,TM2 ! LS, tmp = FPUL
|
||||
extu.b TM2,TM2 ! EX, tmp = (uint8)tmp
|
||||
shll16 TM2 ! EX, tmp <<= 16
|
||||
shll8 TM2 ! EX, tmp <<= 8
|
||||
or TM2,CLO ! EX, OUTCOLOR.a |= tmp
|
||||
|
||||
1:
|
||||
! Store output
|
||||
mov.l CLO,@-OUT ! LS, dst->color = OUTCOLOR
|
||||
fmov.s F_V1,@-OUT ! LS, dst->v = v
|
||||
fmov.s F_U1,@-OUT ! LS, dst->u = u
|
||||
fmov.s F_W ,@-OUT ! LS, dst->w = invW
|
||||
fmov.s F_Y1,@-OUT ! LS, dst->y = y
|
||||
fmov.s F_X1,@-OUT ! LS, dst->x = x
|
||||
|
||||
fschg ! FE (swap to 64 bit FPU loads/stores)
|
||||
rts ! CO, return after executing instruction in delay slot
|
||||
pref @OUT ! LS, trigger store queue flush
|
||||
.size _ClipEdge, .-_ClipEdge
|
||||
.type _ClipEdge, %function
|
||||
|
||||
.align 4
|
||||
_NEAR_CLIP_W:
|
||||
.float 0
|
||||
.global _NEAR_CLIP_W
|
||||
611
misc/dreamcast/VertexDraw.S
Normal file
@@ -0,0 +1,611 @@
|
||||
! r8 = STORE_QUEUE
|
||||
! r9 = num vertices left
|
||||
! r10 = PVR_CMD_VERTEX
|
||||
! r11 = PVR_CMD_VERTEX_EOL
|
||||
! r12 = ClipLine function
|
||||
! r13 = cur vertex
|
||||
! r14 = next vertex (prefetch)
|
||||
|
||||
#define R_VTX r10
|
||||
#define R_EOL r11
|
||||
#define REG_CMD_VTX r10
|
||||
#define REG_CMD_EOL r11
|
||||
#define REG_CLIPFUNC r12
|
||||
|
||||
|
||||
.align 4
|
||||
|
||||
! Pushes a vertex to the store queue
|
||||
! CLOBBERS: r2
|
||||
! INPUTS: R (vertex), r8 (SQ global)
|
||||
! OUTPUTS: r8 altered
|
||||
.macro PushVertex R
|
||||
! memcpy(r8, \R, 32)
|
||||
mov.l @(0,\R), r2
|
||||
mov.l r2, @(0,r8)
|
||||
mov.l @(4,\R), r2
|
||||
mov.l r2, @(4,r8)
|
||||
mov.l @(8,\R), r2
|
||||
mov.l r2, @(8,r8)
|
||||
mov.l @(12,\R),r2
|
||||
mov.l r2,@(12,r8)
|
||||
mov.l @(16,\R),r2
|
||||
mov.l r2,@(16,r8)
|
||||
mov.l @(20,\R),r2
|
||||
mov.l r2,@(20,r8)
|
||||
mov.l @(24,\R),r2
|
||||
mov.l r2,@(24,r8)
|
||||
mov.l @(28,\R),r2
|
||||
mov.l r2,@(28,r8)
|
||||
pref @r8 ! LS, Trigger SQ
|
||||
add #32,r8 ! EX, SQ += 32
|
||||
.endm
|
||||
|
||||
! Transforms then pushes a vertex to the store queue
|
||||
! note: Vertices are assumed as pre viewport transformed already
|
||||
! CLOBBERS: r2, fr0, fr4, fr5
|
||||
! INPUTS: R (vertex), r8 (SQ global)
|
||||
! OUTPUTS: R, r8 altered
|
||||
.macro TransformVertex R
|
||||
! INVERSE W CALCULATION
|
||||
add #28, \R ! EX, SRC += 28
|
||||
fmov.s @\R,fr0 ! LS, fr0 = v->w
|
||||
fmul fr0,fr0 ! FE, fr0 = fr0 * fr0
|
||||
add #-28, \R ! EX, SRC -= 28
|
||||
mov.l @\R+, r2 ! LS, tmp = SRC->flags, SRC += 4
|
||||
mov.l r2,@r8 ! LS, DST->flags = tmp
|
||||
fsrra fr0 ! FE, invW = 1 / sqrt(SRC->W * SRC->W)
|
||||
add #4, r8 ! EX, DST += 4
|
||||
|
||||
! COPY U,V
|
||||
mov.l @(12,\R),r2 ! LS, tmp = SRC->u
|
||||
mov.l r2,@(12,r8) ! LS, DST->u = tmp
|
||||
mov.l @(16,\R),r2 ! LS, tmp = SRC->v
|
||||
mov.l r2,@(16,r8) ! LS, DST->v = tmp
|
||||
|
||||
! TRANSFORM X
|
||||
fmov.s @\R,fr4 ! LS, fr4 = SRC->x
|
||||
fmul fr0,fr4 ! FE, fr4 = invW * SRC->x
|
||||
mov.l @(20,\R),r2 ! LS, tmp = SRC->bgra
|
||||
mov.l r2,@(20,r8) ! LS, SRC->bgra = tmp
|
||||
add #4, \R ! EX, SRC += 4
|
||||
fmov.s fr4,@r8 ! LS, DST->x = fr4
|
||||
|
||||
! TRANSFORM Y
|
||||
fmov.s @\R,fr4 ! LS, fr4 = SRC->y
|
||||
add #8, r8 ! EX, DST += 8
|
||||
fmul fr0,fr4 ! FE, fr4 = invW * SRC->y
|
||||
fmov.s fr0,@r8 ! LS, DST->z = invW
|
||||
add #-4, r8 ! EX, DST -= 4
|
||||
add #-8, \R ! EX, src -= 8 (back to start of vertex)
|
||||
fmov.s fr4,@r8 ! LS, DST->y = fr4
|
||||
|
||||
add #-8,r8 ! EX, DST -= 8 (back to start of vertex)
|
||||
pref @r8 ! LS, Trigger SQ
|
||||
add #32,r8 ! EX, SQ += 32
|
||||
.endm
|
||||
|
||||
|
||||
#define REG_CLIP1 r1
|
||||
#define REG_CLIP2 r2
|
||||
|
||||
#define REG_V0 r4
|
||||
#define REG_V1 r5
|
||||
#define REG_V2 r6
|
||||
#define REG_V3 r7
|
||||
|
||||
! r3 also matches out parameter for ClipLine
|
||||
#define REG_TMP r3
|
||||
#define TMP_SET_A \
|
||||
mov r15, REG_TMP
|
||||
|
||||
#define TMP_SET_B \
|
||||
mov r15, REG_TMP; add #32, REG_TMP
|
||||
|
||||
|
||||
_Case_0_0_0_1:
|
||||
! v0
|
||||
! / |
|
||||
! / |
|
||||
! .....A....B...
|
||||
! / |
|
||||
! v3--v2---v1
|
||||
sts pr,r13
|
||||
|
||||
TMP_SET_A
|
||||
mov REG_V3, REG_CLIP1
|
||||
mov REG_V0, REG_CLIP2
|
||||
jsr @REG_CLIPFUNC
|
||||
mov.l REG_CMD_EOL, @REG_TMP
|
||||
|
||||
TMP_SET_B
|
||||
mov REG_V0, REG_CLIP1
|
||||
mov REG_V1, REG_CLIP2
|
||||
jsr @REG_CLIPFUNC
|
||||
mov.l REG_CMD_VTX, @REG_TMP
|
||||
|
||||
TransformVertex REG_V0
|
||||
TMP_SET_B
|
||||
TransformVertex REG_TMP
|
||||
TMP_SET_A
|
||||
TransformVertex REG_TMP
|
||||
|
||||
lds r13,pr
|
||||
rts
|
||||
nop
|
||||
|
||||
_Case_0_0_1_0:
|
||||
! v1
|
||||
! / |
|
||||
! / |
|
||||
! ....A.....B...
|
||||
! / |
|
||||
! v0--v3---v2
|
||||
sts pr,r13
|
||||
|
||||
TMP_SET_A
|
||||
mov REG_V0, REG_CLIP1
|
||||
mov REG_V1, REG_CLIP2
|
||||
jsr @REG_CLIPFUNC
|
||||
mov.l REG_CMD_VTX, @REG_TMP
|
||||
|
||||
TMP_SET_B
|
||||
mov REG_V1, REG_CLIP1
|
||||
mov REG_V2, REG_CLIP2
|
||||
jsr @REG_CLIPFUNC
|
||||
mov.l REG_CMD_EOL, @REG_TMP
|
||||
|
||||
TMP_SET_A
|
||||
TransformVertex REG_TMP
|
||||
TransformVertex REG_V1
|
||||
TMP_SET_B
|
||||
TransformVertex REG_TMP
|
||||
|
||||
lds r13,pr
|
||||
rts
|
||||
nop
|
||||
|
||||
_Case_0_1_0_0:
|
||||
! v2
|
||||
! / |
|
||||
! / |
|
||||
! ....A.....B...
|
||||
! / |
|
||||
! v1--v0---v3
|
||||
sts pr,r13
|
||||
|
||||
TMP_SET_A
|
||||
mov REG_V1, REG_CLIP1
|
||||
mov REG_V2, REG_CLIP2
|
||||
jsr @REG_CLIPFUNC
|
||||
mov.l REG_CMD_VTX, @REG_TMP
|
||||
|
||||
TMP_SET_B
|
||||
mov REG_V2, REG_CLIP1
|
||||
mov REG_V3, REG_CLIP2
|
||||
jsr @REG_CLIPFUNC
|
||||
mov.l REG_CMD_EOL, @REG_TMP
|
||||
|
||||
TMP_SET_A
|
||||
TransformVertex REG_TMP
|
||||
TransformVertex REG_V2
|
||||
TMP_SET_B
|
||||
TransformVertex REG_TMP
|
||||
|
||||
lds r13,pr
|
||||
rts
|
||||
nop
|
||||
|
||||
_Case_1_0_0_0:
|
||||
! v3
|
||||
! / |
|
||||
! / |
|
||||
! ....A.....B...
|
||||
! / |
|
||||
! v2--v1---v0
|
||||
sts pr,r13
|
||||
|
||||
TMP_SET_A
|
||||
mov REG_V2, REG_CLIP1
|
||||
mov REG_V3, REG_CLIP2
|
||||
jsr @REG_CLIPFUNC
|
||||
mov.l REG_CMD_VTX, @REG_TMP
|
||||
|
||||
TMP_SET_B
|
||||
mov REG_V3, REG_CLIP1
|
||||
mov REG_V0, REG_CLIP2
|
||||
jsr @REG_CLIPFUNC
|
||||
mov.l REG_CMD_VTX, @REG_TMP
|
||||
|
||||
TMP_SET_B
|
||||
TransformVertex REG_TMP
|
||||
TMP_SET_A
|
||||
TransformVertex REG_TMP
|
||||
TransformVertex REG_V3
|
||||
|
||||
lds r13,pr
|
||||
rts
|
||||
nop
|
||||
|
||||
|
||||
_Case_0_0_1_1:
|
||||
! v0-----------v1
|
||||
! \ |
|
||||
! ....B..........A...
|
||||
! \ |
|
||||
! v3-----v2
|
||||
sts pr,r13
|
||||
|
||||
TMP_SET_A
|
||||
mov REG_V1, REG_CLIP1
|
||||
mov REG_V2, REG_CLIP2
|
||||
jsr @REG_CLIPFUNC
|
||||
mov.l REG_CMD_VTX, @REG_TMP
|
||||
|
||||
TMP_SET_B
|
||||
mov REG_V3, REG_CLIP1
|
||||
mov REG_V0, REG_CLIP2
|
||||
jsr @REG_CLIPFUNC
|
||||
mov.l REG_CMD_EOL, @REG_TMP
|
||||
|
||||
TransformVertex REG_V1
|
||||
TMP_SET_A
|
||||
TransformVertex REG_TMP
|
||||
TransformVertex REG_V0
|
||||
TMP_SET_B
|
||||
TransformVertex REG_TMP
|
||||
|
||||
lds r13,pr
|
||||
rts
|
||||
nop
|
||||
|
||||
_Case_1_0_0_1:
|
||||
! v3-----------v0
|
||||
! \ |
|
||||
! ....B..........A...
|
||||
! \ |
|
||||
! v2-----v1
|
||||
sts pr,r13
|
||||
|
||||
TMP_SET_A
|
||||
mov REG_V0, REG_CLIP1
|
||||
mov REG_V1, REG_CLIP2
|
||||
jsr @REG_CLIPFUNC
|
||||
mov.l REG_CMD_VTX, @REG_TMP
|
||||
|
||||
TMP_SET_B
|
||||
mov REG_V2, REG_CLIP1
|
||||
mov REG_V3, REG_CLIP2
|
||||
jsr @REG_CLIPFUNC
|
||||
mov.l REG_CMD_VTX, @REG_TMP
|
||||
|
||||
TMP_SET_A
|
||||
TransformVertex REG_TMP
|
||||
TMP_SET_B
|
||||
TransformVertex REG_TMP
|
||||
TransformVertex REG_V0
|
||||
TransformVertex REG_V3
|
||||
|
||||
lds r13,pr
|
||||
rts
|
||||
nop
|
||||
|
||||
_Case_0_1_1_0:
|
||||
! v1-----------v2
|
||||
! \ |
|
||||
! ....B..........A...
|
||||
! \ |
|
||||
! v0-----v3
|
||||
sts pr,r13
|
||||
|
||||
TMP_SET_A
|
||||
mov REG_V2, REG_CLIP1
|
||||
mov REG_V3, REG_CLIP2
|
||||
jsr @REG_CLIPFUNC
|
||||
mov.l REG_CMD_EOL, @REG_TMP
|
||||
|
||||
TMP_SET_B
|
||||
mov REG_V0, REG_CLIP1
|
||||
mov REG_V1, REG_CLIP2
|
||||
jsr @REG_CLIPFUNC
|
||||
mov.l REG_CMD_VTX, @REG_TMP
|
||||
|
||||
TransformVertex REG_V1
|
||||
TransformVertex REG_V2
|
||||
TMP_SET_B
|
||||
TransformVertex REG_TMP
|
||||
TMP_SET_A
|
||||
TransformVertex REG_TMP
|
||||
|
||||
lds r13,pr
|
||||
rts
|
||||
nop
|
||||
|
||||
_Case_1_1_0_0:
|
||||
! v2-----------v3
|
||||
! \ |
|
||||
! ....B..........A...
|
||||
! \ |
|
||||
! v1-----v0
|
||||
sts pr,r13
|
||||
|
||||
TMP_SET_A
|
||||
mov REG_V3, REG_CLIP1
|
||||
mov REG_V0, REG_CLIP2
|
||||
jsr @REG_CLIPFUNC
|
||||
mov.l REG_CMD_VTX, @REG_TMP
|
||||
|
||||
TMP_SET_B
|
||||
mov REG_V1, REG_CLIP1
|
||||
mov REG_V2, REG_CLIP2
|
||||
jsr @REG_CLIPFUNC
|
||||
mov.l REG_CMD_VTX, @REG_TMP
|
||||
|
||||
TMP_SET_B
|
||||
TransformVertex REG_TMP
|
||||
TransformVertex REG_V2
|
||||
TMP_SET_A
|
||||
TransformVertex REG_TMP
|
||||
TransformVertex REG_V3
|
||||
|
||||
lds r13,pr
|
||||
rts
|
||||
nop
|
||||
|
||||
_Case_0_1_1_1:
|
||||
! --v1--
|
||||
! v0-- --v2
|
||||
! \ |
|
||||
! .....B.....A...
|
||||
! \ |
|
||||
! v3
|
||||
! v1,v2,v0 v2,v0,A v0,A,B
|
||||
sts pr,r13
|
||||
|
||||
TMP_SET_A
|
||||
mov REG_V2, REG_CLIP1
|
||||
mov REG_V3, REG_CLIP2
|
||||
jsr @REG_CLIPFUNC
|
||||
mov.l REG_CMD_VTX, @REG_TMP
|
||||
|
||||
TMP_SET_B
|
||||
mov REG_V3, REG_CLIP1
|
||||
mov REG_V0, REG_CLIP2
|
||||
jsr @REG_CLIPFUNC
|
||||
mov.l REG_CMD_EOL, @REG_TMP
|
||||
|
||||
TransformVertex REG_V1
|
||||
TransformVertex REG_V2
|
||||
TransformVertex REG_V0
|
||||
TMP_SET_A
|
||||
TransformVertex REG_TMP
|
||||
TMP_SET_B
|
||||
TransformVertex REG_TMP
|
||||
|
||||
lds r13,pr
|
||||
rts
|
||||
nop
|
||||
|
||||
_Case_1_0_1_1:
|
||||
! --v0--
|
||||
! v3-- --v1
|
||||
! \ |
|
||||
! .....B.....A...
|
||||
! \ |
|
||||
! v2
|
||||
! v0,v1,v3 v1,v3,A v3,A,B
|
||||
sts pr,r13
|
||||
|
||||
TMP_SET_A
|
||||
mov REG_V1, REG_CLIP1
|
||||
mov REG_V2, REG_CLIP2
|
||||
jsr @REG_CLIPFUNC
|
||||
mov.l REG_CMD_VTX, @REG_TMP
|
||||
|
||||
TMP_SET_B
|
||||
mov REG_V2, REG_CLIP1
|
||||
mov REG_V3, REG_CLIP2
|
||||
jsr @REG_CLIPFUNC
|
||||
mov.l REG_CMD_EOL, @REG_TMP
|
||||
mov.l REG_CMD_VTX, @REG_V3
|
||||
|
||||
TransformVertex REG_V0
|
||||
TransformVertex REG_V1
|
||||
TransformVertex REG_V3
|
||||
TMP_SET_A
|
||||
TransformVertex REG_TMP
|
||||
TMP_SET_B
|
||||
TransformVertex REG_TMP
|
||||
|
||||
lds r13,pr
|
||||
rts
|
||||
nop
|
||||
|
||||
_Case_1_1_0_1:
|
||||
! --v3--
|
||||
! v2-- --v0
|
||||
! \ |
|
||||
! .....B.....A...
|
||||
! \ |
|
||||
! v1
|
||||
! v3,v0,v2 v0,v2,A v2,A,B
|
||||
sts pr,r13
|
||||
|
||||
TMP_SET_A
|
||||
mov REG_V0, REG_CLIP1
|
||||
mov REG_V1, REG_CLIP2
|
||||
jsr @REG_CLIPFUNC
|
||||
mov.l REG_CMD_VTX, @REG_TMP
|
||||
|
||||
TMP_SET_B
|
||||
mov REG_V1, REG_CLIP1
|
||||
mov REG_V2, REG_CLIP2
|
||||
jsr @REG_CLIPFUNC
|
||||
mov.l REG_CMD_EOL, @REG_TMP
|
||||
mov.l REG_CMD_VTX, @REG_V3
|
||||
|
||||
TransformVertex REG_V3
|
||||
TransformVertex REG_V0
|
||||
TransformVertex REG_V2
|
||||
TMP_SET_A
|
||||
TransformVertex REG_TMP
|
||||
TMP_SET_B
|
||||
TransformVertex REG_TMP
|
||||
|
||||
lds r13,pr
|
||||
rts
|
||||
nop
|
||||
|
||||
_Case_1_1_1_0:
|
||||
! --v2--
|
||||
! v1-- --v3
|
||||
! \ |
|
||||
! .....B.....A...
|
||||
! \ |
|
||||
! v0
|
||||
! v2,v3,v1 v3,v1,A v1,A,B
|
||||
sts pr,r13
|
||||
|
||||
TMP_SET_A
|
||||
mov REG_V3, REG_CLIP1
|
||||
mov REG_V0, REG_CLIP2
|
||||
jsr @REG_CLIPFUNC
|
||||
mov.l REG_CMD_VTX, @REG_TMP
|
||||
|
||||
TMP_SET_B
|
||||
mov REG_V0, REG_CLIP1
|
||||
mov REG_V1, REG_CLIP2
|
||||
jsr @REG_CLIPFUNC
|
||||
mov.l REG_CMD_EOL, @REG_TMP
|
||||
mov.l REG_CMD_VTX, @REG_V3
|
||||
|
||||
TransformVertex REG_V2
|
||||
TransformVertex REG_V3
|
||||
TransformVertex REG_V1
|
||||
TMP_SET_A
|
||||
TransformVertex REG_TMP
|
||||
TMP_SET_B
|
||||
TransformVertex REG_TMP
|
||||
|
||||
lds r13,pr
|
||||
rts
|
||||
nop
|
||||
|
||||
_Case_1_1_1_1:
|
||||
! Triangle strip: {1,2,0} {2,0,3}
|
||||
TransformVertex REG_V1
|
||||
TransformVertex REG_V2
|
||||
TransformVertex REG_V0
|
||||
TransformVertex REG_V3
|
||||
rts
|
||||
nop
|
||||
|
||||
.global _ProcessVertexList
|
||||
.align 4
|
||||
_ProcessVertexList:
|
||||
! STORE CPU REGISTERS
|
||||
mov.l r8,@-r15
|
||||
mov.l r9,@-r15
|
||||
mov.l r10,@-r15
|
||||
mov.l r11,@-r15
|
||||
mov.l r12,@-r15
|
||||
mov.l r13,@-r15
|
||||
mov.l r14,@-r15
|
||||
sts.l pr,@-r15
|
||||
! REGISTER SETUP
|
||||
mov r4,r14
|
||||
mov r4,r13
|
||||
mov.l .CLIPFUNC,r12
|
||||
mov.l .PVR_EOL, r11
|
||||
mov.l .PVR_VTX, r10
|
||||
mov r5,r9
|
||||
mov r6,r8
|
||||
bra SUBMIT_LOOP
|
||||
add #-64,r15
|
||||
|
||||
! Submits a PVR2 TA GPU command
|
||||
DO_CMD:
|
||||
PushVertex REG_V0
|
||||
bra NEXT_ITER
|
||||
nop
|
||||
|
||||
SUBMIT_LOOP:
|
||||
mov.l @r13,r0 ! FLAGS = CUR->flags
|
||||
add #32,r14 ! NEXT += sizeof(Vertex)
|
||||
mov r0,r2 ! TYPE = FLAGS
|
||||
and r11,r2 ! TYPE = FLAGS & 0xF000000 (reuse PVR_CMD_VERTEX_EOL as type mask)
|
||||
! Check for PVR_CMD_VERTEX
|
||||
cmp/eq r10,r2 ! T = r2 == PVR_CMD_VERTEX
|
||||
bt.s NEXT_ITER ! if (T) goto NEXT_ITER
|
||||
pref @r14 ! prefetch(NEXT) -- always executed
|
||||
! Check for non PVR_CMD_VERTEX_EOL
|
||||
cmp/eq r11,r2 ! T = r2 == PVR_CMD_VERTEX_EOL
|
||||
bf.s DO_CMD ! if (!T) goto DO_CMD
|
||||
! PVR_CMD_VERTEX_EOL case
|
||||
extu.b r0,r1 ! EX, MASK = FLAGS & 0xFF (branch delay slot)
|
||||
|
||||
! Prepare and then jump to quad drawing function, based on quad clipflags
|
||||
mova .CASES,r0 ! LS, r0 = CASES
|
||||
mov r13,r7 ! MT, r7 = v3
|
||||
shll2 r1 ! EX, MASK <<= 2
|
||||
mov r13,r6 ! MT, r6 = v3
|
||||
mov.l @(r0,r1),r2 ! LS, r1 = CASES[MASK]
|
||||
mov r13,r5 ! MT, r5 = v3
|
||||
add #-32,r6 ! EX, r6 = v3 - 1 (v2)
|
||||
mov r13,r4 ! MT, r4 = v3
|
||||
add #-64,r5 ! EX, r5 = v3 - 2 (v1)
|
||||
jsr @r2 ! C0, jump CASES[MASK]
|
||||
add #-96,r4 ! EX, r4 = v3 - 3 (v0) (branch delay slot)
|
||||
NEXT_ITER:
|
||||
dt r9 ! NUM--; T = NUM == 0
|
||||
bf.s SUBMIT_LOOP
|
||||
mov r14,r13 ! CUR = NEXT
|
||||
|
||||
add #64,r15
|
||||
! RESTORE CPU REGISTERS
|
||||
lds.l @r15+,pr
|
||||
mov.l @r15+,r14
|
||||
mov.l @r15+,r13
|
||||
mov.l @r15+,r12
|
||||
mov.l @r15+,r11
|
||||
mov.l @r15+,r10
|
||||
mov.l @r15+,r9
|
||||
rts
|
||||
mov.l @r15+,r8
|
||||
.size _ProcessVertexList, .-_ProcessVertexList
|
||||
.type _ProcessVertexList, %function
|
||||
|
||||
.align 4
|
||||
.VP_1:
|
||||
.long _vp
|
||||
.PVR_VTX:
|
||||
.long 0xE0000000
|
||||
.PVR_EOL:
|
||||
.long 0xF0000000
|
||||
.CLIPFUNC:
|
||||
.long _ClipLine
|
||||
|
||||
BUGGY_CASE:
|
||||
rts
|
||||
nop
|
||||
|
||||
! CASES table holds the functions to transfer a quad,
|
||||
! based on the visibility clipflags of the 4 vertices
|
||||
! e.g. CASES[15] = V0_VIS | V1_VIS | V2_VIS | V3_VIS (all 4 visible)
|
||||
.CASES:
|
||||
.long BUGGY_CASE ! Should never happen
|
||||
.long _Case_0_0_0_1
|
||||
.long _Case_0_0_1_0
|
||||
.long _Case_0_0_1_1
|
||||
.long _Case_0_1_0_0
|
||||
.long BUGGY_CASE ! V0_VIS | V2_VIS, Should never happen
|
||||
.long _Case_0_1_1_0
|
||||
.long _Case_0_1_1_1
|
||||
.long _Case_1_0_0_0
|
||||
.long _Case_1_0_0_1
|
||||
.long BUGGY_CASE ! V1_VIS | V3_VIS, Should never happen
|
||||
.long _Case_1_0_1_1
|
||||
.long _Case_1_1_0_0
|
||||
.long _Case_1_1_0_1
|
||||
.long _Case_1_1_1_0
|
||||
.long _Case_1_1_1_1
|
||||
230
misc/dreamcast/VertexTransform.S
Normal file
@@ -0,0 +1,230 @@
|
||||
#define FLG r0 // clip flags
|
||||
#define TMP r1 // temp
|
||||
#define VTX r2 // PVR_CMD_VERTEX
|
||||
#define EOS r3 // PVR_CMD_VERTEX_EOL
|
||||
#define SRC r4 // src pointer ARG
|
||||
#define DST r5 // dst pointer ARG
|
||||
#define CNT r6 // quads count ARG
|
||||
#define PFT r7 // prefetch address
|
||||
|
||||
#define ZERO fr0 // 0.0
|
||||
#define F_U fr1 // vertex.u
|
||||
#define F_V fr2 // vertex.v
|
||||
#define F_C fr3 // vertex.colour
|
||||
#define F_X fr4 // vertex.x
|
||||
#define F_Y fr5 // vertex.y
|
||||
#define F_Z fr6 // vertex.z
|
||||
#define F_W fr7 // vertex.w
|
||||
|
||||
#define XYZW fv4 // vertex.xyzw
|
||||
|
||||
|
||||
! =========================================================
|
||||
! ========================= TRANSFORM SETUP ===============
|
||||
! =========================================================
|
||||
.macro TransformSetup
|
||||
mov SRC, PFT ! MT, pft = src
|
||||
add #-32, DST ! EX, dst -= sizeof(VERTEX)
|
||||
mov #0xE0, VTX ! EX, VTX = 0x00 00 00 E0
|
||||
pref @PFT ! LS, PREFETCH pft (first vertex)
|
||||
shll16 VTX ! EX, VTX = 0x00 E0 00 00
|
||||
shll8 VTX ! EX, VTX = 0xE0 00 00 00 (PVR_CMD_VERTEX)
|
||||
mov #0xF0, EOS ! EX, EOS = 0x00 00 00 F0
|
||||
shll16 EOS ! EX, EOS = 0x00 F0 00 00
|
||||
shll8 EOS ! EX, EOS = 0xF0 00 00 00 (PVR_CMD_VERTEX_EOL)
|
||||
fldi0 ZERO ! LS, fr0 = 0.0
|
||||
.endm
|
||||
|
||||
.macro TransformEnd
|
||||
add #32, DST ! EX, DST += sizeof(VERTEX)
|
||||
rts ! CO, return after executing instruction in delay slot
|
||||
mov DST, r0 ! MT, r0 = DST
|
||||
.endm
|
||||
|
||||
|
||||
! =========================================================
|
||||
! ========================= VERTEX LOADING ================
|
||||
! =========================================================
|
||||
.macro LoadColouredVertex
|
||||
! LOAD XYZ
|
||||
fmov @SRC+, F_X ! LS, X = src->x
|
||||
fmov @SRC+, F_Y ! LS, Y = src->y
|
||||
fmov @SRC+, F_Z ! LS, Z = src->z
|
||||
fldi1 F_W ! LS, W = 1.0
|
||||
! PREPARE NEXT VERTEX
|
||||
add #16, PFT ! EX, pft += VERTEX_STRIDE
|
||||
pref @PFT ! LS, PREFETCH pft (next vertex)
|
||||
add #64, DST ! EX, dst += 2 * sizeof(VERTEX)
|
||||
! TRANSFORM VERTEX
|
||||
ftrv xmtrx, XYZW ! FE, TRANSFORM(XYZW)
|
||||
! LOAD ATTRIBUTES
|
||||
fmov @SRC+, F_C ! LS, C = src->color
|
||||
.endm
|
||||
|
||||
.macro LoadTexturedVertex
|
||||
! LOAD XYZ
|
||||
fmov @SRC+, F_X ! LS, X = src->x
|
||||
fmov @SRC+, F_Y ! LS, Y = src->y
|
||||
fmov @SRC+, F_Z ! LS, Z = src->z
|
||||
fldi1 F_W ! LS, W = 1.0
|
||||
! PREPARE NEXT VERTEX
|
||||
add #24, PFT ! EX, pft += VERTEX_STRIDE
|
||||
pref @PFT ! LS, PREFETCH pft (next vertex)
|
||||
add #64, DST ! EX, dst += 2 * sizeof(VERTEX)
|
||||
! TRANSFORM VERTEX
|
||||
ftrv xmtrx, XYZW ! FE, TRANSFORM(XYZW)
|
||||
! LOAD ATTRIBUTES
|
||||
fmov @SRC+, F_C ! LS, C = src->color
|
||||
fmov @SRC+, F_U ! LS, U = src->u
|
||||
fmov @SRC+, F_V ! LS, V = src->v
|
||||
.endm
|
||||
|
||||
! =========================================================
|
||||
! ========================= VERTEX OUTPUT =================
|
||||
! =========================================================
|
||||
! To take advantage of SH4 dual instruction processing,
|
||||
! clipflag calculation and vertex output are interleaved
|
||||
.macro ProcessVertex1
|
||||
fmov.s F_Z,@-DST ! LS, dst->z = Z
|
||||
fmov.s F_C,@-DST ! LS, dst->c = C
|
||||
fmov.s F_V,@-DST ! LS, dst->v = V
|
||||
fcmp/gt ZERO, F_Z ! FE, T = Z > 0
|
||||
fmov.s F_U,@-DST ! LS, dst->u = U
|
||||
movt FLG ! EX, CLIPFLAGS = T
|
||||
fmov.s F_W,@-DST ! LS, dst->w = W
|
||||
fmov.s F_Y,@-DST ! LS, dst->y = Y
|
||||
fmov.s F_X,@-DST ! LS, dst->x = X
|
||||
mov.l VTX,@-DST ! LS, dst->flags = PVR_CMD_VERTEX
|
||||
.endm
|
||||
|
||||
.macro ProcessVertex2
|
||||
fmov.s F_Z,@-DST ! LS, dst->z = Z
|
||||
fmov.s F_C,@-DST ! LS, dst->c = C
|
||||
fmov.s F_V,@-DST ! LS, dst->v = V
|
||||
fcmp/gt ZERO,F_Z ! FE, T = Z > 0
|
||||
fmov.s F_U,@-DST ! LS, dst->u = U
|
||||
movt TMP ! EX, tmp = T
|
||||
fmov.s F_W,@-DST ! LS, dst->w = W
|
||||
add TMP,TMP ! EX, tmp = tmp + tmp
|
||||
fmov.s F_Y,@-DST ! LS, dst->y = Y
|
||||
or TMP,FLG ! EX, CLIPFLAGS |= tmp (T << 1)
|
||||
fmov.s F_X,@-DST ! LS, dst->x = X
|
||||
mov.l VTX,@-DST ! LS, dst->flags = PVR_CMD_VERTEX
|
||||
.endm
|
||||
|
||||
.macro ProcessVertex3
|
||||
fmov.s F_Z,@-DST ! LS, dst->z = Z
|
||||
fmov.s F_C,@-DST ! LS, dst->c = C
|
||||
fmov.s F_V,@-DST ! LS, dst->v = V
|
||||
fcmp/gt ZERO, F_Z ! FE, T = Z > 0
|
||||
fmov.s F_U,@-DST ! LS, dst->u = U
|
||||
movt TMP ! EX, tmp = T
|
||||
fmov.s F_W,@-DST ! LS, dst->w = W
|
||||
fmov.s F_Y,@-DST ! LS, dst->y = Y
|
||||
shll2 TMP ! EX, tmp = tmp << 2
|
||||
fmov.s F_X,@-DST ! LS, dst->x = X
|
||||
or TMP,FLG ! EX, CLIPFLAGS |= tmp (T << 2)
|
||||
mov.l VTX,@-DST ! LS, dst->flags = PVR_CMD_VERTEX
|
||||
.endm
|
||||
|
||||
.macro ProcessVertex4
|
||||
fmov.s F_Z,@-DST ! LS, dst->z = Z
|
||||
or EOS,FLG ! EX, CLIPFLAGS |= PVR_CMD_VERTEX_EOL
|
||||
fmov.s F_C,@-DST ! LS, dst->c = C
|
||||
fmov.s F_V,@-DST ! LS, dst->v = V
|
||||
fcmp/gt ZERO, F_Z ! FE, T = Z > 0
|
||||
fmov.s F_U,@-DST ! LS, dst->u = U
|
||||
movt TMP ! EX, tmp = T
|
||||
fmov.s F_W,@-DST ! LS, dst->w = W
|
||||
shll2 TMP ! EX, tmp = tmp << 2
|
||||
fmov.s F_Y,@-DST ! LS, dst->y = Y
|
||||
add TMP,TMP ! EX, tmp = (tmp << 2) + (tmp << 2) (T << 3)
|
||||
fmov.s F_X,@-DST ! LS, dst->x = X
|
||||
or TMP,FLG ! EX, CLIPFLAGS |= tmp (T << 3)
|
||||
mov.l FLG,@-DST ! LS, dst->flags = PVR_CMD_VERTEX_EOL | CLIPFLAGS
|
||||
.endm
|
||||
|
||||
|
||||
! =========================================================
|
||||
! ==================== TEXTURED VERTEX TRANSFORM ==========
|
||||
! =========================================================
|
||||
.global _DrawTexturedQuads
|
||||
.align 4
|
||||
|
||||
_DrawTexturedQuads:
|
||||
! Setup
|
||||
TransformSetup
|
||||
|
||||
.T_TRANSFORM_QUAD:
|
||||
LoadTexturedVertex
|
||||
ProcessVertex1
|
||||
|
||||
LoadTexturedVertex
|
||||
ProcessVertex2
|
||||
|
||||
LoadTexturedVertex
|
||||
ProcessVertex3
|
||||
|
||||
LoadTexturedVertex
|
||||
ProcessVertex4
|
||||
|
||||
! CLIPFLAGS TESTING
|
||||
and #15,FLG
|
||||
cmp/eq #0,FLG ! T = CLIPFLAGS == 0 (all points invisible)
|
||||
bf/s .T_LOOP_END ! if !T goto LOOP_END
|
||||
nop
|
||||
|
||||
! No points visible case
|
||||
add #-128, DST ! DST -= 4 * sizeof(VERTEX), move back to prior quad, so that this invisible quad gets overwritten in next iteration
|
||||
|
||||
.T_LOOP_END:
|
||||
dt CNT ! count--; T = count == 0
|
||||
bf .T_TRANSFORM_QUAD ! if !T then goto T_TRANSFORM_QUAD
|
||||
nop
|
||||
|
||||
TransformEnd
|
||||
.size _DrawTexturedQuads, .-_DrawTexturedQuads
|
||||
.type _DrawTexturedQuads, %function
|
||||
|
||||
! =========================================================
|
||||
! ==================== COLOURED VERTEX TRANSFORM ==========
|
||||
! =========================================================
|
||||
.global _DrawColouredQuads
|
||||
.align 4
|
||||
|
||||
_DrawColouredQuads:
|
||||
! Setup
|
||||
fldi0 F_U ! U = 0
|
||||
fldi0 F_V ! V = 0
|
||||
TransformSetup
|
||||
|
||||
.C_TRANSFORM_QUAD:
|
||||
LoadColouredVertex
|
||||
ProcessVertex1
|
||||
|
||||
LoadColouredVertex
|
||||
ProcessVertex2
|
||||
|
||||
LoadColouredVertex
|
||||
ProcessVertex3
|
||||
|
||||
LoadColouredVertex
|
||||
ProcessVertex4
|
||||
|
||||
! CLIPFLAGS TESTING
|
||||
and #15,FLG
|
||||
cmp/eq #0,FLG ! T = CLIPFLAGS == 0 (all points invisible)
|
||||
bf/s .C_LOOP_END ! if !T goto LOOP_END
|
||||
nop
|
||||
|
||||
! No points visible case
|
||||
add #-128, DST ! dst -= 4 * sizeof(VERTEX), move back to 1 vertex before start of quad
|
||||
|
||||
.C_LOOP_END:
|
||||
dt CNT ! count--; T = count == 0
|
||||
bf .C_TRANSFORM_QUAD ! if !T then goto TRANSFORM_QUAD
|
||||
nop
|
||||
|
||||
TransformEnd
|
||||
.size _DrawColouredQuads, .-_DrawColouredQuads
|
||||
.type _DrawColouredQuads, %function
|
||||
BIN
misc/dreamcast/boot_logo.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
3
misc/dreamcast/ip.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
Version : V1.360
|
||||
SW Maker Name : ClassiCube team
|
||||
Game Title : ClassiCube
|
||||
9
misc/dreamcast/readme.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
The dreamcast build requires an initial bootstrap program (Initial Program) named IP.bin
|
||||
|
||||
To generate a custom IP.bin, compile https://github.com/Dreamcast-Projects/makeip
|
||||
|
||||
Then run: makeip ip.txt IP.BIN -l boot_logo.png
|
||||
|
||||
---
|
||||
|
||||
For more details about IP.bin, see https://mc.pp.se/dc/ip.bin.html
|
||||
31
misc/dreamcast/sh4_notes.txt
Normal file
@@ -0,0 +1,31 @@
|
||||
=========================================================
|
||||
======================== PROCESSOR INFO =================
|
||||
=========================================================
|
||||
The SH4 can dual issue (i.e. parallel execution) two instructions
|
||||
as long as the groups of the two instructions are different:
|
||||
* LS - most ALU and FPU register load/stores
|
||||
* EX - most ALU arithmetic instructions
|
||||
* MT - TST, CMP, NOP, MOV Rm,Rn (NOTE: Can execute in parallel with other MT)
|
||||
* FE - most FPU arithmetic instructions
|
||||
* CO - other instructions (NOTE: Cannot never execute in parallel)
|
||||
|
||||
The following general aspects of instructions are important to note per the SH4 manual:
|
||||
* Issue rate: Interval between the issue of an instruction and that of the next instruction
|
||||
* Latency: Interval between the issue of an instruction and the generation of its result (completion)
|
||||
* Latency is also the interval between the execution of two instructions with an interdependent relationship.
|
||||
(although different cases may either increase or decrease Latency)
|
||||
|
||||
|
||||
=========================================================
|
||||
======================== REGISTER USAGES ================
|
||||
=========================================================
|
||||
SH4 C ABI:
|
||||
- R0 to R3 are return values (can be overwritten)
|
||||
- R4 to R7 are input arguments (can be overwritten)
|
||||
- R8 to R13 are non-volatile (must be restored at end)
|
||||
- R14 is the frame pointer (must be restored at end)
|
||||
- R15 is the stack pointer (must be restored at end)
|
||||
- FR0 to FR3 are return values (can be overwritten)
|
||||
- FR4 to FR11 are input arguments (can be overwritten)
|
||||
- FR12 to FR13 are non-volatile (must be restored at end)
|
||||
|
||||
60
misc/ds/Makefile
Normal file
@@ -0,0 +1,60 @@
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
#
|
||||
# SPDX-FileContributor: Antonio Niño Díaz, 2023
|
||||
export BLOCKSDS ?= /opt/wonderful/thirdparty/blocksds/core
|
||||
export BLOCKSDSEXT ?= /opt/wonderful/thirdparty/blocksds/external
|
||||
|
||||
GAME_TITLE := ClassiCube
|
||||
GAME_SUBTITLE := Built with BlocksDS
|
||||
GAME_AUTHOR := ClassiCube team
|
||||
GAME_ICON := misc/ds/icon.bmp
|
||||
GAME_FULL_TITLE := $(GAME_TITLE);$(GAME_SUBTITLE);$(GAME_AUTHOR)
|
||||
|
||||
|
||||
# DLDI and internal SD slot of DSi
|
||||
# --------------------------------
|
||||
|
||||
# Root folder of the SD image
|
||||
SDROOT := sdroot
|
||||
# Name of the generated image it "DSi-1.sd" for no$gba in DSi mode
|
||||
SDIMAGE := image.bin
|
||||
|
||||
# Build artfacts
|
||||
# --------------
|
||||
ifdef BUILD_DSI
|
||||
BUILDDIR := build/dsi
|
||||
ROM := ClassiCube-dsi.nds
|
||||
else
|
||||
BUILDDIR := build/nds
|
||||
ROM := ClassiCube-nds.nds
|
||||
endif
|
||||
|
||||
# Targets
|
||||
# -------
|
||||
.PHONY: all clean arm9 arm7 dldipatch sdimage
|
||||
|
||||
all: $(ROM)
|
||||
|
||||
clean:
|
||||
$(MAKE) -f Makefile.arm9 clean --no-print-directory
|
||||
$(MAKE) -f Makefile.arm7 clean --no-print-directory
|
||||
$(RM) $(ROM) $(BUILDDIR) $(SDIMAGE)
|
||||
|
||||
arm9:
|
||||
$(MAKE) -f misc/ds/Makefile.arm9 --no-print-directory
|
||||
|
||||
arm7:
|
||||
$(MAKE) -f misc/ds/Makefile.arm7 --no-print-directory
|
||||
|
||||
|
||||
$(ROM): arm9 arm7
|
||||
$(BLOCKSDS)/tools/ndstool/ndstool -c $@ \
|
||||
-7 $(BUILDDIR)/cc-arm7.elf -9 $(BUILDDIR)/cc-arm9.elf \
|
||||
-b $(GAME_ICON) "$(GAME_FULL_TITLE)"
|
||||
|
||||
|
||||
sdimage:
|
||||
$(BLOCKSDS)/tools/mkfatimg/mkfatimg -t $(SDROOT) $(SDIMAGE)
|
||||
|
||||
dldipatch: $(ROM)
|
||||
$(BLOCKSDS)/tools/dlditool/dlditool $(BLOCKSDS)/tools/dldi/r4tfv2.dldi $(ROM)
|
||||
96
misc/ds/Makefile.arm7
Normal file
@@ -0,0 +1,96 @@
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
#
|
||||
# SPDX-FileContributor: Antonio Niño Díaz, 2023
|
||||
export BLOCKSDS ?= /opt/wonderful/thirdparty/blocksds/core
|
||||
export BLOCKSDSEXT ?= /opt/wonderful/thirdparty/blocksds/external
|
||||
export WONDERFUL_TOOLCHAIN ?= /opt/wonderful
|
||||
ARM_NONE_EABI_PATH ?= $(WONDERFUL_TOOLCHAIN)/toolchain/gcc-arm-none-eabi/bin/
|
||||
|
||||
SOURCEDIRS := misc/ds
|
||||
INCLUDEDIRS :=
|
||||
DSIWIFI := third_party/dsiwifi
|
||||
|
||||
ifdef BUILD_DSI
|
||||
SOURCEDIRS += $(DSIWIFI)/arm_iop/source $(DSIWIFI)/common/source $(DSIWIFI)/arm_iop/source/ath $(DSIWIFI)/arm_iop/source/crypto $(DSIWIFI)/arm_iop/source/ieee
|
||||
INCLUDEDIRS += $(DSIWIFI)/arm_iop/source $(DSIWIFI)/arm_iop/include $(DSIWIFI)/common/source $(DSIWIFI)/include $(DSIWIFI)/include/lwip
|
||||
BUILDDIR := build/dsi
|
||||
LIBS := -lc -lnds7
|
||||
LIBDIRS := $(BLOCKSDS)/libs/libnds
|
||||
else
|
||||
BUILDDIR := build/nds
|
||||
LIBS := -lc -lnds7 -ldswifi7
|
||||
LIBDIRS := $(BLOCKSDS)/libs/libnds $(BLOCKSDS)/libs/dswifi
|
||||
endif
|
||||
|
||||
NAME := cc-arm7
|
||||
ELF := $(BUILDDIR)/$(NAME).elf
|
||||
MAP := $(BUILDDIR)/$(NAME).map
|
||||
|
||||
PREFIX := $(ARM_NONE_EABI_PATH)arm-none-eabi-
|
||||
CC := $(PREFIX)gcc
|
||||
CXX := $(PREFIX)g++
|
||||
LD := $(CC)
|
||||
|
||||
DEFINES := -D__NDS__ -DARM7
|
||||
ARCH := -mcpu=arm7tdmi -mtune=arm7tdmi
|
||||
WARNFLAGS := -Wall
|
||||
|
||||
# Source files
|
||||
# ------------
|
||||
S_FILES := $(foreach dir,$(SOURCEDIRS),$(wildcard $(dir)/*.s))
|
||||
C_FILES := $(foreach dir,$(SOURCEDIRS),$(wildcard $(dir)/*.c))
|
||||
|
||||
|
||||
INCLUDEFLAGS := $(foreach path,$(INCLUDEDIRS),-I$(path)) \
|
||||
$(foreach path,$(LIBDIRS),-I$(path)/include)
|
||||
|
||||
LIBDIRSFLAGS := $(foreach path,$(LIBDIRS),-L$(path)/lib)
|
||||
|
||||
ASFLAGS += -x assembler-with-cpp $(DEFINES) $(ARCH) \
|
||||
-mthumb -mthumb-interwork $(INCLUDEFLAGS) \
|
||||
-ffunction-sections -fdata-sections
|
||||
|
||||
CFLAGS += -std=gnu11 $(WARNFLAGS) $(DEFINES) $(ARCH) \
|
||||
-mthumb -mthumb-interwork $(INCLUDEFLAGS) -O2 \
|
||||
-ffunction-sections -fdata-sections \
|
||||
-fomit-frame-pointer
|
||||
|
||||
LDFLAGS := -mthumb -mthumb-interwork $(LIBDIRSFLAGS) \
|
||||
-Wl,-Map,$(MAP) -Wl,--gc-sections -nostdlib \
|
||||
-T$(BLOCKSDS)/sys/crts/ds_arm7.ld \
|
||||
-Wl,--no-warn-rwx-segments \
|
||||
-Wl,--start-group $(LIBS) -lgcc -Wl,--end-group
|
||||
|
||||
|
||||
# Intermediate build files
|
||||
# ------------------------
|
||||
OBJS := $(addprefix $(BUILDDIR)/, $(notdir $(C_FILES:%.c=%.o) $(S_FILES:%.s=%.o)))
|
||||
DEPS := $(OBJS:.o=.d)
|
||||
export VPATH := $(SOURCEDIRS)
|
||||
|
||||
# Targets
|
||||
# -------
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(BUILDDIR) $(ELF)
|
||||
|
||||
$(BUILDDIR):
|
||||
mkdir -p $(BUILDDIR)
|
||||
|
||||
$(ELF): $(OBJS)
|
||||
$(LD) -o $@ $(OBJS) $(BLOCKSDS)/sys/crts/ds_arm7_crt0.o $(LDFLAGS)
|
||||
clean:
|
||||
rm $(ELF) $(MAP) $(OBJS)
|
||||
|
||||
# Rules
|
||||
# -----
|
||||
$(BUILDDIR)/%.o : %.s
|
||||
$(CC) $(ASFLAGS) -MMD -MP -c -o $@ $<
|
||||
|
||||
$(BUILDDIR)/%.o : %.c
|
||||
$(CC) $(CFLAGS) -MMD -MP -c -o $@ $<
|
||||
|
||||
# Include dependency files if they exist
|
||||
# --------------------------------------
|
||||
|
||||
-include $(DEPS)
|
||||
106
misc/ds/Makefile.arm9
Normal file
@@ -0,0 +1,106 @@
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
#
|
||||
# SPDX-FileContributor: Antonio Niño Díaz, 2023
|
||||
export BLOCKSDS ?= /opt/wonderful/thirdparty/blocksds/core
|
||||
export BLOCKSDSEXT ?= /opt/wonderful/thirdparty/blocksds/external
|
||||
export WONDERFUL_TOOLCHAIN ?= /opt/wonderful
|
||||
ARM_NONE_EABI_PATH ?= $(WONDERFUL_TOOLCHAIN)/toolchain/gcc-arm-none-eabi/bin/
|
||||
|
||||
SOURCEDIRS := src
|
||||
INCLUDEDIRS :=
|
||||
DSIWIFI := third_party/dsiwifi
|
||||
|
||||
ifdef BUILD_DSI
|
||||
SOURCEDIRS += $(DSIWIFI)/arm_host/source $(DSIWIFI)/common/source $(DSIWIFI)/arm_host/source/nds $(DSIWIFI)/arm_host/source/lwip $(DSIWIFI)/arm_host/source/lwip/ipv4 $(DSIWIFI)/arm_host/source/lwip/ipv6 $(DSIWIFI)/arm_host/source/lwip/netif $(DSIWIFI)/arm_host/source/lwip/netif/ppp $(DSIWIFI)/arm_host/source/lwip/api
|
||||
INCLUDEDIRS += $(DSIWIFI)/arm_host/include $(DSIWIFI)/common/source $(DSIWIFI)/include $(DSIWIFI)/include/lwip
|
||||
BUILDDIR := build/dsi
|
||||
DEFINES := -DPLAT_NDS -DBUILD_DSI
|
||||
LIBS := -lnds9 -lc
|
||||
LIBDIRS := $(BLOCKSDS)/libs/libnds
|
||||
else
|
||||
BUILDDIR := build/nds
|
||||
DEFINES := -DPLAT_NDS
|
||||
LIBS := -ldswifi9 -lnds9 -lc
|
||||
LIBDIRS := $(BLOCKSDS)/libs/dswifi $(BLOCKSDS)/libs/libnds
|
||||
endif
|
||||
|
||||
NAME := cc-arm9
|
||||
ELF := $(BUILDDIR)/$(NAME).elf
|
||||
MAP := $(BUILDDIR)/$(NAME).map
|
||||
|
||||
# Tools
|
||||
# -----
|
||||
PREFIX := $(ARM_NONE_EABI_PATH)arm-none-eabi-
|
||||
CC := $(PREFIX)gcc
|
||||
CXX := $(PREFIX)g++
|
||||
LD := $(PREFIX)gcc
|
||||
|
||||
# Source files
|
||||
# ------------
|
||||
S_FILES := $(foreach dir,$(SOURCEDIRS),$(wildcard $(dir)/*.s))
|
||||
C_FILES := $(foreach dir,$(SOURCEDIRS),$(wildcard $(dir)/*.c))
|
||||
|
||||
# Compiler and linker flags
|
||||
# -------------------------
|
||||
|
||||
ARCH := -mthumb -mcpu=arm946e-s+nofp
|
||||
|
||||
SPECS := $(BLOCKSDS)/sys/crts/ds_arm9.specs
|
||||
|
||||
WARNFLAGS := -Wall
|
||||
|
||||
INCLUDEFLAGS := $(foreach path,$(INCLUDEDIRS),-I$(path)) \
|
||||
$(foreach path,$(LIBDIRS),-I$(path)/include)
|
||||
|
||||
LIBDIRSFLAGS := $(foreach path,$(LIBDIRS),-L$(path)/lib)
|
||||
|
||||
ASFLAGS += -x assembler-with-cpp $(DEFINES) $(INCLUDEFLAGS) \
|
||||
$(ARCH) -ffunction-sections -fdata-sections \
|
||||
-specs=$(SPECS)
|
||||
|
||||
CFLAGS += -std=gnu17 $(WARNFLAGS) $(DEFINES) $(INCLUDEFLAGS) \
|
||||
$(ARCH) -O2 -ffunction-sections -fdata-sections \
|
||||
-specs=$(SPECS) -Wstack-usage=10000
|
||||
|
||||
LDFLAGS := $(ARCH) $(LIBDIRSFLAGS) -Wl,-Map,$(MAP) $(DEFINES) \
|
||||
-Wl,--start-group $(LIBS) -Wl,--end-group -specs=$(SPECS)
|
||||
|
||||
# Intermediate build files
|
||||
# ------------------------
|
||||
OBJS := $(addprefix $(BUILDDIR)/, $(notdir $(C_FILES:%.c=%.o) $(S_FILES:%.s=%.o)))
|
||||
DEPS := $(OBJS:.o=.d)
|
||||
export VPATH := $(SOURCEDIRS)
|
||||
|
||||
# Targets
|
||||
# -------
|
||||
|
||||
.PHONY: all
|
||||
|
||||
all: $(BUILDDIR) $(ELF)
|
||||
|
||||
$(BUILDDIR):
|
||||
mkdir -p $(BUILDDIR)
|
||||
|
||||
$(ELF): $(OBJS)
|
||||
$(LD) -o $@ $(OBJS) $(LDFLAGS)
|
||||
|
||||
clean:
|
||||
rm $(ELF) $(MAP) $(OBJS)
|
||||
rm -rf $(BUILDDIR)
|
||||
|
||||
# Rules
|
||||
# -----
|
||||
|
||||
$(BUILDDIR)/%.o : %.s
|
||||
$(CC) $(ASFLAGS) -MMD -MP -c -o $@ $<
|
||||
|
||||
$(BUILDDIR)/%.o : %.c
|
||||
$(CC) $(CFLAGS) -MMD -MP -c -o $@ $<
|
||||
|
||||
$(BUILDDIR)/%.arm.o : %.arm.c
|
||||
$(CC) $(CFLAGS) -MMD -MP -marm -mlong-calls -c -o $@ $<
|
||||
|
||||
# Include dependency files if they exist
|
||||
# --------------------------------------
|
||||
|
||||
-include $(DEPS)
|
||||
BIN
misc/ds/icon.bmp
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
54
misc/ds/main_arm7.c
Normal file
@@ -0,0 +1,54 @@
|
||||
// SPDX-License-Identifier: Zlib
|
||||
//
|
||||
// Copyright (C) 2005 Michael Noland (joat)
|
||||
// Copyright (C) 2005 Jason Rogers (Dovoto)
|
||||
// Copyright (C) 2005-2015 Dave Murphy (WinterMute)
|
||||
// Copyright (C) 2023 Antonio Niño Díaz
|
||||
|
||||
// Default ARM7 core
|
||||
#include <dswifi7.h>
|
||||
#include <nds.h>
|
||||
|
||||
volatile bool exit_loop = false;
|
||||
|
||||
static void power_button_callback(void) {
|
||||
exit_loop = true;
|
||||
}
|
||||
|
||||
static void vblank_handler(void) {
|
||||
inputGetAndSend();
|
||||
Wifi_Update();
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
enableSound();
|
||||
readUserSettings();
|
||||
ledBlink(0);
|
||||
touchInit();
|
||||
|
||||
irqInit();
|
||||
irqSet(IRQ_VBLANK, vblank_handler);
|
||||
|
||||
fifoInit();
|
||||
installWifiFIFO();
|
||||
installSoundFIFO();
|
||||
installSystemFIFO();
|
||||
|
||||
setPowerButtonCB(power_button_callback);
|
||||
|
||||
initClockIRQTimer(3);
|
||||
irqEnable(IRQ_VBLANK | IRQ_RTC);
|
||||
|
||||
while (!exit_loop)
|
||||
{
|
||||
const uint16_t key_mask = KEY_SELECT | KEY_START | KEY_L | KEY_R;
|
||||
uint16_t keys_pressed = ~REG_KEYINPUT;
|
||||
|
||||
if ((keys_pressed & key_mask) == key_mask)
|
||||
exit_loop = true;
|
||||
|
||||
swiWaitForVBlank();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
7
misc/flatpak/ClassiCubeLauncher
Normal file
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
# Fallback Texture Pack and Audio
|
||||
mkdir -p ${XDG_DATA_HOME}/ClassiCube/texpacks ${XDG_DATA_HOME}/ClassiCube/audio
|
||||
test -f ${XDG_DATA_HOME}/ClassiCube/texpacks/classicube.zip || cp /app/share/classicube-texpack.zip ${XDG_DATA_HOME}/ClassiCube/texpacks/classicube.zip
|
||||
test -f ${XDG_DATA_HOME}/ClassiCube/audio/classicube.zip || cp /app/share/classicube-audio.zip ${XDG_DATA_HOME}/ClassiCube/audio/classicube.zip
|
||||
|
||||
cd ${XDG_DATA_HOME}/ClassiCube && exec ClassiCube "$@"
|
||||
136
misc/flatpak/net.classicube.flatpak.client.SDL3.json
Normal file
@@ -0,0 +1,136 @@
|
||||
{
|
||||
"id": "net.classicube.flatpak.client",
|
||||
"runtime": "org.gnome.Platform",
|
||||
"runtime-version": "48",
|
||||
"sdk": "org.gnome.Sdk",
|
||||
"command": "ClassiCubeLauncher",
|
||||
"finish-args": [
|
||||
"--socket=wayland",
|
||||
"--socket=fallback-x11",
|
||||
"--device=dri",
|
||||
"--share=network",
|
||||
"--share=ipc",
|
||||
"--socket=pulseaudio"
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"name": "SDL3",
|
||||
"buildsystem": "cmake-ninja",
|
||||
"builddir": true,
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/libsdl-org/SDL.git",
|
||||
"branch": "main"
|
||||
}
|
||||
],
|
||||
"cleanup": [
|
||||
"/bin/sdl3-config",
|
||||
"/include",
|
||||
"/lib/libSDL3.la",
|
||||
"/lib/libSDL3main.a",
|
||||
"/lib/libSDL3main.la",
|
||||
"/lib/libSDL3_test.a",
|
||||
"/lib/libSDL3_test.la",
|
||||
"/lib/cmake",
|
||||
"/share/aclocal",
|
||||
"/lib/pkgconfig"
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"name": "libdecor",
|
||||
"buildsystem": "meson",
|
||||
"config-opts": [
|
||||
"-Ddemo=false"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://gitlab.freedesktop.org/libdecor/libdecor.git"
|
||||
}
|
||||
],
|
||||
"cleanup": [
|
||||
"/include",
|
||||
"/lib/pkgconfig"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "zenity-gtk3",
|
||||
"buildsystem": "meson",
|
||||
"build-commands": [
|
||||
"mkdir -p ${FLATPAK_DEST}/share/icons/hicolor"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://gitlab.gnome.org/GNOME/zenity/-/archive/3.44.4/zenity-3.44.4.tar.gz",
|
||||
"sha256": "e7b334867d4e11053e6e52e5d51b7a983dc549f93cb3fda757e40309b16bc57b"
|
||||
}
|
||||
],
|
||||
"post-install": [
|
||||
"mv ${FLATPAK_DEST}/bin/zenity ${FLATPAK_DEST}/bin/zenity-gtk3"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "zenity-gtk4",
|
||||
"buildsystem": "meson",
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://gitlab.gnome.org/GNOME/zenity/-/archive/4.0.2/zenity-4.0.2.tar.gz",
|
||||
"sha256": "fdbb74e882a6a56bb2f1a2381b81e08b06c627cc7e944edb71d107092c70dd80",
|
||||
"x-checker-data": {
|
||||
"type": "gnome",
|
||||
"name": "zenity"
|
||||
}
|
||||
}
|
||||
],
|
||||
"post-install": [
|
||||
"mv ${FLATPAK_DEST}/bin/zenity ${FLATPAK_DEST}/bin/zenity-gtk4"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ClassiCubeAssets",
|
||||
"buildsystem": "simple",
|
||||
"build-commands": [
|
||||
"install -Dm644 classicube-texpack.zip ${FLATPAK_DEST}/share/classicube-texpack.zip",
|
||||
"install -Dm644 classicube-audio.zip ${FLATPAK_DEST}/share/classicube-audio.zip"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "file",
|
||||
"dest-filename": "classicube-texpack.zip",
|
||||
"url": "https://classicube.net/static/default.zip",
|
||||
"sha256": "55eac12a9727d209b42694d07dfdca8d50349779ab77ffc11a31d2cb66b45635"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"dest-filename": "classicube-audio.zip",
|
||||
"url": "https://classicube.net/static/audio.zip",
|
||||
"sha256": "13562a712d1cb1de3f36dd93a03245a377f201e7934d19c17de09202b410e04b"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ClassiCube",
|
||||
"buildsystem": "simple",
|
||||
"build-commands": [
|
||||
"gcc -fno-math-errno src/*.c -o src/ClassiCube -rdynamic -lpthread -lGL -DCC_WIN_BACKEND=CC_WIN_BACKEND_SDL3 -DCC_GFX_BACKEND=CC_GFX_BACKEND_GL2 -DCC_BUILD_FLATPAK -L /app/lib -lSDL3",
|
||||
"install -Dm755 src/ClassiCube -t ${FLATPAK_DEST}/bin",
|
||||
"install -Dm755 misc/flatpak/ClassiCubeLauncher -t ${FLATPAK_DEST}/bin",
|
||||
"install -Dm755 misc/flatpak/zenity-wrapper ${FLATPAK_DEST}/bin/zenity",
|
||||
"install -Dm644 misc/flatpak/net.classicube.flatpak.client.svg ${FLATPAK_DEST}/share/icons/hicolor/scalable/apps/net.classicube.flatpak.client.svg",
|
||||
"install -Dm644 misc/flatpak/net.classicube.flatpak.client.desktop ${FLATPAK_DEST}/share/applications/net.classicube.flatpak.client.desktop",
|
||||
"install -Dm644 misc/flatpak/net.classicube.flatpak.client.metainfo.xml ${FLATPAK_DEST}/share/metainfo/net.classicube.flatpak.client.metainfo.xml"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/ClassiCube/ClassiCube.git"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
56
misc/flatpak/net.classicube.flatpak.client.X11.json
Normal file
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"id": "net.classicube.flatpak.client",
|
||||
"runtime": "org.freedesktop.Platform",
|
||||
"runtime-version": "24.08",
|
||||
"sdk": "org.freedesktop.Sdk",
|
||||
"command": "ClassiCubeLauncher",
|
||||
"finish-args": [
|
||||
"--socket=x11",
|
||||
"--device=dri",
|
||||
"--share=network",
|
||||
"--share=ipc",
|
||||
"--socket=pulseaudio"
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"name": "ClassiCubeAssets",
|
||||
"buildsystem": "simple",
|
||||
"build-commands": [
|
||||
"install -Dm644 classicube-texpack.zip ${FLATPAK_DEST}/share/classicube-texpack.zip",
|
||||
"install -Dm644 classicube-audio.zip ${FLATPAK_DEST}/share/classicube-audio.zip"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "file",
|
||||
"dest-filename": "classicube-texpack.zip",
|
||||
"url": "https://classicube.net/static/default.zip",
|
||||
"sha256": "55eac12a9727d209b42694d07dfdca8d50349779ab77ffc11a31d2cb66b45635"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"dest-filename": "classicube-audio.zip",
|
||||
"url": "https://classicube.net/static/audio.zip",
|
||||
"sha256": "13562a712d1cb1de3f36dd93a03245a377f201e7934d19c17de09202b410e04b"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ClassiCube",
|
||||
"buildsystem": "simple",
|
||||
"build-commands": [
|
||||
"gcc -fno-math-errno src/*.c -o src/ClassiCube -O1 -DCC_BUILD_FLATPAK -DCC_GFX_BACKEND=CC_GFX_BACKEND_GL2 -rdynamic -lm -lpthread -lX11 -lXi -lGL -ldl",
|
||||
"install -Dm755 src/ClassiCube -t ${FLATPAK_DEST}/bin",
|
||||
"install -Dm755 misc/flatpak/ClassiCubeLauncher -t ${FLATPAK_DEST}/bin",
|
||||
"install -Dm644 misc/flatpak/net.classicube.flatpak.client.svg ${FLATPAK_DEST}/share/icons/hicolor/scalable/apps/net.classicube.flatpak.client.svg",
|
||||
"install -Dm644 misc/flatpak/net.classicube.flatpak.client.desktop ${FLATPAK_DEST}/share/applications/net.classicube.flatpak.client.desktop",
|
||||
"install -Dm644 misc/flatpak/net.classicube.flatpak.client.metainfo.xml ${FLATPAK_DEST}/share/metainfo/net.classicube.flatpak.client.metainfo.xml"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/ClassiCube/ClassiCube.git"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
10
misc/flatpak/net.classicube.flatpak.client.desktop
Normal file
@@ -0,0 +1,10 @@
|
||||
[Desktop Entry]
|
||||
Name=ClassiCube
|
||||
Exec=ClassiCubeLauncher
|
||||
Comment=Sandbox building-block game
|
||||
Type=Application
|
||||
Icon=net.classicube.flatpak.client
|
||||
Categories=Game;ActionGame;
|
||||
Terminal=false
|
||||
MimeType=x-scheme-handler/mc;
|
||||
StartupWMClass=net.classicube.flatpak.client
|
||||
133
misc/flatpak/net.classicube.flatpak.client.metainfo.xml
Normal file
@@ -0,0 +1,133 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<component type="desktop-application">
|
||||
<id>net.classicube.flatpak.client</id>
|
||||
<name>ClassiCube</name>
|
||||
<summary>Sandbox building-block game</summary>
|
||||
<developer id="net.classicube">
|
||||
<name>The ClassiCube Project</name>
|
||||
</developer>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>BSD-3-Clause</project_license>
|
||||
<description>
|
||||
<p>ClassiCube brings you back to the days of 2009 where one block game ruled them all, it includes such features as:</p>
|
||||
<ul>
|
||||
<li>Loads of blocks and items to choose from</li>
|
||||
<li>Chatting with other players</li>
|
||||
<li>An extremely simple network protocol to tinker with</li>
|
||||
<li>Hundreds of creative and inventive worlds to explore online</li>
|
||||
<li>A growing community</li>
|
||||
<li>Hundreds of hours of entertainment</li>
|
||||
</ul>
|
||||
</description>
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<caption>Classic mode features faithful classic gameplay</caption>
|
||||
<image type="source">https://github.com/ClassiCube/ClassiCube/assets/6509348/eedee53f-f53e-456f-b51c-92c62079eee0</image>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<caption>Enhanced mode allows hacks like flying and noclipping, it also allows servers to provide many custom features</caption>
|
||||
<image type="source">https://github.com/ClassiCube/ClassiCube/assets/6509348/b2fe0e2b-5d76-41ab-909f-048d0ad15f37</image>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<releases>
|
||||
<release version="1.3.6" date="2023-08-28" type="stable">
|
||||
<url>https://github.com/ClassiCube/ClassiCube/releases/tag/1.3.6</url>
|
||||
</release>
|
||||
<release version="1.3.5" date="2023-01-06" type="stable">
|
||||
<url>https://github.com/ClassiCube/ClassiCube/releases/tag/1.3.5</url>
|
||||
</release>
|
||||
<release version="1.3.4" date="2022-11-01" type="stable">
|
||||
<url>https://github.com/ClassiCube/ClassiCube/releases/tag/1.3.4</url>
|
||||
</release>
|
||||
<release version="1.3.3" date="2022-10-08" type="stable">
|
||||
<url>https://github.com/ClassiCube/ClassiCube/releases/tag/1.3.3</url>
|
||||
</release>
|
||||
<release version="1.3.2" date="2022-05-26" type="stable">
|
||||
<url>https://github.com/ClassiCube/ClassiCube/releases/tag/1.3.2</url>
|
||||
</release>
|
||||
<release version="1.3.1" date="2022-01-11" type="stable">
|
||||
<url>https://github.com/ClassiCube/ClassiCube/releases/tag/1.3.1</url>
|
||||
</release>
|
||||
<release version="1.3.0" date="2022-01-04" type="stable">
|
||||
<url>https://github.com/ClassiCube/ClassiCube/releases/tag/1.3.0</url>
|
||||
</release>
|
||||
<release version="1.2.9" date="2021-10-18" type="stable">
|
||||
<url>https://github.com/ClassiCube/ClassiCube/releases/tag/1.2.9</url>
|
||||
</release>
|
||||
<release version="1.2.8" date="2021-09-18" type="stable">
|
||||
<url>https://github.com/ClassiCube/ClassiCube/releases/tag/1.2.8</url>
|
||||
</release>
|
||||
<release version="1.2.7" date="2021-07-22" type="stable">
|
||||
<url>https://github.com/ClassiCube/ClassiCube/releases/tag/1.2.7</url>
|
||||
</release>
|
||||
<release version="1.2.6" date="2021-07-02" type="stable">
|
||||
<url>https://github.com/ClassiCube/ClassiCube/releases/tag/1.2.6</url>
|
||||
</release>
|
||||
<release version="1.2.5" date="2021-04-02" type="stable">
|
||||
<url>https://github.com/ClassiCube/ClassiCube/releases/tag/1.2.5</url>
|
||||
</release>
|
||||
<release version="1.2.4" date="2021-01-23" type="stable">
|
||||
<url>https://github.com/ClassiCube/ClassiCube/releases/tag/1.2.4</url>
|
||||
</release>
|
||||
<release version="1.2.3" date="2020-12-12" type="stable">
|
||||
<url>https://github.com/ClassiCube/ClassiCube/releases/tag/1.2.3</url>
|
||||
</release>
|
||||
<release version="1.2.2" date="2020-12-11" type="stable">
|
||||
<url>https://github.com/ClassiCube/ClassiCube/releases/tag/1.2.2</url>
|
||||
</release>
|
||||
<release version="1.2.1" date="2020-11-28" type="stable">
|
||||
<url>https://github.com/ClassiCube/ClassiCube/releases/tag/1.2.1</url>
|
||||
</release>
|
||||
<release version="1.2.0" date="2020-10-01" type="stable">
|
||||
<url>https://github.com/ClassiCube/ClassiCube/releases/tag/1.2.0</url>
|
||||
</release>
|
||||
<release version="1.1.9" date="2020-08-16" type="stable">
|
||||
<url>https://github.com/ClassiCube/ClassiCube/releases/tag/1.1.9</url>
|
||||
</release>
|
||||
<release version="1.1.8" date="2020-08-05" type="stable">
|
||||
<url>https://github.com/ClassiCube/ClassiCube/releases/tag/1.1.8</url>
|
||||
</release>
|
||||
<release version="1.1.7" date="2020-06-13" type="stable">
|
||||
<url>https://github.com/ClassiCube/ClassiCube/releases/tag/1.1.7</url>
|
||||
</release>
|
||||
<release version="1.1.6" date="2020-05-07" type="stable">
|
||||
<url>https://github.com/ClassiCube/ClassiCube/releases/tag/1.1.6</url>
|
||||
</release>
|
||||
<release version="1.1.5" date="2020-05-01" type="stable">
|
||||
<url>https://github.com/ClassiCube/ClassiCube/releases/tag/1.1.5</url>
|
||||
</release>
|
||||
<release version="1.1.4" date="2020-04-21" type="stable">
|
||||
<url>https://github.com/ClassiCube/ClassiCube/releases/tag/1.1.4</url>
|
||||
</release>
|
||||
<release version="1.1.3" date="2020-03-08" type="stable">
|
||||
<url>https://github.com/ClassiCube/ClassiCube/releases/tag/1.1.3</url>
|
||||
</release>
|
||||
<release version="1.1.2" date="2020-01-26" type="stable">
|
||||
<url>https://github.com/ClassiCube/ClassiCube/releases/tag/1.1.2</url>
|
||||
</release>
|
||||
<release version="1.1.1" date="2019-12-16" type="stable">
|
||||
<url>https://github.com/ClassiCube/ClassiCube/releases/tag/1.1.1</url>
|
||||
</release>
|
||||
</releases>
|
||||
<url type="homepage">https://www.classicube.net/</url>
|
||||
<url type="bugtracker">https://github.com/ClassiCube/ClassiCube/issues</url>
|
||||
<url type="donation">https://www.patreon.com/ClassiCube</url>
|
||||
<url type="vcs-browser">https://github.com/ClassiCube/ClassiCube</url>
|
||||
<categories>
|
||||
<category>Game</category>
|
||||
<category>AdventureGame</category>
|
||||
<category>ActionGame</category>
|
||||
</categories>
|
||||
<recommends>
|
||||
<control>pointing</control>
|
||||
<control>keyboard</control>
|
||||
</recommends>
|
||||
<content_rating type="oars-1.1">
|
||||
<content_attribute id="violence-cartoon">moderate</content_attribute>
|
||||
<content_attribute id="social-chat">intense</content_attribute>
|
||||
</content_rating>
|
||||
<launchable type="desktop-id">net.classicube.flatpak.client.desktop</launchable>
|
||||
<provides>
|
||||
<binary>ClassiCube</binary>
|
||||
</provides>
|
||||
</component>
|
||||
44
misc/flatpak/net.classicube.flatpak.client.svg
Normal file
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="128"
|
||||
height="127.99999"
|
||||
viewBox="0 0 33.866667 33.866664"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
transform="translate(5.8338447,-13.20144)">
|
||||
<g
|
||||
id="g4741"
|
||||
transform="matrix(0.12177585,0,0,0.12056875,-1.6325083,12.971524)">
|
||||
<path
|
||||
id="path4737"
|
||||
d="M -5.8338447,207.40561 V 78.28894 L 106.61407,13.20144 218.79741,78.28894 V 207.40561 L 106.61407,272.4931 Z"
|
||||
style="fill:#f6f6f6;stroke:#000000;stroke-width:8.0626;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
id="path179"
|
||||
d="m 104.07502,141.52929 110.68965,-60.9215 1.62598,125.47985 -109.78346,61.73499 z m 20.61272,94.64566 c 8.561,-1.36503 22.58979,-6.90566 34.77207,-13.73314 8.44846,-4.73489 17.45957,-10.82064 25.81752,-17.43613 8.72093,-6.90281 17.22731,-15.21726 18.55921,-18.14047 0.26981,-0.59217 0.24879,-0.77358 -0.13391,-1.15568 -0.36305,-0.36248 -0.91552,-0.44887 -2.7589,-0.43139 -3.71393,0.0352 -9.27509,1.35366 -16.28846,3.86168 -2.01562,0.7208 -3.69686,1.27297 -3.73608,1.22704 -0.16881,-0.19764 3.44601,-29.37179 6.84564,-55.24912 1.21398,-9.24057 2.15592,-16.89033 2.09321,-16.99948 -0.19747,-0.34365 -6.05941,-0.21541 -8.74964,0.19141 -11.67357,1.7653 -26.1385,9.31897 -38.83406,20.27938 -3.00232,2.59198 -8.66363,8.37481 -10.38554,10.60847 l -1.13332,1.47013 1.06078,5.78494 c 1.66864,9.09991 3.21014,18.62874 5.55847,34.35994 1.6265,10.89577 2.70193,17.7159 2.81167,17.83099 0.23021,0.24143 9.15704,-3.22834 13.96159,-5.42672 4.01374,-1.83655 7.38001,-3.77497 13.6069,-7.83534 5.39432,-3.51748 6.57616,-4.09382 7.18285,-3.50281 1.32604,1.29178 -3.92898,6.46583 -11.75312,11.57204 -5.59387,3.65069 -11.90727,6.67998 -18.54423,8.8979 -3.61228,1.20714 -3.99351,1.40207 -6.48521,3.316 -7.13359,5.47947 -15.77323,13.5129 -18.33378,17.04736 -1.39429,1.92461 -1.60126,3.07547 -0.62376,3.46838 0.81553,0.3278 3.41645,0.32525 5.4901,-0.005 z"
|
||||
style="fill:#cbcbcb;fill-opacity:1;stroke-width:0.264583" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
7
misc/flatpak/zenity-wrapper
Normal file
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
# Allow forcing GTK3/4 through $CC_DIALOG_FORCE_ZENITY_GTK{3,4}
|
||||
if [[ -z "${CC_DIALOG_FORCE_ZENITY_GTK3}" && "${XDG_CURRENT_DESKTOP}" == "GNOME" || ! -z "${CC_DIALOG_FORCE_ZENITY_GTK4}" ]]; then
|
||||
zenity-gtk4 "$@"
|
||||
else
|
||||
zenity-gtk3 "$@"
|
||||
fi
|
||||
88
misc/gba/Makefile
Normal file
@@ -0,0 +1,88 @@
|
||||
ifeq ($(strip $(DEVKITPRO)),)
|
||||
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>devkitPro)
|
||||
endif
|
||||
|
||||
include $(DEVKITPRO)/devkitARM/gba_rules
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Configurable options
|
||||
#---------------------------------------------------------------------------------
|
||||
# Name of the final output
|
||||
TARGET = ClassiCube-gba
|
||||
# List of directories containing source code
|
||||
SOURCE_DIRS = src src/gba
|
||||
# Directory where object files are placed
|
||||
BUILD_DIR = build/gba
|
||||
|
||||
GAME_TITLE = ClassiCube
|
||||
GAME_CODE = 0000
|
||||
MAKER_CODE = 00
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
S_FILES = $(foreach dir,$(SOURCE_DIRS),$(wildcard $(dir)/*.S))
|
||||
C_FILES = $(foreach dir,$(SOURCE_DIRS),$(wildcard $(dir)/*.c))
|
||||
OBJS = $(addprefix $(BUILD_DIR)/, $(notdir $(C_FILES:%.c=%.o) $(S_FILES:%.S=%.o)))
|
||||
|
||||
ARCH = -mthumb -mthumb-interwork
|
||||
CFLAGS = -g -Wall -O2 -DPLAT_GBA -ffunction-sections -fdata-sections -mcpu=arm7tdmi -mtune=arm7tdmi $(ARCH)
|
||||
ASFLAGS = -g $(ARCH)
|
||||
|
||||
LDFLAGS = -specs=gba.specs -g $(ARCH)
|
||||
LIBS = -ltonc
|
||||
|
||||
LIBGBA := $(DEVKITPRO)/libgba
|
||||
INCLUDES += $(foreach dir, $(LIBGBA), -I$(dir)/include)
|
||||
LDFLAGS += $(foreach dir, $(LIBGBA), -L$(dir)/lib)
|
||||
|
||||
LIBTONC = $(DEVKITPRO)/libtonc
|
||||
INCLUDES += $(foreach dir, $(LIBTONC), -I$(dir)/include)
|
||||
LDFLAGS += $(foreach dir, $(LIBTONC), -L$(dir)/lib)
|
||||
|
||||
# Dependency tracking
|
||||
DEPFLAGS = -MT $@ -MMD -MP -MF $(BUILD_DIR)/$*.d
|
||||
DEPFILES := $(OBJS:%.o=%.d)
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
default: $(BUILD_DIR) $(TARGET).gba
|
||||
|
||||
clean:
|
||||
rm $(TARGET).gba $(TARGET).elf $(OBJS)
|
||||
|
||||
$(BUILD_DIR):
|
||||
mkdir -p $(BUILD_DIR)
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Executable generation
|
||||
#---------------------------------------------------------------------------------
|
||||
$(TARGET).elf: $(OBJS)
|
||||
$(CC) $(LDFLAGS) $^ -o $@ $(LIBS)
|
||||
|
||||
$(TARGET).gba: $(TARGET).elf
|
||||
$(OBJCOPY) -O binary $< $@
|
||||
gbafix $@ -t$(GAME_TITLE) -c$(GAME_CODE) -m$(MAKER_CODE)
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Object generation
|
||||
#---------------------------------------------------------------------------------
|
||||
$(BUILD_DIR)/%.o: src/%.c
|
||||
$(CC) $(CFLAGS) $(INCLUDES) $(DEPFLAGS) -c $< -o $@
|
||||
|
||||
$(BUILD_DIR)/%.o: src/gba/%.c
|
||||
$(CC) $(CFLAGS) $(INCLUDES) $(DEPFLAGS) -c $< -o $@
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# Dependency tracking
|
||||
#---------------------------------------------------------------------------------
|
||||
$(DEPFILES):
|
||||
|
||||
include $(wildcard $(DEPFILES))
|
||||