Compare commits

..

17 Commits

Author SHA1 Message Date
Simon Robertshaw
224d646297 Compiler: Fix label generation 2013-02-14 09:40:15 +00:00
Simon Robertshaw
4e1ea552f1 More VM callable functions 2013-02-13 20:59:11 +00:00
Simon Robertshaw
14991cba5f Enforce cdecl calling convention for callable code, global variables, symbol table for exporting programmes 2013-02-09 13:44:09 +00:00
Simon Robertshaw
f3cfa6106b Inform GCC of clobbered registers 2013-02-02 21:10:56 +00:00
Simon Robertshaw
f7b734de0b Better checking for coordinates in GET instruction, empty particles are id'd -1 2013-02-02 16:46:50 +00:00
Simon Robertshaw
316e940e53 Clean up VM and Lua loading functions 2013-02-02 14:46:45 +00:00
Simon Robertshaw
487647645e Don't backup esi/edx registers as there's no way of adjusting variable position on the stack, yet 2013-02-02 01:56:56 +00:00
Simon Robertshaw
acb126e162 More type conversion and enforcement 2013-02-02 01:31:19 +00:00
Simon Robertshaw
1e535a160d Merge 2013-02-01 20:25:48 +00:00
Simon Robertshaw
187bf11d3d tointeger and tofloat instructions. Detection and implicit conversion of number types 2013-02-01 15:21:21 +00:00
Simon Robertshaw
833cbf9b77 Merge 2013-01-31 23:43:11 +00:00
Simon Robertshaw
004710fcea Keep track of variable types 2013-01-31 23:35:16 +00:00
Simon Robertshaw
b1944dfda1 Remove old testing code 2013-01-31 22:41:24 +00:00
Simon Robertshaw
15503177a8 Correct compilation of JNE instruction 2013-01-31 20:58:48 +00:00
Simon Robertshaw
8fb020c59e Return from procedures, correctly address variables in nested scopes, make space for the return address from the callers stack 2013-01-30 23:44:05 +00:00
Simon Robertshaw
ca7c0d777b Working X86 JIT compilation/execution 2013-01-30 18:11:06 +00:00
Simon Robertshaw
c4e5e82fec Work on X86 native compiler 2013-01-28 00:08:22 +00:00
1043 changed files with 70668 additions and 89465 deletions

2
.gitattributes vendored
View File

@ -1,2 +1,2 @@
.gitattributes export-ignore
.gitignore export-ignore
.gitignore export-ignore

2
.github/.gitignore vendored
View File

@ -1,2 +0,0 @@
build_init.bat
jdk.ini

515
.github/build.sh vendored
View File

@ -1,515 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
if [[ -z ${BSH_BUILD_PLATFORM-} ]]; then >&2 echo "BSH_BUILD_PLATFORM not set"; exit 1; fi
if [[ -z ${BSH_HOST_ARCH-} ]]; then >&2 echo "BSH_HOST_ARCH not set"; exit 1; fi
if [[ -z ${BSH_HOST_PLATFORM-} ]]; then >&2 echo "BSH_HOST_PLATFORM not set"; exit 1; fi
if [[ -z ${BSH_HOST_LIBC-} ]]; then >&2 echo "BSH_HOST_LIBC not set"; exit 1; fi
if [[ -z ${BSH_STATIC_DYNAMIC-} ]]; then >&2 echo "BSH_STATIC_DYNAMIC not set"; exit 1; fi
if [[ -z ${BSH_DEBUG_RELEASE-} ]]; then >&2 echo "BSH_DEBUG_RELEASE not set"; exit 1; fi
if [[ -z ${RELEASE_NAME-} ]]; then >&2 echo "RELEASE_NAME not set"; exit 1; fi
if [[ -z ${RELEASE_TYPE-} ]]; then >&2 echo "RELEASE_TYPE not set"; exit 1; fi
if [[ -z ${MOD_ID-} ]]; then >&2 echo "MOD_ID not set"; exit 1; fi
if [[ -z ${SEPARATE_DEBUG-} ]]; then >&2 echo "SEPARATE_DEBUG not set"; exit 1; fi
if [[ -z ${PACKAGE_MODE-} ]]; then >&2 echo "PACKAGE_MODE not set"; exit 1; fi
if [[ -z ${ASSET_PATH-} ]]; then >&2 echo "ASSET_PATH not set"; exit 1; fi
if [[ -z ${DEBUG_ASSET_PATH-} ]]; then >&2 echo "DEBUG_ASSET_PATH not set"; exit 1; fi
if [[ -z ${APP_NAME-} ]]; then >&2 echo "APP_NAME not set"; exit 1; fi
if [[ -z ${APP_COMMENT-} ]]; then >&2 echo "APP_COMMENT not set"; exit 1; fi
if [[ -z ${APP_EXE-} ]]; then >&2 echo "APP_EXE not set"; exit 1; fi
if [[ -z ${APP_ID-} ]]; then >&2 echo "APP_ID not set"; exit 1; fi
if [[ -z ${APP_DATA-} ]]; then >&2 echo "APP_DATA not set"; exit 1; fi
if [[ -z ${APP_VENDOR-} ]]; then >&2 echo "APP_VENDOR not set"; exit 1; fi
case $BSH_HOST_ARCH-$BSH_HOST_PLATFORM-$BSH_HOST_LIBC-$BSH_STATIC_DYNAMIC in
x86_64-linux-gnu-static) ;;
x86_64-linux-gnu-dynamic) ;;
x86_64-windows-mingw-static) ;;
x86_64-windows-mingw-dynamic) ;;
x86_64-windows-msvc-static) ;;
x86_64-windows-msvc-dynamic) ;;
x86-windows-msvc-static) ;;
x86-windows-msvc-dynamic) ;;
x86_64-darwin-macos-static) ;;
x86_64-darwin-macos-dynamic) ;;
aarch64-darwin-macos-static) ;;
aarch64-darwin-macos-dynamic) ;;
x86-android-bionic-static) ;;
x86_64-android-bionic-static) ;;
arm-android-bionic-static) ;;
aarch64-android-bionic-static) ;;
wasm32-emscripten-emscripten-static) ;;
*) >&2 echo "configuration $BSH_HOST_ARCH-$BSH_HOST_PLATFORM-$BSH_HOST_LIBC-$BSH_STATIC_DYNAMIC is not supported" && exit 1;;
esac
if [[ $BSH_HOST_PLATFORM == android ]]; then
android_platform=android-31
if [[ -z "${JAVA_HOME_8_X64-}" ]]; then
>&2 echo "JAVA_HOME_8_X64 not set"
exit 1
fi
if [[ -z "${ANDROID_SDK_ROOT-}" ]]; then
>&2 echo "ANDROID_SDK_ROOT not set"
exit 1
fi
if [[ -z "${ANDROID_NDK_LATEST_HOME-}" ]]; then
>&2 echo "ANDROID_NDK_LATEST_HOME not set"
exit 1
fi
fi
if [[ -z ${BSH_NO_PACKAGES-} ]]; then
case $BSH_HOST_PLATFORM in
android)
(
export PATH=$ANDROID_SDK_ROOT/cmdline-tools/latest/bin:$ANDROID_SDK_ROOT/tools/bin:$PATH
sdkmanager "platforms;$android_platform"
)
;;
windows)
if [[ $BSH_BUILD_PLATFORM-$BSH_HOST_LIBC == windows-mingw ]]; then
pacman -S --noconfirm --needed mingw-w64-ucrt-x86_64-gcc
if [[ $BSH_STATIC_DYNAMIC == static ]]; then
pacman -S --noconfirm --needed mingw-w64-ucrt-x86_64-{cmake,7zip,jq} patch
else
pacman -S --noconfirm --needed mingw-w64-ucrt-x86_64-{pkgconf,bzip2,luajit,jsoncpp,curl,SDL2,libpng,meson,fftw,jq}
fi
export PKG_CONFIG=$(which pkg-config.exe)
fi
;;
linux)
sudo apt update
if [[ $BSH_STATIC_DYNAMIC == static ]]; then
sudo apt install libc6-dev libc6-dev-i386
else
sudo apt install libluajit-5.1-dev libcurl4-openssl-dev libfftw3-dev zlib1g-dev libsdl2-dev libbz2-dev libjsoncpp-dev
fi
;;
darwin)
brew install pkg-config binutils
if [[ $BSH_STATIC_DYNAMIC != static ]]; then
brew install luajit curl fftw zlib sdl2 bzip2 jsoncpp
fi
;;
emscripten)
git clone https://github.com/emscripten-core/emsdk.git --branch 3.1.30
cd emsdk
./emsdk install latest
./emsdk activate latest
. ./emsdk_env.sh
cd ..
;;
esac
fi
function inplace_sed() {
local subst=$1
local path=$2
if [[ $BSH_BUILD_PLATFORM == darwin ]]; then
sed -i "" -e $subst $path
else
sed -i $subst $path
fi
}
if [[ $BSH_HOST_PLATFORM-$BSH_HOST_LIBC == windows-msvc ]]; then
case $BSH_HOST_ARCH in
x86_64) vs_env_arch=x64;;
x86) vs_env_arch=x86;;
esac
VS_ENV_PARAMS=$vs_env_arch$'\t'-vcvars_ver=14.1
. ./.github/vs-env.sh
elif [[ $BSH_HOST_PLATFORM == darwin ]]; then
# may need export SDKROOT=$(xcrun --show-sdk-path --sdk macosx11.1)
CC=clang
CXX=clang++
if [[ $BSH_HOST_ARCH == aarch64 ]]; then
macos_min_ver=11.0
CC+=" -arch arm64"
CXX+=" -arch arm64"
else
macos_min_ver=10.13
CC+=" -arch x86_64"
CXX+=" -arch x86_64"
fi
if [[ $BSH_STATIC_DYNAMIC == static ]]; then
export MACOSX_DEPLOYMENT_TARGET=$macos_min_ver
fi
export CC
export CXX
elif [[ $BSH_HOST_PLATFORM == android ]]; then
case $BSH_HOST_ARCH in
x86_64) android_toolchain_prefix=x86_64-linux-android ; android_system_version=21; android_arch_abi=x86_64 ;;
x86) android_toolchain_prefix=i686-linux-android ; android_system_version=21; android_arch_abi=x86 ;;
aarch64) android_toolchain_prefix=aarch64-linux-android ; android_system_version=21; android_arch_abi=arm64-v8a ;;
arm) android_toolchain_prefix=armv7a-linux-androideabi; android_system_version=21; android_arch_abi=armeabi-v7a;;
esac
android_toolchain_dir=$ANDROID_NDK_LATEST_HOME/toolchains/llvm/prebuilt/linux-x86_64
CC=$android_toolchain_dir/bin/$android_toolchain_prefix$android_system_version-clang
CXX=$android_toolchain_dir/bin/$android_toolchain_prefix$android_system_version-clang++
LD=$android_toolchain_dir/bin/$android_toolchain_prefix-ld
AR=$android_toolchain_dir/bin/llvm-ar
echo $AR
CC+=" -fPIC"
CXX+=" -fPIC"
LD+=" -fPIC"
export CC
export CXX
export LD
export AR
else
export CC=gcc
export CXX=g++
fi
if [[ -d build ]]; then
rm -r build
fi
c_args=
c_link_args=
if [[ $BSH_HOST_PLATFORM-$BSH_HOST_LIBC != windows-msvc ]]; then
c_args+=\'-ffunction-sections\',
c_args+=\'-fdata-sections\',
if [[ $BSH_HOST_PLATFORM == darwin ]]; then
c_link_args+=\'-Wl,-dead_strip\',
else
c_link_args+=\'-Wl,--gc-sections\',
fi
fi
if [[ $BSH_HOST_PLATFORM-$BSH_STATIC_DYNAMIC == darwin-static ]]; then
c_args+=\'-mmacosx-version-min=$macos_min_ver\',
c_link_args+=\'-mmacosx-version-min=$macos_min_ver\',
fi
meson_configure=meson$'\t'setup
if [[ $BSH_DEBUG_RELEASE == release ]]; then
meson_configure+=$'\t'-Dbuildtype=debugoptimized
fi
if [[ $BSH_HOST_PLATFORM == darwin ]]; then
meson_configure+=$'\t'-Dmanifest_macos_min_ver=$macos_min_ver
else
meson_configure+=$'\t'-Dmanifest_date=$(date --iso-8601)
fi
meson_configure+=$'\t'-Dapp_name=$APP_NAME
meson_configure+=$'\t'-Dapp_comment=$APP_COMMENT
meson_configure+=$'\t'-Dapp_exe=$APP_EXE
meson_configure+=$'\t'-Dapp_id=$APP_ID
meson_configure+=$'\t'-Dapp_data=$APP_DATA
meson_configure+=$'\t'-Dapp_vendor=$APP_VENDOR
meson_configure+=$'\t'-Dstrip=false
meson_configure+=$'\t'-Db_staticpic=false
meson_configure+=$'\t'-Dmod_id=$MOD_ID
case $BSH_HOST_ARCH-$BSH_HOST_PLATFORM-$BSH_HOST_LIBC-$BSH_DEBUG_RELEASE in
x86_64-linux-gnu-debug) ;&
x86_64-windows-mingw-debug) ;&
x86_64-windows-msvc-debug) ;&
x86_64-darwin-macos-debug)
meson_configure+=$'\t'-Dbuild_render=true
meson_configure+=$'\t'-Dbuild_font=true
;;
esac
if [[ $PACKAGE_MODE == nohttp ]]; then
meson_configure+=$'\t'-Dhttp=false
fi
if [[ $PACKAGE_MODE == nolua ]]; then
meson_configure+=$'\t'-Dlua=none
fi
if [[ $PACKAGE_MODE == backendvs ]]; then
meson_configure+=$'\t'-Dbackend=vs
# meson 1.2.3 configures vs projects that bring their own manifest, which conflicts with ours
# TODO: remove this patch once https://github.com/mesonbuild/meson/pull/12472 makes it into a release that we can use
meson_configure+=$'\t'-Dwindows_utf8cp=false
fi
if [[ $BSH_STATIC_DYNAMIC == static ]]; then
meson_configure+=$'\t'-Dstatic=prebuilt
if [[ $BSH_HOST_PLATFORM == windows ]]; then
if [[ $BSH_HOST_LIBC == msvc ]]; then
meson_configure+=$'\t'-Db_vscrt=static_from_buildtype
else
c_link_args+=\'-static\',
c_link_args+=\'-static-libgcc\',
c_link_args+=\'-static-libstdc++\',
fi
elif [[ $BSH_HOST_PLATFORM == linux ]]; then
c_link_args+=\'-static-libgcc\',
c_link_args+=\'-static-libstdc++\',
fi
else
if [[ "$BSH_HOST_PLATFORM-$BSH_HOST_LIBC $BSH_BUILD_PLATFORM" == "windows-mingw windows" ]]; then
meson_configure+=$'\t'-Dworkaround_elusive_bzip2=true
meson_configure+=$'\t'-Dworkaround_elusive_bzip2_include_dir=/ucrt64/include
meson_configure+=$'\t'-Dworkaround_elusive_bzip2_lib_dir=/ucrt64/lib
fi
if [[ $BSH_BUILD_PLATFORM == linux ]]; then
meson_configure+=$'\t'-Dworkaround_elusive_bzip2=true
fi
if [[ $BSH_BUILD_PLATFORM == darwin ]]; then
meson_configure+=$'\t'-Dworkaround_elusive_bzip2=true
meson_configure+=$'\t'-Dworkaround_elusive_bzip2_lib_dir=/usr/local/opt/bzip2/lib
meson_configure+=$'\t'-Dworkaround_elusive_bzip2_include_dir=/usr/local/opt/bzip2/include
meson_configure+=$'\t'-Dworkaround_elusive_bzip2_static=true
fi
fi
if [[ $BSH_HOST_PLATFORM == linux ]] && [[ $BSH_HOST_ARCH != aarch64 ]]; then
# certain file managers can't run PIEs https://bugzilla.gnome.org/show_bug.cgi?id=737849
meson_configure+=$'\t'-Db_pie=false
c_link_args+=\'-no-pie\',
fi
stable_or_beta=no
if [[ $RELEASE_TYPE == beta ]]; then
meson_configure+=$'\t'-Dbeta=true
stable_or_beta=yes
fi
if [[ $RELEASE_TYPE == stable ]]; then
stable_or_beta=yes
fi
if [[ $stable_or_beta == yes ]]; then
xyz=$(echo $RELEASE_NAME | cut -d 'v' -f 2 | cut -d 'b' -f 1) # $RELEASE_NAME is vX.Y.Z or vX.Y.Zb
display_version_major=$(echo $xyz | cut -d '.' -f 1)
display_version_minor=$(echo $xyz | cut -d '.' -f 2)
build_num=$(echo $xyz | cut -d '.' -f 3)
if [[ $MOD_ID != 0 ]]; then
meson_configure+=$'\t'-Ddisplay_version_major=$display_version_major
meson_configure+=$'\t'-Ddisplay_version_minor=$display_version_minor
meson_configure+=$'\t'-Dbuild_num=$build_num
fi
fi
if [[ $RELEASE_TYPE == snapshot ]]; then
build_num=$(echo $RELEASE_NAME | cut -d '-' -f 2) # $RELEASE_NAME is snapshot-X
meson_configure+=$'\t'-Dsnapshot=true
if [[ $MOD_ID != 0 ]]; then
meson_configure+=$'\t'-Dbuild_num=$build_num
fi
fi
if [[ $RELEASE_TYPE == snapshot ]] && [[ $MOD_ID != 0 ]]; then
>&2 echo "mods and snapshots do not mix"
exit 1
fi
if [[ $RELEASE_TYPE == snapshot ]] || [[ $MOD_ID != 0 ]]; then
meson_configure+=$'\t'-Dupdate_server=starcatcher.us/TPT
if [[ $BSH_HOST_PLATFORM == emscripten ]]; then
meson_configure+=$'\t'-Dserver=tptserv.starcatcher.us
meson_configure+=$'\t'-Dstatic_server=tptserv.starcatcher.us/Static
fi
fi
if [[ $RELEASE_TYPE != dev ]]; then
meson_configure+=$'\t'-Dignore_updates=false
fi
if [[ "$BSH_HOST_PLATFORM-$BSH_HOST_LIBC" == "windows-mingw" ]]; then
meson_configure+=$'\t'--cross-file=.github/mingw-ghactions.ini
# there is some mingw bug that only ever manifests on ghactions which makes MakeIco.exe use tons of memory and fail
# TODO: remove this hack once we figure out how to fix that
meson_configure+=$'\t'-Dwindows_icons=false
fi
if [[ $BSH_DEBUG_RELEASE-$BSH_STATIC_DYNAMIC == release-static ]]; then
meson_configure+=$'\t'-Db_lto=true
fi
if [[ $BSH_HOST_PLATFORM-$BSH_HOST_ARCH == darwin-aarch64 ]]; then
meson_configure+=$'\t'--cross-file=.github/macaa64-ghactions.ini
fi
if [[ $BSH_HOST_PLATFORM == emscripten ]]; then
meson_configure+=$'\t'--cross-file=.github/emscripten-ghactions.ini
fi
if [[ $RELEASE_TYPE == tptlibsdev ]] && ([[ $BSH_HOST_PLATFORM-$BSH_HOST_LIBC == windows-msvc ]] || [[ $BSH_STATIC_DYNAMIC == static ]]); then
if [[ -z ${TPTLIBSREMOTE-} ]]; then
if [[ -z "${GITHUB_REPOSITORY_OWNER-}" ]]; then
>&2 echo "GITHUB_REPOSITORY_OWNER not set"
exit 1
fi
tptlibsremote=https://github.com/$GITHUB_REPOSITORY_OWNER/tpt-libs
else
tptlibsremote=$TPTLIBSREMOTE
fi
tptlibsbranch=$(echo $RELEASE_NAME | cut -d '-' -f 2-) # $RELEASE_NAME is tptlibsdev-BRANCH
if [[ -d build-tpt-libs ]] && [[ ${TPTLIBSRESET-} == yes ]]; then
rm -rf build-tpt-libs
fi
if [[ ! -d build-tpt-libs/tpt-libs ]]; then
mkdir -p build-tpt-libs
cd build-tpt-libs
git clone $tptlibsremote --branch $tptlibsbranch --depth 1
cd ..
fi
tpt_libs_vtag=v00000000000000
if [[ ! -f build-tpt-libs/tpt-libs/.ok ]]; then
cd build-tpt-libs/tpt-libs
BSH_VTAG=$tpt_libs_vtag ./.github/build.sh
touch .ok
cd ../../subprojects
for i in tpt-libs-prebuilt-*; do
if [[ -d $i ]]; then
rm -r $i
fi
done
7z x ../build-tpt-libs/tpt-libs/temp/libraries.zip
cd ..
fi
meson_configure+=$'\t'-Dtpt_libs_vtag=$tpt_libs_vtag
fi
if [[ $BSH_HOST_PLATFORM == android ]]; then
android_platform_jar=$ANDROID_SDK_ROOT/platforms/$android_platform/android.jar
if ! [[ -f $android_platform_jar ]]; then
>&2 echo "$android_platform_jar not found"
exit 1
fi
meson_configure+=$'\t'--cross-file=android/cross/$BSH_HOST_ARCH.ini
cat << ANDROID_INI > .github/android-ghactions.ini
[constants]
andriod_ndk_toolchain_bin = '$ANDROID_NDK_LATEST_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin'
andriod_sdk_build_tools = '$ANDROID_SDK_ROOT/build-tools/32.0.0'
[properties]
# android_ndk_toolchain_prefix comes from the correct cross-file in ./android/cross
android_ndk_toolchain_prefix = android_ndk_toolchain_prefix
android_platform = '$android_platform'
android_platform_jar = '$android_platform_jar'
java_runtime_jar = '$JAVA_HOME_8_X64/jre/lib/rt.jar'
[binaries]
# android_ndk_toolchain_prefix comes from the correct cross-file in ./android/cross
c = andriod_ndk_toolchain_bin / (android_ndk_toolchain_prefix + 'clang')
cpp = andriod_ndk_toolchain_bin / (android_ndk_toolchain_prefix + 'clang++')
strip = andriod_ndk_toolchain_bin / 'llvm-strip'
javac = '$JAVA_HOME_8_X64/bin/javac'
jar = '$JAVA_HOME_8_X64/bin/jar'
d8 = andriod_sdk_build_tools / 'd8'
aapt = andriod_sdk_build_tools / 'aapt'
aapt2 = andriod_sdk_build_tools / 'aapt2'
zipalign = andriod_sdk_build_tools / 'zipalign'
apksigner = andriod_sdk_build_tools / 'apksigner'
ANDROID_INI
meson_configure+=$'\t'--cross-file=.github/android-ghactions.ini
fi
meson_configure+=$'\t'-Dc_args=[$c_args]
meson_configure+=$'\t'-Dcpp_args=[$c_args]
meson_configure+=$'\t'-Dc_link_args=[$c_link_args]
meson_configure+=$'\t'-Dcpp_link_args=[$c_link_args]
$meson_configure build
cd build
function verify_version_component() {
local key=$1
local expected=$2
local actual=$(jq -r '.[] | select(.name == "'$key'") | .value' < meson-info/intro-buildoptions.json)
if [[ $actual != $expected ]]; then
>&2 echo "meson option $key expected to be $expected, is instead $actual"
exit 1
fi
}
if [[ $stable_or_beta == yes ]] && [[ $MOD_ID == 0 ]]; then
verify_version_component display_version_major $display_version_major
verify_version_component display_version_minor $display_version_minor
verify_version_component build_num $build_num
verify_version_component upstream_version_major $display_version_major
verify_version_component upstream_version_minor $display_version_minor
verify_version_component upstream_build_num $build_num
fi
if [[ $RELEASE_TYPE == snapshot ]] && [[ $MOD_ID == 0 ]]; then
verify_version_component build_num $build_num
verify_version_component upstream_build_num $build_num
fi
strip=strip
objcopy=objcopy
strip_target=$ASSET_PATH
if [[ $BSH_HOST_PLATFORM == android ]]; then
strip=$ANDROID_NDK_LATEST_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-$strip
objcopy=$ANDROID_NDK_LATEST_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-$objcopy
strip_target=lib$APP_EXE.so
fi
if [[ $PACKAGE_MODE == appimage ]]; then
# so far this can only happen with $BSH_HOST_PLATFORM-$BSH_HOST_LIBC == linux-gnu, but this may change later
meson configure -Dcan_install=no -Dignore_updates=true -Dbuild_render=false -Dbuild_font=false
strip_target=$APP_EXE
fi
meson_compile=meson$'\t'compile
meson_compile+=$'\t'-v
if [[ $BSH_BUILD_PLATFORM == windows ]] && [[ $PACKAGE_MODE != backendvs ]]; then
set +e
meson_compile+=$'\t'--ninja-args='["-d","keeprsp"]'
$meson_compile
ninja_code=$?
set -e
cat $APP_EXE.exe.rsp
[[ $ninja_code == 0 ]];
echo # rsps don't usually have a newline at the end
if [[ "$BSH_HOST_PLATFORM-$BSH_STATIC_DYNAMIC $BSH_BUILD_PLATFORM" == "windows-dynamic windows" ]]; then
# on windows we provide the dynamic dependencies also; makes sense to check for their presence
# msys ldd works fine but only on windows build machines
if ldd $APP_EXE | grep "not found"; then
exit 1 # ldd | grep will have printed missing deps
fi
fi
else
$meson_compile
fi
if [[ $SEPARATE_DEBUG == yes ]] && [[ $BSH_HOST_PLATFORM-$BSH_HOST_LIBC != windows-msvc ]]; then
$objcopy --only-keep-debug $strip_target $DEBUG_ASSET_PATH
$strip --strip-debug --strip-unneeded $strip_target
$objcopy --add-gnu-debuglink $DEBUG_ASSET_PATH $strip_target
chmod -x $DEBUG_ASSET_PATH
fi
if [[ $BSH_HOST_PLATFORM == android ]]; then
$JAVA_HOME_8_X64/bin/keytool -genkeypair -keystore keystore.jks -alias androidkey -validity 10000 -keyalg RSA -keysize 2048 -keypass bagelsbagels -storepass bagelsbagels -dname "CN=nobody"
meson configure -Dandroid_keystore=$(realpath keystore.jks)
ANDROID_KEYSTORE_PASS=bagelsbagels ninja android/$APP_EXE.apk
mv android/$APP_EXE.apk $APP_EXE.apk
fi
if [[ $PACKAGE_MODE == dmg ]]; then
# so far this can only happen with $BSH_HOST_PLATFORM-$BSH_HOST_LIBC == darwin-macos
appdir=$APP_NAME.app
mkdir $appdir
mkdir $appdir/Contents
cp resources/Info.plist $appdir/Contents/Info.plist
mkdir $appdir/Contents/MacOS
cp $APP_EXE $appdir/Contents/MacOS/$APP_EXE
mkdir $appdir/Contents/Resources
mkdir icon_exe.iconset
cp ../resources/generated_icons/icon_exe_16.png icon_exe.iconset/icon_16x16.png
cp ../resources/generated_icons/icon_exe_32.png icon_exe.iconset/icon_32x32.png
cp ../resources/generated_icons/icon_exe.png icon_exe.iconset/icon_128x128.png
iconutil -c icns icon_exe.iconset
cp icon_exe.icns $appdir/Contents/Resources/icon_exe.icns
mkdir icon_cps.iconset
cp ../resources/generated_icons/icon_cps_16.png icon_cps.iconset/icon_16x16.png
cp ../resources/generated_icons/icon_cps_32.png icon_cps.iconset/icon_32x32.png
cp ../resources/generated_icons/icon_cps.png icon_cps.iconset/icon_128x128.png
iconutil -c icns icon_cps.iconset
cp icon_cps.icns $appdir/Contents/Resources/icon_cps.icns
mkdir dmgroot
mv $appdir dmgroot/$appdir
cp ../LICENSE dmgroot/LICENSE
cp ../README.md dmgroot/README.md
hdiutil create -format UDZO -volname $APP_NAME -fs HFS+ -srcfolder dmgroot -o $ASSET_PATH
elif [[ $PACKAGE_MODE == emscripten ]]; then
tar cvf $ASSET_PATH $APP_EXE.js $APP_EXE.worker.js $APP_EXE.wasm
elif [[ $PACKAGE_MODE == appimage ]]; then
# so far this can only happen with $BSH_HOST_PLATFORM-$BSH_HOST_LIBC == linux-gnu, but this may change later
case $BSH_HOST_ARCH in
aarch64) appimage_arch=aarch64;;
arm) appimage_arch=armhf ;;
x86) appimage_arch=i686 ;;
x86_64) appimage_arch=x86_64 ;;
esac
curl -fsSLo appimagetool "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-$appimage_arch.AppImage"
curl -fsSLo AppRun "https://github.com/AppImage/AppImageKit/releases/download/continuous/AppRun-$appimage_arch"
chmod +x appimagetool
chmod +x AppRun
appdir=bagels.AppDir # doesn't matter, won't be visible in the resulting appimage
mkdir -p $appdir/usr/bin
mkdir -p $appdir/usr/share/metainfo
mkdir -p $appdir/usr/share/applications
mkdir -p $appdir/usr/share/icons
cp $APP_EXE $appdir/usr/bin/$APP_EXE
mv AppRun $appdir/AppRun
cp ../resources/icon_exe.svg $appdir/$APP_VENDOR-$APP_EXE.svg
cp resources/powder.desktop $appdir/$APP_ID.desktop
cp resources/appdata.xml $appdir/usr/share/metainfo/$APP_ID.appdata.xml
cp $appdir/$APP_VENDOR-$APP_EXE.svg $appdir/usr/share/icons/$APP_VENDOR-$APP_EXE.svg
cp $appdir/$APP_ID.desktop $appdir/usr/share/applications/$APP_ID.desktop
./appimagetool $appdir $ASSET_PATH
fi

View File

@ -1,4 +0,0 @@
set -euo pipefail
IFS=$'\t\n'
gh release create --draft --verify-tag --title $RELEASE_NAME $GITHUB_REF_NAME

View File

@ -1,11 +0,0 @@
[binaries]
c = 'emcc'
cpp = 'em++'
strip = 'emstrip'
ar = 'emar'
[host_machine]
system = 'emscripten'
cpu_family = 'wasm32'
cpu = 'wasm32'
endian = 'little'

View File

@ -1,11 +0,0 @@
[binaries]
c = [ 'clang', '-arch', 'arm64' ]
cpp = [ 'clang++', '-arch', 'arm64' ]
objcpp = [ 'clang++', '-arch', 'arm64' ]
strip = 'strip'
[host_machine]
system = 'darwin'
cpu_family = 'aarch64'
cpu = 'armv8'
endian = 'little'

View File

@ -1,14 +0,0 @@
[constants]
prefix = 'x86_64-w64-mingw32'
[binaries]
c = prefix + '-gcc'
cpp = prefix + '-g++'
strip = prefix + '-strip'
windres = prefix + '-windres'
[host_machine]
system = 'windows'
cpu_family = 'x86_64'
cpu = 'x86_64'
endian = 'little'

1
.github/mod_id.txt vendored
View File

@ -1 +0,0 @@
0

216
.github/prepare.py vendored
View File

@ -1,216 +0,0 @@
import datetime
import json
import os
import re
import subprocess
import sys
ref = os.getenv('GITHUB_REF')
event_name = os.getenv('GITHUB_EVENT_NAME')
publish_hostport = os.getenv('PUBLISH_HOSTPORT')
def set_output(key, value):
with open(os.getenv('GITHUB_OUTPUT'), 'a') as f:
f.write(f"{key}={value}\n")
match_stable = re.fullmatch(r'refs/tags/v([0-9]+)\.([0-9]+)\.([0-9]+)', ref)
match_beta = re.fullmatch(r'refs/tags/v([0-9]+)\.([0-9]+)\.([0-9]+)b', ref)
match_snapshot = re.fullmatch(r'refs/tags/snapshot-([0-9]+)', ref)
match_tptlibsdev = re.fullmatch(r'refs/heads/tptlibsdev-(.*)', ref)
match_alljobs = re.fullmatch(r'refs/heads/(.*)-alljobs', ref)
do_release = False
do_priority = 10
if event_name == 'pull_request':
do_priority = 0
if match_stable:
release_type = 'stable'
release_name = 'v%s.%s.%s' % (match_stable.group(1), match_stable.group(2), match_stable.group(3))
do_release = True
do_priority = 0
elif match_beta:
release_type = 'beta'
release_name = 'v%s.%s.%sb' % (match_beta.group(1), match_beta.group(2), match_beta.group(3))
do_release = True
do_priority = 0
elif match_snapshot:
release_type = 'snapshot'
release_name = 'snapshot-%s' % match_snapshot.group(1)
do_release = True
do_priority = 0
elif match_tptlibsdev:
release_type = 'tptlibsdev'
release_name = 'tptlibsdev-%s' % match_tptlibsdev.group(1)
do_priority = 0
else:
release_type = 'dev'
release_name = 'dev'
if match_alljobs:
do_priority = 0
do_publish = publish_hostport and do_release
set_output('release_type', release_type)
set_output('release_name', release_name)
subprocess.run([ 'meson', 'setup', '-Dprepare=true', 'build-prepare' ], check = True)
build_options = {}
with open('build-prepare/meson-info/intro-buildoptions.json') as f:
for option in json.loads(f.read()):
build_options[option['name']] = option['value']
if int(build_options['mod_id']) == 0 and os.path.exists('.github/mod_id.txt'):
with open('.github/mod_id.txt') as f:
build_options['mod_id'] = f.read()
if int(build_options['mod_id']) == 0:
if release_type == 'stable':
pass
elif release_type == 'beta':
build_options['app_name' ] += ' Beta'
build_options['app_comment'] += ' - Beta'
build_options['app_exe' ] += 'beta'
build_options['app_id' ] += 'beta'
elif release_type == 'snapshot':
build_options['app_name' ] += ' Snapshot'
build_options['app_comment'] += ' - Snapshot'
build_options['app_exe' ] += 'snapshot'
build_options['app_id' ] += 'snapshot'
else:
build_options['app_name' ] += ' Dev'
build_options['app_comment'] += ' - Dev'
build_options['app_exe' ] += 'dev'
build_options['app_id' ] += 'dev'
set_output('mod_id' , build_options['mod_id' ])
set_output('app_name' , build_options['app_name' ])
set_output('app_comment', build_options['app_comment'])
set_output('app_exe' , build_options['app_exe' ])
set_output('app_id' , build_options['app_id' ])
set_output('app_data' , build_options['app_data' ])
set_output('app_vendor' , build_options['app_vendor' ])
app_exe = build_options['app_exe']
app_name = build_options['app_name']
app_name_slug = re.sub('[^A-Za-z0-9]', '_', app_name)
build_matrix = []
publish_matrix = []
# consider disabling line wrapping to edit this monstrosity
for arch, platform, libc, statdyn, bplatform, runson, suffix, publish, artifact, dbgsuffix, mode, starcatcher, dbgrel, priority in [
( 'x86_64', 'linux', 'gnu', 'static', 'linux', 'ubuntu-20.04', '', False, False, None, None, None, 'debug', 0 ), # priority = 0: static debug build
( 'x86_64', 'linux', 'gnu', 'static', 'linux', 'ubuntu-20.04', '', True, True, '.dbg', None, 'x86_64-lin-gcc-static', 'release', 10 ),
( 'x86_64', 'linux', 'gnu', 'static', 'linux', 'ubuntu-20.04', '', False, True, '.dbg', 'appimage', None, 'release', 0 ), # priority = 0: appimage release
( 'x86_64', 'linux', 'gnu', 'dynamic', 'linux', 'ubuntu-20.04', '', False, False, None, None, None, 'debug', 10 ),
( 'x86_64', 'linux', 'gnu', 'dynamic', 'linux', 'ubuntu-20.04', '', False, False, None, 'nohttp', None, 'debug', 10 ),
( 'x86_64', 'linux', 'gnu', 'dynamic', 'linux', 'ubuntu-20.04', '', False, False, None, 'nolua', None, 'debug', 10 ),
( 'x86_64', 'linux', 'gnu', 'dynamic', 'linux', 'ubuntu-20.04', '', False, False, None, None, None, 'release', 10 ),
# ( 'x86_64', 'windows', 'mingw', 'static', 'linux', 'ubuntu-20.04', '', False, False, None, None, None, 'debug', 10 ), # ubuntu-20.04 doesn't have windows TLS headers somehow and I haven't yet figured out how to get them; worse, it's a different toolchain
# ( 'x86_64', 'windows', 'mingw', 'static', 'linux', 'ubuntu-20.04', '', False, True, '.dbg', None, None, 'release', 10 ), # ubuntu-20.04 doesn't have windows TLS headers somehow and I haven't yet figured out how to get them; worse, it's a different toolchain
# ( 'x86_64', 'windows', 'mingw', 'dynamic', 'linux', 'ubuntu-20.04', '', False, False, None, None, None, 'debug', 10 ), # ubuntu-20.04 doesn't have ucrt64-capable mingw >_>
# ( 'x86_64', 'windows', 'mingw', 'dynamic', 'linux', 'ubuntu-20.04', '', False, False, None, None, None, 'release', 10 ), # ubuntu-20.04 doesn't have ucrt64-capable mingw >_>
( 'x86_64', 'windows', 'mingw', 'static', 'windows', 'windows-2019', '.exe', False, False, None, None, None, 'debug', 0 ), # priority = 0: static debug build
( 'x86_64', 'windows', 'mingw', 'static', 'windows', 'windows-2019', '.exe', False, True, '.dbg', None, None, 'release', 10 ),
( 'x86_64', 'windows', 'mingw', 'dynamic', 'windows', 'windows-2019', '.exe', False, False, None, None, None, 'debug', 10 ),
( 'x86_64', 'windows', 'mingw', 'dynamic', 'windows', 'windows-2019', '.exe', False, False, None, None, None, 'release', 10 ),
( 'x86_64', 'windows', 'msvc', 'static', 'windows', 'windows-2019', '.exe', False, False, None, None, None, 'debug', 0 ), # priority = 0: static debug build
( 'x86_64', 'windows', 'msvc', 'static', 'windows', 'windows-2019', '.exe', True, True, '.pdb', None,'x86_64-win-msvc-static', 'release', 10 ),
( 'x86_64', 'windows', 'msvc', 'dynamic', 'windows', 'windows-2019', '.exe', False, False, None, None, None, 'debug', 10 ),
# ( 'x86_64', 'windows', 'msvc', 'dynamic', 'windows', 'windows-2019', '.exe', False, False, None, 'backendvs', None, 'debug', 0 ), # priority = 0: backend=vs build
( 'x86_64', 'windows', 'msvc', 'dynamic', 'windows', 'windows-2019', '.exe', False, False, None, None, None, 'release', 10 ),
( 'x86', 'windows', 'msvc', 'static', 'windows', 'windows-2019', '.exe', False, False, None, None, None, 'debug', 0 ), # priority = 0: static debug build
( 'x86', 'windows', 'msvc', 'static', 'windows', 'windows-2019', '.exe', True, True, '.pdb', None, 'i686-win-msvc-static', 'release', 10 ),
( 'x86', 'windows', 'msvc', 'dynamic', 'windows', 'windows-2019', '.exe', False, False, None, None, None, 'debug', 10 ),
( 'x86', 'windows', 'msvc', 'dynamic', 'windows', 'windows-2019', '.exe', False, False, None, None, None, 'release', 10 ),
( 'x86_64', 'darwin', 'macos', 'static', 'darwin', 'macos-12', '.dmg', False, False, None, 'dmg', None, 'debug', 0 ), # priority = 0: static debug build
( 'x86_64', 'darwin', 'macos', 'static', 'darwin', 'macos-12', '.dmg', True, True, None, 'dmg', 'x86_64-mac-gcc-static', 'release', 10 ), # I have no idea how to separate debug info on macos
( 'x86_64', 'darwin', 'macos', 'dynamic', 'darwin', 'macos-12', '.dmg', False, False, None, 'dmg', None, 'debug', 10 ),
( 'x86_64', 'darwin', 'macos', 'dynamic', 'darwin', 'macos-12', '.dmg', False, False, None, 'dmg', None, 'release', 10 ),
( 'aarch64', 'darwin', 'macos', 'static', 'darwin', 'macos-12', '.dmg', False, False, None, 'dmg', None, 'debug', 0 ), # priority = 0: static debug build
( 'aarch64', 'darwin', 'macos', 'static', 'darwin', 'macos-12', '.dmg', True, True, None, 'dmg', 'arm64-mac-gcc-static', 'release', 10 ),
# ( 'aarch64', 'darwin', 'macos', 'dynamic', 'darwin', 'macos-12', '.dmg', False, False, None, 'dmg', None, 'debug', 10 ), # macos-11.0 is x86_64 and I haven't yet figured out how to get homebrew to install aarch64 libs on x86_64
# ( 'aarch64', 'darwin', 'macos', 'dynamic', 'darwin', 'macos-12', '.dmg', False, False, None, 'dmg', None, 'release', 10 ), # macos-11.0 is x86_64 and I haven't yet figured out how to get homebrew to install aarch64 libs on x86_64
( 'x86', 'android', 'bionic', 'static', 'linux', 'ubuntu-20.04', '.apk', False, False, None, None, None, 'debug', 0 ), # priority = 0: rarely used debug build
( 'x86', 'android', 'bionic', 'static', 'linux', 'ubuntu-20.04', '.apk', True, True, '.dbg', None, 'i686-and-gcc-static', 'release', 10 ),
( 'x86_64', 'android', 'bionic', 'static', 'linux', 'ubuntu-20.04', '.apk', False, False, None, None, None, 'debug', 0 ), # priority = 0: rarely used debug build
( 'x86_64', 'android', 'bionic', 'static', 'linux', 'ubuntu-20.04', '.apk', True, True, '.dbg', None, 'x86_64-and-gcc-static', 'release', 10 ),
( 'arm', 'android', 'bionic', 'static', 'linux', 'ubuntu-20.04', '.apk', False, False, None, None, None, 'debug', 0 ), # priority = 0: rarely used debug build
( 'arm', 'android', 'bionic', 'static', 'linux', 'ubuntu-20.04', '.apk', True, True, '.dbg', None, 'arm-and-gcc-static', 'release', 10 ),
( 'aarch64', 'android', 'bionic', 'static', 'linux', 'ubuntu-20.04', '.apk', False, False, None, None, None, 'debug', 0 ), # priority = 0: rarely used debug build
( 'aarch64', 'android', 'bionic', 'static', 'linux', 'ubuntu-20.04', '.apk', True, True, '.dbg', None, 'arm64-and-gcc-static', 'release', 10 ),
( 'wasm32', 'emscripten', 'emscripten', 'static', 'linux', 'ubuntu-20.04', '.tar', False, False, None, None, None, 'debug', 0 ), # priority = 0: rarely used debug build
( 'wasm32', 'emscripten', 'emscripten', 'static', 'linux', 'ubuntu-20.04', '.tar', True, True, None, 'emscripten', 'wasm32-ems-static', 'release', 10 ), # I have no idea how to separate debug info on emscripten
]:
if priority < do_priority:
continue
job_name = f'build'
if starcatcher:
job_name += f'+target=starcatcher-{starcatcher}'
else:
job_name += f'+target={arch}-{platform}-{libc}-{statdyn}-{dbgrel}'
if mode:
job_name += f'+mode={mode}'
if bplatform != platform:
job_name += f'+bplatform={bplatform}'
if not mode:
mode = 'default'
separate_debug = True
if not dbgsuffix:
dbgsuffix = 'BOGUS'
separate_debug = False
if not starcatcher:
starcatcher = 'BOGUS'
if publish:
assert artifact
if dbgrel != 'release':
assert not publish
assert not artifact
asset_path = f'{app_exe}{suffix}'
asset_name = f'{app_exe}-{release_name}-{arch}-{platform}-{libc}{suffix}'
debug_asset_path = f'{app_exe}{dbgsuffix}'
debug_asset_name = f'{app_exe}-{release_name}-{arch}-{platform}-{libc}{dbgsuffix}'
if mode == 'appimage':
asset_path = f'{app_name_slug}-{arch}.AppImage'
asset_name = f'{app_name_slug}-{arch}.AppImage'
debug_asset_path = f'{app_name_slug}-{arch}.AppImage.dbg'
debug_asset_name = f'{app_name_slug}-{arch}.AppImage.dbg'
starcatcher_name = f'powder-{release_name}-{starcatcher}{suffix}'
msys2_bash = (bplatform == 'windows' and libc == 'mingw')
shell = 'bash'
if msys2_bash:
shell = 'msys2 {0}'
build_matrix.append({
'bsh_build_platform': bplatform, # part of the unique portion of the matrix
'bsh_host_arch': arch, # part of the unique portion of the matrix
'bsh_host_platform': platform, # part of the unique portion of the matrix
'bsh_host_libc': libc, # part of the unique portion of the matrix
'bsh_static_dynamic': statdyn, # part of the unique portion of the matrix
'bsh_debug_release': dbgrel, # part of the unique portion of the matrix
'runs_on': runson,
'force_msys2_bash': msys2_bash and 'yes' or 'no',
'package_suffix': suffix,
'package_mode': mode,
'publish': publish and 'yes' or 'no',
'artifact': artifact and 'yes' or 'no',
'separate_debug': separate_debug and 'yes' or 'no',
'asset_path': asset_path,
'asset_name': asset_name,
'debug_asset_path': debug_asset_path,
'debug_asset_name': debug_asset_name,
'job_name': job_name,
'shell': shell,
})
if publish:
publish_matrix.append({
'bsh_build_platform': bplatform, # part of the unique portion of the matrix
'bsh_host_arch': arch, # part of the unique portion of the matrix
'bsh_host_platform': platform, # part of the unique portion of the matrix
'bsh_host_libc': libc, # part of the unique portion of the matrix
'bsh_static_dynamic': statdyn, # part of the unique portion of the matrix
'asset_path': asset_path,
'asset_name': asset_name,
'starcatcher_name': starcatcher_name,
})
set_output('build_matrix', json.dumps({ 'include': build_matrix }))
set_output('publish_matrix', json.dumps({ 'include': publish_matrix }))
set_output('do_release', do_release and 'yes' or 'no')
set_output('do_publish', do_publish and 'yes' or 'no')

View File

@ -1,20 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
cat << NETRC > ~/.netrc
machine $(echo $PUBLISH_HOSTPORT | cut -d ':' -f 1)
login $PUBLISH_USERNAME
password $PUBLISH_PASSWORD
NETRC
chmod 660 ~/.netrc
mountpoint=ftpmnt
mkdir $mountpoint
curlftpfs "$PUBLISH_HOSTPORT" $mountpoint -o ssl,ciphers='ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-GCM-SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_128_CCM_SHA256'
if [[ -z ${PUBLISH_ACCESSCHECK-} ]]; then
cp $PUBLISH_FILENAME $mountpoint/${PUBLISH_DIRECTORY:-.}/
fi
fusermount -u $mountpoint
rmdir $mountpoint

View File

@ -1,10 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
curl "https://starcatcher.us/TPT/perform-release.lua?mod=$MOD_ID&type=$RELEASE_TYPE&name=$RELEASE_NAME&commit=$GITHUB_SHA" > perform_release
if ! grep "Release complete" < perform_release > /dev/null; then
cat perform_release
exit 1
fi

View File

@ -1,12 +0,0 @@
set -euo pipefail
IFS=$'\t\n'
temp=.temp
mkdir $temp
cp $ASSET_PATH $temp/$ASSET_NAME
(
cd $temp
gh release upload $GITHUB_REF_NAME $ASSET_NAME
)
rm -r $temp
echo browser_download_url=https://github.com/$GITHUB_REPOSITORY/releases/download/$GITHUB_REF_NAME/$ASSET_NAME >> $GITHUB_OUTPUT

31
.github/vs-env.sh vendored
View File

@ -1,31 +0,0 @@
set -euo pipefail
IFS=$'\t\n'
IFS=$'\t\n\r'
for i in $("$(env | grep '^ProgramFiles(x86)=' | cut -d = -f 2-)/Microsoft Visual Studio/Installer/vswhere.exe" \
-sort \
-prerelease \
-requiresAny \
-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 \
-requires Microsoft.VisualStudio.Workload.WDExpress \
-products \* \
-utf8 \
-property installationPath); do
if ! [ -z ${VS_ENV_FILTER-} ]; then
if ! echo $i | grep $VS_ENV_FILTER >/dev/null; then
continue
fi
fi
vs_install_dir=$i
break
done
IFS=$'\t\n'
for i in $(MSYS_NO_PATHCONV=1 cmd /c "$vs_install_dir\\VC\\Auxiliary\\Build\\vcvarsall.bat" $VS_ENV_PARAMS \& env \& exit /b); do
set +e
export "$i" 2>/dev/null
echo $i | grep ERROR
set -e
done
cl

View File

@ -1,182 +0,0 @@
name: build
on:
push:
branches:
- '*'
tags:
- 'v*.*'
- 'snapshot-*'
- 'tptlibsdev-*'
pull_request:
branches:
- '*'
jobs:
prepare:
runs-on: ubuntu-latest
outputs:
do_release: ${{ steps.prepare.outputs.do_release }}
build_matrix: ${{ steps.prepare.outputs.build_matrix }}
publish_matrix: ${{ steps.prepare.outputs.publish_matrix }}
release_type: ${{ steps.prepare.outputs.release_type }}
release_name: ${{ steps.prepare.outputs.release_name }}
mod_id: ${{ steps.prepare.outputs.mod_id }}
app_name: ${{ steps.prepare.outputs.app_name }}
app_comment: ${{ steps.prepare.outputs.app_comment }}
app_exe: ${{ steps.prepare.outputs.app_exe }}
app_id: ${{ steps.prepare.outputs.app_id }}
app_data: ${{ steps.prepare.outputs.app_data }}
app_vendor: ${{ steps.prepare.outputs.app_vendor }}
do_publish: ${{ steps.prepare.outputs.do_publish }}
steps:
- run: git config --global core.autocrlf false
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.10'
- run: python -m pip install meson==1.2.3 ninja # TODO: go back to using latest meson once https://github.com/mesonbuild/meson/pull/12544 is live
- id: prepare
run: python ./.github/prepare.py
env:
PUBLISH_HOSTPORT: ${{ secrets.STARCATCHER_PUBLISH_HOSTPORT }}
GITHUB_REF: ${{ github.ref }}
- if: steps.prepare.outputs.do_publish == 'yes'
run: sudo apt update && sudo apt install curlftpfs && bash -c './.github/starcatcher-publish.sh'
env:
PUBLISH_HOSTPORT: ${{ secrets.STARCATCHER_PUBLISH_HOSTPORT }}
PUBLISH_USERNAME: ${{ secrets.STARCATCHER_PUBLISH_USERNAME }}
PUBLISH_PASSWORD: ${{ secrets.STARCATCHER_PUBLISH_PASSWORD }}
PUBLISH_ACCESSCHECK: yes
- if: steps.prepare.outputs.do_release == 'yes'
id: create_release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RELEASE_NAME: ${{ steps.prepare.outputs.release_name }}
run: bash -c './.github/create-release.sh'
build:
runs-on: ${{ matrix.runs_on }}
name: ${{ matrix.job_name }}
needs: [prepare]
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.prepare.outputs.build_matrix) }}
defaults:
run:
shell: ${{ matrix.shell }}
steps:
- if: matrix.force_msys2_bash == 'yes'
uses: msys2/setup-msys2@v2
with:
msystem: UCRT64
update: true
path-type: strict
cache: true
# this list doesn't have to mirror the one in build.sh perfectly
# but the packages listed here get cached properly and take less time to install
install: >-
git
curl
mingw-w64-ucrt-x86_64-gcc
mingw-w64-ucrt-x86_64-pkgconf
mingw-w64-ucrt-x86_64-bzip2
mingw-w64-ucrt-x86_64-luajit
mingw-w64-ucrt-x86_64-jsoncpp
mingw-w64-ucrt-x86_64-curl
mingw-w64-ucrt-x86_64-SDL2
mingw-w64-ucrt-x86_64-libpng
mingw-w64-ucrt-x86_64-meson
mingw-w64-ucrt-x86_64-python
mingw-w64-ucrt-x86_64-python-pip
mingw-w64-ucrt-x86_64-fftw
mingw-w64-ucrt-x86_64-cmake
mingw-w64-ucrt-x86_64-7zip
mingw-w64-ucrt-x86_64-jq
patch
- run: git config --global core.autocrlf false
- uses: actions/checkout@v4
- if: matrix.force_msys2_bash != 'yes'
uses: actions/setup-python@v5
with:
python-version: '3.10'
- if: matrix.force_msys2_bash != 'yes'
run: python -m pip install meson==1.2.3 ninja # TODO: go back to using latest meson once https://github.com/mesonbuild/meson/pull/12544 is live
- if: matrix.bsh_build_platform == 'darwin'
run: brew install bash coreutils
- run: bash -c './.github/build.sh'
env:
BSH_HOST_ARCH: ${{ matrix.bsh_host_arch }}
BSH_HOST_PLATFORM: ${{ matrix.bsh_host_platform }}
BSH_HOST_LIBC: ${{ matrix.bsh_host_libc }}
BSH_STATIC_DYNAMIC: ${{ matrix.bsh_static_dynamic }}
BSH_BUILD_PLATFORM: ${{ matrix.bsh_build_platform }}
BSH_DEBUG_RELEASE: ${{ matrix.bsh_debug_release }}
RELEASE_NAME: ${{ needs.prepare.outputs.release_name }}
RELEASE_TYPE: ${{ needs.prepare.outputs.release_type }}
MOD_ID: ${{ needs.prepare.outputs.mod_id }}
APP_NAME: ${{ needs.prepare.outputs.app_name }}
APP_COMMENT: ${{ needs.prepare.outputs.app_comment }}
APP_EXE: ${{ needs.prepare.outputs.app_exe }}
APP_ID: ${{ needs.prepare.outputs.app_id }}
APP_DATA: ${{ needs.prepare.outputs.app_data }}
APP_VENDOR: ${{ needs.prepare.outputs.app_vendor }}
SEPARATE_DEBUG: ${{ matrix.separate_debug }}
PACKAGE_MODE: ${{ matrix.package_mode }}
ASSET_PATH: ${{ matrix.asset_path }}
DEBUG_ASSET_PATH: ${{ matrix.debug_asset_path }}
- if: needs.prepare.outputs.do_release == 'yes' && matrix.publish == 'yes' # TODO-NTL: ship licenses
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ASSET_PATH: build/${{ matrix.asset_path }}
ASSET_NAME: ${{ matrix.asset_name }}
run: bash -c './.github/upload-release-asset.sh'
- if: needs.prepare.outputs.do_release == 'yes' && matrix.publish == 'yes' && matrix.separate_debug == 'yes'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ASSET_PATH: build/${{ matrix.debug_asset_path }}
ASSET_NAME: ${{ matrix.debug_asset_name }}
run: bash -c './.github/upload-release-asset.sh'
- uses: actions/upload-artifact@v4
if: matrix.artifact == 'yes'
with:
path: build/${{ matrix.asset_path }}
name: ${{ matrix.asset_name }}
- uses: actions/upload-artifact@v4
if: matrix.artifact == 'yes' && matrix.separate_debug == 'yes'
with:
path: build/${{ matrix.debug_asset_path }}
name: ${{ matrix.debug_asset_name }}
publish:
runs-on: ubuntu-latest
needs: [build, prepare]
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.prepare.outputs.publish_matrix) }}
if: needs.prepare.outputs.do_publish == 'yes'
steps:
- run: git config --global core.autocrlf false
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: ${{ matrix.asset_name }}
- run: mv ${{ matrix.asset_path }} ${{ matrix.starcatcher_name }}
- run: sudo apt update && sudo apt install curlftpfs && bash -c './.github/starcatcher-publish.sh'
env:
PUBLISH_HOSTPORT: ${{ secrets.STARCATCHER_PUBLISH_HOSTPORT }}
PUBLISH_USERNAME: ${{ secrets.STARCATCHER_PUBLISH_USERNAME }}
PUBLISH_PASSWORD: ${{ secrets.STARCATCHER_PUBLISH_PASSWORD }}
PUBLISH_DIRECTORY: ${{ secrets.STARCATCHER_PUBLISH_DIRECTORY }}
PUBLISH_FILENAME: ${{ matrix.starcatcher_name }}
release:
runs-on: ubuntu-latest
needs: [build, publish, prepare]
if: needs.prepare.outputs.do_publish == 'yes'
steps:
- run: git config --global core.autocrlf false
- uses: actions/checkout@v4
- run: ./.github/starcatcher-release.sh
env:
RELEASE_NAME: ${{ needs.prepare.outputs.release_name }}
RELEASE_TYPE: ${{ needs.prepare.outputs.release_type }}
MOD_ID: ${{ needs.prepare.outputs.mod_id }}
GITHUB_SHA: ${{ github.sha }}

84
.gitignore vendored
View File

@ -1,47 +1,30 @@
# Misc extensions, system files
*.zip
*.txt
*.gz
*.out
*.sh
*.py
*.png
*.ppm
*nohup.out
*.swp
*~
.DS_Store
# Build files
build*/*
*.o
*.exe
*.dmg
*.user
*.dll
*.a
*.la
# Legacy SCons files
config.log
*.sconsign.dblite
*.sconf_temp
/site_scons/
/generated/
# User data
/stamps/
/Saves/
/scripts/
/recordings/
*.def
*~
*.pref
*.lua
screenshot_*
# Visual studio
/Debug/
/Release/
/includes/
stdout.txt
stderr.txt
build/*
stamps/*
Saves/*
generated/*
includes/*
generate
Makefile.me
*.xcodeproj
.DS_Store
*.plist
*.lproj
*.vcxproj*
*.opensdf
*.sdf
*.user
*.filter
*.sln
@ -55,40 +38,21 @@ screenshot_*
*.tlog
*.lib
*.ipch
*.ilk
*.log
*.lastbuildstate
*.unsuccessfulbuild
*.pdb
*.db
# QtCreator / KDevelop
*.user
*.config
*.creator*
*.cflags
*.cxxflags
*.files
*.includes
*.kdev4
/.kdev4
# Other IDEs / misc
.vscode/
.vs/
*.sublime-*
*.project
*.cproject
*.settings
*.cbp
*.layout
config.log
*.sconsign.dblite
*.sconf_temp
*.gch
*.pyc
*.xcodeproj
*.plist
*.lproj
*.opensdf
*.sdf
/font/
compile_commands.json
ignore/
site_scons/site_tools/mfprogram/*.pyc
site_scons/site_tools/gch/*.pyc
others*

19
Changelog.txt Normal file
View File

@ -0,0 +1,19 @@
- Special brush types
- Special brush delete
- LOVE
- LOLZ
- Property edit
- Saving, loading, thumbnailing, etc
- HEAT/COOL
- Streamlines
- Grid
- Sign moving
- Electron fancyness with glass, fire_r-g-b now out of scope
- Grav fancyness, use current frame index to determine colour, not globals!
- Emp flash
- Stickman HP
To do:
See TODO's
Char * and string, hmm....
Vectors for things like signs, stamp list, etc where appropriate

99
README Normal file
View File

@ -0,0 +1,99 @@
The Powder Toy - November 2012
Get the latest version here: http://powdertoy.co.uk/Download.html
To use online features such as saving, you need to register at: http://powdertoy.co.uk/Register.html
Have you ever wanted to blow something up? Or maybe you always dreamt of operating an atomic power plant? Do you have a will to develop your own CPU? The Powder Toy lets you to do all of these, and even more!
The Powder Toy is a free physics sandbox game, which simulates air pressure and velocity, heat, gravity and a countless number of interactions between different substances! The game provides you with various building materials, liquids, gases and electronic components which can be used to construct complex machines, guns, bombs, realistic terrains and almost anything else. You can then mine them and watch cool explosions, add intricate wirings, play with little stickmen or operate your machine. You can browse and play thousands of different saves made by the community or upload your own we welcome your creations!
There is a Lua API you can automate your work or even make plugins for the game. The Powder Toy is free and the source code is distributed under the GNU General Public License, so you can modify the game yourself or help with development. Tpt is compiled using scons.
Thanks:
---------------------------------------------------------------------------
Stanislaw K Skowronek - Designed the original
Simon Robertshaw
Skresanov Savely
cracker64
Catelite
Bryan Hoyle
Nathan Cousins
jacksonmj
Lieuwe Mosch
Anthony Boot
Matthew Miller
MaksProg
jacob1
Instructions:
---------------------------------------------------------------------------
Click on the elements with the mouse and draw in the field, like in MS Paint. The rest of the game is learning what happens next.
Controls:
---------------------------------------------------------------------------
TAB Switch between circle/square/triangle brush
Space Pause
Q Quit
Esc Quit
Z Zoom
S Save stamp (+ Ctrl when STK2 is out)
L Load last saved stamp
K Stamp library
1-9 Set view mode
P Save screenshot to .png
F Pause and go to next frame
G Increase grid size
Shift + G Decrease grid size
H Show/Hide HUD
Ctrl + H Show intro text
F1 Show intro text
D Debug mode (+ Ctrl when STK2 is out)
I Invert Pressure and Velocity map
W Toggle gravity modes (+ Ctrl when STK2 is out)
Y Toggle air modes
Ctrl + B Toggle decorations on/off
U Toggle ambient heat on/off
Ctrl + I Install powder toy, for loading saves/stamps by double clicking
~ Console
= Reset pressure and velocity map
Ctrl + = Reset Electricity
[ Decrease brush size
] Increase brush size
Alt + [ Decrease brush size by 1
Alt + ] Increase brush size by 1
Ctrl + C/V/X Copy/Paste/Cut
Ctrl + Z Undo
Ctrl + Cursor drag Rectangle
Shift + Cursor drag Line
Middle click Sample element
Alt + Left click Sample element
Mouse scroll Change brush size
Ctrl + Mouse scroll Change vertical brush size
Shift + Mouse scroll Change horizontal brush size
Shift + Ctrl + R Horizontal mirror for selected area
Ctrl + R Rotate selected area counterclockwise
Only the left Ctrl, Shift, and Alt buttons are enabled to work, not the ones on the right
Command Line:
---------------------------------------------------------------------------
scale:1 Normal window resolution
scale:2 Doubled window resolution
kiosk Fullscreen mode
proxy:server[:port] Proxy server to use [Example: proxy:wwwcache.lancs.ac.uk:8080]
open <file> Opens the file as a stamp or game save
ddir <directory> Directory used for saving stamps and preferences
ptsave:<save id>#<name(Optional)> (ex. ptsave:2198#Destroyable_city_5_wth_metro~dima-gord)

128
README.md
View File

@ -1,128 +0,0 @@
The Powder Toy - April 2024
==========================
Get the latest version [from the Powder Toy website](https://powdertoy.co.uk/Download.html).
To use online features such as saving, you need to [register an account](https://powdertoy.co.uk/Register.html).
You can also visit [the official TPT forum](https://powdertoy.co.uk/Discussions/Categories/Index.html).
Have you ever wanted to blow something up? Or maybe you always dreamt of operating an atomic power plant? Do you have a will to develop your own CPU? The Powder Toy lets you to do all of these, and even more!
The Powder Toy is a free physics sandbox game, which simulates air pressure and velocity, heat, gravity and a countless number of interactions between different substances! The game provides you with various building materials, liquids, gases and electronic components which can be used to construct complex machines, guns, bombs, realistic terrains and almost anything else. You can then mine them and watch cool explosions, add intricate wirings, play with little stickmen or operate your machine. You can browse and play thousands of different saves made by the community or upload your own we welcome your creations!
There is a Lua API you can automate your work or even make plugins for the game. The Powder Toy is free and the source code is distributed under the GNU General Public License, so you can modify the game yourself or help with development.
Build instructions
===========================================================================
See the _Powder Toy Development Help_ section [on the main page of the wiki](https://powdertoy.co.uk/Wiki/W/Main_Page.html).
Thanks
===========================================================================
* Stanislaw K Skowronek - Designed the original
* Simon Robertshaw
* Skresanov Savely
* cracker64
* Catelite
* Victoria Hoyle
* Nathan Cousins
* jacksonmj
* Felix Wallin
* Lieuwe Mosch
* Anthony Boot
* Me4502
* MaksProg
* jacob1
* mniip
* LBPHacker
Libraries and other assets used
===========================================================================
* [BSON](https://github.com/interactive-matter/bson-c)
* [bzip2](http://www.bzip.org/)
* [FFTW](http://fftw.org/)
* [JsonCpp](https://github.com/open-source-parsers/jsoncpp)
* [libcurl](https://curl.se/libcurl/)
* [libpng](http://www.libpng.org/pub/png/libpng.html)
* [Lua](https://www.lua.org/)
* [LuaJIT](https://luajit.org/)
* [Mallangche](https://github.com/JammPark/Mallangche)
* [mbedtls](https://www.trustedfirmware.org/projects/mbed-tls/)
* [SDL](https://libsdl.org/)
* [zlib](https://www.zlib.net/)
Instructions
===========================================================================
Click on the elements with the mouse and draw in the field, like in MS Paint. The rest of the game is learning what happens next.
Controls
===========================================================================
| Key | Action |
| ----------------------- | --------------------------------------------------------------- |
| TAB | Switch between circle/square/triangle brush |
| Space | Pause |
| Q / Esc | Quit |
| Z | Zoom |
| S | Save stamp (use with Ctrl when STK2 is out) |
| L | Load last saved stamp |
| K | Stamp library |
| 0-9 | Set view mode |
| P / F2 | Save screenshot as .png |
| E | Bring up element search |
| F | Pause and step to next frame |
| G | Increase grid size |
| Shift + G | Decrease grid size |
| H | Show/Hide HUD |
| Ctrl + H / F1 | Show intro text |
| D / F3 | Debug mode (use with Ctrl when STK2 is out) |
| I | Invert Pressure and Velocity map |
| W | Cycle gravity modes (use with Ctrl when STK2 is out) |
| Y | Cycle air modes |
| Ctrl + E | Cycle edge modes |
| B | Enter decoration editor menu |
| Ctrl + B | Toggle decorations on/off |
| N | Toggle Newtonian Gravity on/off |
| U | Toggle ambient heat on/off |
| Ctrl + I | Install powder toy, for loading saves/stamps by double clicking |
| Backtick | Toggle console |
| = | Reset pressure and velocity map |
| Ctrl + = | Reset Electricity |
| \[ | Decrease brush size |
| \] | Increase brush size |
| Alt + \[ | Decrease brush size by 1 |
| Alt + \] | Increase brush size by 1 |
| Ctrl + C/V/X | Copy/Paste/Cut |
| Ctrl + Z | Undo |
| Ctrl + Y | Redo |
| Ctrl + Cursor drag | Rectangle |
| Shift + Cursor drag | Line |
| Middle click | Sample element |
| Alt + Left click | Sample element |
| Mouse scroll | Change brush size |
| Ctrl + Mouse scroll | Change vertical brush size |
| Shift + Mouse scroll | Change horizontal brush size |
| Shift + R | Horizontal mirror for selected area when pasting stamps |
| Ctrl + Shift + R | Vertical mirror for selected area when pasting stamps |
| R | Rotate selected area counterclockwise when pasting stamps |
| F11 | Toggle fullscreen |
Command Line
---------------------------------------------------------------------------
| Command | Description | Example |
| --------------------- | ------------------------------------------------ | --------------------------------------------|
| `scale:SIZE` | Change window scale factor | `scale:2` |
| `kiosk` | Fullscreen mode | |
| `proxy:SERVER[:PORT]` | Proxy server to use | `proxy:wwwcache.lancs.ac.uk:8080` |
| `open FILE` | Opens the file as a stamp or game save | |
| `ddir DIRECTORY` | Directory used for saving stamps and preferences | |
| `ptsave:SAVEID` | Open online save, used by ptsave: URLs | `ptsave:2198` |
| `disable-network` | Disables internet connections | |
| `disable-bluescreen` | Disable bluescreen handler | |
| `redirect` | Redirects output to stdout.txt / stderr.txt | |
| `cafile:CAFILE` | Set certificate bundle path | `cafile:/etc/ssl/certs/ca-certificates.crt` |
| `capath:CAPATH` | Set certificate directory path | `capath:/etc/ssl/certs` |

323
SConscript Normal file
View File

@ -0,0 +1,323 @@
import os, sys, subprocess, time
##Fix for long command line - http://scons.org/wiki/LongCmdLinesOnWin32
class ourSpawn:
def ourspawn(self, sh, escape, cmd, args, env):
newargs = ' '.join(args[1:])
cmdline = cmd + " " + newargs
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
proc = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, startupinfo=startupinfo, shell = False, env = env)
data, err = proc.communicate()
rv = proc.wait()
if rv:
print "====="
print err
print "====="
return rv
def SetupSpawn( env ):
if sys.platform == 'win32':
buf = ourSpawn()
buf.ourenv = env
env['SPAWN'] = buf.ourspawn
AddOption('--opengl',dest="opengl",action='store_true',default=False,help="Build with OpenGL interface support.")
AddOption('--opengl-renderer',dest="opengl-renderer",action='store_true',default=False,help="Build with OpenGL renderer support. (requires --opengl)")
AddOption('--renderer',dest="renderer",action='store_true',default=False,help="Save renderer")
AddOption('--win',dest="win",action='store_true',default=False,help="Windows platform target.")
AddOption('--lin',dest="lin",action='store_true',default=False,help="Linux platform target")
AddOption('--macosx',dest="macosx",action='store_true',default=False,help="Mac OS X platform target")
AddOption('--rpi',dest="rpi",action='store_true',default=False,help="Raspbain platform target")
AddOption('--64bit',dest="_64bit",action='store_true',default=False,help="64-bit platform target")
AddOption('--static',dest="static",action="store_true",default=False,help="Static linking, reduces external library dependancies but increased file size")
AddOption('--pthreadw32-static',dest="ptw32-static",action="store_true",default=False,help="Use PTW32_STATIC_LIB for pthreadw32 headers")
AddOption('--python-ver',dest="pythonver",default=False,help="Python version to use for generator.py")
AddOption('--release',dest="release",action='store_true',default=False,help="Enable optimisations (Will slow down compiling)")
AddOption('--lua-dir',dest="lua-dir",default=False,help="Directory for lua includes")
AddOption('--sdl-dir',dest="sdl-dir",default=False,help="Directory for SDL includes")
AddOption('--tool',dest="toolprefix",default=False,help="Prefix")
AddOption('--sse',dest="sse",action='store_true',default=False,help="Enable SSE optimisations")
AddOption('--sse2',dest="sse2",action='store_true',default=False,help="Enable SSE2 optimisations")
AddOption('--sse3',dest="sse3",action='store_true',default=False,help="Enable SSE3 optimisations")
AddOption('--x86',dest="x86",action='store_true',default=True,help="Target Intel x86 platform")
AddOption('--debugging', dest="debug", action="store_true", default=False, help="Enable debug options")
AddOption('--beta',dest="beta",action='store_true',default=False,help="Beta build.")
AddOption('--save-version',dest="save-version",default=False,help="Save version.")
AddOption('--minor-version',dest="minor-version",default=False,help="Minor version.")
AddOption('--build-number',dest="build-number",default=False,help="Build number.")
AddOption('--snapshot',dest="snapshot",action='store_true',default=False,help="Snapshot build.")
AddOption('--snapshot-id',dest="snapshot-id",default=False,help="Snapshot build ID.")
AddOption('--stable',dest="stable",default=True,help="Non snapshot build")
AddOption('--aao', dest="everythingAtOnce", action='store_true', default=False, help="Compile the whole game without generating intermediate objects (very slow), enable this when using compilers like clang or mscc that don't support -fkeep-inline-functions")
if((not GetOption('lin')) and (not GetOption('win')) and (not GetOption('rpi')) and (not GetOption('macosx'))):
print "You must specify a platform to target"
raise SystemExit(1)
if(GetOption('win')):
env = Environment(tools = ['mingw'], ENV = os.environ)
else:
env = Environment(tools = ['default'], ENV = os.environ)
if GetOption("toolprefix"):
env['CC'] = GetOption("toolprefix")+env['CC']
env['CXX'] = GetOption("toolprefix")+env['CXX']
if GetOption('win'):
env['RC'] = GetOption("toolprefix")+env['RC']
#Check for headers and libraries
if not GetOption("macosx"):
conf = Configure(env)
try:
env.ParseConfig('sdl-config --cflags')
env.ParseConfig('sdl-config --libs')
except:
if not conf.CheckLib("SDL"):
print "libSDL not found or not installed"
raise SystemExit(1)
if(GetOption("sdl-dir")):
if not conf.CheckCHeader(GetOption("sdl-dir") + '/SDL.h'):
print "sdl headers not found or not installed"
raise SystemExit(1)
else:
env.Append(CPPPATH=[GetOption("sdl-dir")])
#Find correct lua include dir
try:
env.ParseConfig('pkg-config --cflags lua5.1')
except:
if(GetOption("lua-dir")):
if not conf.CheckCHeader(GetOption("lua-dir") + '/lua.h'):
print "lua5.1 headers not found or not installed"
raise SystemExit(1)
else:
env.Append(CPPPATH=[GetOption("lua-dir")])
#Check for FFT lib
if not conf.CheckLib('fftw3f') and not conf.CheckLib('fftw3f-3'):
print "libfftw3f not found or not installed"
raise SystemExit(1)
#Check for Bzip lib
if not conf.CheckLib('bz2'):
print "libbz2 not found or not installed"
raise SystemExit(1)
#Check for zlib
if not conf.CheckLib('z'):
print "libz not found or not installed"
raise SystemExit(1)
if not conf.CheckCHeader("bzlib.h"):
print "bzip2 headers not found"
raise SystemExit(1)
#Check for Lua lib
if not GetOption("macosx"):
if not conf.CheckLib('lua5.1') and not conf.CheckLib('lua-5.1') and not conf.CheckLib('lua51') and not conf.CheckLib('lua'):
print "liblua not found or not installed"
raise SystemExit(1)
env = conf.Finish();
else:
env.Append(LIBS=['z', 'bz2', 'fftw3f'])
env.Append(CPPPATH=['src/', 'data/', 'generated/'])
env.Append(CCFLAGS=['-w', '-std=c++98', '-fkeep-inline-functions'])
env.Append(LIBS=['pthread', 'm'])
env.Append(CPPDEFINES=["LUACONSOLE", "GRAVFFT", "_GNU_SOURCE", "USE_STDINT", "_POSIX_C_SOURCE=200112L"])
if GetOption("ptw32-static"):
env.Append(CPPDEFINES=['PTW32_STATIC_LIB']);
if(GetOption('static')):
env.Append(LINKFLAGS=['-static-libgcc'])
if(GetOption('renderer')):
env.Append(CPPDEFINES=['RENDERER'])
else:
env.Append(CPPDEFINES=["USE_SDL"])
if(GetOption('rpi')):
if(GetOption('opengl')):
env.ParseConfig('pkg-config --libs glew gl glu')
openGLLibs = ['GL']
env.Append(LIBS=['X11', 'rt'])
env.Append(CPPDEFINES=["LIN"])
if(GetOption('win')):
openGLLibs = ['opengl32', 'glew32']
env.Prepend(LIBS=['mingw32', 'ws2_32', 'SDLmain', 'regex'])
env.Append(CCFLAGS=['-std=gnu++98'])
env.Append(LIBS=['winmm', 'gdi32'])
env.Append(CPPDEFINES=["WIN"])
env.Append(LINKFLAGS=['-mwindows'])
if(GetOption('_64bit')):
env.Append(CPPDEFINES=['__CRT__NO_INLINE'])
env.Append(LINKFLAGS=['-Wl,--stack=16777216'])
if(GetOption('lin')):
if(GetOption('opengl')):
env.ParseConfig('pkg-config --libs glew gl glu')
openGLLibs = ['GL']
env.Append(LIBS=['X11', 'rt'])
env.Append(CPPDEFINES=["LIN"])
if GetOption('_64bit'):
env.Append(LINKFLAGS=['-m64'])
env.Append(CCFLAGS=['-m64'])
else:
env.Append(LINKFLAGS=['-m32'])
env.Append(CCFLAGS=['-m32'])
if(GetOption('macosx')):
env.Append(CPPDEFINES=["MACOSX"])
env.Append(CCFLAGS=['-I/Library/Frameworks/SDL.framework/Headers'])
env.Append(CCFLAGS=['-I/Library/Frameworks/Lua.framework/Headers'])
env.Append(LINKFLAGS=['-lfftw3f'])
env.Append(LINKFLAGS=['-framework'])
env.Append(LINKFLAGS=['SDL'])
env.Append(LINKFLAGS=['-framework'])
env.Append(LINKFLAGS=['Lua'])
env.Append(LINKFLAGS=['-framework']);
env.Append(LINKFLAGS=['Cocoa'])
#env.Append(LINKFLAGS=['-framework SDL'])
#env.Append(LINKFLAGS=['-framework Lua'])
#env.Append(LINKFLAGS=['-framework Cocoa'])
if GetOption('_64bit'):
env.Append(LINKFLAGS=['-m64'])
env.Append(CCFLAGS=['-m64'])
else:
env.Append(LINKFLAGS=['-m32'])
env.Append(CCFLAGS=['-m32'])
if GetOption('_64bit'):
env.Append(CPPDEFINES=["_64BIT"])
if(GetOption('beta')):
env.Append(CPPDEFINES='BETA')
if(not GetOption('snapshot') and not GetOption('beta') and not GetOption('release') and not GetOption('stable')):
env.Append(CPPDEFINES='SNAPSHOT_ID=0')
env.Append(CPPDEFINES='SNAPSHOT')
elif(GetOption('snapshot') or GetOption('snapshot-id')):
if(GetOption('snapshot-id')):
env.Append(CPPDEFINES=['SNAPSHOT_ID=' + GetOption('snapshot-id')])
else:
env.Append(CPPDEFINES=['SNAPSHOT_ID=' + str(int(time.time()))])
env.Append(CPPDEFINES='SNAPSHOT')
elif(GetOption('stable')):
env.Append(CPPDEFINES='STABLE')
if(GetOption('save-version')):
env.Append(CPPDEFINES=['SAVE_VERSION=' + GetOption('save-version')])
if(GetOption('minor-version')):
env.Append(CPPDEFINES=['MINOR_VERSION=' + GetOption('minor-version')])
if(GetOption('build-number')):
env.Append(CPPDEFINES=['BUILD_NUM=' + GetOption('build-number')])
if(GetOption('x86')):
env.Append(CPPDEFINES='X86')
if(GetOption('debug')):
env.Append(CPPDEFINES='DEBUG')
env.Append(CCFLAGS='-g')
if(GetOption('sse')):
env.Append(CCFLAGS='-msse')
env.Append(CPPDEFINES='X86_SSE')
if(GetOption('sse2')):
env.Append(CCFLAGS='-msse2')
env.Append(CPPDEFINES='X86_SSE2')
if(GetOption('sse3')):
env.Append(CCFLAGS='-msse3')
env.Append(CPPDEFINES='X86_SSE3')
if(GetOption('opengl')):
env.Append(CPPDEFINES=["OGLI", "PIX32OGL"])
env.Append(LIBS=openGLLibs)
if(GetOption('opengl') and GetOption('opengl-renderer')):
env.Append(CPPDEFINES=["OGLR"])
elif(GetOption('opengl-renderer')):
print "opengl-renderer requires opengl"
raise SystemExit(1)
sources=Glob("src/*.cpp")
if(GetOption('macosx')):
sources +=["SDLMain.m"]
if(GetOption('win')):
sources += env.RES('resources/powder-res.rc')
sources+=Glob("src/*/*.cpp")
sources+=Glob("src/simulation/elements/*.cpp")
sources+=Glob("src/simulation/tools/*.cpp")
#for source in sources:
# print str(source)
if(GetOption('win')):
sources = filter(lambda source: not 'src\\simulation\\Gravity.cpp' in str(source), sources)
sources = filter(lambda source: not 'src/simulation/Gravity.cpp' in str(source), sources)
SetupSpawn(env)
programName = "powder"
if(GetOption('renderer')):
programName = "render"
if(GetOption('win')):
if(GetOption('renderer')):
programName = "Render"
else:
programName = "Powder"
if(GetOption('_64bit')):
programName += "64"
if(not (GetOption('sse2') or GetOption('sse3'))):
programName += "-legacy"
if(GetOption('macosx')):
programName += "-x"
if(GetOption('win')):
programName += ".exe"
if(GetOption('release')):
if GetOption('macosx'):
env.Append(CCFLAGS=['-O3', '-ftree-vectorize', '-funsafe-math-optimizations', '-ffast-math', '-fomit-frame-pointer'])
else:
env.Append(CCFLAGS=['-O3', '-ftree-vectorize', '-funsafe-math-optimizations', '-ffast-math', '-fomit-frame-pointer', '-funsafe-loop-optimizations', '-Wunsafe-loop-optimizations'])
if(GetOption('pythonver')):
pythonVer = GetOption('pythonver')
elif(GetOption('lin')):
pythonVer = "python2"
else:
pythonVer = "python"
if(GetOption('win')):
envCopy = env.Clone()
envCopy.Append(CCFLAGS=['-mincoming-stack-boundary=2'])
sources+=envCopy.Object('src/simulation/Gravity.cpp')
env.Command(['generated/ElementClasses.cpp', 'generated/ElementClasses.h'], Glob('src/simulation/elements/*.cpp'), pythonVer + " generator.py elements $TARGETS $SOURCES")
sources+=Glob("generated/ElementClasses.cpp")
env.Command(['generated/ToolClasses.cpp', 'generated/ToolClasses.h'], Glob('src/simulation/tools/*.cpp'), pythonVer + " generator.py tools $TARGETS $SOURCES")
sources+=Glob("generated/ToolClasses.cpp")
env.Decider('MD5')
t=env.Program(target=programName, source=sources)
Default(t)

1
SConstruct Normal file
View File

@ -0,0 +1 @@
SConscript('SConscript', variant_dir='build', duplicate=0)

16
SDLMain.h Normal file
View File

@ -0,0 +1,16 @@
/* SDLMain.m - main entry point for our Cocoa-ized SDL app
Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
Non-NIB-Code & other changes: Max Horn <max@quendi.de>
Feel free to customize this file to suit your needs
*/
#ifndef _SDLMain_h_
#define _SDLMain_h_
#import <Cocoa/Cocoa.h>
@interface SDLMain : NSObject
@end
#endif /* _SDLMain_h_ */

381
SDLMain.m Normal file
View File

@ -0,0 +1,381 @@
/* SDLMain.m - main entry point for our Cocoa-ized SDL app
Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
Non-NIB-Code & other changes: Max Horn <max@quendi.de>
Feel free to customize this file to suit your needs
*/
#include "SDL.h"
#include "SDLMain.h"
#include <sys/param.h> /* for MAXPATHLEN */
#include <unistd.h>
/* For some reaon, Apple removed setAppleMenu from the headers in 10.4,
but the method still is there and works. To avoid warnings, we declare
it ourselves here. */
@interface NSApplication(SDL_Missing_Methods)
- (void)setAppleMenu:(NSMenu *)menu;
@end
/* Use this flag to determine whether we use SDLMain.nib or not */
#define SDL_USE_NIB_FILE 0
/* Use this flag to determine whether we use CPS (docking) or not */
#define SDL_USE_CPS 1
#ifdef SDL_USE_CPS
/* Portions of CPS.h */
typedef struct CPSProcessSerNum
{
UInt32 lo;
UInt32 hi;
} CPSProcessSerNum;
extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn);
extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn);
#endif /* SDL_USE_CPS */
static int gArgc;
static char **gArgv;
static BOOL gFinderLaunch;
static BOOL gCalledAppMainline = FALSE;
static NSString *getApplicationName(void)
{
const NSDictionary *dict;
NSString *appName = 0;
/* Determine the application name */
dict = (const NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle());
if (dict)
appName = [dict objectForKey: @"CFBundleName"];
if (![appName length])
appName = [[NSProcessInfo processInfo] processName];
return appName;
}
#if SDL_USE_NIB_FILE
/* A helper category for NSString */
@interface NSString (ReplaceSubString)
- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString;
@end
#endif
@interface NSApplication (SDLApplication)
@end
@implementation NSApplication (SDLApplication)
/* Invoked from the Quit menu item */
- (void)terminate:(id)sender
{
/* Post a SDL_QUIT event */
SDL_Event event;
event.type = SDL_QUIT;
SDL_PushEvent(&event);
}
@end
/* The main class of the application, the application's delegate */
@implementation SDLMain
/* Set the working directory to the .app's parent directory */
- (void) setupWorkingDirectory:(BOOL)shouldChdir
{
if (shouldChdir)
{
char parentdir[MAXPATHLEN];
CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url);
if (CFURLGetFileSystemRepresentation(url2, 1, (UInt8 *)parentdir, MAXPATHLEN)) {
chdir(parentdir); /* chdir to the binary app's parent */
}
CFRelease(url);
CFRelease(url2);
}
}
#if SDL_USE_NIB_FILE
/* Fix menu to contain the real app name instead of "SDL App" */
- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName
{
NSRange aRange;
NSEnumerator *enumerator;
NSMenuItem *menuItem;
aRange = [[aMenu title] rangeOfString:@"SDL App"];
if (aRange.length != 0)
[aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]];
enumerator = [[aMenu itemArray] objectEnumerator];
while ((menuItem = [enumerator nextObject]))
{
aRange = [[menuItem title] rangeOfString:@"SDL App"];
if (aRange.length != 0)
[menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]];
if ([menuItem hasSubmenu])
[self fixMenu:[menuItem submenu] withAppName:appName];
}
}
#else
static void setApplicationMenu(void)
{
/* warning: this code is very odd */
NSMenu *appleMenu;
NSMenuItem *menuItem;
NSString *title;
NSString *appName;
appName = getApplicationName();
appleMenu = [[NSMenu alloc] initWithTitle:@""];
/* Add menu items */
title = [@"About " stringByAppendingString:appName];
[appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
[appleMenu addItem:[NSMenuItem separatorItem]];
title = [@"Hide " stringByAppendingString:appName];
[appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
[menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
[appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
[appleMenu addItem:[NSMenuItem separatorItem]];
title = [@"Quit " stringByAppendingString:appName];
[appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
/* Put menu into the menubar */
menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
[menuItem setSubmenu:appleMenu];
[[NSApp mainMenu] addItem:menuItem];
/* Tell the application object that this is now the application menu */
[NSApp setAppleMenu:appleMenu];
/* Finally give up our references to the objects */
[appleMenu release];
[menuItem release];
}
/* Create a window menu */
static void setupWindowMenu(void)
{
NSMenu *windowMenu;
NSMenuItem *windowMenuItem;
NSMenuItem *menuItem;
windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
/* "Minimize" item */
menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
[windowMenu addItem:menuItem];
[menuItem release];
/* Put menu into the menubar */
windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
[windowMenuItem setSubmenu:windowMenu];
[[NSApp mainMenu] addItem:windowMenuItem];
/* Tell the application object that this is now the window menu */
[NSApp setWindowsMenu:windowMenu];
/* Finally give up our references to the objects */
[windowMenu release];
[windowMenuItem release];
}
/* Replacement for NSApplicationMain */
static void CustomApplicationMain (int argc, char **argv)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
SDLMain *sdlMain;
/* Ensure the application object is initialised */
[NSApplication sharedApplication];
#ifdef SDL_USE_CPS
{
CPSProcessSerNum PSN;
/* Tell the dock about us */
if (!CPSGetCurrentProcess(&PSN))
if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
if (!CPSSetFrontProcess(&PSN))
[NSApplication sharedApplication];
}
#endif /* SDL_USE_CPS */
/* Set up the menubar */
[NSApp setMainMenu:[[NSMenu alloc] init]];
setApplicationMenu();
setupWindowMenu();
/* Create SDLMain and make it the app delegate */
sdlMain = [[SDLMain alloc] init];
[NSApp setDelegate:sdlMain];
/* Start the main event loop */
[NSApp run];
[sdlMain release];
[pool release];
}
#endif
/*
* Catch document open requests...this lets us notice files when the app
* was launched by double-clicking a document, or when a document was
* dragged/dropped on the app's icon. You need to have a
* CFBundleDocumentsType section in your Info.plist to get this message,
* apparently.
*
* Files are added to gArgv, so to the app, they'll look like command line
* arguments. Previously, apps launched from the finder had nothing but
* an argv[0].
*
* This message may be received multiple times to open several docs on launch.
*
* This message is ignored once the app's mainline has been called.
*/
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
{
const char *temparg;
size_t arglen;
char *arg;
char **newargv;
if (!gFinderLaunch) /* MacOS is passing command line args. */
return FALSE;
if (gCalledAppMainline) /* app has started, ignore this document. */
return FALSE;
temparg = [filename UTF8String];
arglen = SDL_strlen(temparg) + 1;
arg = (char *) SDL_malloc(arglen);
if (arg == NULL)
return FALSE;
newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2));
if (newargv == NULL)
{
SDL_free(arg);
return FALSE;
}
gArgv = newargv;
SDL_strlcpy(arg, temparg, arglen);
gArgv[gArgc++] = arg;
gArgv[gArgc] = NULL;
return TRUE;
}
/* Called when the internal event loop has just started running */
- (void) applicationDidFinishLaunching: (NSNotification *) note
{
int status;
/* Set the working directory to the .app's parent directory */
[self setupWorkingDirectory:gFinderLaunch];
#if SDL_USE_NIB_FILE
/* Set the main menu to contain the real app name instead of "SDL App" */
[self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()];
#endif
/* Hand off to main application code */
gCalledAppMainline = TRUE;
status = SDL_main (gArgc, gArgv);
/* We're done, thank you for playing */
exit(status);
}
@end
@implementation NSString (ReplaceSubString)
- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString
{
unsigned int bufferSize;
unsigned int selfLen = [self length];
unsigned int aStringLen = [aString length];
unichar *buffer;
NSRange localRange;
NSString *result;
bufferSize = selfLen + aStringLen - aRange.length;
buffer = (unichar *)NSAllocateMemoryPages(bufferSize*sizeof(unichar));
/* Get first part into buffer */
localRange.location = 0;
localRange.length = aRange.location;
[self getCharacters:buffer range:localRange];
/* Get middle part into buffer */
localRange.location = 0;
localRange.length = aStringLen;
[aString getCharacters:(buffer+aRange.location) range:localRange];
/* Get last part into buffer */
localRange.location = aRange.location + aRange.length;
localRange.length = selfLen - localRange.location;
[self getCharacters:(buffer+aRange.location+aStringLen) range:localRange];
/* Build output string */
result = [NSString stringWithCharacters:buffer length:bufferSize];
NSDeallocateMemoryPages(buffer, bufferSize);
return result;
}
@end
#ifdef main
# undef main
#endif
/* Main entry point to executable - should *not* be SDL_main! */
int main (int argc, char **argv)
{
/* Copy the arguments into a global variable */
/* This is passed if we are launched by double-clicking */
if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
gArgv = (char **) SDL_malloc(sizeof (char *) * 2);
gArgv[0] = argv[0];
gArgv[1] = NULL;
gArgc = 1;
gFinderLaunch = YES;
} else {
int i;
gArgc = argc;
gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1));
for (i = 0; i <= argc; i++)
gArgv[i] = argv[i];
gFinderLaunch = NO;
}
#if SDL_USE_NIB_FILE
NSApplicationMain (argc, argv);
#else
CustomApplicationMain (argc, argv);
#endif
return 0;
}

View File

@ -1,69 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="@APPID@"
android:versionCode="@BUILD_NUM@"
android:versionName="@DISPLAY_VERSION_MAJOR@.@DISPLAY_VERSION_MINOR@.@BUILD_NUM@"
android:installLocation="auto"
>
<uses-sdk
android:minSdkVersion="21"
android:targetSdkVersion="30"
/>
<uses-feature
android:glEsVersion="0x00020000"
/>
<uses-feature
android:name="android.hardware.touchscreen"
android:required="false"
/>
<uses-feature
android:name="android.hardware.bluetooth"
android:required="false"
/>
<uses-feature
android:name="android.hardware.gamepad"
android:required="false"
/>
<uses-feature
android:name="android.hardware.usb.host"
android:required="false"
/>
<uses-feature
android:name="android.hardware.type.pc"
android:required="false"
/>
@ANDROID_PERMISSIONS@
<application
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:allowBackup="true"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:hardwareAccelerated="true"
@ANDROID_PROPERTIES@
>
<activity
android:name=".PowderActivity"
android:screenOrientation="landscape"
android:label="@string/app_name"
android:alwaysRetainTaskState="true"
android:launchMode="singleInstance"
android:configChanges="layoutDirection|locale|orientation|uiMode|screenLayout|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation"
android:preferMinimalPostProcessing="true"
android:exported="true"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!-- <intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter> -->
</activity>
</application>
</manifest>

View File

@ -1,42 +0,0 @@
package @APPID@;
import org.libsdl.app.SDLActivity;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.Enumeration;
import java.io.IOException;
import java.util.Base64;
public class PowderActivity extends SDLActivity
{
public static String getCertificateBundle()
{
String allPems = "";
try {
KeyStore ks = KeyStore.getInstance("AndroidCAStore");
if (ks != null) {
ks.load(null, null);
Enumeration<String> aliases = ks.aliases();
while (aliases.hasMoreElements()) {
String alias = (String)aliases.nextElement();
java.security.cert.X509Certificate cert = (java.security.cert.X509Certificate)ks.getCertificate(alias);
allPems += "-----BEGIN CERTIFICATE-----\n" + Base64.getMimeEncoder().encodeToString(cert.getEncoded()) + "\n-----END CERTIFICATE-----\n";;
}
}
} catch (IOException e) {
e.printStackTrace();
return "";
} catch (KeyStoreException e) {
e.printStackTrace();
return "";
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return "";
} catch (java.security.cert.CertificateException e) {
e.printStackTrace();
return "";
}
return allPems;
}
}

View File

@ -1,26 +0,0 @@
import os
import os.path
import subprocess
import sys
(
script,
zipalign,
build_dir,
unsigned_name,
unaligned_name,
) = sys.argv
unaligned_path = os.path.join(build_dir, unaligned_name)
unsigned_path = os.path.join(build_dir, unsigned_name)
if os.path.exists(unsigned_path):
os.remove(unsigned_path)
if subprocess.run([
zipalign,
'-f', '4',
unaligned_path,
unsigned_path,
]).returncode:
sys.exit(1)

View File

@ -1,104 +0,0 @@
import os
import os.path
import shutil
import subprocess
import sys
(
script,
d8,
aapt,
aapt2,
source_dir,
build_dir,
private_name,
unaligned_name,
sha_name,
android_jar,
sdl_jar,
powder_jar,
tpt_arch,
debug_release,
manifest_xml,
*resources,
) = sys.argv
if tpt_arch == 'x86':
android_arch = 'x86'
if tpt_arch == 'arm':
android_arch = 'armeabi-v7a'
if tpt_arch == 'aarch64':
android_arch = 'arm64-v8a'
if tpt_arch == 'x86_64':
android_arch = 'x86_64'
sha_packaged_name = 'libpowder.so'
manifest_path = os.path.join(build_dir, manifest_xml)
sha_path = os.path.join(build_dir, sha_name)
unaligned_path = os.path.join(build_dir, unaligned_name)
private_dir = os.path.join(build_dir, private_name)
arch_dir = os.path.join(private_dir, 'lib', android_arch)
sha_lib_path = os.path.join(arch_dir, sha_packaged_name)
flat_dir = os.path.join(private_dir, 'flat')
if os.path.exists(arch_dir):
shutil.rmtree(arch_dir)
os.makedirs(arch_dir)
if os.path.exists(sha_lib_path):
os.remove(sha_lib_path)
if os.path.exists(unaligned_path):
os.remove(unaligned_path)
if os.path.exists(flat_dir):
shutil.rmtree(flat_dir)
os.makedirs(flat_dir)
if subprocess.run([
aapt2,
'compile',
'-o', os.path.join(private_dir, 'flat'),
*resources,
], cwd = build_dir).returncode:
sys.exit(1)
aapt2_link_inputs = []
for root, dirs, files in os.walk(flat_dir):
for name in files:
if name.endswith(".flat"):
aapt2_link_inputs.append(os.path.join(root, name))
if subprocess.run([
aapt2,
'link',
'-o', unaligned_path,
'-I', android_jar,
'--manifest', manifest_path,
*aapt2_link_inputs,
]).returncode:
sys.exit(1)
shutil.copy(sha_path, sha_lib_path)
if subprocess.run([
aapt,
'add',
unaligned_path,
os.path.join('lib', android_arch, sha_packaged_name),
], cwd = private_dir).returncode:
sys.exit(1)
if subprocess.run([
d8,
os.path.join(build_dir, sdl_jar),
os.path.join(build_dir, powder_jar),
'--' + debug_release,
'--lib', android_jar,
'--min-api', '21',
], cwd = private_dir).returncode:
sys.exit(1)
if subprocess.run([
aapt,
'add',
unaligned_path,
'classes.dex',
], cwd = private_dir).returncode:
sys.exit(1)

View File

@ -1,8 +0,0 @@
[constants]
android_ndk_toolchain_prefix = 'aarch64-linux-android21-'
[host_machine]
system = 'android'
cpu_family = 'aarch64'
cpu = 'armv8'
endian = 'little'

View File

@ -1,8 +0,0 @@
[constants]
android_ndk_toolchain_prefix = 'armv7a-linux-androideabi21-'
[host_machine]
system = 'android'
cpu_family = 'arm'
cpu = 'armv7a'
endian = 'little'

View File

@ -1,8 +0,0 @@
[constants]
android_ndk_toolchain_prefix = 'i686-linux-android21-'
[host_machine]
system = 'android'
cpu_family = 'x86'
cpu = 'i686'
endian = 'little'

View File

@ -1,8 +0,0 @@
[constants]
android_ndk_toolchain_prefix = 'x86_64-linux-android21-'
[host_machine]
system = 'android'
cpu_family = 'x86_64'
cpu = 'amd64'
endian = 'little'

View File

@ -1,272 +0,0 @@
#!/usr/bin/env bash
# mainly based on https://www.sh-zam.com/2019/05/debugging-krita-on-android.html
set -euo pipefail
IFS=$'\n\t'
function get_buildoption() {
jq -r '.[] | select(.name == "'$1'") | .value' < meson-info/intro-buildoptions.json
}
function get_cpp_compiler() {
jq -r '.[] | select(.name == "'$1'") | .target_sources.[] | select(.language == "cpp") | .compiler.[]' < meson-info/intro-targets.json
}
# customize
default_app_id=uk.co.powdertoy.tpt
default_app_exe=powder
default_lldb_server=/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/lib/clang/17/lib/linux/aarch64/lldb-server
default_lldb_client=/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/lldb.sh
in_build_site=no
if which jq >/dev/null && [[ -f meson-info/intro-buildoptions.json ]]; then
>&2 echo "[+] pwd is a build site, auto-detecting parameters"
in_build_site=yes
default_app_id=$(get_buildoption app_id)
default_app_exe=$(get_buildoption app_exe)
found_lldb=no
compiler_path=$(get_cpp_compiler $default_app_exe)
for line in $compiler_path; do
# iterate over the command array (might be for example [ "ccache", "aarch64-linux-android21-clang++" ])
if (echo $line | grep toolchains && basename $line | grep android | grep clang++) >/dev/null; then
arch=$(basename $line | cut -d '-' -f 1)
default_lldb_server=$(realpath $(dirname $line)/../lib/clang/*/lib/linux/$arch/lldb-server)
default_lldb_client=$(realpath $(dirname $line)/lldb.sh)
found_lldb=yes
fi
done
if [[ $found_lldb != yes ]]; then
>&2 echo "[-] cannot determine LLDB paths from compiler command array:"
for line in $compiler_path; do
>&2 echo "[-] - $line"
done
exit 1
fi
>&2 echo "[+] APP_ID: $default_app_id"
>&2 echo "[+] APP_EXE: $default_app_exe"
>&2 echo "[+] LLDB_SERVER: $default_lldb_server"
>&2 echo "[+] LLDB_CLIENT: $default_lldb_client"
else
>&2 echo "[+] pwd is not a build site, not auto-detecting parameters"
fi
app_id=${APP_ID:-$default_app_id}
app_exe=${APP_EXE:-$default_app_exe}
lldb_server=${LLDB_SERVER:-$default_lldb_server}
lldb_server_port=${LLDB_SERVER_PORT:-9998}
jdb_port=${JDB_PORT:-13456}
lldb_client=${LLDB_CLIENT:-$default_lldb_client}
meson=${MESON:-meson}
adb=${ADB:-adb}
jdb=${JDB:-jdb}
# don't customize unless necessary
app_activity=${APP_ACTIVITY:-PowderActivity}
lldb_server_staging=${LLDB_SERVER_STAGING:-/data/local/tmp/lldb-server}
lldb_server_remote=${LLDB_SERVER_REMOTE:-lldb-server}
pidof_retry_count=${PIDOF_RETRY_COUNT:-20}
pidof_retry_delay=${PIDOF_RETRY_DELAY:-0.1}
function check_which() {
if ! which $1 >/dev/null; then
>&2 echo "[-] can't run $1"
return 1
fi
}
function check_env() {
if ! [[ -f $lldb_server ]]; then
>&2 echo "[-] $lldb_server doesn't exist"
return 1
fi
check_which $lldb_client
check_which $adb
check_which $jdb
}
function check_adb() {
$adb shell whoami >/dev/null
}
function maybe_install_app() {
if [[ $in_build_site != yes ]]; then
return 0
fi
android_keystore=$(get_buildoption android_keystore)
android_keyalias=$(get_buildoption android_keyalias)
if [[ -z ${ANDROID_KEYSTORE_PASS-} ]]; then
>&2 echo "[-] ANDROID_KEYSTORE_PASS not set"
>&2 echo
>&2 cat << HELP
The current directory seems to be a build site, but ANDROID_KEYSTORE_PASS is not set, so android/$app_exe.apk cannot be invoked. If you don't have a keystore yet, create one with:
ANDROID_KEYSTORE_PASS=bagelsbagels keytool -genkey \\
-keystore $android_keystore \\
-alias $android_keyalias \\
-storepass:env ANDROID_KEYSTORE_PASS \\
-keypass:env ANDROID_KEYSTORE_PASS \\
-dname CN=bagels
Then try again with:
ANDROID_KEYSTORE_PASS=bagelsbagels $0
Naturally, replace bagelsbagels with an appropriate password.
HELP
exit 1
fi
>&2 echo "[+] meson compiling android/$app_exe.apk"
if ! $meson compile sign-apk; then
>&2 echo "[-] failed"
return 1
fi
>&2 echo "[+] adb installing android/$app_exe.apk"
if ! $adb install android/$app_exe.apk; then
>&2 echo "[-] failed"
return 1
fi
}
function check_debuggable() {
$adb shell run-as $app_id whoami >/dev/null
}
function find_lldb_server() {
$adb shell run-as $app_id pgrep $lldb_server_remote >/dev/null
}
function kill_lldb_server() {
if ! $adb shell run-as $app_id pkill $lldb_server_remote; then
>&2 echo "[-] failed"
return 1
fi
}
function adb_forward() {
>&2 echo "[+] adb forwarding tcp:$jdb_port jdwp:$pid"
if ! ($adb forward tcp:$jdb_port jdwp:$pid | grep $jdb_port >/dev/null); then
>&2 echo "[+] failed"
return 1
fi
}
function adb_unforward() {
$adb forward --remove tcp:$jdb_port
}
function undo_current_adb_forward() {
>&2 echo "[+] adb un-forwarding orphaned tcp:$jdb_port"
adb_unforward
}
function maybe_undo_previous_adb_forward() {
if $adb forward --list | grep tcp:$jdb_port; then
>&2 echo "[+] adb un-forwarding orphaned tcp:$jdb_port"
adb_unforward
fi
}
function maybe_kill_previous_lldb_server() {
if find_lldb_server; then
>&2 echo "[+] killing orphaned $lldb_server_remote"
kill_lldb_server
fi
}
function kill_current_lldb_server() {
>&2 echo "[+] killing $lldb_server_remote"
kill_lldb_server
}
function start_app() {
>&2 echo "[+] starting $app_id/.$app_activity"
set +e
$adb shell am start -D -n "$app_id/.$app_activity" >/dev/null
set -e
local i
local maybe_pid
local pidof_result
for ((i = 0; i <= $pidof_retry_count; i++)); do
set +e
maybe_pid=$($adb shell pidof $app_id)
pidof_result=$?
set -e
if [[ $pidof_result == 0 ]]; then
pid=$maybe_pid
break
fi
sleep $pidof_retry_delay
done
if [[ -z ${pid-} ]]; then
>&2 echo "[-] failed"
return 1
fi
echo $pid
}
function jdb_attach() {
>&2 echo "[+] attaching jdb in the background"
$jdb -attach localhost:$jdb_port >/dev/null 2>/dev/null &
disown $!
# at some point jdb exits because it doesn't have an stdin... fine by me
}
function maybe_deploy_lldb_server() {
if ! $adb shell [[ -f $lldb_server_staging ]]; then
>&2 echo "[+] $lldb_server_remote not present on host, deploying"
if ! ($adb push $lldb_server $lldb_server_staging && $adb shell chmod +x $lldb_server_staging); then
>&2 echo "[-] failed"
fi
fi
}
function start_lldb_server() {
if ! $adb shell run-as $app_id pgrep $lldb_server_remote >/dev/null; then
>&2 echo "[+] $lldb_server_remote not running on host, starting"
$adb shell run-as $app_id cp $lldb_server_staging /data/data/$app_id/$lldb_server_remote
$adb shell run-as $app_id ./$lldb_server_remote platform --server --listen "*:$lldb_server_port" >/dev/null 2>/dev/null &
disown $!
if ! $adb shell run-as $app_id pgrep $lldb_server_remote >/dev/null; then
>&2 echo "[-] failed"
return 1
fi
fi
}
function start_lldb() {
local pid=$1
>&2 echo "[+] starting $lldb_client"
local lldb_init=$(mktemp)
cat - << LLDB_INIT > $lldb_init
platform select remote-android
platform connect connect://localhost:$lldb_server_port
attach $pid
continue
LLDB_INIT
local lldb_status
set +e
$lldb_client --source $lldb_init
lldb_status=$?
set -e
>&2 echo "[+] $lldb_client exited with status $lldb_status"
rm $lldb_init
}
check_env
check_adb
maybe_install_app
check_debuggable
maybe_kill_previous_lldb_server
maybe_undo_previous_adb_forward
if [[ ${1-} == clean ]]; then
>&2 echo "[+] done"
exit 0
fi
maybe_deploy_lldb_server
start_lldb_server
pid=$(start_app)
adb_forward
jdb_attach
start_lldb $pid
kill_current_lldb_server
undo_current_adb_forward
>&2 echo "[+] done"

View File

@ -1,25 +0,0 @@
import os
import os.path
import subprocess
import sys
(
script,
adb,
build_dir,
phony,
apk_name,
) = sys.argv
apk_path = os.path.join(build_dir, apk_name)
phony_path = os.path.join(build_dir, phony)
if os.path.exists(phony_path):
os.remove(phony_path)
if subprocess.run([
adb,
'install',
apk_path,
]).returncode:
sys.exit(1)

View File

@ -1,105 +0,0 @@
android_manifest_xml = configure_file(
input: 'AndroidManifest.template.xml',
output: 'AndroidManifest.xml',
configuration: conf_data,
)
powder_jar_sources = configure_file(
input: 'PowderActivity.template.java',
output: 'PowderActivity.java',
configuration: conf_data,
)
subdir('res')
python3 = find_program('python3')
android_platform_jar = meson.get_external_property('android_platform_jar')
java_runtime_jar = meson.get_external_property('java_runtime_jar')
android_keystore = get_option('android_keystore')
sdl_jar = tpt_libs.get_variable('sdl_jar')
powder_jar = custom_target(
'powder-jar',
output: app_exe + '.jar',
command: [
python3,
files('powder-jar.py'),
find_program('javac'),
find_program('jar'),
meson.current_source_dir(),
meson.project_build_root(),
'@PRIVATE_DIR@',
'@OUTPUT@',
android_platform_jar,
java_runtime_jar,
sdl_jar,
is_debug ? 'debug' : 'release',
powder_jar_sources,
],
)
unaligned_apk = custom_target(
'build-apk',
output: app_exe + '.unaligned.apk',
input: powder_sha,
command: [
python3,
files('build-apk.py'),
find_program('d8'),
find_program('aapt'),
find_program('aapt2'),
meson.current_source_dir(),
meson.project_build_root(),
'@PRIVATE_DIR@',
'@OUTPUT@',
'@INPUT@',
android_platform_jar,
sdl_jar,
powder_jar,
host_arch,
is_debug ? 'debug' : 'release',
android_manifest_xml,
android_resources,
],
)
unsigned_apk = custom_target(
'align-apk',
output: app_exe + '.unsigned.apk',
input: unaligned_apk,
command: [
python3,
files('align-apk.py'),
find_program('zipalign'),
meson.project_build_root(),
'@OUTPUT@',
'@INPUT@',
],
)
signed_apk = custom_target(
'sign-apk',
output: app_exe + '.apk',
input: unsigned_apk,
command: [
python3,
files('sign-apk.py'),
find_program('apksigner'),
meson.project_build_root(),
'@OUTPUT@',
'@INPUT@',
android_keystore,
get_option('android_keyalias'),
],
)
adb = find_program('adb', required: false)
if adb.found()
install_apk = custom_target(
'install-apk',
input: signed_apk,
output: 'install-apk',
command: [ python3, files('install-apk.py'), adb, meson.project_build_root(), '@OUTPUT@', '@INPUT@' ],
)
custom_target(
'run-apk',
input: [ signed_apk, install_apk ],
build_always_stale: true,
output: 'run-apk',
command: [ python3, files('run-apk.py'), adb, meson.project_build_root(), '@OUTPUT@', '@INPUT0@', app_id ],
)
endif

View File

@ -1,54 +0,0 @@
import os
import os.path
import shutil
import subprocess
import sys
(
script,
javac,
jar,
source_dir,
build_dir,
private_name,
powder_jar_name,
android_jar,
java_runtime,
sdl_jar,
debug_release,
*javac_sources,
) = sys.argv
powder_jar_path = os.path.join(build_dir, powder_jar_name)
private_dir = os.path.join(build_dir, private_name)
class_dir = os.path.join(private_dir, 'class')
if os.path.exists(powder_jar_path):
os.remove(powder_jar_path)
if os.path.exists(class_dir):
shutil.rmtree(class_dir)
os.makedirs(class_dir)
if subprocess.run([
javac,
'-d', class_dir,
'-source', '1.8',
'-target', '1.8',
'-bootclasspath', java_runtime,
'-classpath', os.pathsep.join([ android_jar, sdl_jar ]),
*javac_sources,
], cwd = build_dir).returncode:
sys.exit(1)
jar_inputs = []
for root, dirs, files in os.walk(class_dir):
for name in files:
if name.endswith(".class"):
jar_inputs.append(os.path.relpath(os.path.join(root, name), start = class_dir))
if subprocess.run([
jar,
'cMf',
powder_jar_path,
*jar_inputs,
], cwd = class_dir).returncode:
sys.exit(1)

View File

@ -1,7 +0,0 @@
android_resources = files(
'values/colors.xml',
'values/styles.xml',
)
subdir('values')
subdir('mipmap-mdpi')

View File

@ -1 +0,0 @@
android_resources += fs.copyfile(rendered_icons['icon_exe'], 'ic_launcher.png')

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
</resources>

View File

@ -1,5 +0,0 @@
android_resources += configure_file(
input: 'strings.template.xml',
output: 'strings.xml',
configuration: conf_data,
)

View File

@ -1,3 +0,0 @@
<resources>
<string name="app_name">@APPNAME@</string>
</resources>

View File

@ -1,4 +0,0 @@
<resources>
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
</style>
</resources>

View File

@ -1,25 +0,0 @@
import os
import os.path
import subprocess
import sys
(
script,
adb,
build_dir,
phony,
apk_name,
app_id,
) = sys.argv
apk_path = os.path.join(build_dir, apk_name)
if subprocess.run([
adb,
'shell',
'am',
'start',
'--activity-clear-top',
'-n', app_id + '/.PowderActivity',
]).returncode:
sys.exit(1)

View File

@ -1,35 +0,0 @@
import os
import os.path
import subprocess
import sys
(
script,
apksigner,
build_dir,
apk_name,
unsigned_name,
android_keystore,
android_keyalias,
) = sys.argv
if 'ANDROID_KEYSTORE_PASS' not in os.environ:
print('ANDROID_KEYSTORE_PASS not set')
sys.exit(1)
unsigned_path = os.path.join(build_dir, unsigned_name)
apk_path = os.path.join(build_dir, apk_name)
if os.path.exists(apk_path):
os.remove(apk_path)
if subprocess.run([
apksigner,
'sign',
'--ks', android_keystore,
'--ks-key-alias', android_keyalias,
'--ks-pass', 'env:ANDROID_KEYSTORE_PASS',
'--out', apk_path,
unsigned_path,
]).returncode:
sys.exit(1)

View File

@ -1,3 +0,0 @@
# This file is used by the starcatcher.us update server to pull changelogs for mod releases
# Erase and replace the changelog for every release, do not just append changes to the end
# Lines starting with # and empty lines are ignored

View File

@ -1,25 +0,0 @@
[constants]
andriod_ndk_toolchain_bin = '/opt/android-sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin'
[properties]
# only needed if you want to run the custom target powder_apk (powder.apk)
# android_ndk_toolchain_prefix comes from the correct cross-file in ./android/cross
android_ndk_toolchain_prefix = android_ndk_toolchain_prefix
android_platform = 'android-30'
android_platform_jar = '/opt/android-sdk/platforms/' + android_platform + '/android.jar'
java_runtime_jar = '/usr/lib/jvm/java-8-openjdk/jre/lib/rt.jar'
[binaries]
c = andriod_ndk_toolchain_bin / (android_ndk_toolchain_prefix + 'clang')
# c = [ 'ccache', andriod_ndk_toolchain_bin / (android_ndk_toolchain_prefix + 'clang') ]
cpp = andriod_ndk_toolchain_bin / (android_ndk_toolchain_prefix + 'clang++')
# cpp = [ 'ccache', andriod_ndk_toolchain_bin / (android_ndk_toolchain_prefix + 'clang++') ]
strip = andriod_ndk_toolchain_bin / 'llvm-strip'
# only needed if you want to run the custom target powder_apk (powder.apk)
javac = '/usr/lib/jvm/java-8-openjdk/bin/javac'
jar = '/usr/lib/jvm/java-8-openjdk/bin/jar'
d8 = '/opt/android-sdk/build-tools/32.0.0/d8'
aapt = '/opt/android-sdk/build-tools/32.0.0/aapt'
aapt2 = '/opt/android-sdk/build-tools/32.0.0/aapt2'
zipalign = '/opt/android-sdk/build-tools/32.0.0/zipalign'
apksigner = '/opt/android-sdk/build-tools/32.0.0/apksigner'

View File

@ -1,11 +0,0 @@
[binaries]
c = [ 'clang', '-arch', 'arm64' ]
cpp = [ 'clang++', '-arch', 'arm64' ]
objcpp = [ 'clang++', '-arch', 'arm64' ]
strip = 'strip'
[host_machine]
system = 'darwin'
cpu_family = 'aarch64'
cpu = 'armv8'
endian = 'little'

View File

@ -1,14 +0,0 @@
[constants]
prefix = 'x86_64-w64-mingw32'
[binaries]
c = prefix + '-gcc'
cpp = prefix + '-g++'
strip = prefix + '-strip'
windres = prefix + '-windres'
[host_machine]
system = 'windows'
cpu_family = 'x86_64'
cpu = 'x86_64'
endian = 'little'

52
data/IntroText.h Normal file
View File

@ -0,0 +1,52 @@
static const char *introTextData =
"\blThe Powder Toy - Version " MTOS(SAVE_VERSION) "." MTOS(MINOR_VERSION) " - http://powdertoy.co.uk, irc.freenode.net #powder\n"
"\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\n"
"\n"
"\bgControl+C/V/X are Copy, Paste and cut respectively.\n"
"\bgTo choose a material, hover over one of the icons on the right, it will show a selection of elements in that group.\n"
"\bgPick your material from the menu using mouse left/right buttons.\n"
"Draw freeform lines by dragging your mouse left/right button across the drawing area.\n"
"Shift+drag will create straight lines of particles.\n"
"Ctrl+drag will result in filled rectangles.\n"
"Ctrl+Shift+click will flood-fill a closed area.\n"
"Ctrl+Z will act as Undo.\n"
"Middle click or Alt+Click to \"sample\" the particles.\n"
"\n\boUse 'Z' for a zoom tool. Click to make the drawable zoom window stay around. Use the wheel to change the zoom strength\n"
"Use 'S' to save parts of the window as 'stamps'.\n"
"'L' will load the most recent stamp, 'K' shows a library of stamps you saved.\n"
"Use the mouse scroll wheel to change the tool size for particles.\n"
"The spacebar can be used to pause physics.\n"
"'P' will take a screenshot and save it into the current directory.\n"
"\n"
"Contributors: \bgStanislaw K Skowronek (\brhttp://powder.unaligned.org\bg, \bbirc.unaligned.org #wtf\bg),\n"
"\bgSimon Robertshaw, Skresanov Savely, cracker64, Catelite, Bryan Hoyle, Nathan Cousins, jacksonmj,\n"
"\bgLieuwe Mosch, Anthony Boot, Matthew \"me4502\", MaksProg, jacob1\n"
"\n"
"\bgTo use online features such as saving, you need to register at: \brhttp://powdertoy.co.uk/Register.html\n"
"\n"
"\bt" MTOS(SAVE_VERSION) "." MTOS(MINOR_VERSION) "." MTOS(BUILD_NUM) " " IDENT_PLATFORM " "
#ifdef X86
"X86 "
#endif
#ifdef X86_SSE
"X86_SSE "
#endif
#ifdef X86_SSE2
"X86_SSE2 "
#endif
#ifdef X86_SSE3
"X86_SSE3 "
#endif
#ifdef MACOSX
"MACOSX "
#endif
#ifdef LUACONSOLE
"LUACONSOLE "
#endif
#ifdef GRAVFFT
"GRAVFFT "
#endif
#ifdef REALISTIC
"REALISTIC"
#endif
;

99
data/Shaders.h Normal file
View File

@ -0,0 +1,99 @@
/*
* Shaders.h
*
* Created on: Jan 7, 2012
* Author: Simon
*/
#ifndef SHADERS_H_
#define SHADERS_H_
const char * fireFragment = "#version 120\n\
uniform sampler2D fireAlpha;\
void main () {\
vec4 texColor = texture2D(fireAlpha, gl_PointCoord);\
gl_FragColor = vec4(gl_Color.rgb, texColor.a*gl_Color.a);\
}";
const char * fireVertex = "#version 120\n\
void main(void)\
{\
gl_Position = ftransform();;\
gl_FrontColor = gl_Color;\
}";
const char * lensFragment = "#version 120\n\
uniform sampler2D pTex;\
uniform sampler2D tfX;\
uniform sampler2D tfY;\
uniform float xres;\
uniform float yres;\
void main () {\
vec4 transformX = texture2D(tfX, vec2(gl_TexCoord[0].s, -gl_TexCoord[0].t));\
vec4 transformY = -texture2D(tfY, vec2(gl_TexCoord[0].s, -gl_TexCoord[0].t));\
transformX.r /= xres;\
transformY.g /= yres;\
vec4 texColor = vec4(\
texture2D(pTex, gl_TexCoord[0].st-vec2(transformX.r*0.75, transformY.g*0.75)).r,\
texture2D(pTex, gl_TexCoord[0].st-vec2(transformX.r*0.875, transformY.g*0.875)).g,\
texture2D(pTex, gl_TexCoord[0].st-vec2(transformX.r, transformY.g)).b,\
1.0\
);\
gl_FragColor = texColor;\
}";
const char * lensVertex = "#version 120\n\
void main(void)\
{\
gl_TexCoord[0] = gl_MultiTexCoord0;\
gl_Position = ftransform();;\
gl_FrontColor = gl_Color;\
}";
const char * airVFragment = "#version 120\n\
uniform sampler2D airX;\
uniform sampler2D airY;\
uniform sampler2D airP;\
void main () {\
vec4 texX = texture2D(airX, gl_TexCoord[0].st);\
vec4 texY = texture2D(airY, gl_TexCoord[0].st);\
vec4 texP = texture2D(airP, gl_TexCoord[0].st);\
gl_FragColor = vec4(abs(texX.r)/2.0, texP.b/2.0, abs(texY.g)/2.0, 1.0);\
}";
const char * airVVertex = "#version 120\n\
void main(void)\
{\
gl_TexCoord[0] = gl_MultiTexCoord0;\
gl_Position = ftransform();;\
gl_FrontColor = gl_Color;\
}";
const char * airPFragment = "#version 120\n\
uniform sampler2D airX;\
uniform sampler2D airY;\
uniform sampler2D airP;\
void main () {\
vec4 texP = texture2D(airP, gl_TexCoord[0].st);\
gl_FragColor = vec4(max(texP.b/2.0, 0), 0, abs(min(texP.b/2.0, 0)), 1.0);\
}";
const char * airPVertex = "#version 120\n\
void main(void)\
{\
gl_TexCoord[0] = gl_MultiTexCoord0;\
gl_Position = ftransform();;\
gl_FrontColor = gl_Color;\
}";
const char * airCFragment = "#version 120\n\
uniform sampler2D airX;\
uniform sampler2D airY;\
uniform sampler2D airP;\
void main () {\
vec4 texX = texture2D(airX, gl_TexCoord[0].st);\
vec4 texY = texture2D(airY, gl_TexCoord[0].st);\
vec4 texP = texture2D(airP, gl_TexCoord[0].st);\
gl_FragColor = vec4(max(texP.b/2.0, 0), 0, abs(min(texP.b/2.0, 0)), 1.0) + vec4(abs(texX.r)/8.0, abs(texX.r)/8.0, abs(texX.r)/8.0, 1.0) + vec4(abs(texY.g)/8.0, abs(texY.g)/8.0, abs(texY.g)/8.0, 1.0);\
}";
const char * airCVertex = "#version 120\n\
void main(void)\
{\
gl_TexCoord[0] = gl_MultiTexCoord0;\
gl_Position = ftransform();;\
gl_FrontColor = gl_Color;\
}";
#endif /* SHADERS_H_ */

301
data/font.h Normal file
View File

@ -0,0 +1,301 @@
#ifndef FONT_H_CHECK
#define FONT_H_CHECK
#define FONT_H 10
#ifdef INCLUDE_FONTDATA
char font_data[] = {
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0xC7, 0x31, 0x0C, 0x02, 0x70, 0x04, 0x00, 0x00,
0x05, 0xCC, 0x74, 0x23, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0x00, 0x80, 0x19, 0xCC, 0xE0, 0x3F, 0xCC, 0xF0, 0x2F, 0xCC, 0x90, 0x09, 0x00, 0x00, 0x00,
0x06, 0x30, 0xD0, 0x3F, 0x33, 0xE1, 0x07, 0xF4, 0x12, 0x33, 0xFF, 0x00, 0x03, 0x00, 0x00, 0x00,
0x07, 0x2D, 0xCE, 0xCC, 0xE1, 0x1D, 0xC0, 0x03, 0x74, 0x4B, 0x33, 0xB3, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0x7D, 0x30, 0x0C, 0x13, 0xD0, 0x32, 0xB3, 0x33, 0x1C, 0x7D, 0x07, 0x00, 0x00, 0x00, 0x00,
0x03, 0x4C, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x04, 0x34, 0x1D, 0x07, 0x03, 0x07, 0x1D, 0x34, 0x00, 0x00, 0x00,
0x04, 0x07, 0x1D, 0x34, 0x30, 0x34, 0x1D, 0x07, 0x00, 0x00, 0x00,
0x06, 0x44, 0xD0, 0x1C, 0x64, 0xF0, 0x3F, 0x64, 0xD0, 0x1C, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x02, 0x30, 0xE0, 0x2F, 0x30, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0D, 0x03, 0x00,
0x05, 0x00, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x40, 0x70, 0x00, 0x00, 0x00,
0x06, 0x80, 0x02, 0x0C, 0xA0, 0x00, 0x03, 0x28, 0xC0, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0xF8, 0xE0, 0x39, 0x07, 0x33, 0x32, 0x03, 0xB3, 0x38, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x30, 0xF0, 0x60, 0x03, 0x0C, 0x30, 0xC0, 0x40, 0x07, 0x00, 0x00, 0x00, 0x00,
0x06, 0xFC, 0xB1, 0x34, 0x41, 0x03, 0x0A, 0x2C, 0x70, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
0x06, 0xFC, 0x71, 0x34, 0x01, 0x03, 0x1E, 0x00, 0x33, 0x34, 0xFE, 0x01, 0x00, 0x00, 0x00, 0x00,
0x06, 0xC0, 0x03, 0x37, 0x1C, 0x73, 0x34, 0xBF, 0x03, 0x30, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00,
0x06, 0xFF, 0x33, 0x00, 0x57, 0xE0, 0x2F, 0x00, 0x13, 0x30, 0xFE, 0x01, 0x00, 0x00, 0x00, 0x00,
0x06, 0xF4, 0xD3, 0x00, 0x07, 0xF0, 0x1F, 0x03, 0x33, 0x34, 0xFD, 0x01, 0x00, 0x00, 0x00, 0x00,
0x06, 0xFF, 0x07, 0x34, 0x80, 0x03, 0x0E, 0x38, 0xD0, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0xFC, 0xB1, 0x34, 0x03, 0xD3, 0x1F, 0x03, 0x73, 0x34, 0xFD, 0x01, 0x00, 0x00, 0x00, 0x00,
0x06, 0xFC, 0xB1, 0x34, 0x03, 0xC3, 0x3F, 0x40, 0x23, 0x30, 0xFD, 0x01, 0x00, 0x00, 0x00, 0x00,
0x03, 0x00, 0x70, 0x04, 0x40, 0x70, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x1C, 0x04, 0x00, 0x0C, 0x0D, 0x03, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0xC0, 0xC3, 0x0B, 0x1B, 0xC0, 0x0B, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x0F, 0x80, 0x0F, 0x90, 0x83, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0xFD, 0x71, 0x30, 0x81, 0x03, 0x0E, 0x34, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00,
0x08, 0xF8, 0x0F, 0x1D, 0x30, 0xE7, 0x37, 0x73, 0x1C, 0xE3, 0x2F, 0x07, 0x00, 0xFD, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0x74, 0xD0, 0x1D, 0x47, 0x33, 0x30, 0xFF, 0x33, 0x30, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00,
0x06, 0xBF, 0x30, 0x38, 0x43, 0xF3, 0x1F, 0x43, 0x33, 0x34, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00,
0x06, 0xF4, 0xD1, 0x34, 0x03, 0x31, 0x00, 0x03, 0x70, 0x34, 0xFD, 0x01, 0x00, 0x00, 0x00, 0x00,
0x06, 0x7F, 0x30, 0x1D, 0x43, 0x33, 0x30, 0x03, 0x33, 0x34, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00,
0x06, 0xFF, 0x32, 0x00, 0x03, 0xF0, 0x0B, 0x03, 0x30, 0x10, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
0x06, 0xFF, 0x33, 0x10, 0x03, 0xF0, 0x0B, 0x03, 0x30, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0xF4, 0xD1, 0x34, 0x03, 0x30, 0x3E, 0x03, 0x73, 0x34, 0xFD, 0x01, 0x00, 0x00, 0x00, 0x00,
0x06, 0x47, 0x33, 0x30, 0x03, 0xF3, 0x3F, 0x03, 0x33, 0x30, 0x47, 0x03, 0x00, 0x00, 0x00, 0x00,
0x04, 0x1D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1D, 0x00, 0x00, 0x00,
0x06, 0xD0, 0x01, 0x0C, 0xC0, 0x00, 0x0C, 0xC0, 0x10, 0x0D, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00,
0x07, 0x47, 0xC3, 0x34, 0x70, 0x03, 0xBC, 0x00, 0xB3, 0xC0, 0xB0, 0x70, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0x07, 0x30, 0x00, 0x03, 0x30, 0x00, 0x03, 0x30, 0x10, 0xFF, 0x02, 0x00, 0x00, 0x00, 0x00,
0x08, 0x03, 0x30, 0x1F, 0x3D, 0x7B, 0x3B, 0xE3, 0x32, 0x83, 0x30, 0x03, 0x30, 0x03, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x07, 0x07, 0xCD, 0x03, 0x73, 0xC3, 0x8C, 0x32, 0xC3, 0xCD, 0xC0, 0x33, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x07, 0xF4, 0x41, 0xC7, 0x71, 0xD0, 0x0C, 0x30, 0x03, 0xCD, 0xD1, 0xD1, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0x7F, 0x30, 0x1D, 0x43, 0x73, 0x34, 0xFF, 0x31, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
0x07, 0xF4, 0x41, 0xD3, 0x71, 0xD0, 0x0C, 0x30, 0xC3, 0xCD, 0xD1, 0xD1, 0xDF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0xFF, 0x31, 0x34, 0x03, 0xF3, 0x0F, 0xD7, 0x30, 0x34, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00,
0x06, 0xFC, 0xB1, 0x31, 0x07, 0xD0, 0x0F, 0x90, 0x23, 0x34, 0xFE, 0x01, 0x00, 0x00, 0x00, 0x00,
0x06, 0xFF, 0x13, 0x13, 0x30, 0x00, 0x03, 0x30, 0x00, 0x03, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00,
0x07, 0x03, 0xCC, 0x00, 0x33, 0xC0, 0x0C, 0x30, 0x03, 0xCD, 0xD2, 0xD1, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0x03, 0x33, 0x30, 0x03, 0xB3, 0x38, 0xCD, 0xC1, 0x0D, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
0x08, 0x03, 0x30, 0x43, 0x30, 0xC7, 0x34, 0xCD, 0x1C, 0xED, 0x1E, 0x2C, 0x0E, 0x0C, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x07, 0x03, 0x4C, 0xC3, 0x81, 0x3B, 0xD0, 0x03, 0xDC, 0x42, 0xC3, 0x31, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0x03, 0xB3, 0x38, 0xDC, 0x40, 0x07, 0x30, 0x00, 0x03, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
0x07, 0xFF, 0x0F, 0xD0, 0x02, 0x2C, 0xC0, 0x02, 0x2D, 0xC0, 0x06, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x04, 0x2F, 0x03, 0x03, 0x03, 0x03, 0x03, 0x2F, 0x00, 0x00, 0x00,
0x05, 0x03, 0x28, 0xC0, 0x00, 0x0A, 0x30, 0x80, 0x02, 0x0C, 0x00, 0x00, 0x00, 0x00,
0x04, 0x3E, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3E, 0x00, 0x00, 0x00,
0x04, 0x1D, 0x37, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
0x03, 0x83, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0xD0, 0x47, 0x30, 0xFC, 0x0C, 0xD3, 0x1F, 0x00, 0x00, 0x00, 0x00,
0x05, 0x07, 0x0C, 0xF0, 0xC7, 0x35, 0xC3, 0x0C, 0xF3, 0x07, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0xD0, 0xC3, 0x25, 0x03, 0x4C, 0xD2, 0x03, 0x00, 0x00, 0x00, 0x00,
0x05, 0xD0, 0x00, 0x83, 0x8F, 0x33, 0xC3, 0x1C, 0xD3, 0x1F, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0xD0, 0xC7, 0x30, 0xBF, 0x0C, 0xD0, 0x0B, 0x00, 0x00, 0x00, 0x00,
0x04, 0x3D, 0x07, 0x03, 0x2F, 0x03, 0x03, 0x07, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0xC0, 0xCB, 0x32, 0xC3, 0xF4, 0x03, 0x4C, 0x30, 0x7E, 0x00, 0x00,
0x05, 0x03, 0x0C, 0xF0, 0xC7, 0x39, 0xC3, 0x0C, 0x73, 0x1C, 0x00, 0x00, 0x00, 0x00,
0x04, 0x04, 0x1C, 0x00, 0x0D, 0x0C, 0x0C, 0x1D, 0x00, 0x00, 0x00,
0x04, 0x00, 0x30, 0x00, 0x34, 0x30, 0x30, 0x30, 0x30, 0x1E, 0x00,
0x05, 0x03, 0x0C, 0x31, 0xCE, 0x0E, 0x1F, 0xCC, 0x31, 0x1C, 0x00, 0x00, 0x00, 0x00,
0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x47, 0x3D, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x9B, 0x71, 0x37, 0x33, 0x33, 0x32, 0x43, 0x03, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0xF0, 0xC7, 0x31, 0xC3, 0x0C, 0x33, 0x0D, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0xD0, 0xC7, 0x31, 0xC3, 0x4C, 0xD3, 0x07, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0xF0, 0xC7, 0x31, 0xC3, 0x4C, 0xF3, 0xC7, 0x00, 0x03, 0x00, 0x00,
0x05, 0x00, 0x00, 0xD0, 0xDF, 0x31, 0xC3, 0x4C, 0xD3, 0x0F, 0x30, 0xC0, 0x00, 0x05,
0x04, 0x00, 0x00, 0x33, 0x1F, 0x07, 0x03, 0x03, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0xC0, 0xC7, 0x10, 0x3C, 0x04, 0xF3, 0x03, 0x00, 0x00, 0x00, 0x00,
0x04, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x1C, 0x74, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x70, 0xDC, 0x30, 0xC3, 0x4C, 0xD3, 0x1F, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x30, 0xCC, 0x30, 0xD3, 0xDC, 0xC2, 0x02, 0x00, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x47, 0x33, 0x32, 0x33, 0x73, 0x37, 0xCD, 0x01, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x30, 0xCD, 0x32, 0x7D, 0x8C, 0x73, 0x0C, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x30, 0xCC, 0x30, 0xC7, 0x74, 0x43, 0x07, 0x0C, 0x1F, 0x00, 0x00,
0x05, 0x00, 0x00, 0xF0, 0x4F, 0x2C, 0x2C, 0x2C, 0xF1, 0x0F, 0x00, 0x00, 0x00, 0x00,
0x04, 0x38, 0x0C, 0x0C, 0x03, 0x0C, 0x0C, 0x38, 0x00, 0x00, 0x00,
0x02, 0x32, 0x33, 0x33, 0x13, 0x00,
0x04, 0x0B, 0x0C, 0x0C, 0x30, 0x0C, 0x0C, 0x0B, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x1D, 0x72, 0x37, 0xD2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x04, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x08, 0x07, 0x00, 0x1F, 0x00, 0x7F, 0x00, 0xFF, 0x01, 0xFF, 0x07, 0xFF, 0x1F, 0xFF, 0x7F, 0xFF, 0x1B, 0xBF, 0x01, 0x1B, 0x00,
0x0C, 0x00, 0x40, 0xFF, 0x00, 0x00, 0xF8, 0xF0, 0x3F, 0xEE, 0x2C, 0x30, 0xCB, 0x0B, 0x30, 0x42, 0xC3, 0x33, 0x00, 0x03, 0x30, 0x00, 0xF3, 0x33, 0x00, 0x03, 0x30, 0x00, 0xFF, 0x3F, 0x00,
0x0C, 0xC2, 0x00, 0x00, 0xCB, 0x00, 0x00, 0xEE, 0xC0, 0xFF, 0xF8, 0xB0, 0xC0, 0xFF, 0x2C, 0xC0, 0x00, 0x0C, 0xCF, 0x00, 0x0C, 0xC0, 0x00, 0xCC, 0xCF, 0x00, 0x0C, 0xC0, 0x00, 0xFC, 0xFF,
0x0A, 0x00, 0x00, 0x0D, 0x00, 0x70, 0x00, 0x00, 0xF3, 0xFF, 0xD3, 0x03, 0xE0, 0x3C, 0x3F, 0x38, 0x03, 0xD0, 0x33, 0xFF, 0x38, 0x03, 0xE0, 0xF0, 0xFF, 0x03,
0x0C, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x8B, 0xF7, 0x0C, 0x13, 0x9F, 0x3B, 0x37, 0x00, 0xC0, 0x23, 0xFF, 0xFF, 0x8B, 0x03, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0A, 0xD0, 0x7F, 0x80, 0x03, 0x2C, 0x0D, 0x00, 0x37, 0x00, 0xC0, 0xF3, 0xFF, 0x3C, 0xFF, 0xCF, 0x03, 0x00, 0xDC, 0x00, 0x70, 0x38, 0xC0, 0x02, 0xFD, 0x07,
0x0A, 0x00, 0x00, 0x00, 0xFC, 0x03, 0xF0, 0xFF, 0xC0, 0xFF, 0x3F, 0xFC, 0xFF, 0xC3, 0xFF, 0x3F, 0xFC, 0xFF, 0x03, 0xFF, 0x0F, 0xC0, 0x3F, 0x00, 0x00, 0x00,
0x0A, 0xFF, 0xFF, 0x3F, 0x00, 0xC0, 0x03, 0x00, 0x3C, 0xF0, 0xC0, 0xC3, 0x3A, 0x3C, 0x0B, 0xCE, 0x2B, 0x80, 0x7E, 0x00, 0xD0, 0x03, 0x00, 0xFC, 0xFF, 0xFF,
0x0A, 0x00, 0x00, 0xC0, 0xFF, 0x3F, 0xFC, 0xFF, 0xC3, 0xFF, 0x3F, 0xFC, 0xFF, 0xC3, 0xFF, 0x3F, 0xFC, 0xFF, 0xC3, 0xFF, 0x3F, 0xFC, 0xFF, 0x03, 0x00, 0x00,
0x0A, 0xD0, 0x7F, 0x80, 0x03, 0x2C, 0x0D, 0x0F, 0x37, 0xF0, 0xC0, 0xF3, 0xFF, 0x3C, 0xFF, 0xCF, 0x03, 0x0F, 0xDC, 0xF0, 0x70, 0x38, 0xC0, 0x02, 0xFD, 0x07,
0x0A, 0x40, 0x1F, 0x00, 0xAD, 0x07, 0xB0, 0xC5, 0x00, 0x17, 0x0C, 0x70, 0xD0, 0x00, 0x0C, 0x03, 0xBC, 0xEF, 0xB3, 0x11, 0xE0, 0x07, 0x05, 0x3C, 0x52, 0xC8,
0x0A, 0x00, 0x00, 0x00, 0xF0, 0x00, 0xC0, 0x3F, 0x00, 0xFC, 0x03, 0xC0, 0x3F, 0x00, 0xF0, 0x00, 0xC0, 0x30, 0xC0, 0xFF, 0x3F, 0xFC, 0xFF, 0xC3, 0xFF, 0x3F,
0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xFC, 0xFF, 0x0F, 0xFC, 0xFF, 0x3F, 0xFC, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0xB8, 0xE0, 0x2F, 0xFF, 0xE3, 0x2F, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0A, 0xD0, 0x7F, 0x80, 0xFF, 0x2F, 0xFD, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0x7F, 0xF8, 0xFF, 0x02, 0xFD, 0x07,
0x0A, 0x40, 0x01, 0x00, 0x02, 0x00, 0xC8, 0x07, 0x10, 0xC3, 0x00, 0x31, 0x0D, 0x00, 0xFD, 0x01, 0x00, 0x74, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0A, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0xF0, 0xF0, 0x00, 0x0F, 0x0F, 0xF0, 0xF0, 0x00, 0x0F, 0x0F, 0xF0, 0xF0, 0x00, 0x0F, 0x0F, 0xF0, 0xF0, 0x00, 0x00, 0x00,
0x0A, 0x40, 0x05, 0x80, 0xFF, 0x8B, 0x1E, 0xD0, 0x2E, 0x00, 0xF0, 0x00, 0xE0, 0xFF, 0x0B, 0x00, 0x0F, 0x00, 0xB8, 0x03, 0xB0, 0xE2, 0xFF, 0x02, 0x50, 0x01,
0x08, 0xFF, 0x07, 0x03, 0x1E, 0x03, 0x73, 0x03, 0xEF, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0xFF, 0xFF,
0x0B, 0x00, 0x00, 0x00, 0xE4, 0x2F, 0xE0, 0x1B, 0x0C, 0x1D, 0x00, 0xFF, 0x03, 0xBE, 0xF0, 0xC1, 0x01, 0xAD, 0x34, 0xC0, 0x36, 0x0B, 0x30, 0xDC, 0xE4, 0x07, 0xFD, 0x1B, 0x00,
0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x02, 0xA0, 0xAA, 0x00, 0xA8, 0xC2, 0x0F, 0x2A, 0xFF, 0x03, 0xCA, 0x3F, 0x80, 0xFC, 0x0F, 0x20, 0x0F, 0x00, 0x00, 0x00, 0x00,
0x0C, 0x00, 0xC0, 0x01, 0x00, 0xC0, 0x07, 0xAA, 0xEA, 0x1F, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xAA, 0xEA, 0x1F, 0x00, 0xC0, 0x07, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x00,
0x0C, 0x40, 0x03, 0x00, 0xD0, 0x03, 0x00, 0xF4, 0xAB, 0xAA, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xF4, 0xAB, 0xAA, 0xD0, 0x03, 0x00, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00,
0x09, 0xFE, 0xFF, 0xE3, 0xFF, 0x0F, 0xAA, 0x3E, 0x0A, 0xF8, 0x2E, 0xE0, 0xBF, 0x80, 0xFF, 0xAA, 0xFE, 0xFF, 0xE2, 0xFF, 0x02, 0x02, 0x00, 0x00,
0x09, 0x00, 0x80, 0x04, 0xD0, 0xE2, 0xFF, 0x02, 0x00, 0x00, 0xFF, 0x6F, 0x00, 0x40, 0xE6, 0xAF, 0x50, 0x00, 0x09, 0x00, 0x20, 0x00, 0x64, 0x00,
0x09, 0xE0, 0x3F, 0x70, 0x60, 0x63, 0xC0, 0xE4, 0x80, 0xC2, 0x03, 0x07, 0x0F, 0x1E, 0x6C, 0xFF, 0x27, 0xFF, 0x3F, 0xE0, 0x2F, 0x00, 0x00, 0x00,
0x09, 0x44, 0x44, 0x00, 0x12, 0x41, 0x88, 0x04, 0x21, 0x21, 0x84, 0x48, 0x20, 0x23, 0xC2, 0xCC, 0x08, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
0x09, 0x00, 0x1D, 0x00, 0x1D, 0x00, 0x78, 0x00, 0xB4, 0x07, 0xF0, 0x2F, 0xC0, 0xFB, 0x00, 0xBE, 0x02, 0xF4, 0x07, 0xFD, 0xFF, 0x01, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x01, 0x00, 0x19, 0x00, 0xA8, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x3F, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0xFC, 0xFF, 0x3F, 0x00, 0xF0, 0xDC, 0xCB, 0x03, 0x00, 0xFF, 0xFF, 0x4F, 0x07, 0x40, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x0F, 0xFF, 0x3F, 0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0A, 0xFF, 0xFF, 0x3F, 0x00, 0xC0, 0x07, 0x00, 0xBD, 0x02, 0xE8, 0xB3, 0xE0, 0x3C, 0xAC, 0xC3, 0x03, 0x0F, 0x3C, 0x00, 0xC0, 0x03, 0x00, 0xFC, 0xFF, 0xFF,
0x0B, 0xC0, 0xC8, 0xC0, 0x91, 0x1B, 0xCD, 0x36, 0xE7, 0x00, 0x47, 0x03, 0xA7, 0x80, 0x36, 0xFD, 0xFF, 0xC1, 0x9B, 0xF9, 0xB8, 0xB8, 0xB8, 0xB7, 0x99, 0xF7, 0xFF, 0xFF, 0x0F,
0x0B, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xF0, 0x03, 0x00, 0xFC, 0x00, 0xC0, 0xFF, 0x00, 0xF0, 0x3F, 0x00, 0xFF, 0x3F, 0xF0, 0xFF, 0x3F, 0xFC, 0xFF, 0xCF, 0xFF, 0xFF, 0x0F,
0x08, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x1F, 0xCB, 0x30, 0xC3, 0x3F, 0xC7, 0x00, 0x7E, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0A, 0xFC, 0xFF, 0xC3, 0xFF, 0x3F, 0x0C, 0x00, 0xC3, 0xFC, 0x33, 0x0C, 0x24, 0xC3, 0xC0, 0x31, 0x0C, 0x06, 0xC3, 0x30, 0x30, 0x0C, 0x00, 0xC3, 0xFF, 0x3F,
0x0A, 0xFF, 0x3F, 0x30, 0x00, 0x03, 0xC3, 0x30, 0x30, 0x3F, 0xFF, 0xFF, 0x3F, 0x3C, 0x00, 0xFF, 0xFF, 0xFF, 0x0C, 0x0C, 0xC3, 0xC0, 0x00, 0x0C, 0xFC, 0xFF,
0x0A, 0x00, 0x00, 0xC0, 0xFF, 0x00, 0xFC, 0x0F, 0xC0, 0xFF, 0x00, 0xFC, 0x0F, 0xC0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x3C, 0x00, 0xC0, 0x03, 0xF0, 0x3F, 0x00, 0xFF, 0x03, 0x00, 0x00,
0x09, 0xE0, 0x2F, 0xF0, 0xFF, 0xE3, 0xB8, 0xEC, 0x9B, 0xF9, 0xBF, 0xF8, 0xBF, 0x99, 0xEF, 0xB8, 0x2C, 0xFF, 0x3F, 0xE0, 0x2F, 0x00, 0x00, 0x00,
0x04, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
0x03, 0x87, 0x87, 0xC3, 0x30, 0x0C, 0xE3, 0xDE, 0x01,
0x03, 0x74, 0xBB, 0x0C, 0xC3, 0x30, 0x2C, 0x2D, 0x0D,
0x05, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x0F,
0x05, 0x00, 0x00, 0xD0, 0xC7, 0x34, 0xC3, 0x0C, 0x73, 0x4C, 0x1F, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x03, 0x0F, 0x39, 0xC0, 0x00, 0x43, 0x2F, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0xD0, 0x87, 0x30, 0x60, 0x60, 0x60, 0xC0, 0x3F, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0xD0, 0x87, 0x30, 0xB8, 0x00, 0x23, 0x4C, 0x1F, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x0E, 0x36, 0xC6, 0xFC, 0x03, 0x0C, 0x30, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0xF0, 0xCB, 0x00, 0x7F, 0x40, 0x13, 0x8C, 0x1F, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0xD0, 0xCB, 0x10, 0x2F, 0x4C, 0x33, 0x4C, 0x1F, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0xF0, 0x0F, 0x30, 0x60, 0x60, 0xC0, 0x00, 0x03, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0xD0, 0xC7, 0x30, 0x7D, 0x4C, 0x33, 0x4C, 0x1F, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0xD0, 0xC7, 0x30, 0xC6, 0xE0, 0x03, 0x8C, 0x1F, 0x00, 0x00, 0x00,
0x04, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
0x03, 0xC0, 0xF0, 0x3C, 0xCF, 0xF3, 0x3C, 0x03, 0x00,
0x03, 0x00, 0xCC, 0xF3, 0x3C, 0xCF, 0xF3, 0x30, 0x00,
0x05, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00,
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x03, 0x30, 0xC0, 0x0F, 0x30, 0x00, 0x00,
0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0xD0, 0x7F, 0x40, 0xFF, 0x1F, 0xFC, 0xFF, 0x43, 0xFF, 0x1F, 0x40, 0x15, 0x00, 0x00, 0x00,
0x0A, 0xE4, 0x06, 0x90, 0x91, 0x01, 0x06, 0x24, 0x30, 0x90, 0x1B, 0x46, 0x6E, 0x96, 0xB9, 0x91, 0xE4, 0x06, 0x0C, 0x18, 0x90, 0x40, 0x46, 0x06, 0x90, 0x1B,
0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3F, 0x02, 0xC2, 0xAB, 0xAA, 0x3E, 0x20, 0xE0, 0xAB, 0xAA, 0x3E, 0x02, 0xC2, 0xFF, 0xFF, 0x0F, 0x00, 0x00,
0x0A, 0x00, 0x00, 0x00, 0x08, 0x02, 0xC0, 0x30, 0x00, 0x0C, 0x03, 0xF0, 0xFF, 0x00, 0xFE, 0x0B, 0xD0, 0x7F, 0x00, 0xA4, 0x01, 0x00, 0x0A, 0x00, 0xA0, 0x00,
0x0A, 0x00, 0x80, 0x00, 0x81, 0x24, 0x10, 0x85, 0x00, 0x20, 0x66, 0x40, 0x15, 0x45, 0x62, 0x90, 0x4D, 0xD0, 0xF1, 0x23, 0x01, 0xFD, 0x41, 0x41, 0x07, 0x00,
0x0A, 0x00, 0x05, 0x00, 0xA0, 0x00, 0x40, 0x1F, 0x00, 0xF8, 0x02, 0xD0, 0x7F, 0x00, 0xFE, 0x0B, 0xF0, 0xEF, 0x00, 0xFF, 0x0D, 0xD0, 0x77, 0x00, 0xF4, 0x01,
0x0A, 0x00, 0x20, 0x00, 0x00, 0x3C, 0x00, 0xD4, 0x01, 0xD0, 0x06, 0x40, 0x7F, 0x00, 0xFD, 0x01, 0xF4, 0x07, 0xD0, 0x1F, 0x00, 0x7F, 0x00, 0xD0, 0x01, 0x00,
0x0A, 0x40, 0x15, 0x00, 0xFE, 0x0B, 0x88, 0x2F, 0x52, 0xF0, 0x50, 0x01, 0x0A, 0xD4, 0xAF, 0x7F, 0xFD, 0xF5, 0xC7, 0x0B, 0x3E, 0x70, 0xD0, 0x00, 0xA8, 0x02,
0x0A, 0x80, 0x2F, 0x80, 0x5F, 0x2F, 0x0C, 0x00, 0xC3, 0x00, 0x30, 0x0C, 0x00, 0xC3, 0x01, 0x34, 0x34, 0xC0, 0x01, 0x07, 0x0D, 0xD0, 0x75, 0x00, 0xF4, 0x01,
0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0xF4, 0x01, 0xC0, 0x3F, 0x00, 0xF0, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0A, 0x00, 0x00, 0x00, 0xF0, 0x00, 0xE0, 0xEF, 0x00, 0xBB, 0x0B, 0xA0, 0xAA, 0x00, 0xAA, 0x0A, 0x80, 0x19, 0x00, 0x64, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00,
0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x10, 0x2D, 0x80, 0xE7, 0x0B, 0xBE, 0xF8, 0xFA, 0x02, 0xFE, 0x0B, 0x80, 0x2F, 0x00, 0x50, 0x00,
0x0A, 0x00, 0x05, 0x00, 0xF8, 0x02, 0xE0, 0xBF, 0x80, 0xAF, 0x2F, 0xBE, 0xE0, 0xDB, 0x02, 0x78, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0A, 0x00, 0x05, 0x00, 0xA0, 0x00, 0x40, 0x1F, 0x50, 0xFE, 0x5B, 0xFD, 0xFF, 0x47, 0xFF, 0x1F, 0xE0, 0xBF, 0x00, 0xFE, 0x0B, 0xF0, 0xF5, 0x40, 0x01, 0x14,
0x0A, 0x40, 0x1A, 0x00, 0x09, 0x06, 0x20, 0x80, 0x00, 0x02, 0x08, 0xFC, 0xFF, 0xC3, 0x00, 0x30, 0x0C, 0x00, 0xC3, 0x00, 0x30, 0x0C, 0x00, 0xC3, 0xFF, 0x3F,
0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x0A, 0xF0, 0xFF, 0x00, 0xAA, 0x0A, 0xF0, 0xFF, 0x00, 0x00, 0x00,
0x09, 0xE0, 0x2F, 0xF0, 0xFF, 0xE3, 0xFF, 0xED, 0xFF, 0xE1, 0xDF, 0xE1, 0x2F, 0xE1, 0xEF, 0xE2, 0x2F, 0xEF, 0x3F, 0xE0, 0x2F, 0x00, 0x00, 0x00,
0x0A, 0xC0, 0x31, 0x00, 0x30, 0x01, 0x40, 0x34, 0x00, 0xCC, 0x00, 0x00, 0x0A, 0x00, 0xF8, 0x02, 0xE0, 0xBF, 0x80, 0xFF, 0x2F, 0xFE, 0xFF, 0xFB, 0xFF, 0xFF,
0x0A, 0x00, 0x00, 0x80, 0xFF, 0x2F, 0xFC, 0xFF, 0xC3, 0x07, 0x3D, 0x3C, 0xC0, 0xC3, 0x03, 0x3C, 0x7C, 0xD0, 0xC3, 0xFF, 0x3F, 0xF8, 0xFF, 0x02, 0x00, 0x00,
0x0A, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x3C, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0xC0, 0xF3, 0x3C, 0x3C, 0xCF, 0x03, 0x00, 0x00,
0x0A, 0xB9, 0x91, 0xE3, 0x46, 0x2E, 0x1B, 0xB9, 0x61, 0xE4, 0x06, 0x91, 0x1B, 0x41, 0x6E, 0x24, 0xB9, 0x91, 0xE3, 0x46, 0x2E, 0x1B, 0xB9, 0x01, 0x00, 0x00,
0x0A, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x0C, 0xC0, 0x23, 0x00, 0x80, 0x08, 0x00, 0x20, 0x0F, 0xC0, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0A, 0xE0, 0x2F, 0xC0, 0x01, 0x0D, 0x06, 0x40, 0x32, 0x00, 0x30, 0x03, 0x00, 0x33, 0x00, 0x30, 0x06, 0x40, 0xC2, 0x01, 0x0D, 0xE0, 0x2F, 0x00, 0x00, 0x00,
0x0A, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x23, 0x80, 0x32, 0x0A, 0x0D, 0xC3, 0xD1, 0x10, 0x1C, 0x0D, 0xC0, 0x81, 0x02, 0x0A, 0xE0, 0x2F, 0x00, 0x54, 0x00,
0x0A, 0x00, 0x00, 0x00, 0xFC, 0x03, 0xB0, 0xE0, 0x00, 0x03, 0x0C, 0x30, 0xC0, 0x00, 0x0B, 0x0E, 0xC0, 0x3F, 0x00, 0xAC, 0x03, 0xC0, 0x3A, 0x00, 0xAC, 0x03,
0x05, 0x6F, 0xBC, 0xF1, 0xC6, 0x1B, 0x6F, 0xBC, 0xF1, 0xC6, 0x1B, 0x6F, 0x00, 0x00,
0x08, 0xE4, 0x6F, 0xE4, 0x6F, 0xE4, 0x6F, 0xE4, 0x6F, 0xE4, 0x6F, 0xE4, 0x6F, 0xE4, 0x6F, 0xE4, 0x6F, 0xE4, 0x6F, 0x00, 0x00,
0x09, 0x00, 0xE4, 0x03, 0x90, 0x0F, 0x40, 0x3E, 0x00, 0xF9, 0x00, 0xE4, 0x03, 0x90, 0x0F, 0x40, 0x3E, 0x00, 0xF9, 0x00, 0xE4, 0x03, 0x00, 0x00,
0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0xFF, 0x03, 0xF0, 0x3F, 0x00, 0xFF, 0x03, 0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0A, 0x08, 0x82, 0xE0, 0xBA, 0x2E, 0x08, 0x82, 0x80, 0x20, 0x08, 0xAE, 0xEB, 0x82, 0x20, 0x08, 0x08, 0x82, 0xE0, 0xBA, 0x2E, 0x08, 0x82, 0x00, 0x00, 0x00,
0x0A, 0x00, 0x30, 0x00, 0x00, 0x03, 0x30, 0xFC, 0x00, 0x43, 0x07, 0xFC, 0x20, 0x40, 0x07, 0x30, 0x20, 0x00, 0x03, 0x00, 0xFC, 0x00, 0x40, 0x07, 0x00, 0x20,
0x0A, 0x00, 0x43, 0xC0, 0x20, 0x1D, 0x20, 0x61, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x84, 0x01, 0x24, 0xB4, 0xF1, 0x01, 0xFE, 0x0F, 0xD0, 0x0F, 0x00, 0xFC,
0x0A, 0x00, 0x00, 0x00, 0x54, 0x00, 0x90, 0x1A, 0x40, 0xFE, 0x06, 0xE4, 0x6F, 0x40, 0xFE, 0x06, 0x90, 0x1A, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x88, 0x88, 0x88, 0x55, 0x55, 0x55, 0xFF, 0x00, 0x54, 0x55, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0A, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x02, 0x00, 0x64, 0x00, 0xA5, 0x6B, 0x01, 0x64, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x0A, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xFF, 0x86, 0xC0, 0x00, 0x2C, 0x40, 0xFE, 0x0B, 0xE4, 0xBF, 0x0C, 0xC0, 0xF2, 0x6F, 0x08, 0x0C, 0x00, 0x00, 0x00, 0x00,
0x0A, 0x00, 0x05, 0x00, 0xF4, 0x01, 0xC0, 0x30, 0x00, 0x0D, 0x07, 0xF0, 0xF0, 0x40, 0x5F, 0x1F, 0xFC, 0xFA, 0xD3, 0xFF, 0x7F, 0xFF, 0xF0, 0xDF, 0xFF, 0x7F,
0x0C, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x1E, 0x00, 0x80, 0x07, 0x00, 0xE0, 0x01, 0x00, 0x78, 0x60, 0x00, 0x24, 0x98, 0x01, 0x80, 0x42, 0x06, 0x00, 0x00, 0x19, 0x00, 0x00, 0x04,
0x0A, 0x00, 0x00, 0x40, 0x7F, 0x00, 0x5C, 0x0D, 0xC0, 0xC1, 0x00, 0x1C, 0x0C, 0x40, 0xFF, 0x01, 0x00, 0x74, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0A, 0x00, 0x00, 0x01, 0x00, 0x68, 0x00, 0xA2, 0x02, 0x80, 0x0A, 0x00, 0x25, 0x00, 0x44, 0x08, 0x10, 0x01, 0x40, 0x04, 0x00, 0x14, 0x00, 0x10, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x03, 0x08, 0x00, 0x00,
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
0x05, 0x74, 0x30, 0xC3, 0x0D, 0x33, 0xDC, 0x30, 0x93, 0xD9, 0xC0, 0x89, 0xD1, 0x01,
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
};
short font_ptrs[] = {
0x0000, 0x000E, 0x001C, 0x002A, 0x0038, 0x0046, 0x0054, 0x0062,
0x0070, 0x007E, 0x008C, 0x009A, 0x00A8, 0x00B6, 0x00C4, 0x00D2,
0x00E0, 0x00EE, 0x00FC, 0x010A, 0x0118, 0x0126, 0x0134, 0x0142,
0x0150, 0x015E, 0x016C, 0x017A, 0x0188, 0x0196, 0x01A4, 0x01B2,
0x01C0, 0x01CE, 0x01D7, 0x01E5, 0x01F5, 0x0205, 0x0218, 0x0228,
0x0231, 0x023C, 0x0247, 0x0257, 0x0267, 0x0272, 0x0280, 0x0289,
0x0299, 0x02A9, 0x02B7, 0x02C7, 0x02D7, 0x02E7, 0x02F7, 0x0307,
0x0317, 0x0327, 0x0337, 0x0340, 0x034B, 0x035B, 0x036B, 0x037B,
0x038B, 0x03A0, 0x03B0, 0x03C0, 0x03D0, 0x03E0, 0x03F0, 0x0400,
0x0410, 0x0420, 0x042B, 0x043B, 0x044E, 0x045E, 0x0473, 0x0486,
0x0499, 0x04A9, 0x04BC, 0x04CC, 0x04DC, 0x04EC, 0x04FF, 0x050F,
0x0524, 0x0537, 0x0547, 0x055A, 0x0565, 0x0573, 0x057E, 0x0589,
0x0599, 0x05A2, 0x05B0, 0x05BE, 0x05CC, 0x05DA, 0x05E8, 0x05F3,
0x0601, 0x060F, 0x061A, 0x0625, 0x0633, 0x063E, 0x064E, 0x065C,
0x066A, 0x0678, 0x0686, 0x0691, 0x069F, 0x06AA, 0x06B8, 0x06C6,
0x06D6, 0x06E4, 0x06F2, 0x0700, 0x070B, 0x0711, 0x071C, 0x072C,
0x0737, 0x074C, 0x076B, 0x078A, 0x07A4, 0x07C3, 0x07DD, 0x07F7,
0x0811, 0x082B, 0x0845, 0x085F, 0x0879, 0x0898, 0x08A8, 0x08C2,
0x08DC, 0x08F6, 0x0910, 0x0925, 0x0942, 0x095F, 0x097E, 0x099D,
0x09B5, 0x09CD, 0x09E5, 0x09FD, 0x0A15, 0x0A2D, 0x0A45, 0x0A5D,
0x0A75, 0x0A8D, 0x0AA5, 0x0ABF, 0x0ADC, 0x0AF9, 0x0B0E, 0x0B28,
0x0B42, 0x0B5C, 0x0B76, 0x0B8E, 0x0B99, 0x0BA2, 0x0BAB, 0x0BB9,
0x0BC7, 0x0BD5, 0x0BE3, 0x0BF1, 0x0BFF, 0x0C0D, 0x0C1B, 0x0C29,
0x0C37, 0x0C45, 0x0C50, 0x0C59, 0x0C62, 0x0C70, 0x0C80, 0x0C90,
0x0CAA, 0x0CC4, 0x0CDE, 0x0CF8, 0x0D12, 0x0D2C, 0x0D46, 0x0D60,
0x0D7A, 0x0D94, 0x0DAE, 0x0DC8, 0x0DE2, 0x0DFC, 0x0E16, 0x0E30,
0x0E48, 0x0E62, 0x0E7C, 0x0E96, 0x0EB0, 0x0ECA, 0x0EE4, 0x0EFE,
0x0F18, 0x0F26, 0x0F3B, 0x0F53, 0x0F6D, 0x0F87, 0x0FA1, 0x0FBB,
0x0FD5, 0x0FF2, 0x100C, 0x1026, 0x1040, 0x105F, 0x1079, 0x1093,
0x10A3, 0x10B3, 0x10C3, 0x10D3, 0x10E1, 0x10F1, 0x1101, 0x1111,
0x1121, 0x1131, 0x1141, 0x1151, 0x1161, 0x1171, 0x1181, 0x1191,
0x11A1, 0x11B1, 0x11C1, 0x11D1, 0x11E1, 0x11F1, 0x1201, 0x1211,
};
#else
extern char font_data[];
extern short font_ptrs[];
#endif
#endif

26
data/hmap.h Normal file

File diff suppressed because one or more lines are too long

22
data/icon.h Normal file

File diff suppressed because one or more lines are too long

138
data/icondoc.h Normal file
View File

@ -0,0 +1,138 @@
/**
* Powder Toy - Main source
*
* Copyright (c) 2008 - 2010 Stanislaw Skowronek.
* Copyright (c) 2010 Simon Robertshaw
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
static unsigned char icon_doc_32_png[] = {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x08, 0x06, 0x00, 0x00, 0x00, 0x73, 0x7a, 0x7a,
0xf4, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00,
0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93,
0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13,
0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x04,
0x06, 0x11, 0x21, 0x0c, 0xfc, 0x0b, 0x2f, 0xdf, 0x00, 0x00, 0x04, 0x65, 0x49, 0x44, 0x41, 0x54,
0x58, 0xc3, 0xb5, 0x96, 0x7f, 0x4c, 0xd4, 0x65, 0x1c, 0xc7, 0x5f, 0xcf, 0x73, 0xdf, 0xe3, 0x7e,
0x90, 0x8b, 0x98, 0xb8, 0x36, 0x12, 0xb8, 0x38, 0x69, 0x03, 0x4c, 0x64, 0xec, 0x6a, 0xa2, 0xd3,
0xb5, 0x74, 0x78, 0x4c, 0x42, 0x33, 0x51, 0xda, 0x5c, 0xe3, 0x97, 0x72, 0x79, 0xcc, 0x5c, 0xfd,
0x53, 0xcb, 0x50, 0x69, 0x93, 0xda, 0x9a, 0x3a, 0x0d, 0x0d, 0x99, 0xf3, 0x9f, 0x3b, 0x98, 0x89,
0x72, 0x14, 0x64, 0xb2, 0x62, 0x2b, 0x56, 0xad, 0x56, 0x20, 0xbf, 0x06, 0x3a, 0xe1, 0x1c, 0x8b,
0xed, 0x86, 0x89, 0x77, 0x96, 0x7f, 0x30, 0xf6, 0xed, 0x0f, 0xb9, 0x1b, 0xe6, 0x1d, 0x7c, 0x39,
0xe8, 0xb3, 0x3d, 0x7b, 0xbe, 0xcf, 0xb3, 0xef, 0xf3, 0x7c, 0x5f, 0xcf, 0xfb, 0xf3, 0xe3, 0xf9,
0x0a, 0x9e, 0xb4, 0xd5, 0x40, 0x0a, 0x0b, 0x37, 0x3f, 0x30, 0x0a, 0x78, 0x17, 0xb2, 0x48, 0x09,
0x33, 0x97, 0x52, 0x52, 0x52, 0xe2, 0x11, 0x42, 0xa0, 0xaa, 0x2a, 0x42, 0x08, 0x80, 0xd0, 0xb3,
0xaa, 0xaa, 0xa1, 0x17, 0x55, 0x55, 0x45, 0x55, 0x55, 0xcc, 0x66, 0x33, 0x05, 0x05, 0x05, 0x3e,
0xa7, 0xd3, 0x59, 0x73, 0xf3, 0xe6, 0xcd, 0xd6, 0x19, 0x90, 0xa8, 0x01, 0xa4, 0x10, 0x82, 0xce,
0xce, 0x4e, 0x4d, 0x1b, 0x5c, 0xe8, 0xed, 0x61, 0x6f, 0x7a, 0x26, 0x89, 0x89, 0x89, 0x2b, 0xda,
0xdb, 0xdb, 0x3f, 0xcd, 0xcb, 0xcb, 0xd3, 0xdf, 0xba, 0x75, 0xab, 0x59, 0x2b, 0x84, 0x0c, 0x33,
0xa7, 0x9f, 0x7d, 0xca, 0xf9, 0xec, 0xfc, 0xa9, 0xd3, 0x08, 0x21, 0x68, 0x68, 0x68, 0xc0, 0xe7,
0xf3, 0x19, 0x3a, 0x3a, 0x3a, 0x6a, 0xad, 0x56, 0xeb, 0x0e, 0xad, 0x6e, 0x94, 0x91, 0x14, 0xd0,
0xd2, 0x00, 0xba, 0xea, 0xeb, 0x11, 0x42, 0x30, 0x35, 0x35, 0x45, 0x57, 0x57, 0x17, 0x89, 0x89,
0x89, 0x4a, 0x5b, 0x5b, 0x5b, 0xad, 0xc5, 0x62, 0x79, 0x5d, 0x0b, 0x84, 0x24, 0x4a, 0xeb, 0x77,
0x55, 0x86, 0x20, 0x84, 0x10, 0x48, 0x29, 0x19, 0x1e, 0x1e, 0x46, 0x4a, 0x49, 0x52, 0x52, 0x92,
0xd2, 0xda, 0xda, 0x7a, 0x5c, 0x0b, 0x44, 0xd4, 0x00, 0x19, 0xc5, 0x75, 0xa1, 0x8f, 0x03, 0x48,
0x29, 0x19, 0x1f, 0x1f, 0x0f, 0xc1, 0x58, 0x2c, 0x16, 0xa5, 0xb9, 0xb9, 0x79, 0x5e, 0x25, 0xa2,
0x06, 0x98, 0x6d, 0x41, 0x97, 0x04, 0x01, 0x14, 0x45, 0x41, 0x51, 0x14, 0x52, 0x53, 0x53, 0x75,
0x4d, 0x4d, 0x4d, 0xb5, 0xc9, 0xc9, 0xc9, 0x11, 0x21, 0x16, 0x05, 0x30, 0xe0, 0x7e, 0xfb, 0x31,
0x08, 0x9f, 0xcf, 0x47, 0x42, 0x42, 0x02, 0xf1, 0xf1, 0xf1, 0x58, 0xad, 0x56, 0xb2, 0xb3, 0xb3,
0x71, 0x3a, 0x9d, 0x3a, 0x87, 0xc3, 0x71, 0x24, 0x21, 0x21, 0xe1, 0x9d, 0x70, 0x10, 0x32, 0xd2,
0x89, 0xe6, 0x8d, 0x01, 0xb7, 0x83, 0xf4, 0x3d, 0x67, 0x1e, 0x5b, 0xa3, 0xd7, 0xeb, 0x31, 0x9b,
0xcd, 0xc4, 0xc6, 0xc6, 0x32, 0x3d, 0x3d, 0x4d, 0x20, 0x10, 0x60, 0x64, 0x64, 0x84, 0x93, 0x27,
0x4f, 0xc6, 0x66, 0x66, 0x66, 0x96, 0x6a, 0x06, 0x98, 0x2d, 0x6b, 0xb8, 0x76, 0x65, 0x70, 0x90,
0xcc, 0xe2, 0xba, 0xd0, 0x78, 0xc0, 0xed, 0x08, 0xf9, 0x3e, 0x26, 0x26, 0x06, 0xa3, 0xd1, 0x88,
0xc1, 0x60, 0xc0, 0x64, 0x32, 0x61, 0x30, 0x18, 0x1e, 0x15, 0x1c, 0x45, 0x89, 0x05, 0xe2, 0x16,
0xed, 0x82, 0x6a, 0xcf, 0x55, 0x76, 0xa4, 0xa7, 0x87, 0xc6, 0x6f, 0x1c, 0x3b, 0xfa, 0x44, 0x40,
0x06, 0x61, 0xa4, 0x94, 0xe8, 0x74, 0x3a, 0xf4, 0x7a, 0x3d, 0x26, 0x93, 0x09, 0x40, 0xa7, 0xa5,
0x12, 0x22, 0x65, 0x64, 0xae, 0xea, 0x82, 0xc2, 0xc7, 0xc6, 0x97, 0x3e, 0x3c, 0xfc, 0x84, 0x72,
0xb3, 0x4b, 0xb8, 0x94, 0x12, 0x55, 0x55, 0x31, 0x1a, 0x8d, 0x61, 0x0f, 0xac, 0xf0, 0x3f, 0xd8,
0x7f, 0x21, 0x66, 0x5c, 0x00, 0x20, 0x16, 0x1d, 0x03, 0x59, 0x7b, 0x76, 0xa3, 0xb5, 0x52, 0x06,
0x9b, 0x94, 0x32, 0x08, 0xc0, 0xa2, 0xb3, 0xa0, 0xa7, 0xb1, 0x29, 0xf4, 0x5c, 0x7a, 0xea, 0x04,
0xfd, 0x2e, 0x07, 0x73, 0xed, 0x11, 0xec, 0x75, 0x3a, 0x9d, 0xe6, 0xdb, 0x10, 0xad, 0x97, 0x51,
0x43, 0xd5, 0x41, 0x1a, 0xe6, 0x71, 0x45, 0xd0, 0x22, 0x01, 0x44, 0x5d, 0x07, 0xa2, 0xa9, 0x94,
0x0b, 0xaa, 0x84, 0x5a, 0xfd, 0xbb, 0xab, 0xe6, 0x98, 0xa6, 0x5b, 0x33, 0x52, 0x66, 0x45, 0xad,
0x40, 0xb5, 0xe7, 0x2a, 0xa5, 0xa7, 0x4e, 0x60, 0x2f, 0x2c, 0x5c, 0x7a, 0x05, 0xe6, 0x02, 0x08,
0x06, 0xdd, 0xd8, 0xa8, 0x97, 0x86, 0xaa, 0x83, 0xd8, 0x7a, 0xcf, 0x92, 0xb5, 0xbb, 0x48, 0x13,
0x84, 0x66, 0x80, 0xb9, 0x82, 0x70, 0x5f, 0xe7, 0x14, 0x17, 0x7a, 0x7b, 0xe8, 0xfc, 0xe6, 0x1a,
0xab, 0xf2, 0xed, 0x68, 0x0d, 0x97, 0x48, 0x7b, 0x2a, 0x0b, 0x91, 0xcc, 0xba, 0x75, 0x2b, 0x5d,
0xf5, 0xe7, 0xe9, 0xaa, 0x3f, 0xcf, 0x85, 0x1b, 0x3d, 0x20, 0xa0, 0xb8, 0xe6, 0x63, 0xfe, 0x0e,
0x04, 0xd8, 0x75, 0xec, 0x28, 0x97, 0x0e, 0x7f, 0xb4, 0x34, 0x0a, 0x44, 0x32, 0xcf, 0x5e, 0x0b,
0xd5, 0x9e, 0x16, 0x06, 0xdc, 0x0e, 0x6c, 0x7d, 0xe7, 0x98, 0xbc, 0x37, 0x49, 0x4e, 0x6e, 0x2e,
0x4f, 0x2d, 0x5b, 0x86, 0x7d, 0xfb, 0x76, 0xaa, 0x3d, 0x57, 0xb1, 0xda, 0xed, 0x54, 0x7b, 0x5a,
0x34, 0xef, 0xa9, 0x09, 0x20, 0xe8, 0xe3, 0x8a, 0xef, 0xa7, 0x00, 0x95, 0xa1, 0x35, 0x07, 0xb8,
0xfe, 0x5c, 0x11, 0x5b, 0xc6, 0x9a, 0x58, 0x99, 0x92, 0xc2, 0x2b, 0xf9, 0xf9, 0xd8, 0x7a, 0xcf,
0xd2, 0xe2, 0x72, 0x03, 0x2a, 0x63, 0xa3, 0xa3, 0xac, 0xaf, 0x28, 0xd7, 0xa4, 0x80, 0xa2, 0x45,
0xae, 0xee, 0xc6, 0x26, 0xd6, 0xee, 0x2e, 0xa2, 0xcc, 0xe9, 0xc4, 0x7b, 0xfb, 0x36, 0x69, 0xdd,
0xa7, 0x39, 0xf7, 0xbb, 0x09, 0xef, 0x6a, 0x1b, 0x65, 0x0f, 0xae, 0x71, 0xc4, 0xfb, 0x2c, 0x5f,
0xae, 0xd9, 0x42, 0x61, 0x31, 0xec, 0x7c, 0xf0, 0x2d, 0x30, 0xc4, 0x91, 0x95, 0x2b, 0x97, 0x46,
0x81, 0x0d, 0xfb, 0x2a, 0x38, 0x74, 0xf1, 0x22, 0x55, 0x1f, 0xbc, 0x8f, 0xad, 0xef, 0x2c, 0x77,
0xbc, 0x5e, 0xf6, 0x77, 0x4e, 0xb1, 0xaf, 0xa4, 0x14, 0x21, 0x04, 0xc3, 0x59, 0x07, 0x58, 0xb7,
0x69, 0x23, 0x57, 0x5c, 0x6e, 0x9e, 0x8e, 0x7b, 0x06, 0x21, 0x1e, 0x05, 0xea, 0x56, 0x0d, 0xe9,
0x39, 0x67, 0x1a, 0x0a, 0x21, 0xd8, 0x50, 0x51, 0x4e, 0xc0, 0xef, 0xa7, 0x2c, 0xe6, 0x17, 0x4a,
0x5e, 0xcc, 0x22, 0xa3, 0xb8, 0x8e, 0xa1, 0xbe, 0x3e, 0x02, 0x81, 0x00, 0x3f, 0xfc, 0xf6, 0x2b,
0xdf, 0xb5, 0xb5, 0xe1, 0xbd, 0x3b, 0x41, 0x5f, 0x77, 0x0f, 0x39, 0xb9, 0xeb, 0x38, 0x73, 0xbc,
0x96, 0x8c, 0xe2, 0x3a, 0x6c, 0xeb, 0xd7, 0x73, 0x67, 0x64, 0x84, 0x55, 0xf9, 0x76, 0xec, 0xef,
0xbd, 0x3b, 0x67, 0x5a, 0x47, 0x54, 0x20, 0xb7, 0xbc, 0x8c, 0x07, 0x7e, 0x3f, 0x69, 0x19, 0x19,
0xbc, 0xe9, 0xf9, 0x8b, 0x7e, 0x57, 0x25, 0xcd, 0x03, 0x03, 0x6c, 0xde, 0xb6, 0x0d, 0x57, 0x41,
0x3c, 0x83, 0x37, 0x7a, 0x71, 0xbf, 0xb6, 0x9c, 0x2d, 0x63, 0x8d, 0xe4, 0xbf, 0xba, 0x99, 0x43,
0xcb, 0x87, 0x10, 0x42, 0xd0, 0xef, 0xaa, 0xc4, 0x7f, 0x7f, 0x92, 0xfb, 0x93, 0x93, 0x6c, 0xcc,
0xcb, 0x23, 0xe0, 0xf7, 0xcf, 0x59, 0x09, 0x23, 0xfe, 0x0f, 0x7c, 0x51, 0xf8, 0x02, 0x8d, 0xe3,
0x71, 0xdc, 0x9b, 0xb8, 0xcb, 0x8a, 0xac, 0x2c, 0xba, 0x9f, 0xdf, 0xc4, 0x1f, 0x1d, 0xd7, 0x11,
0x42, 0xf0, 0xd9, 0xc4, 0x0a, 0xf6, 0xbf, 0xb5, 0x93, 0x31, 0x9d, 0x0e, 0xef, 0xf8, 0x9f, 0x74,
0x7b, 0x5a, 0x90, 0xf9, 0x0e, 0x3e, 0xa9, 0x85, 0xcf, 0xbf, 0xfe, 0x0a, 0x23, 0x0f, 0xc9, 0xb1,
0xbd, 0xc4, 0xda, 0xbb, 0x3f, 0xa2, 0xa6, 0xa6, 0xd1, 0x5d, 0xf2, 0x13, 0x6d, 0x97, 0x2f, 0x87,
0x4f, 0xcf, 0x30, 0x73, 0x2f, 0x03, 0x99, 0x80, 0x69, 0x89, 0xff, 0x53, 0x1e, 0x02, 0x7d, 0xc0,
0xcf, 0xf3, 0x01, 0x98, 0x81, 0x65, 0x33, 0xfd, 0x52, 0xda, 0x3f, 0x40, 0x60, 0xa6, 0x0f, 0xd9,
0xbf, 0x2f, 0x89, 0x69, 0x46, 0x25, 0x68, 0x1c, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e,
0x44, 0xae, 0x42, 0x60, 0x82
};
static unsigned char icon_doc_16_png[] = {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff,
0x61, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00,
0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93,
0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13,
0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x04,
0x06, 0x11, 0x21, 0x22, 0x20, 0xdd, 0x22, 0x10, 0x00, 0x00, 0x01, 0x95, 0x49, 0x44, 0x41, 0x54,
0x38, 0xcb, 0x95, 0x93, 0x3d, 0x4b, 0x82, 0x51, 0x14, 0xc7, 0x7f, 0xc7, 0x24, 0x4d, 0x7c, 0x96,
0x96, 0x50, 0x48, 0x14, 0x8a, 0x86, 0x16, 0x23, 0x28, 0xea, 0x23, 0xd8, 0xd0, 0xcb, 0x20, 0x86,
0x6b, 0x11, 0xb4, 0xd8, 0x10, 0x6d, 0x81, 0xbd, 0x7c, 0x02, 0x5b, 0xa2, 0x10, 0x47, 0x6b, 0x2a,
0xa7, 0x1c, 0x0b, 0x24, 0xb3, 0xa9, 0xf7, 0xa1, 0x25, 0xb2, 0x20, 0xe4, 0x59, 0xad, 0xd0, 0xb2,
0xdb, 0x50, 0x8f, 0x3c, 0xbe, 0x3c, 0x50, 0x07, 0x2e, 0xdc, 0x73, 0xef, 0x39, 0xff, 0xf3, 0x3b,
0x87, 0x7b, 0x45, 0x29, 0x05, 0x80, 0x88, 0x0c, 0x02, 0x1a, 0x16, 0xa6, 0x94, 0x3a, 0x6b, 0x77,
0x6e, 0x37, 0xed, 0xb5, 0x68, 0x34, 0x9a, 0x37, 0x1c, 0x8f, 0xcf, 0xc7, 0x4b, 0xb1, 0x08, 0x40,
0xa9, 0x54, 0x42, 0x44, 0xc6, 0xda, 0x89, 0x98, 0x05, 0x04, 0xa0, 0x50, 0x28, 0x10, 0xcf, 0x1c,
0x12, 0x9f, 0x9c, 0xaa, 0x5f, 0xf4, 0x0e, 0x05, 0xd1, 0x75, 0x3d, 0x2f, 0x22, 0xe3, 0x4a, 0xa9,
0xbc, 0x59, 0xc0, 0x66, 0x76, 0x44, 0x04, 0xa0, 0x21, 0x19, 0xe0, 0xfe, 0x34, 0x8f, 0xcb, 0xe5,
0x42, 0xd7, 0xf5, 0x53, 0x11, 0x19, 0xb3, 0x12, 0x10, 0x43, 0xa4, 0x79, 0x01, 0x38, 0x1c, 0x0e,
0xb3, 0xc8, 0x78, 0xdb, 0x16, 0x8c, 0xe0, 0xe0, 0x6c, 0x84, 0x8b, 0xf4, 0x5e, 0x03, 0x99, 0xd7,
0xeb, 0x05, 0x20, 0x10, 0x08, 0xd4, 0x8b, 0x35, 0x13, 0xd8, 0x8c, 0x8a, 0x97, 0x7b, 0xfb, 0xf5,
0xea, 0xf3, 0x5b, 0x09, 0x1e, 0x0e, 0x96, 0xd1, 0x34, 0x0d, 0x4d, 0xd3, 0xf0, 0xfb, 0xfd, 0x0d,
0x79, 0x2d, 0x04, 0x06, 0x85, 0x61, 0xc9, 0xd8, 0x12, 0x49, 0xc0, 0x6e, 0xff, 0x09, 0x75, 0x3a,
0x9d, 0x96, 0x04, 0xd2, 0x9c, 0xdc, 0xce, 0x7e, 0x63, 0xe4, 0x5f, 0x43, 0x0c, 0x6f, 0xac, 0xd3,
0x44, 0xf7, 0x37, 0x82, 0x78, 0x26, 0xc3, 0x5c, 0x22, 0x41, 0x68, 0x7a, 0xfa, 0x4f, 0x04, 0xf5,
0x21, 0xde, 0xa5, 0x17, 0x11, 0x11, 0x9e, 0x8b, 0x8f, 0x24, 0x63, 0x31, 0x46, 0x6f, 0xb6, 0x19,
0x9a, 0x8d, 0x98, 0x29, 0x6c, 0x96, 0x2d, 0x00, 0x2c, 0x1c, 0x7f, 0x92, 0xba, 0xbe, 0xe2, 0x24,
0x9b, 0xa5, 0x7f, 0x22, 0x64, 0xbe, 0x6a, 0x89, 0x6d, 0x79, 0xca, 0x7d, 0xa1, 0x10, 0xb9, 0x9d,
0x5d, 0x72, 0x3b, 0xbb, 0xa4, 0xae, 0xaf, 0x00, 0x88, 0x6e, 0x6e, 0xf2, 0x5a, 0x2e, 0x13, 0x5e,
0x5f, 0xe3, 0xe9, 0x28, 0x6b, 0x29, 0x40, 0xad, 0x56, 0x63, 0xb8, 0xf3, 0x8b, 0x81, 0x99, 0x19,
0xdc, 0x5f, 0x6f, 0x64, 0x57, 0x57, 0x78, 0xb3, 0xbb, 0xe9, 0xa9, 0x54, 0xa8, 0x54, 0x3f, 0xa8,
0xde, 0xde, 0xd1, 0xed, 0xf1, 0x34, 0xa2, 0x98, 0xbe, 0xf3, 0x08, 0xe0, 0x01, 0xba, 0x00, 0x37,
0xe0, 0x00, 0x3a, 0x0c, 0x6d, 0xa0, 0x02, 0x94, 0x81, 0x77, 0xe0, 0x45, 0x29, 0x75, 0x0e, 0xf0,
0x0d, 0xff, 0x1c, 0x7a, 0x37, 0x5c, 0xfd, 0x46, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e,
0x44, 0xae, 0x42, 0x60, 0x82
};

29
data/images.h Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,290 +0,0 @@
#!/usr/bin/env python3
import bz2
import math
import re
import argparse
CP_MAX = 0x10FFFF
FONT_CPP = "resources/font.bz2"
FONT_HEIGHT = 12
class ReadBDFError(RuntimeError):
def __init__(self, line_number, message):
super().__init__(self, 'line %i: %s' % (line_number, message))
class FontTool:
def __init__(self, file):
self.file = file
with open(self.file, 'rb') as font_cpp:
font_cpp_data = bz2.decompress(font_cpp.read())
i = 0
self.code_points = [False for _ in range(CP_MAX + 2)]
while i < len(font_cpp_data):
cp = font_cpp_data[i] | (font_cpp_data[i + 1] << 8) | (font_cpp_data[i + 2] << 16)
width = font_cpp_data[i + 3]
n = i + 4 + 3 * width
self.code_points[cp] = font_cpp_data[(i + 3): n]
i = n
def commit(self):
l = []
for i, data in enumerate(self.code_points):
if data:
l.append(i & 0xFF)
l.append((i >> 8) & 0xFF)
l.append((i >> 16) & 0xFF)
l += data
with open(self.file, 'wb') as font_cpp:
font_cpp.write(bz2.compress(bytes(l)))
def pack(cp_matrix):
width = 0
for row in cp_matrix:
if width < len(row):
width = len(row)
cp_data = [width]
bits = 8
for row in cp_matrix:
padded = row + [0] * (width - len(row))
for cv in padded:
if bits == 8:
cp_data.append(0)
bits = 0
cp_data[-1] |= (cv & 3) << bits
bits += 2
return cp_data
def unpack(cp_data):
ptr = 1
bits = 0
buf = 0
cp_matrix = []
for y in range(FONT_HEIGHT):
cp_matrix.append([])
for x in range(cp_data[0]):
if bits == 0:
buf = cp_data[ptr]
ptr += 1
bits = 8
cp_matrix[-1].append(buf & 3)
buf >>= 2
bits -= 2
return cp_matrix
def dump(self, i, print):
lut = [' ', '░░', '▒▒', '▓▓']
if self.code_points[i]:
print('code point %i (%c)' % (i, i))
print('')
for l in [''.join([lut[ch] for ch in row]) for row in FontTool.unpack(self.code_points[i])]:
print(l)
print('')
else:
print('code point %i (%c) is not available' % (i, i))
class RawReader:
def __init__(self, path):
self.code_points = [False for _ in range(CP_MAX + 2)]
with open(path) as raw:
items = [int(v) for v in re.findall(r'[0-9]+', raw.read())]
ptr = 0
while ptr <= len(items) - 2:
cp = items[ptr]
width = items[ptr + 1]
ptr += 2
matrix = []
for i in range(ptr, ptr + width * FONT_HEIGHT, width):
matrix.append(items[i: (i + width)])
ptr += width * FONT_HEIGHT
self.code_points[cp] = FontTool.pack(matrix)
class BDFReader:
def __init__(self, path, xoffs, yoffs):
self.code_points = [False for _ in range(CP_MAX + 2)]
item_re = re.compile(r'[^ \n\r]+')
with open(path) as bdf:
global_dw = False
startchar = False
bitmap = False
char_dw = False
char_cp = False
char_bbx = False
skip = 0
for line_number, line in enumerate(bdf):
if skip:
skip -= 1
continue
items = re.findall(item_re, line)
if startchar and items[0] == 'ENDCHAR':
if len(bitmap) != char_bbx[1]:
raise ReadBDFError(line_number, "invalid bitmap data")
cp_matrix = []
for y in range(FONT_HEIGHT):
cp_matrix.append([])
for x in range(char_dw):
cv = 0
xx = x + xoffs
yy = FONT_HEIGHT - 1 - y + yoffs
if char_bbx[2] <= xx < char_bbx[0] + char_bbx[2] and char_bbx[3] <= yy < char_bbx[1] + \
char_bbx[3]:
cv = bitmap[char_bbx[1] - 1 - (yy - char_bbx[3])][xx - char_bbx[2]] * 3
cp_matrix[-1].append(cv)
self.code_points[char_cp] = FontTool.pack(cp_matrix)
startchar = False
bitmap = False
char_dw = False
char_cp = False
char_bbx = False
elif bitmap != False:
if len(items) != 1:
raise ReadBDFError(line_number, "missing bitmap data")
bits = []
for ch in items[0]:
cv = int(ch, 16)
bits += [cv & 8 and 1 or 0, cv & 4 and 1 or 0, cv & 2 and 1 or 0, cv & 1 and 1 or 0]
bitmap.append(bits[: char_bbx[0]])
elif items[0] == 'SIZE':
if len(items) != 4:
raise ReadBDFError(line_number, "invalid directive")
elif items[0] == 'FONTBOUNDINGBOX':
if len(items) != 5:
raise ReadBDFError(line_number, "invalid directive")
elif not startchar and items[0] == 'STARTCHAR':
startchar = True
char_dw = global_dw
elif items[0] == 'STARTPROPERTIES':
if len(items) != 2:
raise ReadBDFError(line_number, "invalid directive")
skip = int(items[1]) + 1
elif startchar and items[0] == 'BITMAP':
bitmap = []
elif startchar and items[0] == 'BBX':
if len(items) != 5:
raise ReadBDFError(line_number, "invalid directive")
char_bbx = [int(items[1]), int(items[2]), int(items[3]), int(items[4])]
elif startchar and items[0] == 'ENCODING':
if len(items) != 2:
raise ReadBDFError(line_number, "invalid directive")
char_cp = int(items[1])
elif items[0] == 'METRICSSET':
if len(items) != 2:
raise ReadBDFError(line_number, "invalid directive")
if int(items[1]) == 1:
raise ReadBDFError(line_number, "font does not support writing direction 0")
elif items[0] == 'DWIDTH':
if len(items) != 3:
raise ReadBDFError(line_number, "invalid directive")
if int(items[2]) != 0:
raise ReadBDFError(line_number, "vertical component of dwidth vector is non-zero")
char_dw = int(items[1])
if not startchar:
global_dw = char_dw
def pad_str(s, pad, n):
return s + pad * (n - len(s))
if __name__ == "__main__":
parser = argparse.ArgumentParser("fonttool.py", description="font tools for managing fonts, this script can be"
" imported as a module",
fromfile_prefix_chars="@")
command = parser.add_subparsers(dest="command", required=True)
addbdf = command.add_parser("addbdf", help="Adds BDF Formated Font")
addbdf.add_argument("first", metavar="FIRST", type=int)
addbdf.add_argument("last", metavar="LAST", type=int)
addbdf.add_argument("bdffile", metavar="BDFFILE", help="BDF is an archaic bitmap font format")
addbdf.add_argument("xoffs", metavar="XOFFS", nargs="?", default=0, type=int, help="Defaults to 0")
addbdf.add_argument("yoffs", metavar="YOFFS", nargs="?", default=0, type=int, help="Defaults to 0")
addraw = command.add_parser("addraw", help="Adds a Raw Formated Font")
addraw.add_argument("first", metavar="FIRST", type=int)
addraw.add_argument("last", metavar="LAST", type=int)
addraw.add_argument("rawfile", metavar="RAWFILE", help=""""Raw" files are simply ASCII-encoded white-space delimited \
lists
of decimal integer constants. These lists of integers encode
characters as any number of consecutive character description
structures laid out as follows:
* the code point corresponding to the character being described;
* the width in pixels of the character being described;
* width times %i brightness levels between 0 and 3, a row-major matrix.""")
remove = command.add_parser("remove", help="Remove a range of characters")
remove.add_argument("first", metavar="FIRST", type=int)
remove.add_argument("last", metavar="LAST", type=int, default=None, nargs="?", help="Defaults to FIRST")
copy = command.add_parser("copy", help="Copy a range of characters to another range")
copy.add_argument("dest", metavar="DSTFIRST", type=int)
copy.add_argument("first", metavar="SRCFIRST", type=int)
copy.add_argument("last", metavar="SRCLAST", type=int, default=None, nargs="?", help="Defaults to SRCFIRST")
inspect = command.add_parser("inspect", help="Inspect a range of characters")
inspect.add_argument("first", metavar="FIRST", type=int)
inspect.add_argument("last", metavar="LAST", type=int, default=None, nargs="?", help="Defaults to FIRST")
diff = command.add_parser("diff", help="Prints subranges that changed between the current and an external font file")
diff.add_argument("external", metavar="EXTERNAL", help="External font.bz2")
args = parser.parse_args()
if 'first' in args:
cp_first = args.first
if args.last is None:
cp_last = cp_first
else:
cp_last = args.last
if cp_first < 0 or cp_last > CP_MAX or cp_first > cp_last:
print('invalid range')
exit(1)
ft = FontTool(FONT_CPP)
if args.command == "addbdf":
xoffs = args.xoffs
yoffs = args.yoffs
bdfr = BDFReader(args.bdffile, xoffs, yoffs)
for i in range(cp_first, cp_last + 1):
if bdfr.code_points[i] and not ft.code_points[i]:
ft.code_points[i] = bdfr.code_points[i]
ft.commit()
elif args.command == 'addraw':
rr = RawReader(args.rawfile)
for i in range(cp_first, cp_last + 1):
if rr.code_points[i] and not ft.code_points[i]:
ft.code_points[i] = rr.code_points[i]
ft.commit()
elif args.command == 'remove':
for i in range(cp_first, cp_last + 1):
ft.code_points[i] = False
ft.commit()
elif args.command == 'copy':
for i in range(cp_first, cp_last + 1):
ft.code_points[i + (args.dest - cp_first)] = ft.code_points[i]
ft.commit()
elif args.command == 'inspect':
for i in range(cp_first, cp_last + 1):
ft.dump(i, print)
elif args.command == 'diff':
pad_to = 50
eft = FontTool(args.external)
for i in range(0, CP_MAX + 1):
if eft.code_points[i] != ft.code_points[i]:
cur = []
def add_cur(line):
global cur
cur.append(line)
ft.dump(i, add_cur)
ext = []
def add_ext(line):
global ext
ext.append(line)
eft.dump(i, add_ext)
print('#' * (2 * pad_to + 7))
for j in range(max(len(cur), len(ext))):
print('# ' + pad_str(j < len(cur) and cur[j] or '', ' ', pad_to) + ' # ' + pad_str(j < len(ext) and ext[j] or '', ' ', pad_to) + ' #')

208
generator.py Normal file
View File

@ -0,0 +1,208 @@
import re, os, shutil, string, sys
def generateElements(elementFiles, outputCpp, outputH):
elementClasses = dict()
baseClasses = dict()
elementHeader = """#ifndef ELEMENTCLASSES_H
#define ELEMENTCLASSES_H
#include <vector>
#include "simulation/Element.h"
#include "simulation/elements/Element.h"
"""
directives = []
for elementFile in elementFiles:
f = open(elementFile, "r")
fileData = f.read()
f.close()
directiveMatcher = '//#TPT-Directive\s+([^\r\n]+)'
matcher = re.compile(directiveMatcher)
directiveMatches = matcher.findall(fileData)
for match in directiveMatches:
directives.append(match.split(" "))
classDirectives = []
for d in directives:
if d[0] == "ElementClass":
d[3] = string.atoi(d[3])
classDirectives.append(d)
elementIDs = sorted(classDirectives, key=lambda directive: directive[3])
for d in elementIDs:
tmpClass = d[1]
newClass = ""
baseClass = "Element"
if ':' in tmpClass:
classBits = tmpClass.split(':')
newClass = classBits[0]
baseClass = classBits[1]
else:
newClass = tmpClass
elementClasses[newClass] = []
baseClasses[newClass] = baseClass
elementHeader += "#define %s %s\n" % (d[2], d[3])
for d in directives:
if d[0] == "ElementHeader":
tmpClass = d[1]
newClass = ""
baseClass = "Element"
if ':' in tmpClass:
classBits = tmpClass.split(':')
newClass = classBits[0]
baseClass = classBits[1]
else:
newClass = tmpClass
elementClasses[newClass].append(string.join(d[2:], " ")+";")
#for className, classMembers in elementClasses.items():
for d in elementIDs:
tmpClass = d[1]
newClass = ""
baseClass = "Element"
if ':' in tmpClass:
classBits = tmpClass.split(':')
newClass = classBits[0]
baseClass = classBits[1]
else:
newClass = tmpClass
className = newClass
classMembers = elementClasses[newClass]
elementBase = baseClass
elementHeader += """
class {0}: public {1}
{{
public:
{0}();
virtual ~{0}();
{2}
}};
""".format(className, elementBase, string.join(classMembers, "\n\t"))
elementHeader += """
std::vector<Element> GetElements();
#endif
"""
elementContent = """#include "ElementClasses.h"
std::vector<Element> GetElements()
{
std::vector<Element> elements;
""";
for d in elementIDs:
tmpClass = d[1]
newClass = ""
baseClass = "Element"
if ':' in tmpClass:
classBits = tmpClass.split(':')
newClass = classBits[0]
baseClass = classBits[1]
else:
newClass = tmpClass
elementContent += """elements.push_back(%s());
""" % (newClass)
elementContent += """ return elements;
}
""";
f = open(outputH, "w")
f.write(elementHeader)
f.close()
f = open(outputCpp, "w")
f.write(elementContent)
f.close()
def generateTools(toolFiles, outputCpp, outputH):
toolClasses = dict()
toolHeader = """#ifndef TOOLCLASSES_H
#define TOOLCLASSES_H
#include <vector>
#include "simulation/Tools.h"
#include "simulation/tools/SimTool.h"
"""
directives = []
for toolFile in toolFiles:
f = open(toolFile, "r")
fileData = f.read()
f.close()
directiveMatcher = '//#TPT-Directive\s+([^\r\n]+)'
matcher = re.compile(directiveMatcher)
directiveMatches = matcher.findall(fileData)
for match in directiveMatches:
directives.append(match.split(" "))
classDirectives = []
for d in directives:
if d[0] == "ToolClass":
toolClasses[d[1]] = []
toolHeader += "#define %s %s\n" % (d[2], d[3])
d[3] = string.atoi(d[3])
classDirectives.append(d)
for d in directives:
if d[0] == "ToolHeader":
toolClasses[d[1]].append(string.join(d[2:], " ")+";")
for className, classMembers in toolClasses.items():
toolHeader += """class {0}: public SimTool
{{
public:
{0}();
virtual ~{0}();
virtual int Perform(Simulation * sim, Particle * cpart, int x, int y, float strength);
{1}
}};
""".format(className, string.join(classMembers, "\n"))
toolHeader += """std::vector<SimTool*> GetTools();
#endif
"""
toolContent = """#include "ToolClasses.h"
std::vector<SimTool*> GetTools()
{
std::vector<SimTool*> tools;
""";
toolIDs = sorted(classDirectives, key=lambda directive: directive[3])
for d in toolIDs:
toolContent += """ tools.push_back(new %s());
""" % (d[1])
toolContent += """ return tools;
}
""";
f = open(outputH, "w")
f.write(toolHeader)
f.close()
f = open(outputCpp, "w")
f.write(toolContent)
f.close()
if(sys.argv[1] == "elements"):
generateElements(sys.argv[4:], sys.argv[2], sys.argv[3])
elif(sys.argv[1] == "tools"):
generateTools(sys.argv[4:], sys.argv[2], sys.argv[3])

View File

@ -1,484 +0,0 @@
project(
'the-powder-toy',
[ 'c', 'cpp' ],
version: 'the.cake.is.a.lie',
default_options: [
'c_std=c99',
'cpp_std=c++17',
'cpp_rtti=false',
'build.c_std=c99', # used by to_array
'build.cpp_std=c++17', # used by to_array
'build.cpp_rtti=false', # used by to_array
],
meson_version: '>=0.64.0',
)
if get_option('prepare')
# we're being run by prepare.py in a ghactions workflow only to determine the values of options; exit early
subdir_done()
endif
fs = import('fs')
to_array = generator(
executable('toarray', sources: 'resources/ToArray.cpp', native: true),
output: [ '@PLAINNAME@.cpp', '@PLAINNAME@.h' ],
arguments: [ '@OUTPUT0@', '@OUTPUT1@', '@INPUT@', '@EXTRA_ARGS@' ]
)
render_icons_with_inkscape = get_option('render_icons_with_inkscape')
inkscape = find_program('inkscape', required: render_icons_with_inkscape)
c_compiler = meson.get_compiler('c')
is_x86 = host_machine.cpu_family() in [ 'x86', 'x86_64' ]
is_64bit = host_machine.cpu_family() in [ 'aarch64', 'x86_64' ]
is_msvc = c_compiler.get_id() in [ 'msvc' ]
host_arch = host_machine.cpu_family()
host_platform = host_machine.system()
# educated guesses follow, PRs welcome
if c_compiler.get_id() in [ 'msvc' ]
if host_platform != 'windows'
error('this seems fishy')
endif
host_libc = 'msvc'
elif c_compiler.get_id() in [ 'gcc' ] and host_platform == 'windows'
host_libc = 'mingw'
elif host_platform in [ 'darwin' ]
host_libc = 'macos'
elif host_platform in [ 'emscripten' ]
host_platform = 'emscripten'
host_libc = 'emscripten'
elif host_platform in [ 'android' ]
host_platform = 'android'
host_libc = 'bionic'
else
if host_platform != 'linux'
# TODO: maybe use 'default' in place of 'linux', or use something other than host_platform where details such as desktop integration are concerned
warning('host platform is not linux but we will pretend that it is')
host_platform = 'linux'
endif
host_libc = 'gnu'
endif
static_variant = get_option('static')
if static_variant != 'prebuilt' and host_platform == 'android'
warning('only prebuilt libs are supported for android')
static_variant = 'prebuilt'
endif
if static_variant == 'system' and host_platform == 'windows' and host_libc == 'msvc'
warning('no way to find system libs for msvc on windows')
static_variant = 'prebuilt'
endif
is_static = static_variant != 'none'
is_debug = get_option('optimization') in [ '0', 'g' ]
app_exe = get_option('app_exe')
tpt_libs_static = 'none'
if static_variant == 'prebuilt'
tpt_libs_static = 'static'
endif
if static_variant == 'none' and host_platform == 'windows' and host_libc == 'msvc'
tpt_libs_static = 'dynamic'
endif
tpt_libs_debug = is_debug ? 'debug' : 'release'
tpt_libs_variant = '@0@-@1@-@2@-@3@'.format(host_arch, host_platform, host_libc, tpt_libs_static)
tpt_libs_vtag = get_option('tpt_libs_vtag')
if tpt_libs_vtag == ''
tpt_libs_vtag = 'v20240112165024'
endif
if tpt_libs_static != 'none'
if tpt_libs_variant not in [
'x86_64-linux-gnu-static',
'x86_64-windows-mingw-static',
'x86_64-windows-msvc-static',
'x86_64-windows-msvc-dynamic',
'x86-windows-msvc-static',
'x86-windows-msvc-dynamic',
'x86_64-darwin-macos-static',
'aarch64-darwin-macos-static',
'x86-android-bionic-static',
'x86_64-android-bionic-static',
'arm-android-bionic-static',
'aarch64-android-bionic-static',
'wasm32-emscripten-emscripten-static',
]
error('no prebuilt @0@ libraries are currently provided'.format(tpt_libs_variant))
endif
tpt_libs = subproject('tpt-libs-prebuilt-@0@-@1@-@2@'.format(tpt_libs_variant, tpt_libs_debug, tpt_libs_vtag))
else
if get_option('workaround_elusive_bzip2')
bzip2_lib_name = get_option('workaround_elusive_bzip2_lib_name')
bzip2_include_name = get_option('workaround_elusive_bzip2_include_name')
bzip2_lib_dir = get_option('workaround_elusive_bzip2_lib_dir')
bzip2_include_dir = include_directories(get_option('workaround_elusive_bzip2_include_dir'))
bzip2_static = get_option('workaround_elusive_bzip2_static')
meson.override_dependency('bzip2', declare_dependency(
dependencies: c_compiler.find_library(
bzip2_lib_name,
has_headers: bzip2_include_name,
dirs: bzip2_lib_dir,
header_include_directories: bzip2_include_dir,
static: bzip2_static,
),
include_directories: bzip2_include_dir,
))
endif
endif
x86_sse_level_str = get_option('x86_sse')
if x86_sse_level_str == 'auto'
x86_sse_level = 20
if not is_x86 or not is_64bit or host_platform == 'darwin' or (is_64bit and is_msvc)
x86_sse_level = 0
endif
elif x86_sse_level_str == 'sse3'
x86_sse_level = 30
elif x86_sse_level_str == 'sse2'
x86_sse_level = 20
elif x86_sse_level_str == 'sse'
x86_sse_level = 10
elif x86_sse_level_str == 'none'
x86_sse_level = 0
endif
lua_variant = get_option('lua')
if lua_variant == 'auto'
if host_platform == 'emscripten'
lua_variant = 'lua5.2'
else
lua_variant = 'luajit'
endif
endif
if lua_variant == 'luajit' and host_platform == 'emscripten'
error('luajit does not work with emscripten')
endif
if lua_variant == 'none'
lua_dep = []
elif lua_variant == 'lua5.1' or lua_variant == 'lua5.2'
lua_dep = dependency(lua_variant + '-c++', static: is_static, required: false)
if not lua_dep.found()
if not get_option('workaround_noncpp_lua')
error('your system @0@ is not compatible with C++, configure with -Dworkaround_noncpp_lua=true to disable this error'.format(lua_variant))
endif
lua_dep = dependency(lua_variant, static: is_static)
endif
elif lua_variant == 'luajit'
lua_dep = dependency('luajit', static: is_static)
endif
enable_http = get_option('http')
if host_platform == 'android'
android_ndk_toolchain_prefix = meson.get_external_property('android_ndk_toolchain_prefix')
android_platform = meson.get_external_property('android_platform')
tpt_libs_android_toolchain_prefix = tpt_libs.get_variable('android_toolchain_prefix')
tpt_libs_android_system_version = tpt_libs.get_variable('android_system_version')
tpt_libs_android_platform = tpt_libs.get_variable('android_platform')
if '@0@@1@-'.format(tpt_libs_android_toolchain_prefix, tpt_libs_android_system_version) != android_ndk_toolchain_prefix
error('tpt-libs android toolchain mismatch')
endif
if tpt_libs_android_platform != android_platform
error('tpt-libs android platform mismatch')
endif
endif
curl_dep = []
if enable_http and host_platform != 'emscripten'
curl_dep = dependency('libcurl', static: is_static)
endif
project_link_args = []
project_c_args = []
project_cpp_args = []
fftw_dep = dependency('fftw3f', static: is_static)
threads_dep = dependency('threads')
if host_platform == 'emscripten'
zlib_dep = []
png_dep = []
sdl2_dep = []
bzip2_dep = []
project_link_args += [
'--no-heap-copy',
'-s', 'WASM=1',
'-s', 'ALLOW_MEMORY_GROWTH=1',
'-s', 'FORCE_FILESYSTEM=1',
'-s', 'EXIT_RUNTIME=0',
'-s', 'EXPORTED_RUNTIME_METHODS=ccall,cwrap',
'-s', 'FS_DEBUG',
'-s', 'MODULARIZE',
'-s', 'EXPORT_NAME=create_' + app_exe,
'-Wl,-u,_emscripten_run_callback_on_thread',
'-lidbfs.js',
]
emcc_args = [
'-s', 'USE_SDL=2',
'-s', 'USE_BZIP2=1',
'-s', 'USE_LIBPNG',
'-s', 'USE_ZLIB=1',
'-s', 'DISABLE_EXCEPTION_CATCHING=0',
]
if is_debug
project_link_args += [ '--source-map-base=./' ]
emcc_args += [ '-gsource-map' ]
endif
project_link_args += emcc_args
project_c_args += emcc_args
project_cpp_args += emcc_args
else
zlib_dep = dependency('zlib', static: is_static)
png_dep = dependency('libpng16', static: is_static)
sdl2_dep = dependency('sdl2', static: is_static)
bzip2_dep = dependency('bzip2', static: is_static)
endif
json_dep = dependency('jsoncpp', static: is_static)
if is_msvc
if x86_sse_level >= 30
warning('SSE3 configured to be enabled but unavailable in msvc')
x86_sse_level = 20
endif
if is_64bit and x86_sse_level > 0
warning('SSE explicitly configured but unavailable in msvc targeting 64-bit machines')
x86_sse_level = 0
endif
args_msvc = [
'/GS',
'/D_SCL_SECURE_NO_WARNINGS',
'/DUNICODE',
'/D_UNICODE',
]
if x86_sse_level >= 20
args_msvc += [ '/arch:SSE2' ]
elif x86_sse_level >= 10
args_msvc += [ '/arch:SSE' ]
endif
if not is_debug
args_msvc += [
'/Oy-',
'/fp:fast',
'/GL',
]
project_link_args += [
'/OPT:REF',
'/OPT:ICF',
'/LTCG',
]
endif
project_c_args += args_msvc
project_cpp_args += args_msvc
else
args_ccomp = []
if host_platform == 'darwin' and x86_sse_level > 0
message('SSE level explicitly configured but unavailable on macosx')
x86_sse_level = 0
endif
if x86_sse_level >= 30
args_ccomp += [ '-msse3' ]
elif x86_sse_level >= 20
args_ccomp += [ '-msse2' ]
elif x86_sse_level >= 10
args_ccomp += [ '-msse' ]
endif
if host_platform == 'windows'
args_ccomp += [
'-DUNICODE',
'-D_UNICODE',
]
endif
if not is_debug
args_ccomp += [
'-ftree-vectorize',
'-funsafe-math-optimizations',
'-ffast-math',
'-fomit-frame-pointer',
]
endif
if host_platform == 'android'
if not is_64bit
args_ccomp += [ '-U_FILE_OFFSET_BITS' ]
endif
# android doesn't ship libc++_shared.so, so we might as well link it statically;
# the alternative would be to grab libc++_shared.so from the NDK and ship it with
# the app alongside libpowder.so, and possibly add it to SDL's list of libraries to load
project_link_args += [ '-static-libstdc++' ]
endif
project_c_args += args_ccomp + [
'-Wno-implicit-fallthrough',
'-Wno-missing-field-initializers',
'-Wno-unused-result',
'-Wno-unused-parameter',
]
project_cpp_args += args_ccomp + [
'-Wno-invalid-offsetof',
'-Wno-unused-result',
'-Wno-missing-field-initializers',
'-Wno-unused-parameter',
]
endif
if host_platform == 'windows'
args_ccomp_win = [ '-D_WIN32_WINNT=0x0501', '-DNOMINMAX' ]
windows_mod = import('windows')
if is_static
args_ccomp_win += [ '-DCURL_STATICLIB' ]
if host_arch == 'x86_64'
args_ccomp_win += [ '-DZLIB_WINAPI' ]
endif
endif
if tpt_libs_static == 'dynamic'
foreach input_output_condition : tpt_libs.get_variable('config_dlls')
dll_input = input_output_condition[0]
dll_output = input_output_condition[1]
dll_condition = input_output_condition[2]
do_copy = false
if dll_condition == 'all'
do_copy = true
elif dll_condition == 'lua=' + lua_variant
do_copy = true
endif
if do_copy
fs.copyfile(dll_input, dll_output)
endif
endforeach
endif
project_c_args += args_ccomp_win
project_cpp_args += args_ccomp_win
endif
project_inc = include_directories([ 'src', 'resources' ])
if host_platform == 'windows'
ident_platform = is_64bit ? 'WIN64' : 'WIN32'
elif host_platform == 'linux'
ident_platform = is_64bit ? 'LIN64' : 'LIN32'
elif host_platform == 'darwin'
ident_platform = host_arch == 'aarch64' ? 'MACOSARM' : 'MACOSX'
else
ident_platform = 'UNKNOWN'
endif
project_deps = []
data_files = []
powder_deps = []
project_export_dynamic = false
subdir('src')
subdir('resources')
powder_files += data_files
render_files += data_files
font_files += data_files
if host_platform == 'emscripten'
project_link_args += [
'-o', app_exe + '.js', # so we get a .wasm, and a .js
]
endif
if get_option('export_lua_symbols')
if is_static and lua_variant != 'none' and not project_export_dynamic
if host_platform == 'windows'
error('Lua symbols are currently impossible to export correctly on Windows')
elif c_compiler.has_link_argument('-Wl,--export-dynamic-symbol')
project_link_args += [
'-Wl,--export-dynamic-symbol=lua_*',
'-Wl,--export-dynamic-symbol=luaL_*',
'-Wl,--export-dynamic-symbol=luaopen_*',
]
else
warning('your linker does not support -Wl,--export-dynamic-symbol so Meson will be instructed to export all symbols in order to enable loading Lua shared modules, which may blow up the size of the resulting binary')
project_export_dynamic = true
endif
endif
endif
if get_option('build_powder')
powder_deps += project_deps + [
threads_dep,
zlib_dep,
png_dep,
sdl2_dep,
lua_dep,
curl_dep,
fftw_dep,
bzip2_dep,
json_dep,
]
if host_platform == 'android'
powder_sha = shared_library(
app_exe,
sources: powder_files,
include_directories: project_inc,
c_args: project_c_args,
cpp_args: project_cpp_args,
link_args: project_link_args,
dependencies: powder_deps,
)
subdir('android')
else
executable(
app_exe,
sources: powder_files,
include_directories: project_inc,
c_args: project_c_args,
cpp_args: project_cpp_args,
win_subsystem: is_debug ? 'console' : 'windows',
link_args: project_link_args,
dependencies: powder_deps,
export_dynamic: project_export_dynamic,
install: true,
)
endif
endif
if get_option('build_render')
if host_platform == 'emscripten'
error('render does not target emscripten')
endif
render_deps = project_deps + [
threads_dep,
zlib_dep,
bzip2_dep,
json_dep,
png_dep,
]
render_link_args = project_link_args
if host_platform == 'linux' and is_static
render_link_args += [ '-static' ]
endif
executable(
'render',
sources: render_files,
include_directories: project_inc,
c_args: project_c_args,
cpp_args: project_cpp_args,
link_args: render_link_args,
dependencies: render_deps,
export_dynamic: project_export_dynamic,
)
endif
if get_option('build_font')
if host_platform == 'emscripten'
error('font does not target emscripten')
endif
font_deps = project_deps + [
threads_dep,
zlib_dep,
png_dep,
sdl2_dep,
bzip2_dep,
json_dep,
]
executable(
'font',
sources: font_files,
include_directories: project_inc,
c_args: project_c_args,
cpp_args: project_cpp_args,
link_args: project_link_args,
dependencies: font_deps,
export_dynamic: project_export_dynamic,
)
endif

View File

@ -1,313 +0,0 @@
option(
'static',
type: 'combo',
choices: [ 'none', 'system', 'prebuilt' ],
value: 'none',
description: 'Build statically using libraries present on the system (\'system\') or using prebuilt libraries official builds use (\'prebuilt\')'
)
option(
'beta',
type: 'boolean',
value: false,
description: 'Beta build'
)
option(
'ignore_updates',
type: 'boolean',
value: true,
description: 'Don\'t show notifications about available updates'
)
option(
'can_install',
type: 'combo',
choices: [ 'no', 'yes', 'yes_check', 'auto' ],
value: 'auto',
description: 'Disable (\'no\') or enable (\'yes\') setting up file and URL associations, or even offer to do it at startup (\'yes_check\')'
)
option(
'http',
type: 'boolean',
value: true,
description: 'Enable HTTP via libcurl'
)
option(
'snapshot',
type: 'boolean',
value: false,
description: 'Snapshot build'
)
option(
'display_version_major',
type: 'integer',
min: 0,
value: 98,
description: 'Major component of the display version, should more or less map to the MINOR version in semantic versioning'
)
option(
'display_version_minor',
type: 'integer',
min: 0,
value: 2,
description: 'Minor component of the display version, should more or less map to the PATCH version in semantic versioning'
)
option(
'build_num',
type: 'integer',
min: 0,
value: 365,
description: 'Build number, should be strictly monotonously increasing across public releases'
)
option(
'upstream_version_major',
type: 'integer',
min: 0,
value: 98,
description: 'Major component of the upstream display version, mod owners should not change this but merge upstream changes to it'
)
option(
'upstream_version_minor',
type: 'integer',
min: 0,
value: 2,
description: 'Minor component of the upstream display version, mod owners should not change this but merge upstream changes to it'
)
option(
'upstream_build_num',
type: 'integer',
min: 0,
value: 365,
description: 'Upstream build number, mod owners should not change this but merge upstream changes to it'
)
option(
'mod_id',
type: 'integer',
min: 0,
value: 0,
description: 'Mod ID, used on the https://starcatcher.us/TPT build server, the build server will compile for all platforms for you and send updates in-game, see jacob1 to get a mod ID'
)
option(
'lua',
type: 'combo',
choices: [ 'none', 'lua5.1', 'lua5.2', 'luajit', 'auto' ],
value: 'auto',
description: 'Lua library to use'
)
option(
'x86_sse',
type: 'combo',
choices: [ 'none', 'sse', 'sse2', 'sse3', 'auto' ],
value: 'auto',
description: 'Enable SSE (available only on x86)'
)
option(
'build_powder',
type: 'boolean',
value: true,
description: 'Build the game'
)
option(
'build_render',
type: 'boolean',
value: false,
description: 'Build the thumbnail renderer'
)
option(
'build_font',
type: 'boolean',
value: false,
description: 'Build the font editor'
)
option(
'server',
type: 'string',
value: 'powdertoy.co.uk',
description: 'Simulation server'
)
option(
'static_server',
type: 'string',
value: 'static.powdertoy.co.uk',
description: 'Static simulation server'
)
option(
'update_server',
type: 'string',
value: '',
description: 'Update server, only used by snapshots and mods, see \'snapshot\' and \'mod_id\''
)
option(
'workaround_noncpp_lua',
type: 'boolean',
value: false,
description: 'Allow linking against a non-C++ system Lua'
)
option(
'workaround_elusive_bzip2',
type: 'boolean',
value: true,
description: 'acquire bzip2 dependency with find_library'
)
option(
'workaround_elusive_bzip2_lib_name',
type: 'string',
value: 'bz2',
description: 'bzip2 library name, see \'workaround_elusive_bzip2\''
)
option(
'workaround_elusive_bzip2_lib_dir',
type: 'string',
value: '/usr/lib/x86_64-linux-gnu',
description: 'bzip2 library directory, see \'workaround_elusive_bzip2\''
)
option(
'workaround_elusive_bzip2_include_name',
type: 'string',
value: 'bzlib.h',
description: 'bzip2 header name, see \'workaround_elusive_bzip2\''
)
option(
'workaround_elusive_bzip2_include_dir',
type: 'string',
value: '/usr/include',
description: 'bzip2 header directory, see \'workaround_elusive_bzip2\''
)
option(
'workaround_elusive_bzip2_static',
type: 'boolean',
value: false,
description: 'bzip2 static setting, see \'workaround_elusive_bzip2\''
)
option(
'tpt_libs_vtag',
type: 'string',
value: '',
description: 'tpt-libs vtag override, only used for tpt-libs development'
)
option(
'android_keystore',
type: 'string',
value: '',
description: 'Path to Java keystore for signing an APK, only used for Android development'
)
option(
'android_keyalias',
type: 'string',
value: 'androidkey',
description: 'Signing key alias for signing an APK, only used for Android development'
)
option(
'app_name',
type: 'string',
value: 'The Powder Toy',
description: 'App name, used for desktop integration and the window title, change if you work on a mod'
)
option(
'app_comment',
type: 'string',
value: 'Physics sandbox game',
description: 'App comment, used for desktop integration, change if you work on a mod'
)
option(
'app_exe',
type: 'string',
value: 'powder',
description: 'App executable name, used for desktop integration, change if you work on a mod'
)
option(
'app_id',
type: 'string',
value: 'uk.co.powdertoy.tpt',
description: 'App ID, a D-Bus well-known name, used for desktop integration, change if you work on a mod'
)
option(
'app_data',
type: 'string',
value: 'The Powder Toy',
description: 'App data directory name, do not change even if you work on a mod, only if you know what you are doing'
)
option(
'app_vendor',
type: 'string',
value: 'powdertoy',
description: 'App vendor prefix, used for desktop integration, do not change even if you work on a mod, only if you know what you are doing'
)
option(
'enforce_https',
type: 'boolean',
value: true,
description: 'Enforce encrypted HTTP traffic, may be disabled for debugging'
)
option(
'secure_ciphers_only',
type: 'boolean',
value: false,
description: 'Use only secure ciphers for encrypted HTTP traffic, please review cipher list before enabling'
)
option(
'prepare',
type: 'boolean',
value: false,
description: 'Used by ghactions workflows, not useful otherwise'
)
option(
'render_icons_with_inkscape',
type: 'feature',
value: 'disabled',
description: 'Render icons with Inkscape (inkscape binary needs to be in PATH)'
)
option(
'resolve_vcs_tag',
type: 'combo',
choices: [ 'no', 'static_release_only', 'yes' ],
value: 'static_release_only',
description: 'Enable VCS tag resolution, introduces an always-stale custom target'
)
option(
'manifest_copyright',
type: 'string',
value: 'Copyright © 2008-2011 Stanislaw K Skowrenek, Copyright © 2011-2023 Simon Robertshaw, Copyright © 2016-2023 jacob1',
description: 'Copyright string, don\'t take too seriously, subject to change'
)
option(
'manifest_macos_min_ver',
type: 'string',
value: '',
description: 'MacOS minimum allowed platform version string, used by ghactions workflows, not useful otherwise'
)
option(
'manifest_date',
type: 'string',
value: '',
description: 'Build date string, used by ghactions workflows, not useful otherwise'
)
option(
'platform_clipboard',
type: 'boolean',
value: true,
description: 'Enable platform clipboard, allows copying simulation data between different windows'
)
option(
'use_bluescreen',
type: 'combo',
choices: [ 'no', 'yes', 'auto' ],
value: 'auto',
description: 'Show blue error screen upon unhandled signals and exceptions'
)
option(
'windows_icons',
type: 'boolean',
value: true,
description: 'Add icon resources to the executable on Windows'
)
option(
'windows_utf8cp',
type: 'boolean',
value: true,
description: 'Ask Windows nicely for UTF-8 as the codepage'
)
option(
'export_lua_symbols',
type: 'boolean',
value: false,
description: 'Export Lua symbols to enable loading of Lua shared modules'
)

View File

@ -1,70 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>ptsave</string>
</array>
<key>CFBundleURLName</key>
<string>Powder Toy Save URL</string>
</dict>
</array>
<key>CFBundleName</key>
<string>@APPNAME@</string>
<key>CFBundleIconFile</key>
<string>icon_exe.icns</string>
<key>NSHumanReadableCopyright</key>
<string>@MANIFEST_COPYRIGHT@</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>stm</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icon_cps.icns</string>
<key>CFBundleTypeName</key>
<string>Powder Toy Save</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>cps</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icon_cps.icns</string>
<key>CFBundleTypeName</key>
<string>Powder Toy Stamp</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
</array>
<key>CFBundleExecutable</key>
<string>@APPEXE@</string>
<key>CFBundleIdentifier</key>
<string>@APPID@</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>@DISPLAY_VERSION_MAJOR@.@DISPLAY_VERSION_MINOR@</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>@DISPLAY_VERSION_MAJOR@.@DISPLAY_VERSION_MINOR@ (build @BUILD_NUM@)</string>
<key>LSMinimumSystemVersion</key>
<string>@MANIFEST_MACOS_MIN_VER@</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>

View File

@ -1,137 +0,0 @@
#include <cstdint>
#include <cstring>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
static void writeU32LE(uint8_t *dest, uint32_t value)
{
dest[0] = uint8_t( value & 0xFF);
dest[1] = uint8_t((value >> 8) & 0xFF);
dest[2] = uint8_t((value >> 16) & 0xFF);
dest[3] = uint8_t((value >> 24) & 0xFF);
}
static uint32_t readU32BE(const uint8_t *src)
{
return uint32_t(src[3]) |
(uint32_t(src[2]) << 8) |
(uint32_t(src[1]) << 16) |
(uint32_t(src[0]) << 24);
}
int main(int argc, char *argv[])
{
if (argc < 3)
{
std::cerr << "usage: " << argv[0] << " OUTPUT INPUT..." << std::endl;
exit(1);
}
auto images = argc - 2;
if (images > 255)
{
std::cerr << "too many images specified" << std::endl;
exit(1);
}
std::string outputPath = argv[1];
std::ofstream output(outputPath, std::ios::binary);
auto outputFailure = [&outputPath](std::string action) {
std::cerr << "failed to " << action << " " << outputPath << ": " << strerror(errno) << std::endl;
exit(1);
};
if (!output)
{
outputFailure("open");
}
std::vector<char> header(6 + images * 16, 0);
auto writeHeader = [&header, &output, &outputFailure]() {
output.seekp(0, std::ios_base::beg);
output.write(&header[0], header.size());
if (!output)
{
outputFailure("write");
}
};
writeHeader(); // make space for header
auto *headerU8 = reinterpret_cast<uint8_t *>(&header[0]);
headerU8[2] = 1;
headerU8[4] = images;
for (auto image = 0; image < images; ++image)
{
std::string inputPath = argv[2 + image];
std::ifstream input(inputPath, std::ios::binary);
auto inputFailure = [&inputPath](std::string action) {
std::cerr << "failed to " << action << " " << inputPath << ": " << strerror(errno) << std::endl;
exit(1);
};
auto imageFailure = [&inputPath](std::string failure) {
std::cerr << "failed to process " << inputPath << ": " << failure << std::endl;
exit(1);
};
if (!input)
{
inputFailure("open");
}
std::vector<char> buf;
input.seekg(0, std::ios_base::end);
buf.resize(input.tellg());
input.seekg(0, std::ios_base::beg);
input.read(&buf[0], buf.size());
if (!input)
{
inputFailure("read");
}
auto *bufU8 = reinterpret_cast<uint8_t *>(&buf[0]);
if (buf.size() < 0x21 ||
readU32BE(&bufU8[0]) != UINT32_C(0x89504E47) ||
readU32BE(&bufU8[4]) != UINT32_C(0x0D0A1A0A) ||
bufU8[0x18] != 8 ||
bufU8[0x19] != 6)
{
imageFailure("not a 32bpp RGBA PNG");
}
auto writeOffset = output.tellp();
output.write(&buf[0], buf.size());
if (!output)
{
outputFailure("write");
}
auto width = readU32BE(&bufU8[0x10]);
auto height = readU32BE(&bufU8[0x14]);
if (width == 256)
{
width = 0;
}
if (width > 255)
{
imageFailure("width exceeds U8 limit");
}
if (height == 256)
{
height = 0;
}
if (height > 255)
{
imageFailure("height exceeds U8 limit");
}
auto *entryU8 = headerU8 + 6 + image * 16;
entryU8[0] = width;
entryU8[1] = height;
entryU8[4] = 1;
entryU8[6] = 32;
if (buf.size() > UINT32_MAX)
{
imageFailure("data size exceeds U32 limit");
}
writeU32LE(&entryU8[8], uint32_t(buf.size()));
if (writeOffset > UINT32_MAX)
{
std::cerr << "output data size exceeds U32 limit" << std::endl;
exit(1);
}
writeU32LE(&entryU8[12], uint32_t(writeOffset));
}
writeHeader(); // actually write it out
return 0;
}

View File

@ -1,52 +0,0 @@
#include <fstream>
int main(int argc, char *argv[])
{
if (argc != 5)
{
return 1;
}
auto *outputCppPath = argv[1];
auto *outputHPath = argv[2];
auto *inputAnyPath = argv[3];
auto *symbolName = argv[4];
std::ifstream inputAny(inputAnyPath, std::ios::binary);
std::ofstream outputCpp(outputCppPath);
if (!outputCpp)
{
return 2;
}
outputCpp << "#include \"" << outputHPath << "\"\nconst unsigned char " << symbolName << "[] = { ";
auto dataLen = 0U;
while (true)
{
char ch;
inputAny.read(&ch, 1);
if (inputAny.eof())
{
break;
}
if (!inputAny)
{
return 3;
}
outputCpp << (unsigned int)(unsigned char)(ch) << ", ";
dataLen += 1;
}
outputCpp << " }; const unsigned int " << symbolName << "_size = " << dataLen << ";\n";
if (!outputCpp)
{
return 4;
}
std::ofstream outputH(outputHPath);
if (!outputH)
{
return 5;
}
outputH << "#pragma once\nextern const unsigned char " << symbolName << "[]; extern const unsigned int " << symbolName << "_size;\n";
if (!outputH)
{
return 6;
}
return 0;
}

View File

@ -1,34 +0,0 @@
<?xml version="1.0"?>
<component type="desktop">
<id>@APPID@</id>
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-3.0</project_license>
<name>@APPNAME@</name>
<summary>@APPCOMMENT@</summary>
<content_rating type="oars-1.1">
<content_attribute id="social-chat">moderate</content_attribute>
</content_rating>
<launchable type="desktop-id">@APPID@.desktop</launchable>
<description>
<p>
Have you ever wanted to blow something up? Or maybe you always dreamt of operating an atomic power plant? Do you have a will to develop your own CPU? The Powder Toy lets you to do all of these, and even more!
</p>
<p>
The Powder Toy is a free physics sandbox game, which simulates air pressure and velocity, heat, gravity and a countless number of interactions between different substances! The game provides you with various building materials, liquids, gases and electronic components which can be used to construct complex machines, guns, bombs, realistic terrains and almost anything else. You can then mine them and watch cool explosions, add intricate wirings, play with little stickmen or operate your machine. You can browse and play thousands of different saves made by the community or upload your own we welcome your creations!
</p>
<p>
There is a Lua API you can automate your work or even make plugins for the game. The Powder Toy is free and the source code is distributed under the GNU General Public License, so you can modify the game yourself or help with development.
</p>
</description>
<screenshots>
<screenshot>
<image>https://powdertoy.co.uk/Themes/Next/Design/Images/Screen2.png</image>
</screenshot>
</screenshots>
<url type="homepage">https://powdertoy.co.uk/</url>
<url type="bugtracker">https://github.com/The-Powder-Toy/The-Powder-Toy/issues</url>
<url type="help">https://powdertoy.co.uk/Wiki/W/Main_Page.html</url>
<releases>
<release date="@MANIFEST_DATE@" version="@DISPLAY_VERSION_MAJOR@.@DISPLAY_VERSION_MINOR@.@BUILD_NUM@" />
</releases>
</component>

BIN
resources/document.icns Normal file

Binary file not shown.

BIN
resources/document.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

View File

@ -1,9 +0,0 @@
We keep these icons here to make it possible to build TPT without Inkscape. If
you have Inkscape and want to change the game's icons, edit the SVGs in the
parent directory and configure your build sites with
`-Drender_icons_with_inkscape=true`.
The GitHub Actions workflows currently do not use Inkscape and use these icons
instead, so once you are satisfied with the state of the SVGs, replace these
icons with the ones in your build site in the same subdirectory and make a new
commit.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 563 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 644 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 255 KiB

View File

@ -1,533 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="64"
height="64"
viewBox="0 0 16.933331 16.933331"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="icon_exe.svg"
inkscape:export-filename="icon.png"
inkscape:export-xdpi="192"
inkscape:export-ydpi="192"
xml:space="preserve"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#ffffff"
inkscape:document-units="px"
showgrid="false"
inkscape:zoom="16.970563"
inkscape:cx="57.422963"
inkscape:cy="24.188945"
inkscape:window-width="1280"
inkscape:window-height="1054"
inkscape:window-x="1297"
inkscape:window-y="26"
inkscape:window-maximized="0"
inkscape:current-layer="layer7" /><defs
id="defs2"><linearGradient
id="linearGradient10317"><stop
style="stop-color:#f5ffff;stop-opacity:1;"
offset="0"
id="stop10311" /><stop
style="stop-color:#f5ffff;stop-opacity:1;"
offset="0.58129495"
id="stop10313" /><stop
style="stop-color:#f5ffff;stop-opacity:0;"
offset="1"
id="stop10315" /></linearGradient><linearGradient
id="linearGradient7451"><stop
style="stop-color:#f5ffff;stop-opacity:0.98309183;"
offset="0"
id="stop7445" /><stop
style="stop-color:#f5ffff;stop-opacity:0.65823293;"
offset="0.44851306"
id="stop7447" /><stop
style="stop-color:#f5ffff;stop-opacity:0;"
offset="1"
id="stop7449" /></linearGradient><linearGradient
id="linearGradient7331"><stop
style="stop-color:#f5ffff;stop-opacity:1;"
offset="0"
id="stop7325" /><stop
style="stop-color:#f5ffff;stop-opacity:1;"
offset="0.37253886"
id="stop7327" /><stop
style="stop-color:#f5ffff;stop-opacity:0;"
offset="1"
id="stop7329" /></linearGradient><linearGradient
id="linearGradient6957"><stop
style="stop-color:#f5ffff;stop-opacity:1;"
offset="0"
id="stop6951" /><stop
style="stop-color:#f5ffff;stop-opacity:1;"
offset="0.61608356"
id="stop6953" /><stop
style="stop-color:#f5ffff;stop-opacity:0;"
offset="1"
id="stop6955" /></linearGradient><linearGradient
id="linearGradient6573"><stop
style="stop-color:#f5ff08;stop-opacity:1;"
offset="0"
id="stop6567" /><stop
style="stop-color:#f5ff08;stop-opacity:0.823915;"
offset="0.62599742"
id="stop6569" /><stop
style="stop-color:#f5ff08;stop-opacity:0;"
offset="1"
id="stop6571" /></linearGradient><linearGradient
id="linearGradient6175"><stop
style="stop-color:#f5ff08;stop-opacity:0.47854495;"
offset="0"
id="stop6169" /><stop
style="stop-color:#f5ff08;stop-opacity:0.29862821;"
offset="0.67936534"
id="stop6171" /><stop
style="stop-color:#f5ff08;stop-opacity:0;"
offset="1"
id="stop6173" /></linearGradient><linearGradient
id="linearGradient5893"><stop
style="stop-color:#f5ff08;stop-opacity:0.71252441;"
offset="0"
id="stop5887" /><stop
style="stop-color:#f5ff08;stop-opacity:0.5904839;"
offset="0.67936534"
id="stop5889" /><stop
style="stop-color:#f5ff08;stop-opacity:0;"
offset="1"
id="stop5891" /></linearGradient><linearGradient
id="linearGradient5757"><stop
style="stop-color:#f5ff08;stop-opacity:1;"
offset="0"
id="stop5751" /><stop
style="stop-color:#f5ff08;stop-opacity:1;"
offset="0.75665909"
id="stop5753" /><stop
style="stop-color:#f5ff08;stop-opacity:0;"
offset="1"
id="stop5755" /></linearGradient><linearGradient
id="linearGradient5685"><stop
style="stop-color:#f5ff08;stop-opacity:1;"
offset="0"
id="stop5679" /><stop
style="stop-color:#f5ff08;stop-opacity:1;"
offset="0.63781762"
id="stop5681" /><stop
style="stop-color:#f5ff08;stop-opacity:0;"
offset="1"
id="stop5683" /></linearGradient><linearGradient
id="linearGradient5619"><stop
style="stop-color:#f5ff08;stop-opacity:1;"
offset="0"
id="stop5613" /><stop
style="stop-color:#f5ff08;stop-opacity:1;"
offset="0.73820531"
id="stop5615" /><stop
style="stop-color:#f5ff08;stop-opacity:0;"
offset="1"
id="stop5617" /></linearGradient><linearGradient
id="linearGradient5441"><stop
style="stop-color:#f5ff08;stop-opacity:0.89862061;"
offset="0"
id="stop5435" /><stop
style="stop-color:#f5ff08;stop-opacity:0.72535044;"
offset="0.62599742"
id="stop5437" /><stop
style="stop-color:#f5ff08;stop-opacity:0;"
offset="1"
id="stop5439" /></linearGradient><linearGradient
id="linearGradient1452"><stop
style="stop-color:#f50008;stop-opacity:1;"
offset="0"
id="stop1446" /><stop
style="stop-color:#f50008;stop-opacity:1;"
offset="0.7918601"
id="stop1448" /><stop
style="stop-color:#f50008;stop-opacity:0;"
offset="1"
id="stop1450" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient1452"
id="radialGradient522"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.78484331,0,0,0.78747227,696.44887,-323.11915)"
cx="85.568382"
cy="110.37487"
fx="85.568382"
fy="110.37487"
r="80.962494" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient1452"
id="radialGradient524"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.8981104,0,0,0.76442481,749.97364,-321.90886)"
cx="85.568382"
cy="110.37487"
fx="85.568382"
fy="110.37487"
r="80.962494" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient6573"
id="radialGradient526"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.63729372,0,0,0.41448086,723.17431,-328.11791)"
cx="85.568382"
cy="110.37487"
fx="85.568382"
fy="110.37487"
r="80.962494" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5619"
id="radialGradient528"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.44694866,0,0,0.65155251,787.10411,-304.51482)"
cx="85.568382"
cy="110.37487"
fx="85.568382"
fy="110.37487"
r="80.962494" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5619"
id="radialGradient530"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.44694866,0,0,0.40774632,806.63991,-285.18279)"
cx="85.568382"
cy="110.37487"
fx="85.568382"
fy="110.37487"
r="80.962494" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5685"
id="radialGradient532"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.31040892,0,0,0.40774632,771.18902,-267.79397)"
cx="85.568382"
cy="110.37487"
fx="85.568382"
fy="110.37487"
r="80.962494" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5757"
id="radialGradient534"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.61485849,0,0,0.48365086,699.42828,-280.26845)"
cx="85.568382"
cy="110.37487"
fx="85.568382"
fy="110.37487"
r="80.962494" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5893"
id="radialGradient536"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.18217879,0,0,0.57948295,785.06567,-317.57229)"
cx="85.568382"
cy="110.37487"
fx="85.568382"
fy="110.37487"
r="80.962494" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient6175"
id="radialGradient538"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.17110206,0,0,0.57948295,813.03511,-347.11197)"
cx="85.568382"
cy="110.37487"
fx="85.568382"
fy="110.37487"
r="80.962494" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient6175"
id="radialGradient540"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.65699536,0,0,0.23041338,805.19531,-234.77302)"
cx="85.568382"
cy="110.37487"
fx="85.568382"
fy="110.37487"
r="80.962494" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient6175"
id="radialGradient542"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.65699536,0,0,0.23041338,673.99742,-230.76895)"
cx="85.568382"
cy="110.37487"
fx="85.568382"
fy="110.37487"
r="80.962494" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5441"
id="radialGradient544"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.44694866,0,0,0.46338383,720.63883,-314.42592)"
cx="85.568382"
cy="110.37487"
fx="85.568382"
fy="110.37487"
r="80.962494" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient6957"
id="radialGradient546"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.81417897,0,0,0.30393809,713.08122,-253.70655)"
cx="85.568382"
cy="110.37487"
fx="85.568382"
fy="110.37487"
r="80.962494" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient10317"
id="radialGradient548"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.37560777,0,0,0.52796713,798.71131,-289.99247)"
cx="85.568382"
cy="110.37487"
fx="85.568382"
fy="110.37487"
r="80.962494" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient7331"
id="radialGradient550"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.51429536,0,0,0.55006434,705.69388,-287.70068)"
cx="85.568382"
cy="110.37487"
fx="85.568382"
fy="110.37487"
r="80.962494" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient7451"
id="radialGradient552"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.51429536,0,0,0.55006434,726.67823,-322.63777)"
cx="85.568382"
cy="110.37487"
fx="85.568382"
fy="110.37487"
r="80.962494" /></defs><g
inkscape:groupmode="layer"
id="layer7"
inkscape:label="icon"><rect
style="opacity:1;fill:#cccccc;stroke-width:0.0500064;stroke-linecap:square;stroke-dasharray:none"
id="rect9549"
width="16.933332"
height="13.229165"
x="0"
y="1.8520831" /><path
style="opacity:1;fill:#000000;stroke-width:0.0500063;stroke-linecap:square;stroke-dasharray:none"
d="m 16.139581,13.493748 v 0.529167 h 0.529166 v -0.529167 z"
id="path2369" /><path
style="opacity:1;fill:#000000;stroke-width:0.0500063;stroke-linecap:square;stroke-dasharray:none"
d="m 16.139581,12.699998 v 0.529167 h 0.529166 v -0.529167 z"
id="path2367" /><path
style="opacity:1;fill:#000000;stroke-width:0.0500063;stroke-linecap:square;stroke-dasharray:none"
d="m 16.139581,11.906248 v 0.529167 h 0.529166 v -0.529167 z"
id="path2365" /><path
style="opacity:1;fill:#000000;stroke-width:0.0500063;stroke-linecap:square;stroke-dasharray:none"
d="m 16.139581,11.112498 v 0.529167 h 0.529166 v -0.529167 z"
id="path2363" /><path
style="opacity:1;fill:#000000;stroke-width:0.0500063;stroke-linecap:square;stroke-dasharray:none"
d="m 16.139581,10.318749 v 0.529166 h 0.529166 v -0.529166 z"
id="path2361" /><path
style="opacity:1;fill:#000000;stroke-width:0.0500063;stroke-linecap:square;stroke-dasharray:none"
d="m 16.139581,9.5249987 v 0.5291663 h 0.529166 V 9.5249987 Z"
id="path2359" /><path
style="opacity:1;fill:#000000;stroke-width:0.0500063;stroke-linecap:square;stroke-dasharray:none"
d="m 16.139581,8.7312488 v 0.5291666 h 0.529166 V 8.7312488 Z"
id="path2357" /><path
style="opacity:1;fill:#000000;stroke-width:0.0500063;stroke-linecap:square;stroke-dasharray:none"
d="m 16.139581,6.0854158 v 2.3812497 h 0.529166 V 6.0854158 Z"
id="path2355" /><path
style="opacity:1;fill:#000000;stroke-width:0.0500063;stroke-linecap:square;stroke-dasharray:none"
d="m 16.139581,5.2916659 v 0.5291666 h 0.529166 V 5.2916659 Z"
id="path2353" /><path
style="opacity:1;fill:#000000;stroke-width:0.0500063;stroke-linecap:square;stroke-dasharray:none"
d="m 16.139581,4.497916 v 0.5291666 h 0.529166 V 4.497916 Z"
id="path2351" /><path
style="opacity:1;fill:#000000;stroke-width:0.0500063;stroke-linecap:square;stroke-dasharray:none"
d="m 16.139581,3.7041662 v 0.5291665 h 0.529166 V 3.7041662 Z"
id="path2349" /><path
style="opacity:1;fill:#000000;stroke-width:0.0500063;stroke-linecap:square;stroke-dasharray:none"
d="m 16.139581,2.9104163 v 0.5291666 h 0.529166 V 2.9104163 Z"
id="rect14444" /><rect
style="opacity:1;fill:#666666;stroke-width:0.0500064;stroke-linecap:square;stroke-dasharray:none"
id="rect15056"
width="1.0583332"
height="0.52916658"
x="15.610415"
y="2.1166663" /><rect
style="opacity:1;fill:#666666;stroke-width:0.0500064;stroke-linecap:square;stroke-dasharray:none"
id="rect15468"
width="1.0583332"
height="0.52916658"
x="14.287498"
y="2.1166663" /><rect
style="opacity:1;fill:#666666;stroke-width:0.0500064;stroke-linecap:square;stroke-dasharray:none"
id="rect15470"
width="1.0583332"
height="0.52916658"
x="12.964582"
y="2.1166663" /><rect
style="opacity:1;fill:#999999;stroke-width:0.0500063;stroke-linecap:square;stroke-dasharray:none"
id="rect15882"
width="3.9687495"
height="0.52916658"
x="0.26458329"
y="2.1166663" /><path
style="opacity:1;fill:#000000;stroke-width:0.0500063;stroke-linecap:square;stroke-dasharray:none"
d="m 14.287498,-16.139581 h 0.529167 v -0.529167 h -0.529167 z"
transform="rotate(90)"
id="path2231" /><path
style="opacity:1;fill:#000000;stroke-width:0.0500063;stroke-linecap:square;stroke-dasharray:none"
d="m 14.287498,-15.345831 h 0.529167 v -0.529167 h -0.529167 z"
transform="rotate(90)"
id="path2229" /><path
style="opacity:1;fill:#000000;stroke-width:0.0500063;stroke-linecap:square;stroke-dasharray:none"
d="m 14.287498,-14.552081 h 0.529167 v -0.529167 h -0.529167 z"
transform="rotate(90)"
id="path2227" /><path
style="opacity:1;fill:#000000;stroke-width:0.0500063;stroke-linecap:square;stroke-dasharray:none"
d="m 14.287498,-11.641665 h 0.529167 v -2.645833 h -0.529167 z"
transform="rotate(90)"
id="path2225" /><path
style="opacity:1;fill:#000000;stroke-width:0.0500063;stroke-linecap:square;stroke-dasharray:none"
d="m 14.287498,-5.8208325 h 0.529167 v -5.5562495 h -0.529167 z"
transform="rotate(90)"
id="path2223" /><path
style="opacity:1;fill:#000000;stroke-width:0.0500063;stroke-linecap:square;stroke-dasharray:none"
d="m 14.287498,-4.7624993 h 0.529167 v -0.7937499 h -0.529167 z"
transform="rotate(90)"
id="path2221" /><path
style="opacity:1;fill:#000000;stroke-width:0.0500063;stroke-linecap:square;stroke-dasharray:none"
d="m 14.287498,-1.8520831 h 0.529167 V -4.497916 h -0.529167 z"
transform="rotate(90)"
id="path2219" /><path
style="opacity:1;fill:#000000;stroke-width:0.0500063;stroke-linecap:square;stroke-dasharray:none"
d="m 14.287498,-1.0583332 h 0.529167 v -0.5291666 h -0.529167 z"
transform="rotate(90)"
id="path2217" /><path
style="opacity:1;fill:#000000;stroke-width:0.0500063;stroke-linecap:square;stroke-dasharray:none"
d="m 14.287498,-0.2645833 h 0.529167 v -0.52916659 h -0.529167 z"
transform="rotate(90)"
id="rect16090" /></g><g
id="g1799"
transform="matrix(0.9833263,0,0,0.93331382,-31.070772,-23.035828)"
style="stroke-width:1.04385"><rect
style="fill:#000000;fill-opacity:1;stroke-width:0.445374;stroke-linecap:square"
id="rect486"
width="135.46664"
height="101.59999"
x="753.36902"
y="-330.61847"
inkscape:label="rect-bg"
transform="matrix(0.1171875,0,0,0.1171875,-56.418761,66.544469)"
mask="none" /><path
id="rect488"
mask="none"
style="fill:url(#radialGradient522);fill-opacity:1;stroke-width:0.445431;stroke-linecap:square;stroke-dasharray:none"
inkscape:label="rect-red"
d="m 725.48004,-288.15082 v 101.59998 h 101.67054 v -101.59998 z"
transform="matrix(0.1171875,0,0,0.1171875,-53.150408,61.568041)" /><path
id="rect490"
mask="none"
style="fill:url(#radialGradient524);fill-opacity:1;stroke-width:0.445431;stroke-linecap:square;stroke-dasharray:none"
inkscape:label="rect-red"
d="m 754.10795,-288.15082 v 101.59998 h 106.83874 v -101.59998 z"
transform="matrix(0.1171875,0,0,0.1171875,-53.150408,61.568041)" /><path
id="rect492"
mask="none"
style="fill:url(#radialGradient526);fill-opacity:1;stroke-width:0.445431;stroke-linecap:square;stroke-dasharray:none"
inkscape:label="rect-yellow"
d="m 726.11063,-288.15082 v 39.33912 h 103.1919 v -39.33912 z"
transform="matrix(0.1171875,0,0,0.1171875,-53.150408,61.568041)" /><path
id="rect494"
mask="none"
style="fill:url(#radialGradient528);fill-opacity:1;stroke-width:0.44543;stroke-linecap:square;stroke-dasharray:none"
inkscape:label="rect-yellow"
d="m 789.16083,-285.35065 v 98.79981 h 71.78586 v -98.79981 z"
transform="matrix(0.1171875,0,0,0.1171875,-53.150408,61.568041)" /><path
id="rect496"
mask="none"
style="fill:url(#radialGradient530);fill-opacity:1;stroke-width:0.44543;stroke-linecap:square;stroke-dasharray:none"
inkscape:label="rect-yellow"
d="m 808.70031,-273.18864 v 66.02235 h 52.24638 v -66.02235 z"
transform="matrix(0.1171875,0,0,0.1171875,-53.150408,61.568041)" /><path
id="rect498"
mask="none"
style="fill:url(#radialGradient532);fill-opacity:1;stroke-width:0.44543;stroke-linecap:square;stroke-dasharray:none"
inkscape:label="rect-yellow"
d="m 772.61997,-255.80111 v 66.02236 h 50.262 v -66.02236 z"
transform="matrix(0.1171875,0,0,0.1171875,-53.150408,61.568041)" /><path
id="rect500"
mask="none"
style="fill:url(#radialGradient534);fill-opacity:1;stroke-width:0.44543;stroke-linecap:square;stroke-dasharray:none"
inkscape:label="rect-yellow"
d="m 725.48004,-266.04489 v 78.31666 h 76.3411 v -78.31666 z"
transform="matrix(0.1171875,0,0,0.1171875,-53.150408,61.568041)" /><path
id="rect502"
mask="none"
style="fill:url(#radialGradient536);fill-opacity:1;stroke-width:0.44543;stroke-linecap:square;stroke-dasharray:none"
inkscape:label="rect-yellow"
d="m 785.90646,-288.15082 v 81.45637 h 29.49662 v -81.45637 z"
transform="matrix(0.1171875,0,0,0.1171875,-53.150408,61.568041)" /><path
id="rect504"
mask="none"
style="fill:url(#radialGradient538);fill-opacity:1;stroke-width:0.44543;stroke-linecap:square;stroke-dasharray:none"
inkscape:label="rect-yellow"
d="m 813.8244,-288.15082 v 51.91565 h 27.70629 v -51.91565 z"
transform="matrix(0.1171875,0,0,0.1171875,-53.150408,61.568041)" /><path
id="rect506"
mask="none"
style="fill:url(#radialGradient540);fill-opacity:1;stroke-width:0.445429;stroke-linecap:square;stroke-dasharray:none"
inkscape:label="rect-yellow"
d="m 808.21965,-227.99781 v 37.31065 h 52.72704 v -37.31065 z"
transform="matrix(0.1171875,0,0,0.1171875,-53.150408,61.568041)" /><path
id="rect508"
mask="none"
style="fill:url(#radialGradient542);fill-opacity:1;stroke-width:0.445429;stroke-linecap:square;stroke-dasharray:none"
inkscape:label="rect-yellow"
d="m 725.48004,-223.99378 v 37.31065 h 57.9261 v -37.31065 z"
transform="matrix(0.1171875,0,0,0.1171875,-53.150408,61.568041)" /><path
id="rect510"
mask="none"
style="fill:url(#radialGradient544);fill-opacity:1;stroke-width:0.445431;stroke-linecap:square;stroke-dasharray:none"
inkscape:label="rect-yellow"
d="m 725.48004,-288.15082 v 62.38874 h 69.58982 v -62.38874 z"
transform="matrix(0.1171875,0,0,0.1171875,-53.150408,61.568041)" /><path
id="rect512"
mask="none"
style="fill:url(#radialGradient546);fill-opacity:1;stroke-width:0.445431;stroke-linecap:square;stroke-dasharray:none"
inkscape:label="rect-white"
d="m 725.48004,-244.76798 v 49.2169 h 123.18557 v -49.2169 z"
transform="matrix(0.1171875,0,0,0.1171875,-53.150408,61.568041)" /><path
id="rect514"
mask="none"
style="fill:url(#radialGradient548);fill-opacity:1;stroke-width:0.445431;stroke-linecap:square;stroke-dasharray:none"
inkscape:label="rect-white"
d="m 800.4409,-274.46305 v 85.49128 h 60.50579 v -85.49128 z"
transform="matrix(0.1171875,0,0,0.1171875,-53.150408,61.568041)" /><path
id="rect516"
mask="none"
style="fill:url(#radialGradient550);fill-opacity:1;stroke-width:0.445431;stroke-linecap:square;stroke-dasharray:none"
inkscape:label="rect-white"
d="m 725.48004,-271.52176 v 84.97092 h 65.85919 v -84.97092 z"
transform="matrix(0.1171875,0,0,0.1171875,-53.150408,61.568041)" /><path
id="rect518"
mask="none"
style="fill:url(#radialGradient552);fill-opacity:1;stroke-width:0.445431;stroke-linecap:square;stroke-dasharray:none"
inkscape:label="rect-white"
d="m 729.04751,-288.15082 v 70.7628 h 83.27759 v -70.7628 z"
transform="matrix(0.1171875,0,0,0.1171875,-53.150408,61.568041)" /></g></svg>

Before

Width:  |  Height:  |  Size: 23 KiB

View File

@ -1,120 +0,0 @@
rendered_icons_optionally_from_svg = {
'icon_exe' : { 'png': 'icon_exe.png' , 'svg': 'icon_exe.svg', 'width': '256', 'height': '256' },
'icon_exe_48': { 'png': 'icon_exe_48.png', 'svg': 'icon_exe.svg', 'width': '48', 'height': '48' },
'icon_exe_32': { 'png': 'icon_exe_32.png', 'svg': 'icon_exe.svg', 'width': '32', 'height': '32' },
'icon_exe_16': { 'png': 'icon_exe_16.png', 'svg': 'icon_exe.svg', 'width': '16', 'height': '16' },
'icon_cps' : { 'png': 'icon_cps.png' , 'svg': 'icon_cps.svg', 'width': '256', 'height': '256' },
'icon_cps_48': { 'png': 'icon_cps_48.png', 'svg': 'icon_cps.svg', 'width': '48', 'height': '48' },
'icon_cps_32': { 'png': 'icon_cps_32.png', 'svg': 'icon_cps.svg', 'width': '32', 'height': '32' },
'icon_cps_16': { 'png': 'icon_cps_16.png', 'svg': 'icon_cps.svg', 'width': '16', 'height': '16' },
}
rendered_icons = {}
if render_icons_with_inkscape.allowed()
foreach key, info : rendered_icons_optionally_from_svg
rendered_icons += { key: custom_target(
key + '-from-svg',
output: info['png'],
command: [
inkscape,
'--export-area-page',
'--export-type', 'png',
'--export-filename', '@OUTPUT@',
'--export-width', info['width'],
'--export-height', info['height'],
files(info['svg']),
],
) }
endforeach
else
foreach key, info : rendered_icons_optionally_from_svg
rendered_icons += { key: files('generated_icons/' + info['png']) }
endforeach
endif
if host_platform == 'windows'
windows_icons = get_option('windows_icons')
windows_utf8cp = get_option('windows_utf8cp')
rc_conf_depends = []
rc_conf_depend_files = [
'resource.h',
]
icon_exe_ico_path = ''
icon_cps_ico_path = ''
winutf8_xml_path = ''
if windows_icons
make_ico = executable('makeico', sources: 'MakeIco.cpp', native: true)
generated_win_icos = {}
win_icos = {
'icon_exe': [ 'icon_exe', 'icon_exe_48', 'icon_exe_32', 'icon_exe_16' ],
'icon_cps': [ 'icon_cps', 'icon_cps_48', 'icon_cps_32', 'icon_cps_16' ],
}
foreach key, icons : win_icos
command = [
make_ico,
'@OUTPUT@',
]
foreach ikey : icons
command += [ rendered_icons[ikey] ]
endforeach
generated_win_icos += { key: custom_target(
key + '-ico',
output: key + '.ico',
command: command,
) }
endforeach
rc_conf_depends += [
generated_win_icos['icon_exe'],
generated_win_icos['icon_cps'],
]
icon_exe_ico_path = join_paths(meson.current_build_dir(), 'icon_exe.ico')
icon_cps_ico_path = join_paths(meson.current_build_dir(), 'icon_cps.ico')
endif
if windows_utf8cp
rc_conf_depend_files += [
'winutf8.xml',
]
winutf8_xml_path = join_paths(meson.current_source_dir(), 'winutf8.xml')
endif
rc_conf_data = configuration_data()
rc_conf_data.merge_from(conf_data)
rc_conf_data.set('HAVE_ICONS', windows_icons ? 1 : 0)
rc_conf_data.set('HAVE_UTF8CP', windows_utf8cp ? 1 : 0)
rc_conf_data.set('RESOUCE_H', join_paths(meson.current_source_dir(), 'resource.h'))
rc_conf_data.set('WINUTF8_XML', winutf8_xml_path)
rc_conf_data.set('ICON_EXE_ICO', icon_exe_ico_path)
rc_conf_data.set('ICON_CPS_ICO', icon_cps_ico_path)
powder_files += windows_mod.compile_resources(
configure_file(
input: 'powder-res.template.rc',
output: 'powder-res.rc',
configuration: rc_conf_data,
),
depends: rc_conf_depends,
depend_files: rc_conf_depend_files,
)
elif host_platform == 'darwin'
configure_file(
input: 'Info.template.plist',
output: 'Info.plist',
configuration: conf_data,
)
elif host_platform == 'linux'
data_files += to_array.process(rendered_icons['icon_exe'], extra_args: 'icon_exe_png')
data_files += to_array.process(rendered_icons['icon_cps'], extra_args: 'icon_cps_png')
data_files += to_array.process('save.xml', extra_args: 'save_xml')
data_files += to_array.process(configure_file(
input: 'powder.template.desktop',
output: 'powder.desktop',
configuration: conf_data,
), extra_args: 'powder_desktop')
configure_file(
input: 'appdata.template.xml',
output: 'appdata.xml',
configuration: conf_data,
)
endif
data_files += to_array.process('save_local.png', extra_args: 'save_local_png')
data_files += to_array.process('save_online.png', extra_args: 'save_online_png')
data_files += to_array.process('font.bz2', extra_args: 'compressed_font_data')

4
resources/powder-res.rc Normal file
View File

@ -0,0 +1,4 @@
#define IDI_ICON1 101
#define IDI_ICON2 102
IDI_ICON1 ICON DISCARDABLE "powder.ico"
IDI_ICON2 ICON DISCARDABLE "document.ico"

View File

@ -1,40 +0,0 @@
#pragma code_page(65001) // UTF-8
#include "@RESOUCE_H@"
#include <winuser.h>
#include <winver.h>
#include <ntdef.h>
#define HAVE_ICONS @HAVE_ICONS@
#define HAVE_UTF8CP @HAVE_UTF8CP@
#if HAVE_ICONS
IDI_ICON ICON DISCARDABLE "@ICON_EXE_ICO@"
IDI_DOC_ICON ICON DISCARDABLE "@ICON_CPS_ICO@"
#endif
#if HAVE_UTF8CP
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "@WINUTF8_XML@"
#endif
VS_VERSION_INFO VERSIONINFO
FILEVERSION @DISPLAY_VERSION_MAJOR@,@DISPLAY_VERSION_MINOR@,0,@BUILD_NUM@
PRODUCTVERSION @DISPLAY_VERSION_MAJOR@,@DISPLAY_VERSION_MINOR@,0,@BUILD_NUM@
{
BLOCK "StringFileInfo"
{
BLOCK "040904b0"
{
VALUE "CompanyName", "https://powdertoy.co.uk/\0"
VALUE "FileDescription", "@APPNAME@\0"
VALUE "FileVersion", "@DISPLAY_VERSION_MAJOR@.@DISPLAY_VERSION_MINOR@.0.@BUILD_NUM@\0"
VALUE "OriginalFilename", "@APPEXE@.exe\0"
VALUE "LegalCopyright", "@MANIFEST_COPYRIGHT@\0"
VALUE "ProductName", "@APPCOMMENT@\0"
VALUE "ProductVersion", "@DISPLAY_VERSION_MAJOR@.@DISPLAY_VERSION_MINOR@.0.@BUILD_NUM@\0"
VALUE "InternalName", "@APPID@\0"
}
}
BLOCK "VarFileInfo"
{
VALUE "Translation", 0x409, 65001
}
}

BIN
resources/powder.icns Executable file

Binary file not shown.

BIN
resources/powder.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

View File

@ -1,56 +0,0 @@
.TH POWDER 6 "2019-09-25" "" "Games manual"
.
.SH NAME
powder \- a physics sandbox game
.
.SH SYNOPSIS
.SY powder
[\fIOPTIONS...\fR]
.YS
.
.SH DESCRIPTION
The Powder Toy is a free physics sandbox game, which simulates
air pressure and velocity, heat, gravity and a number of other interactions
between different substances.
The game provides the player with various building materials, liquids,
gases and electronic components which can be used to construct
complex machines, guns, bombs, realistic terrains and almost anything else.
The player can then mine them and watch cool explosions, add intricate wirings,
play with little stickmen or operate their machine.
The game also features a Lua API, which allows to automate work or even
make plugins for the program.
.
.SH OPTIONS
\fBNOTE:\fR Program options should be written exactly as specified on this
man page \- there are \fBno leading dashes\fR in front of their names.
.TP
\fBddir\fR \fIDIRECTORY\fR
Load and save preferences, savegames etc. in \fIDIRECTORY\fR.
The directory must already exist (if missing, it will not be created).
.TP
.B disable-network
Disable network access.
.TP
.B kiosk
Run in fullscreen mode.
.TP
\fBopen\fR \fIFILE\fR
Open the specified savegame on program start.
.TP
\fBproxy\fR:\fISERVER\fR[:\fIPORT\fR]
Use the specified proxy server.
.TP
\fBptsave\fR:\fISAVEID\fR
Open an on-line save with the given ID.
.TP
.B redirect
Do not print anything to standard output nor the standard error stream;
redirect all messages to \fIstdout.log\fR and \fIstderr.log\fR files.
.
.SH SEE ALSO
.TP
.B https://powdertoy.co.uk/
Official website. To use on-line features, such as saving and sharing their
creations, players need to register an account.

View File

@ -1,8 +0,0 @@
[Desktop Entry]
Name=@APPNAME@
Type=Application
Comment=@APPCOMMENT@
MimeType=application/vnd.powdertoy.save;x-scheme-handler/ptsave;
Categories=Game;Simulation;
Exec=@APPEXE@ %u
Icon=@APPVENDOR@-@APPEXE@

View File

@ -1,3 +0,0 @@
#define IDI_ICON 101
#define IDI_DOC_ICON 102

View File

@ -1,8 +0,0 @@
<?xml version="1.0"?>
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
<mime-type type="application/vnd.powdertoy.save">
<comment>Powder Toy save</comment>
<glob pattern="*.cps"/>
<glob pattern="*.stm"/>
</mime-type>
</mime-info>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

View File

@ -1,8 +0,0 @@
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity name="." version="6.0.0.0"/>
<application>
<windowsSettings>
<activeCodePage xmlns="http://schemas.microsoft.com/SMI/2019/WindowsSettings">UTF-8</activeCodePage>
</windowsSettings>
</application>
</assembly>

View File

@ -0,0 +1,126 @@
#
# SCons builder for gcc's precompiled headers
# Copyright (C) 2006 Tim Blechmann
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
# 1.1
#
# 09-11-2011 Pedro Larroy: Fixed dependency emitter not working with variant dir
#
#
import SCons.Action
import SCons.Builder
import SCons.Scanner.C
import SCons.Util
import SCons.Script
import os
SCons.Script.EnsureSConsVersion(0,96,92)
GchAction = SCons.Action.Action('$GCHCOM', '$GCHCOMSTR')
GchShAction = SCons.Action.Action('$GCHSHCOM', '$GCHSHCOMSTR')
def gen_suffix(env, sources):
return sources[0].get_suffix() + env['GCHSUFFIX']
GchShBuilder = SCons.Builder.Builder(action = GchShAction,
source_scanner = SCons.Scanner.C.CScanner(),
suffix = gen_suffix)
GchBuilder = SCons.Builder.Builder(action = GchAction,
source_scanner = SCons.Scanner.C.CScanner(),
suffix = gen_suffix)
def header_path(node):
h_path = node.abspath
idx = h_path.rfind('.gch')
if idx != -1:
h_path = h_path[0:idx]
if not os.path.isfile(h_path):
raise SCons.Errors.StopError("can't find header file: {0}".format(h_path))
return h_path
else:
raise SCons.Errors.StopError("{0} file doesn't have .gch extension".format(h_path))
def static_pch_emitter(target,source,env):
SCons.Defaults.StaticObjectEmitter( target, source, env )
scanner = SCons.Scanner.C.CScanner()
path = scanner.path(env)
deps = scanner(source[0], env, path)
if env.get('Gch'):
h_path = header_path(env['Gch'])
if h_path in [x.abspath for x in deps]:
#print 'Found dep. on pch: ', target[0], ' -> ', env['Gch']
env.Depends(target, env['Gch'])
return (target, source)
def shared_pch_emitter(target,source,env):
SCons.Defaults.SharedObjectEmitter( target, source, env )
scanner = SCons.Scanner.C.CScanner()
path = scanner.path(env)
deps = scanner(source[0], env, path)
if env.get('GchSh'):
h_path = header_path(env['GchSh'])
if h_path in [x.abspath for x in deps]:
#print 'Found dep. on pch (shared): ', target[0], ' -> ', env['Gch']
env.Depends(target, env['GchSh'])
return (target, source)
def generate(env):
"""
Add builders and construction variables for the Gch builder.
"""
env.Append(BUILDERS = {
'gch': env.Builder(
action = GchAction,
target_factory = env.fs.File,
),
'gchsh': env.Builder(
action = GchShAction,
target_factory = env.fs.File,
),
})
try:
bld = env['BUILDERS']['Gch']
bldsh = env['BUILDERS']['GchSh']
except KeyError:
bld = GchBuilder
bldsh = GchShBuilder
env['BUILDERS']['Gch'] = bld
env['BUILDERS']['GchSh'] = bldsh
env['GCHCOM'] = '$CXX -Wall -o $TARGET -x c++-header -c $CXXFLAGS $CCFLAGS $_CCCOMCOM $SOURCE'
env['GCHSHCOM'] = '$CXX -o $TARGET -x c++-header -c $SHCXXFLAGS $CCFLAGS $_CCCOMCOM $SOURCE'
env['GCHSUFFIX'] = '.gch'
for suffix in SCons.Util.Split('.c .C .cc .cxx .cpp .c++'):
env['BUILDERS']['StaticObject'].add_emitter( suffix, static_pch_emitter )
env['BUILDERS']['SharedObject'].add_emitter( suffix, shared_pch_emitter )
def exists(env):
return env.Detect('g++')

Binary file not shown.

View File

@ -0,0 +1,241 @@
#
# Copyright (c) 2010 Western Digital Corporation
# Alan Somers asomers (at) gmail (dot) com
#
# 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.
#
####
import os
import new
import sys
##
import SCons
if sys.version_info < (2,6,0):
from relpath import relpath
else:
from os.path import relpath
def sc_relpath(src, destdir):
"""Like relpath but aware of SCons convention regarding '#' in pathnames"""
if src[0] == '#':
return relpath(src[1:], destdir)
else:
return relpath(os.path.join(destdir, src), destdir)
class MF_Executor(SCons.Executor.Executor):
"""Custom Executor that can scan each target file for its dependencies
individually, rather than giving every target the same deps.
Assumes that there is a one-to-one relationship between sources and targets
and the targets have the same basenames as their respective sources
ie. [[foo.o, bar.o], [foo.c, bar.c]]"""
def scan(self, scanner, node_list):
tgt_names = [os.path.splitext(
os.path.basename(str(i)))[0] for i in self.targets]
env = self.get_build_env()
if scanner:
for node in node_list:
tgt = \
self.targets[tgt_names.index(
os.path.splitext(
os.path.basename(str(node)))[0])]
node.disambiguate()
s = scanner.select(node)
if not s:
continue
path = self.get_build_scanner_path(s)
tgt.add_to_implicit(node.get_implicit_deps(env, s, path))
else:
kw = self.get_kw()
for node in node_list:
tgt = \
self.targets[tgt_names.index(
os.path.splitext(
os.path.basename(str(node)))[0])]
node.disambiguate()
scanner = node.get_env_scanner(env, kw)
if not scanner:
continue
scanner = scanner.select(node)
if not scanner:
continue
path = self.get_build_scanner_path(scanner)
tgt.add_to_implicit(node.get_implicit_deps(env, scanner, path))
def MF_get_single_executor(self, env, tlist, slist, executor_kw):
if not self.action:
raise UserError, "Builder %s must have an action to build %s." % \
(self.get_name(env or self.env), map(str,tlist))
return MF_Executor(self.action, env, [], tlist, slist, executor_kw)
def exists(env):
return env.WhereIs(env.subst['$CC']) or env.WhereIs(env.subst['$CXX'])
def MFProgramEmitter(target, source, env):
"""Ensures that target list is complete, and does validity checking. Sets precious"""
if len(target) == 1 and len(source) > 1:
#Looks like the user specified many sources and SCons created 1 target
#targets are implicit, but the builder doesn't know how to handle
#suffixes for multiple target files, so we'll do it here
objdir = env.get('OBJDIR', '')
#target = [os.path.join(
# objdir,
# os.path.splitext(
# os.path.basename(str(i)))[0] + '.o' ) for i in source]
elif len(source) == 1 and 'OBJDIR' in env:
target = os.path.join(
env['OBJDIR'],
os.path.splitext(
os.path.basename(str(source[0])))[0] + '.o' )
else:
#targets are explicit, we need to check their validity
tgt_names = [os.path.splitext(
os.path.basename(str(i)))[0] for i in target]
src_names = [os.path.splitext(
os.path.basename(str(i)))[0] for i in source]
tgt_dirs = [os.path.dirname(str(i)) for i in target]
if sorted(tgt_names) != sorted(src_names):
raise ValueError, "target files do not have obvious one-one relationship to source files"
if len(set(src_names)) != len(src_names):
raise ValueError, "source files may not include identically named files in different directories"
if len(set(tgt_dirs)) != 1:
raise ValueError, "Target files must all be in same directory"
for t in target:
env.Precious(t)
return target, source
def MFProgramGenerator(source, target, env, for_signature):
#Rebuild everything if
# a) the number of dependencies has changed
# b) any target does not exist
# c) the build command has changed
#Else rebuild only those c files that have changed_since_last_build
#The signature of this builder should always be the same, because the
#multifile compile is always functionally equivalent to rebuilding
#everything
if for_signature:
pared_sources = source
else:
#First a sanity check
assert len(set([os.path.splitext(str(i))[1] for i in source])) == 1, \
"All source files must have the same extension."
pared_sources = []
src_names = [os.path.splitext(os.path.basename(str(i)))[0]
for i in source]
tgt_names = [os.path.splitext(os.path.basename(str(t)))[0]
for t in target]
ni = target[0].get_binfo()
oi = target[0].get_stored_info().binfo
if ni.bactsig != oi.bactsig:
#Command line has changed
pared_sources = source
else:
for i in range(len(tgt_names)):
t = target[i]
tgt_name = tgt_names[i]
if not t.exists():
#a target does not exist
pared_sources = source
break
bi = t.get_stored_info().binfo
then = bi.bsourcesigs + bi.bdependsigs + bi.bimplicitsigs
children = t.children()
if len(children) != len(then):
#the number of dependencies has changed
pared_sources = source
break
for child, prev_ni in zip(children, then):
if child.changed_since_last_build(t, prev_ni) and \
not t in pared_sources:
#If child is a source file, not an explicit or implicit
#dependency, then it is not truly a dependency of any target
#except that with the same basename. This is a limitation
#of SCons.node, which assumes that all sources of a Node
#are dependencies of all targets. So we check for that case
#here and only rebuild as necessary.
src_name = os.path.splitext(os.path.basename(str(child)))[0]
if src_name not in tgt_names or src_name == tgt_name:
s = source[src_names.index(tgt_name)]
pared_sources.append(s)
assert len(pared_sources) > 0
destdir = str(target[0].dir)
#finding sconscript_dir is a bit of a hack. It assumes that the source
#files are always going to be in the same directory as the SConscript file
#which is not necessarily true. BUG BY Alan Somers
sconscript_dir = os.path.dirname(str(pared_sources[0]))
prefixed_sources = [relpath(str(i), destdir) for i in pared_sources]
prefixed_sources_str = ' '.join([str(i) for i in prefixed_sources])
lang_ext = os.path.splitext(prefixed_sources[0])[1]
tgt_names2 = [os.path.splitext(os.path.basename(str(t)))[0]
for t in target]
_CPPPATH = []
if 'CPPPATH' in env:
for i in env['CPPPATH']:
#if i[0] == '#':
##_CPPPATH.append(relpath(i[1:], destdir))
_CPPPATH.append(i)
#else:
# _CPPPATH.append(relpath(os.path.join(sconscript_dir, i),
# destdir))
defines = ""
for t in env['CPPDEFINES']:
defines += ("-D"+str(t)+" ")
_CPPINCFLAGS = ['-I' + i for i in _CPPPATH]
_CCOMCOM = '$CPPFLAGS $_CPPDEFFLAGS $defines %s' % ' '.join(_CPPINCFLAGS)
libstr = ""
for t in env['LIBS']:
libstr += ("-l"+t+" ")
if lang_ext == '.c' :
_CCCOM = 'cd %s && $CC $CFLAGS $CCFLAGS %s %s $LINKFLAGS %s -o %s' % \
(destdir, _CCOMCOM, prefixed_sources_str, libstr, tgt_names2[0])
#XXX BUG BY Alan Somers. $CCCOMSTR gets substituted using the full list of target files,
#not prefixed_sources
cmd = SCons.Script.Action(env.subst(_CCCOM), "$CCCOMSTR")
elif lang_ext in ['.cc', '.cpp']:
_CXXCOM = 'cd %s && $CXX $CXXFLAGS $CCFLAGS %s %s $LINKFLAGS %s -o %s' % \
(destdir, _CCOMCOM, prefixed_sources_str, libstr, tgt_names2[0])
cmd = SCons.Script.Action(env.subst(_CXXCOM), "$CXXCOMSTR")
else:
assert False, "Unknown source file extension %s" % lang_ext
return cmd
def generate(env):
"""Adds the MFObject builder to your environment"""
MFProgramBld = env.Builder(generator = MFProgramGenerator,
emitter = MFProgramEmitter,
suffix = '.o',
source_scanner=SCons.Tool.SourceFileScanner)
MFProgramBld.get_single_executor = new.instancemethod(MF_get_single_executor,
MFProgramBld, MFProgramBld.__class__)
env.Append(BUILDERS = {'MFProgram': MFProgramBld})

Binary file not shown.

View File

@ -0,0 +1,73 @@
#PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
#--------------------------------------------
#
#1. This LICENSE AGREEMENT is between the Python Software Foundation
#("PSF"), and the Individual or Organization ("Licensee") accessing and
#otherwise using this software ("Python") in source or binary form and
#its associated documentation.
#
#2. Subject to the terms and conditions of this License Agreement, PSF hereby
#grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
#analyze, test, perform and/or display publicly, prepare derivative works,
#distribute, and otherwise use Python alone or in any derivative version,
#provided, however, that PSF's License Agreement and PSF's notice of copyright,
#i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
#Python Software Foundation; All Rights Reserved" are retained in Python alone or
#in any derivative version prepared by Licensee.
#
#3. In the event Licensee prepares a derivative work that is based on
#or incorporates Python or any part thereof, and wants to make
#the derivative work available to others as provided herein, then
#Licensee hereby agrees to include in any such work a brief summary of
#the changes made to Python.
#
#4. PSF is making Python available to Licensee on an "AS IS"
#basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
#IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
#DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
#FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
#INFRINGE ANY THIRD PARTY RIGHTS.
#
#5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
#FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
#A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
#OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
#
#6. This License Agreement will automatically terminate upon a material
#breach of its terms and conditions.
#
#7. Nothing in this License Agreement shall be deemed to create any
#relationship of agency, partnership, or joint venture between PSF and
#Licensee. This License Agreement does not grant permission to use PSF
#trademarks or trade name in a trademark sense to endorse or promote
#products or services of Licensee, or any third party.
#
#8. By copying, installing or otherwise using Python, Licensee
#agrees to be bound by the terms and conditions of this License
#Agreement.
# Changelog:
# 3-12-2010 Alan Somers Copied verbatim from posixpath.py in Python 2.6.4
from os.path import *
def relpath(path, start=curdir):
"""Return a relative version of a path"""
if not path:
raise ValueError("no path specified")
start_list = abspath(start).split(sep)
path_list = abspath(path).split(sep)
# Work out how much of the filepath is shared by start and path.
i = len(commonprefix([start_list, path_list]))
rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
if not rel_list:
return curdir
return join(*rel_list)

View File

@ -1,5 +1,6 @@
#pragma once
#include "gui/interface/Window.h"
#include "interface/Window.h"
class Activity
{
@ -18,18 +19,24 @@ public:
{
Show();
}
void Exit() override
virtual void Exit()
{
Hide();
SelfDestruct();
}
void Show() override
virtual void Show()
{
MakeActiveWindow();
if(ui::Engine::Ref().GetWindow() != this)
{
ui::Engine::Ref().ShowWindow(this);
}
}
void Hide() override
virtual void Hide()
{
CloseActiveWindow();
if(ui::Engine::Ref().GetWindow() == this)
{
ui::Engine::Ref().CloseWindow();
}
}
virtual ~WindowActivity() {}
};
};

226
src/Config.h Normal file
View File

@ -0,0 +1,226 @@
/*
* Config.h
*
* Created on: Jan 5, 2012
* Author: Simon
*/
//#ifndef CONFIG_H_
//#define CONFIG_H_
#ifdef WIN
#define PATH_SEP "\\"
#define PATH_SEP_CHAR '\\'
#else
#define PATH_SEP "/"
#define PATH_SEP_CHAR '/'
#endif
//VersionInfoStart
#ifndef SAVE_VERSION
#define SAVE_VERSION 85
#endif
#ifndef MINOR_VERSION
#define MINOR_VERSION 0
#endif
#ifndef BUILD_NUM
#define BUILD_NUM 255
#endif
#ifndef SNAPSHOT_ID
#define SNAPSHOT_ID 0
#endif
#ifndef STABLE
#ifndef BETA
#define BETA
#define SNAPSHOT
#endif
#endif
//VersionInfoEnd
//#define IGNORE_UPDATES //uncomment this for mods, to not get any update notifications
#if defined(DEBUG) || defined(RENDERER) || defined(X86_SSE2)
#define HIGH_QUALITY_RESAMPLE //High quality image resampling, slower but much higher quality than my terribad linear interpolation
#endif
#if defined(SNAPSHOT)
#define IDENT_RELTYPE "S"
#elif defined(BETA)
#define IDENT_RELTYPE "B"
#else
#define IDENT_RELTYPE "R"
#endif
#if defined(WIN)
#if defined(_64BIT)
#define IDENT_PLATFORM "WIN64"
#else
#define IDENT_PLATFORM "WIN32"
#endif
#elif defined(LIN)
#if defined(_64BIT)
#define IDENT_PLATFORM "LIN64"
#else
#define IDENT_PLATFORM "LIN32"
#endif
#elif defined(MACOSX)
#define IDENT_PLATFORM "MACOSX"
#else
#define IDENT_PLATFORM "UNKNOWN"
#endif
#if defined(X86_SSE3)
#define IDENT_BUILD "SSE3"
#elif defined(X86_SSE2)
#define IDENT_BUILD "SSE2"
#elif defined(X86_SSE)
#define IDENT_BUILD "SSE"
#else
#define IDENT_BUILD "NO"
#endif
#define IDENT_VERSION "G" //Change this if you're not Simon! It should be a single letter
#define MTOS_EXPAND(str) #str
#define MTOS(str) MTOS_EXPAND(str)
#define SERVER "powdertoy.co.uk"
#define SCRIPTSERVER "powdertoy.co.uk"
#define STATICSERVER "static.powdertoy.co.uk"
#define LOCAL_SAVE_DIR "Saves"
#define STAMPS_DIR "stamps"
#define BRUSH_DIR "Brushes"
#define APPDATA_SUBDIR "\\HardWIRED"
//Number of unique thumbnails to have in cache at one time
#define THUMB_CACHE_SIZE 256
#ifndef M_PI
#define M_PI 3.14159265f
#endif
#ifndef M_GRAV
#define M_GRAV 6.67300e-1
#endif
//Number of asynchronous connections used to retrieve thumnails
#define IMGCONNS 5
//Not sure
#define TIMEOUT 100
//HTTP request timeout in seconds
#define HTTP_TIMEOUT 10
#ifdef RENDERER
#define MENUSIZE 0
#define BARSIZE 0
#else
#define MENUSIZE 40
//#define MENUSIZE 20
//#define BARSIZE 50
#define BARSIZE 17
#endif
#define XRES 612
#define YRES 384
#define NPART XRES*YRES
#define XCNTR 306
#define YCNTR 192
#define MAX_DISTANCE sqrt(pow((float)XRES, 2)+pow((float)YRES, 2))
#define GRAV_DIFF
#define MAXSIGNS 16
#define TAG_MAX 256
#define ZSIZE_D 16
#define ZFACTOR_D 8
extern unsigned char ZFACTOR;
extern unsigned char ZSIZE;
#define CELL 4
#define ISTP (CELL/2)
#define CFDS (4.0f/CELL)
#define AIR_TSTEPP 0.3f
#define AIR_TSTEPV 0.4f
#define AIR_VADV 0.3f
#define AIR_VLOSS 0.999f
#define AIR_PLOSS 0.9999f
#define GRID_X 5
#define GRID_Y 4
#define GRID_P 3
#define GRID_S 6
#define GRID_Z 3
#define CATALOGUE_X 4
#define CATALOGUE_Y 3
#define CATALOGUE_S 6
#define CATALOGUE_Z 3
#define STAMP_MAX 240
#define SAVE_OPS
#define NGOL 24
#define NGOLALT 24 //NGOL should be 24, but use this var until I find out why
#define CIRCLE_BRUSH 0
#define SQUARE_BRUSH 1
#define TRI_BRUSH 2
#define BRUSH_NUM 3
#define SURF_RANGE 10
#define NORMAL_MIN_EST 3
#define NORMAL_INTERP 20
#define NORMAL_FRAC 16
#define REFRACT 0x80000000
/* heavy flint glass, for awesome refraction/dispersion
this way you can make roof prisms easily */
#define GLASS_IOR 1.9
#define GLASS_DISP 0.07
#ifdef WIN
#define strcasecmp stricmp
#endif
#if defined(_MSC_VER)
#define fmin min
#define fminf min
#define fmax max
#define fmaxf max
#endif
#if defined(_MSC_VER)
#define TPT_INLINE _inline
#define TPT_NO_INLINE
#elif defined(__llvm__)
#define TPT_INLINE
#define TPT_NO_INLINE
#else
#define TPT_INLINE inline
#define TPT_NO_INLINE inline
#endif
#define TPT_VM_CALLABLE __cdecl
#define SDEUT
//#define REALHEAT
#define DEBUG_PARTS 0x0001
#define DEBUG_PARTCOUNT 0x0002
#define DEBUG_DRAWTOOL 0x0004
#define DEBUG_PERFORMANCE_CALC 0x0008
#define DEBUG_PERFORMANCE_FRAME 0x0010
//#endif /* CONFIG_H_ */

View File

@ -1,70 +0,0 @@
#pragma once
#include "VcsTag.h"
#include "common/Version.h"
constexpr bool SET_WINDOW_ICON = @SET_WINDOW_ICON@;
constexpr bool DEBUG = @DEBUG@;
constexpr bool X86 = @X86@;
constexpr bool BETA = @BETA@;
constexpr bool SNAPSHOT = @SNAPSHOT@;
constexpr bool MOD = @MOD@;
constexpr bool NOHTTP = @NOHTTP@;
constexpr bool LUACONSOLE = @LUACONSOLE@;
constexpr bool ALLOW_FAKE_NEWER_VERSION = @ALLOW_FAKE_NEWER_VERSION@;
constexpr bool USE_UPDATESERVER = @USE_UPDATESERVER@;
constexpr bool CAN_INSTALL = @CAN_INSTALL@;
constexpr bool USE_BLUESCREEN = @USE_BLUESCREEN@;
constexpr bool INSTALL_CHECK = @INSTALL_CHECK@;
constexpr bool IGNORE_UPDATES = @IGNORE_UPDATES@;
constexpr bool ENFORCE_HTTPS = @ENFORCE_HTTPS@;
constexpr bool SECURE_CIPHERS_ONLY = @SECURE_CIPHERS_ONLY@;
constexpr bool PLATFORM_CLIPBOARD = @PLATFORM_CLIPBOARD@;
constexpr bool USE_SYSTEM_CERT_PROVIDER = @USE_SYSTEM_CERT_PROVIDER@;
constexpr bool FFTW_PLAN_MEASURE = @FFTW_PLAN_MEASURE@;
constexpr bool ALLOW_QUIT = @ALLOW_QUIT@;
constexpr bool DEFAULT_TOUCH_UI = @DEFAULT_TOUCH_UI@;
constexpr bool ALLOW_DATA_FOLDER = @ALLOW_DATA_FOLDER@;
constexpr char PATH_SEP_CHAR = '@PATH_SEP_CHAR@';
enum ForceWindowFrameOps
{
forceWindowFrameOpsNone, // usual behaviour
forceWindowFrameOpsEmbedded, // e.g. into a webpage; this sweeps a few emscripten limitations under the rug
forceWindowFrameOpsHandheld, // e.g. the system doesn't support windowed mode; includes odd setups like chromebooks
};
constexpr ForceWindowFrameOps FORCE_WINDOW_FRAME_OPS = @FORCE_WINDOW_FRAME_OPS@;
constexpr char SERVER[] = "@SERVER@";
constexpr char STATICSERVER[] = "@STATICSERVER@";
constexpr char UPDATESERVER[] = "@UPDATESERVER@";
constexpr char IDENT_PLATFORM[] = "@IDENT_PLATFORM@";
constexpr char IDENT[] = "@IDENT@";
constexpr char APPNAME[] = "@APPNAME@";
constexpr char APPCOMMENT[] = "@APPCOMMENT@";
constexpr char APPEXE[] = "@APPEXE@";
constexpr char APPID[] = "@APPID@";
constexpr char APPDATA[] = "@APPDATA@";
constexpr char APPVENDOR[] = "@APPVENDOR@";
constexpr int MOD_ID = @MOD_ID@;
struct DisplayVersionWithBuild
{
Version<2> displayVersion;
size_t build;
};
constexpr DisplayVersionWithBuild APP_VERSION = { { @DISPLAY_VERSION_MAJOR@, @DISPLAY_VERSION_MINOR@ }, @BUILD_NUM@ };
constexpr DisplayVersionWithBuild UPSTREAM_VERSION = { { @UPSTREAM_VERSION_MAJOR@, @UPSTREAM_VERSION_MINOR@ }, @UPSTREAM_BUILD_NUM@ };
constexpr auto DISPLAY_VERSION = APP_VERSION.displayVersion;
constexpr char IDENT_RELTYPE = SNAPSHOT ? 'S' : (BETA ? 'B' : 'R');
constexpr char SCHEME[] = "https://";
constexpr char STATICSCHEME[] = "https://";
constexpr char LOCAL_SAVE_DIR[] = "Saves";
constexpr char STAMPS_DIR[] = "stamps";
constexpr char BRUSH_DIR[] = "Brushes";
constexpr int httpMaxConcurrentStreams = 50;
constexpr int httpConnectTimeoutS = 15;

View File

@ -1,9 +1,27 @@
#pragma once
/*
* Controller.h
*
* Created on: Jan 25, 2012
* Author: Simon
*/
#ifndef CONTROLLER_H_
#define CONTROLLER_H_
class ControllerCallback
{
public:
ControllerCallback() {}
virtual void ControllerExit() {}
virtual ~ControllerCallback() {}
};
class Controller
{
private:
virtual void Exit();
virtual void Show();
virtual void Hide();
virtual ~Controller() = default;
};
#endif /* CONTROLLER_H_ */

View File

@ -1,42 +1,65 @@
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <string>
#include <stdexcept>
#include <iostream>
#include <iterator>
#include <optional>
#include <stdexcept>
#include <png.h>
#include <zlib.h>
#include <stdio.h>
#include "Format.h"
#include "graphics/Graphics.h"
ByteString format::UnixtimeToDate(time_t unixtime, ByteString dateFormat, bool local)
std::string format::URLEncode(std::string source)
{
char * src = (char *)source.c_str();
char * dst = new char[(source.length()*3)+2];
std::fill(dst, dst+(source.length()*3)+2, 0);
char *d;
unsigned char *s;
for (d=dst; *d; d++) ;
for (s=(unsigned char *)src; *s; s++)
{
if ((*s>='0' && *s<='9') ||
(*s>='a' && *s<='z') ||
(*s>='A' && *s<='Z'))
*(d++) = *s;
else
{
*(d++) = '%';
*(d++) = hex[*s>>4];
*(d++) = hex[*s&15];
}
}
*d = 0;
std::string finalString(dst);
delete[] dst;
return finalString;
}
std::string format::UnixtimeToDate(time_t unixtime, std::string dateFormat)
{
struct tm * timeData;
char buffer[128];
if (local)
{
timeData = localtime(&unixtime);
}
else
{
timeData = gmtime(&unixtime);
}
timeData = localtime(&unixtime);
strftime(buffer, 128, dateFormat.c_str(), timeData);
return ByteString(buffer);
return std::string(buffer);
}
ByteString format::UnixtimeToDateMini(time_t unixtime)
std::string format::UnixtimeToDateMini(time_t unixtime)
{
time_t currentTime = time(NULL);
struct tm currentTimeData = *gmtime(&currentTime);
struct tm timeData = *gmtime(&unixtime);
struct tm currentTimeData = *localtime(&currentTime);
struct tm timeData = *localtime(&unixtime);
if(currentTimeData.tm_year != timeData.tm_year)
{
return UnixtimeToDate(unixtime, "%d %b %Y");
return UnixtimeToDate(unixtime, "%b %Y");
}
else if(currentTimeData.tm_mon != timeData.tm_mon || currentTimeData.tm_mday != timeData.tm_mday)
{
@ -48,347 +71,351 @@ ByteString format::UnixtimeToDateMini(time_t unixtime)
}
}
String format::CleanString(String dirtyString, bool ascii, bool color, bool newlines, bool numeric)
std::string format::CleanString(std::string dirtyString, int maxStringLength)
{
for (size_t i = 0; i < dirtyString.size(); i++)
{
switch(dirtyString[i])
{
case '\b':
if (color)
{
dirtyString.erase(i, 2);
i--;
}
else
i++;
break;
case '\x0E':
if (color)
{
dirtyString.erase(i, 1);
i--;
}
break;
case '\x0F':
if (color)
{
dirtyString.erase(i, 4);
i--;
}
else
i += 3;
break;
case '\r':
case '\n':
if (newlines)
dirtyString[i] = ' ';
break;
default:
if (numeric && (dirtyString[i] < '0' || dirtyString[i] > '9'))
{
dirtyString.erase(i, 1);
i--;
}
// if less than ascii 20 or greater than ascii 126, delete
else if (ascii && (dirtyString[i] < ' ' || dirtyString[i] > '~'))
{
dirtyString.erase(i, 1);
i--;
}
break;
}
}
return dirtyString;
return CleanString(dirtyString, std::string::npos, maxStringLength);
}
std::vector<char> format::PixelsToPPM(PlaneAdapter<std::vector<pixel>> const &input)
std::string format::CleanString(std::string dirtyString, int maxVisualSize, int maxStringLength)
{
std::string newString = dirtyString;
if(maxStringLength != std::string::npos && newString.size() > maxStringLength)
{
newString = newString.substr(0, maxStringLength);
}
if(maxVisualSize != std::string::npos && newString.size()*10 > maxVisualSize)
{
newString = newString.substr(0, maxVisualSize/10);
}
for(int i = 0; i < newString.size(); i++){
if(!(newString[i]>=' ' && newString[i]<127)){ //Clamp to ASCII range
newString[i] = '?'; //Replace with "huh" char
}
}
return newString;
}
std::string format::CleanString(char * dirtyData, int maxStringLength)
{
return CleanString(dirtyData, std::string::npos, maxStringLength);
}
std::string format::CleanString(char * dirtyData, int maxVisualSize, int maxStringLength)
{
char * newData = new char[maxStringLength+1];
strncpy(newData, dirtyData, maxStringLength);
newData[maxStringLength] = 0;
std::string newString = std::string(newData);
delete[] newData;
if(maxVisualSize != std::string::npos && newString.size()*10 > maxVisualSize)
{
newString = newString.substr(0, maxVisualSize/10);
}
for(int i = 0; i < newString.size(); i++){
if(!(newString[i]>=' ' && newString[i]<127)){ //Clamp to ASCII range
newString[i] = '?'; //Replace with "huh" char
}
}
return newString;
}
std::vector<char> format::VideoBufferToPTI(const VideoBuffer & vidBuf)
{
std::vector<char> data;
char buffer[256];
sprintf(buffer, "P6\n%d %d\n255\n", input.Size().X, input.Size().Y);
data.insert(data.end(), buffer, buffer + strlen(buffer));
int dataSize = 0;
char * buffer = (char*)Graphics::ptif_pack(vidBuf.Buffer, vidBuf.Width, vidBuf.Height, &dataSize);
data.reserve(data.size() + input.Size().X * input.Size().Y * 3);
for (int i = 0; i < input.Size().X * input.Size().Y; i++)
if(buffer)
{
auto colour = RGB<uint8_t>::Unpack(input.data()[i]);
data.push_back(colour.Red);
data.push_back(colour.Green);
data.push_back(colour.Blue);
data.insert(data.end(), buffer, buffer+dataSize);
free(buffer);
}
return data;
}
static std::unique_ptr<PlaneAdapter<std::vector<uint32_t>>> readPNG(
std::vector<char> const &data,
// If omitted,
// RGB data is returned with A=0xFF
// RGBA data is returned as itself
// If specified
// RGB data is returned with A=0x00
// RGBA data is blended against the background and returned with A=0x00
std::optional<RGB<uint8_t>> background
)
std::vector<char> format::VideoBufferToPPM(const VideoBuffer & vidBuf)
{
png_infop info = nullptr;
auto deleter = [&info](png_struct *png) {
png_destroy_read_struct(&png, &info, NULL);
};
auto png = std::unique_ptr<png_struct, decltype(deleter)>(
png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
[](png_structp png, png_const_charp msg) {
fprintf(stderr, "PNG error: %s\n", msg);
},
[](png_structp png, png_const_charp msg) {
fprintf(stderr, "PNG warning: %s\n", msg);
}
), deleter
);
if (!png)
return nullptr;
std::vector<char> data;
char buffer[256];
sprintf(buffer, "P6\n%d %d\n255\n", vidBuf.Width, vidBuf.Height);
data.insert(data.end(), buffer, buffer+strlen(buffer));
// libpng might longjmp() here in case of error
// Every time we create an object with a non-trivial destructor we must call setjmp again
if (setjmp(png_jmpbuf(png.get())))
return nullptr;
info = png_create_info_struct(png.get());
if (!info)
return nullptr;
auto it = data.begin();
auto const end = data.end();
auto readFn = [&it, end](png_structp png, png_bytep data, size_t length) {
if (size_t(end - it) < length)
png_error(png, "Tried to read beyond the buffer");
std::copy_n(it, length, data);
it += length;
};
// See above
if (setjmp(png_jmpbuf(png.get())))
return nullptr;
png_set_read_fn(png.get(), static_cast<void *>(&readFn), [](png_structp png, png_bytep data, size_t length) {
(*static_cast<decltype(readFn) *>(png_get_io_ptr(png)))(png, data, length);
});
png_set_user_limits(png.get(), RES.X, RES.Y); // Refuse to parse larger images
png_read_info(png.get(), info);
auto output = std::make_unique<PlaneAdapter<std::vector<uint32_t>>>(
Vec2<int>(png_get_image_width(png.get(), info), png_get_image_height(png.get(), info))
);
std::vector<png_bytep> rowPointers(output->Size().Y);
for (int y = 0; y < output->Size().Y; y++)
rowPointers[y] = reinterpret_cast<png_bytep>(&*output->RowIterator(Vec2(0, y)));
// See above
if (setjmp(png_jmpbuf(png.get())))
return nullptr;
png_set_filler(png.get(), background ? 0x00 : 0xFF, PNG_FILLER_AFTER);
png_set_bgr(png.get());
auto bitDepth = png_get_bit_depth(png.get(), info);
auto colorType = png_get_color_type(png.get(), info);
if (colorType == PNG_COLOR_TYPE_PALETTE)
png_set_palette_to_rgb(png.get());
if (colorType == PNG_COLOR_TYPE_GRAY && bitDepth < 8)
png_set_expand_gray_1_2_4_to_8(png.get());
if (bitDepth == 16)
png_set_scale_16(png.get());
if (png_get_valid(png.get(), info, PNG_INFO_tRNS))
png_set_tRNS_to_alpha(png.get());
if (colorType == PNG_COLOR_TYPE_GRAY || colorType == PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_gray_to_rgb(png.get());
if (background)
unsigned char * currentRow = new unsigned char[vidBuf.Width*3];
for(int y = 0; y < vidBuf.Height; y++)
{
png_color_16 colour;
colour.red = background->Red;
colour.green = background->Green;
colour.blue = background->Blue;
png_set_background(png.get(), &colour, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
}
png_read_image(png.get(), rowPointers.data());
return output;
}
std::unique_ptr<PlaneAdapter<std::vector<pixel_rgba>>> format::PixelsFromPNG(std::vector<char> const &data)
{
return readPNG(data, std::nullopt);
}
std::unique_ptr<PlaneAdapter<std::vector<pixel>>> format::PixelsFromPNG(std::vector<char> const &data, RGB<uint8_t> background)
{
return readPNG(data, background);
}
std::unique_ptr<std::vector<char>> format::PixelsToPNG(PlaneAdapter<std::vector<pixel>> const &input)
{
png_infop info = nullptr;
auto deleter = [&info](png_struct *png) {
png_destroy_write_struct(&png, &info);
};
auto png = std::unique_ptr<png_struct, decltype(deleter)>(
png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,
[](png_structp png, png_const_charp msg) {
fprintf(stderr, "PNG error: %s\n", msg);
},
[](png_structp png, png_const_charp msg) {
fprintf(stderr, "PNG warning: %s\n", msg);
}
), deleter
);
if (!png)
return nullptr;
// libpng might longjmp() here in case of error
// Every time we create an object with a non-trivial destructor we must call setjmp again
if (setjmp(png_jmpbuf(png.get())))
return nullptr;
info = png_create_info_struct(png.get());
if (!info)
return nullptr;
std::vector<char> output;
auto writeFn = [&output](png_structp png, png_bytep data, size_t length) {
output.insert(output.end(), data, data + length);
};
std::vector<png_const_bytep> rowPointers(input.Size().Y);
for (int y = 0; y < input.Size().Y; y++)
rowPointers[y] = reinterpret_cast<png_const_bytep>(&*input.RowIterator(Vec2(0, y)));
// See above
if (setjmp(png_jmpbuf(png.get())))
return nullptr;
png_set_write_fn(png.get(), static_cast<void *>(&writeFn), [](png_structp png, png_bytep data, size_t length) {
(*static_cast<decltype(writeFn) *>(png_get_io_ptr(png)))(png, data, length);
}, NULL);
png_set_IHDR(png.get(), info, input.Size().X, input.Size().Y, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
png_write_info(png.get(), info);
png_set_filler(png.get(), 0x00, PNG_FILLER_AFTER);
png_set_bgr(png.get());
png_write_image(png.get(), const_cast<png_bytepp>(rowPointers.data()));
png_write_end(png.get(), NULL);
return std::make_unique<std::vector<char>>(std::move(output));
}
const static char hex[] = "0123456789ABCDEF";
ByteString format::URLEncode(ByteString source)
{
ByteString result;
for (auto it = source.begin(); it < source.end(); ++it)
{
if (!((*it >= 'a' && *it <= 'z') ||
(*it >= 'A' && *it <= 'Z') ||
(*it >= '0' && *it <= '9')))
int rowPos = 0;
for(int x = 0; x < vidBuf.Width; x++)
{
auto byte = uint8_t(*it);
result.append(1, '%');
result.append(1, hex[(byte >> 4) & 0xF]);
result.append(1, hex[ byte & 0xF]);
currentRow[rowPos++] = PIXR(vidBuf.Buffer[(y*vidBuf.Width)+x]);
currentRow[rowPos++] = PIXG(vidBuf.Buffer[(y*vidBuf.Width)+x]);
currentRow[rowPos++] = PIXB(vidBuf.Buffer[(y*vidBuf.Width)+x]);
}
data.insert(data.end(), currentRow, currentRow+(vidBuf.Width*3));
}
delete currentRow;
return data;
}
struct PNGChunk
{
int Length;
char Name[4];
char * Data;
//char[4] CRC();
PNGChunk(int length, std::string name)
{
if(name.length()!=4)
throw std::runtime_error("Invalid chunk name");
std::copy(name.begin(), name.begin()+4, Name);
Length = length;
if(length)
{
Data = new char[length];
std::fill(Data, Data+length, 0);
}
else
{
result.append(1, *it);
Data = NULL;
}
}
return result;
}
ByteString format::URLDecode(ByteString source)
{
ByteString result;
for (auto it = source.begin(); it < source.end(); ++it)
unsigned long CRC()
{
if (*it == '%' && it < source.end() + 2)
if(!Data)
{
auto byte = uint8_t(0);
for (auto i = 0; i < 2; ++i)
{
it += 1;
auto *off = strchr(hex, tolower(*it));
if (!off)
{
return {};
}
byte = (byte << 4) | (off - hex);
}
result.append(1, byte);
}
else if (*it == '+')
{
result.append(1, ' ');
return format::CalculateCRC((unsigned char*)Name, 4);
}
else
{
result.append(1, *it);
unsigned char * temp = new unsigned char[4+Length];
std::copy(Name, Name+4, temp);
std::copy(Data, Data+Length, temp+4);
unsigned long tempRet = format::CalculateCRC(temp, 4+Length);
delete[] temp;
return tempRet;
}
}
return result;
~PNGChunk()
{
if(Data)
delete[] Data;
}
};
std::vector<char> format::VideoBufferToPNG(const VideoBuffer & vidBuf)
{
std::vector<PNGChunk*> chunks;
//Begin IHDR (Image header) chunk (Image size and depth)
PNGChunk IHDRChunk = PNGChunk(13, "IHDR");
//Image Width
IHDRChunk.Data[0] = (vidBuf.Width>>24)&0xFF;
IHDRChunk.Data[1] = (vidBuf.Width>>16)&0xFF;
IHDRChunk.Data[2] = (vidBuf.Width>>8)&0xFF;
IHDRChunk.Data[3] = (vidBuf.Width)&0xFF;
//Image Height
IHDRChunk.Data[4] = (vidBuf.Height>>24)&0xFF;
IHDRChunk.Data[5] = (vidBuf.Height>>16)&0xFF;
IHDRChunk.Data[6] = (vidBuf.Height>>8)&0xFF;
IHDRChunk.Data[7] = (vidBuf.Height)&0xFF;
//Bit depth
IHDRChunk.Data[8] = 8; //8bits per channel or 24bpp
//Colour type
IHDRChunk.Data[9] = 2; //RGB triple
//Everything else is default
chunks.push_back(&IHDRChunk);
//Begin image data, format is 8bit RGB (24bit pixel)
int dataPos = 0;
unsigned char * uncompressedData = new unsigned char[(vidBuf.Width*vidBuf.Height*3)+vidBuf.Height];
//Byte ordering and filtering
unsigned char * previousRow = new unsigned char[vidBuf.Width*3];
std::fill(previousRow, previousRow+(vidBuf.Width*3), 0);
unsigned char * currentRow = new unsigned char[vidBuf.Width*3];
for(int y = 0; y < vidBuf.Height; y++)
{
int rowPos = 0;
for(int x = 0; x < vidBuf.Width; x++)
{
currentRow[rowPos++] = PIXR(vidBuf.Buffer[(y*vidBuf.Width)+x]);
currentRow[rowPos++] = PIXG(vidBuf.Buffer[(y*vidBuf.Width)+x]);
currentRow[rowPos++] = PIXB(vidBuf.Buffer[(y*vidBuf.Width)+x]);
}
uncompressedData[dataPos++] = 2; //Up Sub(x) filter
for(int b = 0; b < rowPos; b++)
{
int filteredByte = (currentRow[b]-previousRow[b])&0xFF;
uncompressedData[dataPos++] = filteredByte;
}
unsigned char * tempRow = previousRow;
previousRow = currentRow;
currentRow = tempRow;
}
delete[] currentRow;
delete[] previousRow;
//Compression
int compressedBufferSize = (vidBuf.Width*vidBuf.Height*3)*2;
unsigned char * compressedData = new unsigned char[compressedBufferSize];
int result;
z_stream zipStream;
zipStream.zalloc = Z_NULL;
zipStream.zfree = Z_NULL;
zipStream.opaque = Z_NULL;
result = deflateInit2(&zipStream,
9, // level
Z_DEFLATED, // method
10, // windowBits
1, // memLevel
Z_DEFAULT_STRATEGY // strategy
);
if (result != Z_OK) exit(result);
zipStream.next_in = uncompressedData;
zipStream.avail_in = dataPos;
zipStream.next_out = compressedData;
zipStream.avail_out = compressedBufferSize;
result = deflate(&zipStream, Z_FINISH);
if (result != Z_STREAM_END) exit(result);
int compressedSize = compressedBufferSize-zipStream.avail_out;
PNGChunk IDATChunk = PNGChunk(compressedSize, "IDAT");
std::copy(compressedData, compressedData+compressedSize, IDATChunk.Data);
chunks.push_back(&IDATChunk);
deflateEnd(&zipStream);
delete[] compressedData;
delete[] uncompressedData;
PNGChunk IENDChunk = PNGChunk(0, "IEND");
chunks.push_back(&IENDChunk);
//Write chunks to output buffer
int finalDataSize = 8;
for(std::vector<PNGChunk*>::iterator iter = chunks.begin(), end = chunks.end(); iter != end; ++iter)
{
PNGChunk * cChunk = *iter;
finalDataSize += 4 + 4 + 4;
finalDataSize += cChunk->Length;
}
unsigned char * finalData = new unsigned char[finalDataSize];
int finalDataPos = 0;
//PNG File header
finalData[finalDataPos++] = 0x89;
finalData[finalDataPos++] = 0x50;
finalData[finalDataPos++] = 0x4E;
finalData[finalDataPos++] = 0x47;
finalData[finalDataPos++] = 0x0D;
finalData[finalDataPos++] = 0x0A;
finalData[finalDataPos++] = 0x1A;
finalData[finalDataPos++] = 0x0A;
for(std::vector<PNGChunk*>::iterator iter = chunks.begin(), end = chunks.end(); iter != end; ++iter)
{
PNGChunk * cChunk = *iter;
//Chunk length
finalData[finalDataPos++] = (cChunk->Length>>24)&0xFF;
finalData[finalDataPos++] = (cChunk->Length>>16)&0xFF;
finalData[finalDataPos++] = (cChunk->Length>>8)&0xFF;
finalData[finalDataPos++] = (cChunk->Length)&0xFF;
//Chunk name
std::copy(cChunk->Name, cChunk->Name+4, finalData+finalDataPos);
finalDataPos += 4;
//Chunk data
if(cChunk->Data)
{
std::copy(cChunk->Data, cChunk->Data+cChunk->Length, finalData+finalDataPos);
finalDataPos += cChunk->Length;
}
//Chunk CRC
unsigned long tempCRC = cChunk->CRC();
finalData[finalDataPos++] = (tempCRC>>24)&0xFF;
finalData[finalDataPos++] = (tempCRC>>16)&0xFF;
finalData[finalDataPos++] = (tempCRC>>8)&0xFF;
finalData[finalDataPos++] = (tempCRC)&0xFF;
}
std::vector<char> outputData(finalData, finalData+finalDataPos);
delete[] finalData;
return outputData;
}
void format::RenderTemperature(StringBuilder &sb, float temp, int scale)
//CRC functions, copypasta from W3 PNG spec.
/* Table of CRCs of all 8-bit messages. */
unsigned long crc_table[256];
/* Flag: has the table been computed? Initially false. */
int crc_table_computed = 0;
/* Make the table for a fast CRC. */
void make_crc_table(void)
{
switch (scale)
{
case 1:
sb << (temp - 273.15f) << "C";
break;
case 2:
sb << (temp - 273.15f) * 1.8f + 32.0f << "F";
break;
default:
sb << temp << "K";
break;
}
unsigned long c;
int n, k;
for (n = 0; n < 256; n++) {
c = (unsigned long) n;
for (k = 0; k < 8; k++) {
if (c & 1)
c = 0xedb88320L ^ (c >> 1);
else
c = c >> 1;
}
crc_table[n] = c;
}
crc_table_computed = 1;
}
float format::StringToTemperature(String str, int defaultScale)
/* Update a running CRC with the bytes buf[0..len-1]--the CRC
should be initialized to all 1's, and the transmitted value
is the 1's complement of the final running CRC (see the
crc() routine below)). */
unsigned long update_crc(unsigned long crc, unsigned char *buf, int len)
{
auto scale = defaultScale;
if (str.size())
unsigned long c = crc;
int n;
if (!crc_table_computed)
make_crc_table();
for (n = 0; n < len; n++)
{
if (str.EndsWith("K"))
{
scale = 0;
str = str.SubstrFromEnd(1);
}
else if (str.EndsWith("C"))
{
scale = 1;
str = str.SubstrFromEnd(1);
}
else if (str.EndsWith("F"))
{
scale = 2;
str = str.SubstrFromEnd(1);
}
c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
}
if (!str.size())
{
throw std::out_of_range("empty string");
}
auto out = str.ToNumber<float>();
switch (scale)
{
case 1:
out = out + 273.15;
break;
case 2:
out = (out - 32.0f) / 1.8f + 273.15f;
break;
}
return out;
return c;
}
unsigned long format::CalculateCRC(unsigned char * data, int len)
{
return update_crc(0xffffffffL, data, len) ^ 0xffffffffL;
}

View File

@ -1,23 +1,37 @@
#pragma once
#include <memory>
#include <sstream>
#include <vector>
#include "common/String.h"
#include "common/Plane.h"
#include "graphics/Pixel.h"
class VideoBuffer;
namespace format
{
ByteString URLEncode(ByteString value);
ByteString URLDecode(ByteString value);
ByteString UnixtimeToDate(time_t unixtime, ByteString dateFomat = ByteString("%d %b %Y"), bool local = true);
ByteString UnixtimeToDateMini(time_t unixtime);
String CleanString(String dirtyString, bool ascii, bool color, bool newlines, bool numeric = false);
std::vector<char> PixelsToPPM(PlaneAdapter<std::vector<pixel>> const &);
std::unique_ptr<std::vector<char>> PixelsToPNG(PlaneAdapter<std::vector<pixel>> const &);
std::unique_ptr<PlaneAdapter<std::vector<pixel_rgba>>> PixelsFromPNG(std::vector<char> const &);
std::unique_ptr<PlaneAdapter<std::vector<pixel>>> PixelsFromPNG(std::vector<char> const &, RGB<uint8_t> background);
void RenderTemperature(StringBuilder &sb, float temp, int scale);
float StringToTemperature(String str, int defaultScale);
}
static char hex[] = "0123456789ABCDEF";
template <typename T> std::string NumberToString(T number)
{
std::stringstream ss;
ss << number;
return ss.str();
}
template <typename T> T StringToNumber(const std::string & text)
{
std::stringstream ss(text);
T number;
return (ss >> number)?number:0;
}
std::string URLEncode(std::string value);
std::string UnixtimeToDate(time_t unixtime, std::string dateFomat = "%d %b %Y");
std::string UnixtimeToDateMini(time_t unixtime);
std::string CleanString(std::string dirtyString, int maxVisualSize, int maxStringLength);
std::string CleanString(std::string dirtyString, int maxStringLength = std::string::npos);
std::string CleanString(char * dirtyData, int maxVisualSize, int maxStringLength);
std::string CleanString(char * dirtyData, int maxStringLength);
std::vector<char> VideoBufferToPNG(const VideoBuffer & vidBuf);
std::vector<char> VideoBufferToPPM(const VideoBuffer & vidBuf);
std::vector<char> VideoBufferToPTI(const VideoBuffer & vidBuf);
unsigned long CalculateCRC(unsigned char * data, int length);
}

View File

@ -1,14 +0,0 @@
#pragma once
#include <variant>
struct FpsLimitVsync
{
};
struct FpsLimitNone
{
};
struct FpsLimitExplicit
{
float value;
};
using FpsLimit = std::variant<FpsLimitVsync, FpsLimitNone, FpsLimitExplicit>;

View File

@ -1,9 +1,540 @@
#include "Misc.h"
#include "common/String.h"
#include <cstring>
#include <stdio.h>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <regex.h>
#include <sys/types.h>
#include <cmath>
#include <algorithm>
#include "Config.h"
#include "Misc.h"
#include "icondoc.h"
#if defined(WIN)
#include <shlobj.h>
#include <shlwapi.h>
#include <windows.h>
#else
#include <unistd.h>
#endif
#ifdef MACOSX
#include <mach-o/dyld.h>
#include <ApplicationServices/ApplicationServices.h>
#endif
std::string URLEscape(std::string source)
{
char * src = (char *)source.c_str();
char * dst = (char *)calloc((source.length()*3)+2, 1);
char *d;
unsigned char *s;
for (d=dst; *d; d++) ;
for (s=(unsigned char *)src; *s; s++)
{
if ((*s>='0' && *s<='9') ||
(*s>='a' && *s<='z') ||
(*s>='A' && *s<='Z'))
*(d++) = *s;
else
{
*(d++) = '%';
*(d++) = hex[*s>>4];
*(d++) = hex[*s&15];
}
}
*d = 0;
std::string finalString(dst);
free(dst);
return finalString;
}
char *exe_name(void)
{
#if defined(WIN)
char *name= (char *)malloc(64);
DWORD max=64, res;
while ((res = GetModuleFileName(NULL, name, max)) >= max)
{
#elif defined MACOSX
char *fn=(char*)malloc(64),*name=(char*)malloc(PATH_MAX);
uint32_t max=64, res;
if (_NSGetExecutablePath(fn, &max) != 0)
{
fn = (char*)realloc(fn, max);
_NSGetExecutablePath(fn, &max);
}
if (realpath(fn, name) == NULL)
{
free(fn);
free(name);
return NULL;
}
res = 1;
#else
char fn[64], *name=(char *)malloc(64);
size_t max=64, res;
sprintf(fn, "/proc/self/exe");
memset(name, 0, max);
while ((res = readlink(fn, name, max)) >= max-1)
{
#endif
#ifndef MACOSX
max *= 2;
name = (char *)realloc(name, max);
memset(name, 0, max);
}
#endif
if (res <= 0)
{
free(name);
return NULL;
}
return name;
}
//Signum function
int isign(float i) //TODO: INline or macro
{
if (i<0)
return -1;
if (i>0)
return 1;
return 0;
}
TPT_NO_INLINE unsigned clamp_flt(float f, float min, float max) //TODO: Also inline/macro
{
if (f<min)
return 0;
if (f>max)
return 255;
return (int)(255.0f*(f-min)/(max-min));
}
TPT_NO_INLINE float restrict_flt(float f, float min, float max) //TODO Inline or macro or something
{
if (f<min)
return min;
if (f>max)
return max;
return f;
}
char *mystrdup(char *s)
{
char *x;
if (s)
{
x = (char*)malloc(strlen(s)+1);
strcpy(x, s);
return x;
}
return s;
}
void strlist_add(struct strlist **list, char *str)
{
struct strlist *item = (struct strlist*)malloc(sizeof(struct strlist));
item->str = mystrdup(str);
item->next = *list;
*list = item;
}
int strlist_find(struct strlist **list, char *str)
{
struct strlist *item;
for (item=*list; item; item=item->next)
if (!strcmp(item->str, str))
return 1;
return 0;
}
void strlist_free(struct strlist **list)
{
struct strlist *item;
while (*list)
{
item = *list;
*list = (*list)->next;
free(item);
}
}
void clean_text(char *text, int vwidth)
{
int i = 0;
if(strlen(text)*10 > vwidth){
text[vwidth/10] = 0;
}
for(i = 0; i < strlen(text); i++){
if(! (text[i]>=' ' && text[i]<127)){
text[i] = ' ';
}
}
}
int sregexp(const char *str, char *pattern)
{
int result;
regex_t patternc;
if (regcomp(&patternc, pattern, 0)!=0)
return 1;
result = regexec(&patternc, str, 0, NULL, 0);
regfree(&patternc);
return result;
}
void save_string(FILE *f, char *str)
{
int li = strlen(str);
unsigned char lb[2];
lb[0] = li;
lb[1] = li >> 8;
fwrite(lb, 2, 1, f);
fwrite(str, li, 1, f);
}
int load_string(FILE *f, char *str, int max)
{
int li;
unsigned char lb[2];
fread(lb, 2, 1, f);
li = lb[0] | (lb[1] << 8);
if (li > max)
{
str[0] = 0;
return 1;
}
fread(str, li, 1, f);
str[li] = 0;
return 0;
}
void strcaturl(char *dst, char *src)
{
char *d;
unsigned char *s;
for (d=dst; *d; d++) ;
for (s=(unsigned char *)src; *s; s++)
{
if ((*s>='0' && *s<='9') ||
(*s>='a' && *s<='z') ||
(*s>='A' && *s<='Z'))
*(d++) = *s;
else
{
*(d++) = '%';
*(d++) = hex[*s>>4];
*(d++) = hex[*s&15];
}
}
*d = 0;
}
void strappend(char *dst, char *src)
{
char *d;
unsigned char *s;
for (d=dst; *d; d++) ;
for (s=(unsigned char *)src; *s; s++)
{
*(d++) = *s;
}
*d = 0;
}
void *file_load(char *fn, int *size)
{
FILE *f = fopen(fn, "rb");
void *s;
if (!f)
return NULL;
fseek(f, 0, SEEK_END);
*size = ftell(f);
fseek(f, 0, SEEK_SET);
s = malloc(*size);
if (!s)
{
fclose(f);
return NULL;
}
fread(s, *size, 1, f);
fclose(f);
return s;
}
int cpu_check(void)
{
/*#ifdef MACOSX
return 0;
#else
#ifdef X86
unsigned af,bf,cf,df;
x86_cpuid(0, af, bf, cf, df);
//if (bf==0x68747541 && cf==0x444D4163 && df==0x69746E65)
// amd = 1;
x86_cpuid(1, af, bf, cf, df);
#ifdef X86_SSE
if (!(df&(1<<25)))
return 1;
#endif
#ifdef X86_SSE2
if (!(df&(1<<26)))
return 1;
#endif
#ifdef X86_SSE3
if (!(cf&1))
return 1;
#endif
#endif
#endif*/
return 0;
}
matrix2d m2d_multiply_m2d(matrix2d m1, matrix2d m2)
{
matrix2d result = {
m1.a*m2.a+m1.b*m2.c, m1.a*m2.b+m1.b*m2.d,
m1.c*m2.a+m1.d*m2.c, m1.c*m2.b+m1.d*m2.d
};
return result;
}
vector2d m2d_multiply_v2d(matrix2d m, vector2d v)
{
vector2d result = {
m.a*v.x+m.b*v.y,
m.c*v.x+m.d*v.y
};
return result;
}
matrix2d m2d_multiply_float(matrix2d m, float s)
{
matrix2d result = {
m.a*s, m.b*s,
m.c*s, m.d*s,
};
return result;
}
vector2d v2d_multiply_float(vector2d v, float s)
{
vector2d result = {
v.x*s,
v.y*s
};
return result;
}
vector2d v2d_add(vector2d v1, vector2d v2)
{
vector2d result = {
v1.x+v2.x,
v1.y+v2.y
};
return result;
}
vector2d v2d_sub(vector2d v1, vector2d v2)
{
vector2d result = {
v1.x-v2.x,
v1.y-v2.y
};
return result;
}
matrix2d m2d_new(float me0, float me1, float me2, float me3)
{
matrix2d result = {me0,me1,me2,me3};
return result;
}
vector2d v2d_new(float x, float y)
{
vector2d result = {x, y};
return result;
}
int register_extension()
{
#if defined(WIN)
int returnval;
LONG rresult;
HKEY newkey;
char *currentfilename = exe_name();
char *iconname = NULL;
char *opencommand = NULL;
//char AppDataPath[MAX_PATH];
char *AppDataPath = NULL;
iconname = (char*)malloc(strlen(currentfilename)+6);
sprintf(iconname, "%s,-102", currentfilename);
//Create Roaming application data folder
/*if(!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE, NULL, 0, AppDataPath)))
{
returnval = 0;
goto finalise;
}*/
//AppDataPath = _getcwd(NULL, 0);
//Move Game executable into application data folder
//TODO: Implement
opencommand = (char*)malloc(strlen(currentfilename)+53+strlen(AppDataPath));
/*if((strlen(AppDataPath)+strlen(APPDATA_SUBDIR "\\Powder Toy"))<MAX_PATH)
{
strappend(AppDataPath, APPDATA_SUBDIR);
_mkdir(AppDataPath);
strappend(AppDataPath, "\\Powder Toy");
_mkdir(AppDataPath);
} else {
returnval = 0;
goto finalise;
}*/
sprintf(opencommand, "\"%s\" open \"%%1\" ddir \"%s\"", currentfilename, AppDataPath);
//Create extension entry
rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\.cps", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL);
if (rresult != ERROR_SUCCESS) {
returnval = 0;
goto finalise;
}
rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)"PowderToySave", strlen("PowderToySave")+1);
if (rresult != ERROR_SUCCESS) {
RegCloseKey(newkey);
returnval = 0;
goto finalise;
}
RegCloseKey(newkey);
rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\.stm", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL);
if (rresult != ERROR_SUCCESS) {
returnval = 0;
goto finalise;
}
rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)"PowderToySave", strlen("PowderToySave")+1);
if (rresult != ERROR_SUCCESS) {
RegCloseKey(newkey);
returnval = 0;
goto finalise;
}
RegCloseKey(newkey);
//Create program entry
rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\PowderToySave", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL);
if (rresult != ERROR_SUCCESS) {
returnval = 0;
goto finalise;
}
rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)"Powder Toy Save", strlen("Powder Toy Save")+1);
if (rresult != ERROR_SUCCESS) {
RegCloseKey(newkey);
returnval = 0;
goto finalise;
}
RegCloseKey(newkey);
//Set DefaultIcon
rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\PowderToySave\\DefaultIcon", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL);
if (rresult != ERROR_SUCCESS) {
returnval = 0;
goto finalise;
}
rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)iconname, strlen(iconname)+1);
if (rresult != ERROR_SUCCESS) {
RegCloseKey(newkey);
returnval = 0;
goto finalise;
}
RegCloseKey(newkey);
//Set Launch command
rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\PowderToySave\\shell\\open\\command", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL);
if (rresult != ERROR_SUCCESS) {
returnval = 0;
goto finalise;
}
rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)opencommand, strlen(opencommand)+1);
if (rresult != ERROR_SUCCESS) {
RegCloseKey(newkey);
returnval = 0;
goto finalise;
}
RegCloseKey(newkey);
returnval = 1;
finalise:
if(iconname) free(iconname);
if(opencommand) free(opencommand);
if(currentfilename) free(currentfilename);
return returnval;
#elif defined(LIN)
char *currentfilename = exe_name();
FILE *f;
char *mimedata =
"<?xml version=\"1.0\"?>\n"
" <mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>\n"
" <mime-type type=\"application/vnd.powdertoy.save\">\n"
" <comment>Powder Toy save</comment>\n"
" <glob pattern=\"*.cps\"/>\n"
" <glob pattern=\"*.stm\"/>\n"
" </mime-type>\n"
"</mime-info>\n";
f = fopen("powdertoy-save.xml", "wb");
if (!f)
return 0;
fwrite(mimedata, 1, strlen(mimedata), f);
fclose(f);
char *desktopfiledata_tmp =
"[Desktop Entry]\n"
"Type=Application\n"
"Name=Powder Toy\n"
"Comment=Physics sandbox game\n"
"MimeType=application/vnd.powdertoy.save;\n"
"NoDisplay=true\n";
char *desktopfiledata = (char *)malloc(strlen(desktopfiledata_tmp)+strlen(currentfilename)+100);
strcpy(desktopfiledata, desktopfiledata_tmp);
strappend(desktopfiledata, "Exec=");
strappend(desktopfiledata, currentfilename);
strappend(desktopfiledata, " open %f\n");
f = fopen("powdertoy-tpt.desktop", "wb");
if (!f)
return 0;
fwrite(desktopfiledata, 1, strlen(desktopfiledata), f);
fclose(f);
system("xdg-mime install powdertoy-save.xml");
system("xdg-desktop-menu install powdertoy-tpt.desktop");
f = fopen("powdertoy-save-32.png", "wb");
if (!f)
return 0;
fwrite(icon_doc_32_png, 1, sizeof(icon_doc_32_png), f);
fclose(f);
f = fopen("powdertoy-save-16.png", "wb");
if (!f)
return 0;
fwrite(icon_doc_16_png, 1, sizeof(icon_doc_16_png), f);
fclose(f);
system("xdg-icon-resource install --noupdate --context mimetypes --size 32 powdertoy-save-32.png application-vnd.powdertoy.save");
system("xdg-icon-resource install --noupdate --context mimetypes --size 16 powdertoy-save-16.png application-vnd.powdertoy.save");
system("xdg-icon-resource forceupdate");
system("xdg-mime default powdertoy-tpt.desktop application/vnd.powdertoy.save");
unlink("powdertoy-save-32.png");
unlink("powdertoy-save-16.png");
unlink("powdertoy-save.xml");
unlink("powdertoy-tpt.desktop");
return 1;
#elif defined MACOSX
return 0;
#endif
}
void HSV_to_RGB(int h,int s,int v,int *r,int *g,int *b)//convert 0-255(0-360 for H) HSV values to 0-255 RGB
{
@ -50,16 +581,34 @@ void HSV_to_RGB(int h,int s,int v,int *r,int *g,int *b)//convert 0-255(0-360 for
*b += m;
}
void OpenURI(std::string uri) {
#if defined(WIN)
ShellExecute(0, "OPEN", uri.c_str(), NULL, NULL, 0);
#elif defined(MACOSX)
char *cmd = (char*)malloc(7+uri.length());
strcpy(cmd, "open ");
strappend(cmd, (char*)uri.c_str());
system(cmd);
#elif defined(LIN)
char *cmd = (char*)malloc(11+uri.length());
strcpy(cmd, "xdg-open ");
strappend(cmd, (char*)uri.c_str());
system(cmd);
#else
printf("Cannot open browser\n");
#endif
}
void RGB_to_HSV(int r,int g,int b,int *h,int *s,int *v)//convert 0-255 RGB values to 0-255(0-360 for H) HSV
{
float rr, gg, bb, a,x,c,d;
rr = r/255.0f;//normalize values
gg = g/255.0f;
bb = b/255.0f;
a = std::min(rr,gg);
a = std::min(a,bb);
x = std::max(rr,gg);
x = std::max(x,bb);
a = fmin(rr,gg);
a = fmin(a,bb);
x = fmax(rr,gg);
x = fmax(x,bb);
if (a==x)//greyscale
{
*h = 0;
@ -69,7 +618,7 @@ void RGB_to_HSV(int r,int g,int b,int *h,int *s,int *v)//convert 0-255 RGB value
else
{
c = (rr==a) ? gg-bb : ((bb==a) ? rr-gg : bb-rr);
d = (rr==a) ? 3.f : ((bb==a) ? 1.f : 5.f);
d = (rr==a) ? 3 : ((bb==a) ? 1 : 5);
*h = (int)(60.0*(d - c/(x - a)));
*s = (int)(255.0*((x - a)/x));
*v = (int)(255.0*x);
@ -85,8 +634,5 @@ void membwand(void * destv, void * srcv, size_t destsize, size_t srcsize)
dest[i] = dest[i] & src[i%srcsize];
}
}
bool byteStringEqualsString(const ByteString &str, const char *data, size_t size)
{
return str.size() == size && !memcmp(str.data(), data, size);
}
vector2d v2d_zero = {0,0};
matrix2d m2d_identity = {1,0,0,1};

Some files were not shown because too many files have changed in this diff Show More