This commit is contained in:
Saveliy Skresanov 2023-11-26 22:11:32 +07:00
commit 2f25c3fe32
105 changed files with 967 additions and 520 deletions

5
.github/build.sh vendored
View File

@ -143,9 +143,9 @@ elif [[ $BSH_HOST_PLATFORM == darwin ]]; then
elif [[ $BSH_HOST_PLATFORM == android ]]; then elif [[ $BSH_HOST_PLATFORM == android ]]; then
case $BSH_HOST_ARCH in case $BSH_HOST_ARCH in
x86_64) android_toolchain_prefix=x86_64-linux-android ; android_system_version=21; android_arch_abi=x86_64 ;; 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=19; android_arch_abi=x86 ;; 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 ;; 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=19; android_arch_abi=armeabi-v7a;; arm) android_toolchain_prefix=armv7a-linux-androideabi; android_system_version=21; android_arch_abi=armeabi-v7a;;
esac esac
android_toolchain_dir=$ANDROID_NDK_LATEST_HOME/toolchains/llvm/prebuilt/linux-x86_64 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 CC=$android_toolchain_dir/bin/$android_toolchain_prefix$android_system_version-clang
@ -369,7 +369,6 @@ zipalign = andriod_sdk_build_tools / 'zipalign'
apksigner = andriod_sdk_build_tools / 'apksigner' apksigner = andriod_sdk_build_tools / 'apksigner'
ANDROID_INI ANDROID_INI
meson_configure+=$'\t'--cross-file=.github/android-ghactions.ini meson_configure+=$'\t'--cross-file=.github/android-ghactions.ini
meson_configure+=$'\t'-Dhttp=false
fi fi
meson_configure+=$'\t'-Dc_args=[$c_args] meson_configure+=$'\t'-Dc_args=[$c_args]
meson_configure+=$'\t'-Dcpp_args=[$c_args] meson_configure+=$'\t'-Dcpp_args=[$c_args]

11
.github/prepare.py vendored
View File

@ -51,16 +51,23 @@ if int(build_options['mod_id']) == 0 and os.path.exists('.github/mod_id.txt'):
build_options['mod_id'] = f.read() build_options['mod_id'] = f.read()
if int(build_options['mod_id']) == 0: if int(build_options['mod_id']) == 0:
if release_type == 'beta': if release_type == 'stable':
pass
elif release_type == 'beta':
build_options['app_name' ] += ' Beta' build_options['app_name' ] += ' Beta'
build_options['app_comment'] += ' - Beta' build_options['app_comment'] += ' - Beta'
build_options['app_exe' ] += 'beta' build_options['app_exe' ] += 'beta'
build_options['app_id' ] += 'beta' build_options['app_id' ] += 'beta'
if release_type == 'snapshot': elif release_type == 'snapshot':
build_options['app_name' ] += ' Snapshot' build_options['app_name' ] += ' Snapshot'
build_options['app_comment'] += ' - Snapshot' build_options['app_comment'] += ' - Snapshot'
build_options['app_exe' ] += 'snapshot' build_options['app_exe' ] += 'snapshot'
build_options['app_id' ] += '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('mod_id' , build_options['mod_id' ])
set_output('app_name' , build_options['app_name' ]) set_output('app_name' , build_options['app_name' ])

View File

@ -82,6 +82,7 @@ Controls
| I | Invert Pressure and Velocity map | | I | Invert Pressure and Velocity map |
| W | Cycle gravity modes (use with Ctrl when STK2 is out) | | W | Cycle gravity modes (use with Ctrl when STK2 is out) |
| Y | Cycle air modes | | Y | Cycle air modes |
| Ctrl + E | Cycle edge modes |
| B | Enter decoration editor menu | | B | Enter decoration editor menu |
| Ctrl + B | Toggle decorations on/off | | Ctrl + B | Toggle decorations on/off |
| N | Toggle Newtonian Gravity on/off | | N | Toggle Newtonian Gravity on/off |

View File

@ -7,7 +7,7 @@
android:installLocation="auto" android:installLocation="auto"
> >
<uses-sdk <uses-sdk
android:minSdkVersion="19" android:minSdkVersion="21"
android:targetSdkVersion="30" android:targetSdkVersion="30"
/> />
<uses-feature <uses-feature
@ -33,16 +33,18 @@
android:name="android.hardware.type.pc" android:name="android.hardware.type.pc"
android:required="false" android:required="false"
/> />
<uses-permission android:name="android.permission.VIBRATE" /> @ANDROID_PERMISSIONS@
<application <application
android:label="@string/app_name" android:label="@string/app_name"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:allowBackup="true" android:allowBackup="true"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
@ANDROID_PROPERTIES@
> >
<activity <activity
android:name=".PowderActivity" android:name=".PowderActivity"
android:screenOrientation="landscape"
android:label="@string/app_name" android:label="@string/app_name"
android:alwaysRetainTaskState="true" android:alwaysRetainTaskState="true"
android:launchMode="singleInstance" android:launchMode="singleInstance"

View File

@ -1,7 +1,42 @@
package @APPID@; package @APPID@;
import org.libsdl.app.SDLActivity; 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 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,5 +1,5 @@
[constants] [constants]
android_ndk_toolchain_prefix = 'armv7a-linux-androideabi19-' android_ndk_toolchain_prefix = 'armv7a-linux-androideabi21-'
[host_machine] [host_machine]
system = 'android' system = 'android'

View File

@ -1,5 +1,5 @@
[constants] [constants]
android_ndk_toolchain_prefix = 'i686-linux-android19-' android_ndk_toolchain_prefix = 'i686-linux-android21-'
[host_machine] [host_machine]
system = 'android' system = 'android'

View File

@ -1,5 +1 @@
android_resources += configure_file( android_resources += fs.copyfile(rendered_icons['icon_exe'], 'ic_launcher.png')
input: rendered_icons['icon_exe'],
output: 'ic_launcher.png',
copy: true,
)

View File

@ -18,6 +18,7 @@ if get_option('prepare')
subdir_done() subdir_done()
endif endif
fs = import('fs')
to_array = generator( to_array = generator(
executable('toarray', sources: 'resources/ToArray.cpp', native: true), executable('toarray', sources: 'resources/ToArray.cpp', native: true),
output: [ '@PLAINNAME@.cpp', '@PLAINNAME@.h' ], output: [ '@PLAINNAME@.cpp', '@PLAINNAME@.h' ],
@ -88,7 +89,7 @@ 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_variant = '@0@-@1@-@2@-@3@'.format(host_arch, host_platform, host_libc, tpt_libs_static)
tpt_libs_vtag = get_option('tpt_libs_vtag') tpt_libs_vtag = get_option('tpt_libs_vtag')
if tpt_libs_vtag == '' if tpt_libs_vtag == ''
tpt_libs_vtag = 'v20230819222922' tpt_libs_vtag = 'v20231003175140'
endif endif
if tpt_libs_static != 'none' if tpt_libs_static != 'none'
if tpt_libs_variant not in [ if tpt_libs_variant not in [
@ -172,9 +173,6 @@ elif lua_variant == 'luajit'
endif endif
enable_http = get_option('http') enable_http = get_option('http')
if host_platform == 'android'
enable_http = false
endif
if host_platform == 'android' if host_platform == 'android'
android_ndk_toolchain_prefix = meson.get_external_property('android_ndk_toolchain_prefix') android_ndk_toolchain_prefix = meson.get_external_property('android_ndk_toolchain_prefix')
android_platform = meson.get_external_property('android_platform') android_platform = meson.get_external_property('android_platform')
@ -342,7 +340,7 @@ if host_platform == 'windows'
do_copy = true do_copy = true
endif endif
if do_copy if do_copy
configure_file(input: dll_input, output: dll_output, copy: true) fs.copyfile(dll_input, dll_output)
endif endif
endforeach endforeach
endif endif

Binary file not shown.

View File

@ -17,12 +17,21 @@ constexpr bool INSTALL_CHECK = @INSTALL_CHECK@;
constexpr bool IGNORE_UPDATES = @IGNORE_UPDATES@; constexpr bool IGNORE_UPDATES = @IGNORE_UPDATES@;
constexpr bool ENFORCE_HTTPS = @ENFORCE_HTTPS@; constexpr bool ENFORCE_HTTPS = @ENFORCE_HTTPS@;
constexpr bool SECURE_CIPHERS_ONLY = @SECURE_CIPHERS_ONLY@; constexpr bool SECURE_CIPHERS_ONLY = @SECURE_CIPHERS_ONLY@;
constexpr bool USE_SYSTEM_CERT_PROVIDER = @USE_SYSTEM_CERT_PROVIDER@;
constexpr bool FFTW_PLAN_MEASURE = @FFTW_PLAN_MEASURE@; constexpr bool FFTW_PLAN_MEASURE = @FFTW_PLAN_MEASURE@;
constexpr bool ALLOW_QUIT = @ALLOW_QUIT@; constexpr bool ALLOW_QUIT = @ALLOW_QUIT@;
constexpr bool ALLOW_WINDOW_FRAME_OPS = @ALLOW_WINDOW_FRAME_OPS@; constexpr bool DEFAULT_TOUCH_UI = @DEFAULT_TOUCH_UI@;
constexpr bool ALLOW_DATA_FOLDER = @ALLOW_DATA_FOLDER@; constexpr bool ALLOW_DATA_FOLDER = @ALLOW_DATA_FOLDER@;
constexpr char PATH_SEP_CHAR = '@PATH_SEP_CHAR@'; 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 SERVER[] = "@SERVER@";
constexpr char STATICSERVER[] = "@STATICSERVER@"; constexpr char STATICSERVER[] = "@STATICSERVER@";
constexpr char UPDATESERVER[] = "@UPDATESERVER@"; constexpr char UPDATESERVER[] = "@UPDATESERVER@";

View File

@ -17,6 +17,7 @@
#include "gui/Style.h" #include "gui/Style.h"
#include "gui/game/GameController.h" #include "gui/game/GameController.h"
#include "gui/game/GameView.h" #include "gui/game/GameView.h"
#include "gui/game/IntroText.h"
#include "gui/dialogues/ConfirmPrompt.h" #include "gui/dialogues/ConfirmPrompt.h"
#include "gui/dialogues/ErrorMessage.h" #include "gui/dialogues/ErrorMessage.h"
#include "gui/interface/Engine.h" #include "gui/interface/Engine.h"
@ -80,12 +81,13 @@ void SaveWindowPosition()
void LargeScreenDialog() void LargeScreenDialog()
{ {
StringBuilder message; StringBuilder message;
auto scale = ui::Engine::Ref().windowFrameOps.scale;
message << "Switching to " << scale << "x size mode since your screen was determined to be large enough: "; message << "Switching to " << scale << "x size mode since your screen was determined to be large enough: ";
message << desktopWidth << "x" << desktopHeight << " detected, " << WINDOWW*scale << "x" << WINDOWH*scale << " required"; message << desktopWidth << "x" << desktopHeight << " detected, " << WINDOWW * scale << "x" << WINDOWH * scale << " required";
message << "\nTo undo this, hit Cancel. You can change this in settings at any time."; message << "\nTo undo this, hit Cancel. You can change this in settings at any time.";
new ConfirmPrompt("Large screen detected", message.Build(), { nullptr, []() { new ConfirmPrompt("Large screen detected", message.Build(), { nullptr, []() {
GlobalPrefs::Ref().Set("Scale", 1); GlobalPrefs::Ref().Set("Scale", 1);
ui::Engine::Ref().SetScale(1); ui::Engine::Ref().windowFrameOps.scale = 1;
} }); } });
} }
@ -102,6 +104,7 @@ void BlueScreen(String detailMessage)
String errorTitle = "ERROR"; String errorTitle = "ERROR";
String errorDetails = "Details: " + detailMessage; String errorDetails = "Details: " + detailMessage;
String errorHelp = String("An unrecoverable fault has occurred, please report the error by visiting the website below\n") + SCHEME + SERVER; String errorHelp = String("An unrecoverable fault has occurred, please report the error by visiting the website below\n") + SCHEME + SERVER;
auto versionInfo = ByteString::Build("Version: ", VersionInfo(), "\nTag: ", VCS_TAG).FromUtf8();
// We use the width of errorHelp to center, but heights of the individual texts for vertical spacing // We use the width of errorHelp to center, but heights of the individual texts for vertical spacing
auto pos = engine.g->Size() / 2 - Vec2(Graphics::TextSize(errorHelp).X / 2, 100); auto pos = engine.g->Size() / 2 - Vec2(Graphics::TextSize(errorHelp).X / 2, 100);
@ -110,6 +113,8 @@ void BlueScreen(String detailMessage)
engine.g->BlendText(pos, errorDetails, 0xFFFFFF_rgb .WithAlpha(0xFF)); engine.g->BlendText(pos, errorDetails, 0xFFFFFF_rgb .WithAlpha(0xFF));
pos.Y += 4 + Graphics::TextSize(errorDetails).Y; pos.Y += 4 + Graphics::TextSize(errorDetails).Y;
engine.g->BlendText(pos, errorHelp, 0xFFFFFF_rgb .WithAlpha(0xFF)); engine.g->BlendText(pos, errorHelp, 0xFFFFFF_rgb .WithAlpha(0xFF));
pos.Y += 4 + Graphics::TextSize(errorHelp).Y;
engine.g->BlendText(pos, versionInfo, 0xFFFFFF_rgb .WithAlpha(0xFF));
//Death loop //Death loop
SDL_Event event; SDL_Event event;
@ -281,12 +286,16 @@ int Main(int argc, char *argv[])
explicitSingletons->globalPrefs = std::make_unique<GlobalPrefs>(); explicitSingletons->globalPrefs = std::make_unique<GlobalPrefs>();
auto &prefs = GlobalPrefs::Ref(); auto &prefs = GlobalPrefs::Ref();
scale = prefs.Get("Scale", 1);
WindowFrameOps windowFrameOps{
prefs.Get("Scale", 1),
prefs.Get("Resizable", false),
prefs.Get("Fullscreen", false),
prefs.Get("AltFullscreen", false),
prefs.Get("ForceIntegerScaling", true),
prefs.Get("BlurryScaling", false),
};
auto graveExitsConsole = prefs.Get("GraveExitsConsole", true); auto graveExitsConsole = prefs.Get("GraveExitsConsole", true);
resizable = prefs.Get("Resizable", false);
fullscreen = prefs.Get("Fullscreen", false);
altFullscreen = prefs.Get("AltFullscreen", false);
forceIntegerScaling = prefs.Get("ForceIntegerScaling", true);
momentumScroll = prefs.Get("MomentumScroll", true); momentumScroll = prefs.Get("MomentumScroll", true);
showAvatars = prefs.Get("ShowAvatars", true); showAvatars = prefs.Get("ShowAvatars", true);
@ -307,8 +316,8 @@ int Main(int argc, char *argv[])
auto kioskArg = arguments["kiosk"]; auto kioskArg = arguments["kiosk"];
if (kioskArg.has_value()) if (kioskArg.has_value())
{ {
fullscreen = true_string(kioskArg.value()); windowFrameOps.fullscreen = true_string(kioskArg.value());
prefs.Set("Fullscreen", fullscreen); prefs.Set("Fullscreen", windowFrameOps.fullscreen);
} }
if (true_arg(arguments["redirect"])) if (true_arg(arguments["redirect"]))
@ -326,8 +335,8 @@ int Main(int argc, char *argv[])
{ {
try try
{ {
scale = scaleArg.value().ToNumber<int>(); windowFrameOps.scale = scaleArg.value().ToNumber<int>();
prefs.Set("Scale", scale); prefs.Set("Scale", windowFrameOps.scale);
} }
catch (const std::runtime_error &e) catch (const std::runtime_error &e)
{ {
@ -366,36 +375,29 @@ int Main(int argc, char *argv[])
explicitSingletons->engine = std::make_unique<ui::Engine>(); explicitSingletons->engine = std::make_unique<ui::Engine>();
// TODO: maybe bind the maximum allowed scale to screen size somehow // TODO: maybe bind the maximum allowed scale to screen size somehow
if(scale < 1 || scale > SCALE_MAXIMUM) if(windowFrameOps.scale < 1 || windowFrameOps.scale > SCALE_MAXIMUM)
scale = 1; windowFrameOps.scale = 1;
SDLOpen();
if (Client::Ref().IsFirstRun())
{
scale = GuessBestScale();
if (scale > 1)
{
prefs.Set("Scale", scale);
SDL_SetWindowSize(sdl_window, WINDOWW * scale, WINDOWH * scale);
showLargeScreenDialog = true;
}
}
StopTextInput();
auto &engine = ui::Engine::Ref(); auto &engine = ui::Engine::Ref();
engine.g = new Graphics(); engine.g = new Graphics();
engine.Scale = scale;
engine.GraveExitsConsole = graveExitsConsole; engine.GraveExitsConsole = graveExitsConsole;
engine.SetResizable(resizable);
engine.Fullscreen = fullscreen;
engine.SetAltFullscreen(altFullscreen);
engine.SetForceIntegerScaling(forceIntegerScaling);
engine.MomentumScroll = momentumScroll; engine.MomentumScroll = momentumScroll;
engine.ShowAvatars = showAvatars; engine.ShowAvatars = showAvatars;
engine.Begin(); engine.Begin();
engine.SetFastQuit(prefs.Get("FastQuit", true)); engine.SetFastQuit(prefs.Get("FastQuit", true));
engine.TouchUI = prefs.Get("TouchUI", DEFAULT_TOUCH_UI);
if (Client::Ref().IsFirstRun() && FORCE_WINDOW_FRAME_OPS == forceWindowFrameOpsNone)
{
windowFrameOps.scale = GuessBestScale();
if (windowFrameOps.scale)
{
prefs.Set("Scale", windowFrameOps.scale);
showLargeScreenDialog = true;
}
}
engine.windowFrameOps = windowFrameOps;
SDLOpen();
bool enableBluescreen = USE_BLUESCREEN && !true_arg(arguments["disable-bluescreen"]); bool enableBluescreen = USE_BLUESCREEN && !true_arg(arguments["disable-bluescreen"]);
if (enableBluescreen) if (enableBluescreen)

View File

@ -41,38 +41,30 @@ int main(int argc, char * argv[])
}); });
explicitSingletons = std::make_unique<ExplicitSingletons>(); explicitSingletons = std::make_unique<ExplicitSingletons>();
scale = 1; WindowFrameOps windowFrameOps;
if (argc >= 3) if (argc >= 3)
{ {
std::istringstream ss(argv[2]); std::istringstream ss(argv[2]);
int buf; int buf;
if (ss >> buf) if (ss >> buf)
{ {
scale = buf; windowFrameOps.scale = buf;
} }
} }
resizable = false;
fullscreen = false;
altFullscreen = false;
forceIntegerScaling = true;
// TODO: maybe bind the maximum allowed scale to screen size somehow // TODO: maybe bind the maximum allowed scale to screen size somehow
if(scale < 1 || scale > 10) if (windowFrameOps.scale < 1 || windowFrameOps.scale > 10)
scale = 1; {
windowFrameOps.scale = 1;
}
explicitSingletons->engine = std::make_unique<ui::Engine>(); explicitSingletons->engine = std::make_unique<ui::Engine>();
SDLOpen();
StopTextInput();
auto &engine = ui::Engine::Ref(); auto &engine = ui::Engine::Ref();
engine.g = new Graphics(); engine.g = new Graphics();
engine.Scale = scale; engine.windowFrameOps = windowFrameOps;
engine.SetResizable(resizable);
engine.Fullscreen = fullscreen; SDLOpen();
engine.SetAltFullscreen(altFullscreen);
engine.SetForceIntegerScaling(forceIntegerScaling);
engine.Begin(); engine.Begin();
engine.SetFastQuit(true); engine.SetFastQuit(true);

View File

@ -12,12 +12,8 @@ int desktopHeight = 1024;
SDL_Window *sdl_window = NULL; SDL_Window *sdl_window = NULL;
SDL_Renderer *sdl_renderer = NULL; SDL_Renderer *sdl_renderer = NULL;
SDL_Texture *sdl_texture = NULL; SDL_Texture *sdl_texture = NULL;
int scale = 1;
bool fullscreen = false;
bool altFullscreen = false;
bool forceIntegerScaling = true;
bool vsyncHint = false; bool vsyncHint = false;
bool resizable = false; WindowFrameOps currentFrameOps;
bool momentumScroll = true; bool momentumScroll = true;
bool showAvatars = true; bool showAvatars = true;
uint64_t lastTick = 0; uint64_t lastTick = 0;
@ -46,11 +42,24 @@ void StopTextInput()
void SetTextInputRect(int x, int y, int w, int h) void SetTextInputRect(int x, int y, int w, int h)
{ {
// Why does SDL_SetTextInputRect not take logical coordinates???
SDL_Rect rect; SDL_Rect rect;
rect.x = x; #if SDL_VERSION_ATLEAST(2, 0, 18)
rect.y = y; int wx, wy, wwx, why;
rect.w = w; SDL_RenderLogicalToWindow(sdl_renderer, x, y, &wx, &wy);
rect.h = h; SDL_RenderLogicalToWindow(sdl_renderer, x + w, y + h, &wwx, &why);
rect.x = wx;
rect.y = wy;
rect.w = wwx - wx;
rect.h = why - wy;
#else
// TODO: use SDL_RenderLogicalToWindow when ubuntu deigns to update to sdl 2.0.18
auto scale = ui::Engine::Ref().windowFrameOps.scale;
rect.x = x * scale;
rect.y = y * scale;
rect.w = w * scale;
rect.h = h * scale;
#endif
SDL_SetTextInputRect(&rect); SDL_SetTextInputRect(&rect);
} }
@ -74,7 +83,7 @@ unsigned int GetTicks()
return SDL_GetTicks(); return SDL_GetTicks();
} }
void CalculateMousePosition(int *x, int *y) static void CalculateMousePosition(int *x, int *y)
{ {
int globalMx, globalMy; int globalMx, globalMy;
SDL_GetGlobalMouseState(&globalMx, &globalMy); SDL_GetGlobalMouseState(&globalMx, &globalMy);
@ -82,16 +91,16 @@ void CalculateMousePosition(int *x, int *y)
SDL_GetWindowPosition(sdl_window, &windowX, &windowY); SDL_GetWindowPosition(sdl_window, &windowX, &windowY);
if (x) if (x)
*x = (globalMx - windowX) / scale; *x = (globalMx - windowX) / currentFrameOps.scale;
if (y) if (y)
*y = (globalMy - windowY) / scale; *y = (globalMy - windowY) / currentFrameOps.scale;
} }
void blit(pixel *vid) void blit(pixel *vid)
{ {
SDL_UpdateTexture(sdl_texture, NULL, vid, WINDOWW * sizeof (Uint32)); SDL_UpdateTexture(sdl_texture, NULL, vid, WINDOWW * sizeof (Uint32));
// need to clear the renderer if there are black edges (fullscreen, or resizable window) // need to clear the renderer if there are black edges (fullscreen, or resizable window)
if (fullscreen || resizable) if (currentFrameOps.fullscreen || currentFrameOps.resizable)
SDL_RenderClear(sdl_renderer); SDL_RenderClear(sdl_renderer);
SDL_RenderCopy(sdl_renderer, sdl_texture, NULL, NULL); SDL_RenderCopy(sdl_renderer, sdl_texture, NULL, NULL);
SDL_RenderPresent(sdl_renderer); SDL_RenderPresent(sdl_renderer);
@ -105,11 +114,7 @@ void SDLOpen()
Platform::Exit(-1); Platform::Exit(-1);
} }
if (!RecreateWindow()) SDLSetScreen();
{
fprintf(stderr, "Creating SDL window: %s\n", SDL_GetError());
Platform::Exit(-1);
}
int displayIndex = SDL_GetWindowDisplayIndex(sdl_window); int displayIndex = SDL_GetWindowDisplayIndex(sdl_window);
if (displayIndex >= 0) if (displayIndex >= 0)
@ -122,10 +127,7 @@ void SDLOpen()
} }
} }
if constexpr (SET_WINDOW_ICON) StopTextInput();
{
WindowIcon(sdl_window);
}
} }
void SDLClose() void SDLClose()
@ -144,67 +146,95 @@ void SDLClose()
SDL_Quit(); SDL_Quit();
} }
void SDLSetScreen(int scale_, bool resizable_, bool fullscreen_, bool altFullscreen_, bool forceIntegerScaling_, bool vsyncHint_) void SDLSetScreen()
{ {
// bool changingScale = scale != scale_; auto newFrameOps = ui::Engine::Ref().windowFrameOps;
bool changingFullscreen = fullscreen_ != fullscreen || (altFullscreen_ != altFullscreen && fullscreen); auto newVsyncHint = std::holds_alternative<FpsLimitVsync>(ui::Engine::Ref().GetFpsLimit());
bool changingResizable = resizable != resizable_; if (FORCE_WINDOW_FRAME_OPS == forceWindowFrameOpsEmbedded)
bool changingVsync = vsyncHint != vsyncHint_; {
scale = scale_; newFrameOps.resizable = false;
fullscreen = fullscreen_; newFrameOps.fullscreen = false;
altFullscreen = altFullscreen_; newFrameOps.changeResolution = false;
resizable = resizable_; newFrameOps.forceIntegerScaling = false;
forceIntegerScaling = forceIntegerScaling_; }
vsyncHint = vsyncHint_; if (FORCE_WINDOW_FRAME_OPS == forceWindowFrameOpsHandheld)
{
newFrameOps.resizable = false;
newFrameOps.fullscreen = true;
newFrameOps.changeResolution = false;
newFrameOps.forceIntegerScaling = false;
}
auto currentFrameOpsNorm = currentFrameOps.Normalize();
auto newFrameOpsNorm = newFrameOps.Normalize();
auto recreate = !sdl_window ||
// Recreate the window when toggling fullscreen, due to occasional issues // Recreate the window when toggling fullscreen, due to occasional issues
newFrameOpsNorm.fullscreen != currentFrameOpsNorm.fullscreen ||
// Also recreate it when enabling resizable windows, to fix bugs on windows, // Also recreate it when enabling resizable windows, to fix bugs on windows,
// see https://github.com/jacob1/The-Powder-Toy/issues/24 // see https://github.com/jacob1/The-Powder-Toy/issues/24
if (changingFullscreen || altFullscreen || (changingResizable && resizable && !fullscreen) || changingVsync) newFrameOpsNorm.resizable != currentFrameOpsNorm.resizable ||
newFrameOpsNorm.changeResolution != currentFrameOpsNorm.changeResolution ||
newFrameOpsNorm.blurryScaling != currentFrameOpsNorm.blurryScaling ||
newVsyncHint != vsyncHint;
if (!(recreate ||
newFrameOpsNorm.scale != currentFrameOpsNorm.scale ||
newFrameOpsNorm.forceIntegerScaling != currentFrameOpsNorm.forceIntegerScaling))
{ {
RecreateWindow();
return; return;
} }
if (changingResizable)
SDL_RestoreWindow(sdl_window);
SDL_SetWindowSize(sdl_window, WINDOWW * scale, WINDOWH * scale); auto size = WINDOW * newFrameOpsNorm.scale;
SDL_RenderSetIntegerScale(sdl_renderer, forceIntegerScaling && fullscreen ? SDL_TRUE : SDL_FALSE); if (sdl_window && newFrameOpsNorm.resizable)
unsigned int flags = 0; {
if (fullscreen) SDL_GetWindowSize(sdl_window, &size.X, &size.Y);
flags = altFullscreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP; }
SDL_SetWindowFullscreen(sdl_window, flags);
if (fullscreen)
SDL_RaiseWindow(sdl_window);
SDL_SetWindowResizable(sdl_window, resizable ? SDL_TRUE : SDL_FALSE);
}
bool RecreateWindow()
{
unsigned int flags = 0;
unsigned int rendererFlags = 0;
if (fullscreen)
flags = altFullscreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP;
if (resizable && !fullscreen)
flags |= SDL_WINDOW_RESIZABLE;
if (vsyncHint)
rendererFlags |= SDL_RENDERER_PRESENTVSYNC;
if (recreate)
{
if (sdl_texture) if (sdl_texture)
{
SDL_DestroyTexture(sdl_texture); SDL_DestroyTexture(sdl_texture);
sdl_texture = NULL;
}
if (sdl_renderer) if (sdl_renderer)
{
SDL_DestroyRenderer(sdl_renderer); SDL_DestroyRenderer(sdl_renderer);
sdl_renderer = NULL;
}
if (sdl_window) if (sdl_window)
{ {
SaveWindowPosition(); SaveWindowPosition();
SDL_DestroyWindow(sdl_window); SDL_DestroyWindow(sdl_window);
sdl_window = NULL;
} }
sdl_window = SDL_CreateWindow(APPNAME, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOWW * scale, WINDOWH * scale, unsigned int flags = 0;
flags); unsigned int rendererFlags = 0;
if (newFrameOpsNorm.fullscreen)
{
flags = newFrameOpsNorm.changeResolution ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP;
}
if (newFrameOpsNorm.resizable)
{
flags |= SDL_WINDOW_RESIZABLE;
}
if (vsyncHint)
{
rendererFlags |= SDL_RENDERER_PRESENTVSYNC;
}
sdl_window = SDL_CreateWindow(APPNAME, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, size.X, size.Y, flags);
if (!sdl_window) if (!sdl_window)
{ {
return false; fprintf(stderr, "SDL_CreateWindow failed: %s\n", SDL_GetError());
Platform::Exit(-1);
} }
if constexpr (SET_WINDOW_ICON)
{
WindowIcon(sdl_window);
}
SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1");
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, newFrameOpsNorm.blurryScaling ? "linear" : "nearest");
sdl_renderer = SDL_CreateRenderer(sdl_window, -1, rendererFlags); sdl_renderer = SDL_CreateRenderer(sdl_window, -1, rendererFlags);
if (!sdl_renderer) if (!sdl_renderer)
{ {
@ -216,25 +246,33 @@ bool RecreateWindow()
SDL_GetRenderDriverInfo(i, &info); SDL_GetRenderDriverInfo(i, &info);
fprintf(stderr, " - %s\n", info.name); fprintf(stderr, " - %s\n", info.name);
} }
return false; Platform::Exit(-1);
} }
SDL_RenderSetLogicalSize(sdl_renderer, WINDOWW, WINDOWH); SDL_RenderSetLogicalSize(sdl_renderer, WINDOWW, WINDOWH);
if (forceIntegerScaling && fullscreen)
SDL_RenderSetIntegerScale(sdl_renderer, SDL_TRUE);
sdl_texture = SDL_CreateTexture(sdl_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, WINDOWW, WINDOWH); sdl_texture = SDL_CreateTexture(sdl_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, WINDOWW, WINDOWH);
if (!sdl_texture)
{
fprintf(stderr, "SDL_CreateTexture failed: %s\n", SDL_GetError());
Platform::Exit(-1);
}
SDL_RaiseWindow(sdl_window); SDL_RaiseWindow(sdl_window);
SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1"); }
//Uncomment this to enable resizing SDL_RenderSetIntegerScale(sdl_renderer, newFrameOpsNorm.forceIntegerScaling ? SDL_TRUE : SDL_FALSE);
//SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); if (!(newFrameOpsNorm.resizable && SDL_GetWindowFlags(sdl_window) & SDL_WINDOW_MAXIMIZED))
//SDL_SetWindowResizable(sdl_window, SDL_TRUE); {
SDL_SetWindowSize(sdl_window, size.X, size.Y);
LoadWindowPosition(); LoadWindowPosition();
}
UpdateFpsLimit(); UpdateFpsLimit();
if (newFrameOpsNorm.fullscreen)
return true; {
SDL_RaiseWindow(sdl_window);
}
currentFrameOps = newFrameOps;
vsyncHint = newVsyncHint;
} }
void EventProcess(const SDL_Event &event) static void EventProcess(const SDL_Event &event)
{ {
auto &engine = ui::Engine::Ref(); auto &engine = ui::Engine::Ref();
switch (event.type) switch (event.type)
@ -388,18 +426,7 @@ void EngineProcess()
{ {
engine.Draw(); engine.Draw();
drawingTimer = 0; drawingTimer = 0;
SDLSetScreen();
auto wantVsync = bool(std::get_if<FpsLimitVsync>(&fpsLimit));
if (scale != engine.Scale ||
fullscreen != engine.Fullscreen ||
altFullscreen != engine.GetAltFullscreen() ||
forceIntegerScaling != engine.GetForceIntegerScaling() ||
resizable != engine.GetResizable() ||
vsyncHint != wantVsync)
{
SDLSetScreen(engine.Scale, engine.GetResizable(), engine.Fullscreen, engine.GetAltFullscreen(), engine.GetForceIntegerScaling(), wantVsync);
}
blit(engine.g->Data()); blit(engine.g->Data());
} }
auto now = uint64_t(SDL_GetTicks()) * UINT64_C(1'000'000); auto now = uint64_t(SDL_GetTicks()) * UINT64_C(1'000'000);

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "common/String.h" #include "common/String.h"
#include "graphics/Pixel.h" #include "graphics/Pixel.h"
#include "gui/WindowFrameOps.h"
#include "FpsLimit.h" #include "FpsLimit.h"
#include <cstdint> #include <cstdint>
#include <SDL.h> #include <SDL.h>
@ -11,11 +12,6 @@ extern int desktopHeight;
extern SDL_Window *sdl_window; extern SDL_Window *sdl_window;
extern SDL_Renderer *sdl_renderer; extern SDL_Renderer *sdl_renderer;
extern SDL_Texture *sdl_texture; extern SDL_Texture *sdl_texture;
extern int scale;
extern bool fullscreen;
extern bool altFullscreen;
extern bool forceIntegerScaling;
extern bool resizable;
extern bool momentumScroll; extern bool momentumScroll;
extern bool showAvatars; extern bool showAvatars;
extern uint64_t lastTick; extern uint64_t lastTick;
@ -37,16 +33,13 @@ void ClipboardPush(ByteString text);
ByteString ClipboardPull(); ByteString ClipboardPull();
int GetModifiers(); int GetModifiers();
unsigned int GetTicks(); unsigned int GetTicks();
void CalculateMousePosition(int *x, int *y);
void blit(pixel *vid); void blit(pixel *vid);
void SDLOpen(); void SDLOpen();
void SDLClose(); void SDLClose();
void SDLSetScreen(int scale_, bool resizable_, bool fullscreen_, bool altFullscreen_, bool forceIntegerScaling_); void SDLSetScreen();
void SetFpsLimit(FpsLimit newFpsLimit); void SetFpsLimit(FpsLimit newFpsLimit);
bool RecreateWindow();
void LoadWindowPosition(); void LoadWindowPosition();
void SaveWindowPosition(); void SaveWindowPosition();
void LargeScreenDialog(); void LargeScreenDialog();
void TickClient(); void TickClient();
void EventProcess(const SDL_Event &event);
void UpdateFpsLimit(); void UpdateFpsLimit();

View File

@ -31,7 +31,7 @@ constexpr int MAXSIGNS = 16;
constexpr int ISTP = CELL / 2; constexpr int ISTP = CELL / 2;
constexpr float CFDS = 4.0f / CELL; constexpr float CFDS = 4.0f / CELL;
constexpr float SIM_MAXVELOCITY = 1e4f; constexpr float MAX_VELOCITY = 1e4f;
//Air constants //Air constants
constexpr float AIR_TSTEPP = 0.3f; constexpr float AIR_TSTEPP = 0.3f;

View File

@ -1251,8 +1251,8 @@ void GameSave::readPSv(const std::vector<char> &dataVec)
auto partP = blockP * CELL; auto partP = blockP * CELL;
if (ver<46) { if (ver<46) {
gravityMode = 0; gravityMode = GRAV_VERTICAL;
airMode = 0; airMode = AIR_ON;
} }
PlaneAdapter<std::vector<int>> particleIDMap(RES, 0); PlaneAdapter<std::vector<int>> particleIDMap(RES, 0);
@ -2295,7 +2295,7 @@ std::pair<bool, std::vector<char>> GameSave::serialiseOPS() const
bson_append_string(&b, "platform", IDENT_PLATFORM); bson_append_string(&b, "platform", IDENT_PLATFORM);
bson_append_string(&b, "ident", IDENT); bson_append_string(&b, "ident", IDENT);
bson_append_finish_object(&b); bson_append_finish_object(&b);
if (gravityMode == 3) if (gravityMode == GRAV_CUSTOM)
{ {
bson_append_double(&b, "customGravityX", double(customGravityX)); bson_append_double(&b, "customGravityX", double(customGravityX));
bson_append_double(&b, "customGravityY", double(customGravityY)); bson_append_double(&b, "customGravityY", double(customGravityY));

View File

@ -0,0 +1,86 @@
#include "CurlError.h"
#include "common/String.h"
#include "Config.h"
#include <iostream>
#include <SDL.h>
#include <jni.h>
#include <android/log.h>
static jclass FindClass(JNIEnv *env, const char *name)
{
jobject nativeActivity = (jobject)SDL_AndroidGetActivity(); if (!nativeActivity) return NULL;
jclass acl = env->GetObjectClass(nativeActivity); if (!acl ) return NULL;
jmethodID getClassLoader = env->GetMethodID(acl, "getClassLoader", "()Ljava/lang/ClassLoader;"); if (!getClassLoader) return NULL;
jobject cls = env->CallObjectMethod(nativeActivity, getClassLoader); if (!cls ) return NULL;
jclass classLoader = env->FindClass("java/lang/ClassLoader"); if (!classLoader ) return NULL;
jmethodID findClass = env->GetMethodID(classLoader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;"); if (!findClass ) return NULL;
jstring strClassName = env->NewStringUTF(name); if (!strClassName ) return NULL;
jclass clazz = (jclass)(env->CallObjectMethod(cls, findClass, strClassName));
env->DeleteLocalRef(strClassName);
return clazz;
}
namespace http
{
void UseSystemCertProvider(CURL *easy)
{
struct DoOnce
{
ByteString allPems;
void InitPem()
{
auto die = [](ByteString message) {
__android_log_print(ANDROID_LOG_ERROR, "AndroidCertProvider", "%s", ("failed to enumerate system certificates: " + message).c_str());
};
auto *env = (JNIEnv *)SDL_AndroidGetJNIEnv();
if (!env)
{
return die("SDL_AndroidGetJNIEnv failed");
}
jclass mPowderActivity = FindClass(env, ByteString::Build(APPID, ".PowderActivity").c_str());
if (!mPowderActivity)
{
return die("FindClass failed");
}
jmethodID midGetCertificateBundle = env->GetStaticMethodID(mPowderActivity, "getCertificateBundle", "()Ljava/lang/String;");
if (!midGetCertificateBundle)
{
return die("GetStaticMethodID failed");
}
jstring str = (jstring)env->CallStaticObjectMethod(mPowderActivity, midGetCertificateBundle);
if (!str)
{
return die("getCertificateBundle failed");
}
const char *utf = env->GetStringUTFChars(str, 0);
if (utf)
{
allPems = utf;
env->ReleaseStringUTFChars(str, utf);
}
else
{
__android_log_print(ANDROID_LOG_ERROR, "AndroidCertProvider", "out of memory???");
}
env->DeleteLocalRef(str);
__android_log_print(ANDROID_LOG_ERROR, "AndroidCertProvider", "certificate bundle loaded");
}
DoOnce()
{
InitPem();
}
};
static DoOnce doOnce;
if (doOnce.allPems.size())
{
curl_blob blob;
blob.data = &doOnce.allPems[0];
blob.len = doOnce.allPems.size();
blob.flags = CURL_BLOB_COPY;
HandleCURLcode(curl_easy_setopt(easy, CURLOPT_CAINFO_BLOB, &blob));
}
}
}

View File

@ -9,6 +9,7 @@ namespace http
using runtime_error::runtime_error; using runtime_error::runtime_error;
}; };
void UseSystemCertProvider(CURL *easy);
void SetupCurlEasyCiphers(CURL *easy); void SetupCurlEasyCiphers(CURL *easy);
void HandleCURLcode(CURLcode code); void HandleCURLcode(CURLcode code);
void HandleCURLMcode(CURLMcode code); void HandleCURLMcode(CURLMcode code);

View File

@ -462,14 +462,6 @@ namespace http
{ {
HandleCURLcode(curl_easy_setopt(handle->curlEasy, CURLOPT_PROXY, proxy.c_str())); HandleCURLcode(curl_easy_setopt(handle->curlEasy, CURLOPT_PROXY, proxy.c_str()));
} }
if (cafile.size())
{
HandleCURLcode(curl_easy_setopt(handle->curlEasy, CURLOPT_CAINFO, cafile.c_str()));
}
if (capath.size())
{
HandleCURLcode(curl_easy_setopt(handle->curlEasy, CURLOPT_CAPATH, capath.c_str()));
}
HandleCURLcode(curl_easy_setopt(handle->curlEasy, CURLOPT_PRIVATE, (void *)handle)); HandleCURLcode(curl_easy_setopt(handle->curlEasy, CURLOPT_PRIVATE, (void *)handle));
HandleCURLcode(curl_easy_setopt(handle->curlEasy, CURLOPT_USERAGENT, userAgent.c_str())); HandleCURLcode(curl_easy_setopt(handle->curlEasy, CURLOPT_USERAGENT, userAgent.c_str()));
HandleCURLcode(curl_easy_setopt(handle->curlEasy, CURLOPT_HEADERDATA, (void *)handle)); HandleCURLcode(curl_easy_setopt(handle->curlEasy, CURLOPT_HEADERDATA, (void *)handle));
@ -562,5 +554,20 @@ namespace http
#elif defined(CURL_AT_LEAST_VERSION) && CURL_AT_LEAST_VERSION(7, 44, 0) #elif defined(CURL_AT_LEAST_VERSION) && CURL_AT_LEAST_VERSION(7, 44, 0)
HandleCURLcode(curl_easy_setopt(easy, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE)); HandleCURLcode(curl_easy_setopt(easy, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE));
#endif #endif
auto &capath = http::RequestManager::Ref().Capath();
auto &cafile = http::RequestManager::Ref().Cafile();
if (capath.size())
{
HandleCURLcode(curl_easy_setopt(easy, CURLOPT_CAPATH, capath.c_str()));
}
else if (cafile.size())
{
HandleCURLcode(curl_easy_setopt(easy, CURLOPT_CAINFO, cafile.c_str()));
}
else if constexpr (USE_SYSTEM_CERT_PROVIDER)
{
UseSystemCertProvider(easy);
}
} }
} }

View File

@ -89,6 +89,16 @@ namespace http
return disableNetwork; return disableNetwork;
} }
const ByteString &Cafile() const
{
return cafile;
}
const ByteString &Capath() const
{
return capath;
}
static RequestManagerPtr Create(ByteString newProxy, ByteString newCafile, ByteString newCapath, bool newDisableNetwork); static RequestManagerPtr Create(ByteString newProxy, ByteString newCafile, ByteString newCapath, bool newDisableNetwork);
}; };
} }

View File

@ -0,0 +1,95 @@
#include "CurlError.h"
#include "common/String.h"
#include <wincrypt.h> // crypt32.lib is pulled in by tpt-libs
#include <iostream>
#include <memory>
namespace http
{
// see https://stackoverflow.com/questions/9507184/can-openssl-on-windows-use-the-system-certificate-store
void UseSystemCertProvider(CURL *easy)
{
struct DoOnce
{
ByteString allPems;
void InitPem()
{
struct StoreDeleter
{
typedef HCERTSTORE pointer;
void operator ()(HCERTSTORE p) const
{
::CertCloseStore(p, 0);
}
};
using StorePtr = std::unique_ptr<void, StoreDeleter>;
struct ContextDeleter
{
typedef PCCERT_CONTEXT pointer;
void operator ()(PCCERT_CONTEXT p) const
{
::CertFreeCertificateContext(p);
}
};
using ContextPtr = std::unique_ptr<void, ContextDeleter>;
auto die = [](ByteString message) {
std::cerr << "failed to enumerate system certificates: " << message << ": " << GetLastError() << std::endl;
};
auto store = StorePtr(::CertOpenSystemStore(0, L"ROOT"), StoreDeleter{});
if (!store)
{
return die("CertOpenSystemStore failed");
}
ContextPtr context;
while (true)
{
context = ContextPtr(::CertEnumCertificatesInStore(store.get(), context.release()), ContextDeleter{});
if (!context)
{
if (::GetLastError() != DWORD(CRYPT_E_NOT_FOUND))
{
return die("CertEnumCertificatesInStore failed");
}
break;
}
DWORD pemLength;
// get required buffer size first
if (!CryptBinaryToStringA(context->pbCertEncoded, context->cbCertEncoded, CRYPT_STRING_BASE64HEADER, NULL, &pemLength))
{
return die("CryptBinaryToStringA failed");
}
std::vector<char> pem(pemLength);
// actually get the data
if (!CryptBinaryToStringA(context->pbCertEncoded, context->cbCertEncoded, CRYPT_STRING_BASE64HEADER, &pem[0], &pemLength))
{
return die("CryptBinaryToStringA failed");
}
allPems += ByteString(&pem[0], &pem[0] + pem.size() - 1); // buffer includes the zero terminator, omit that
}
if (!allPems.size())
{
die("no system certificates");
}
}
DoOnce()
{
InitPem();
}
};
static DoOnce doOnce;
if (doOnce.allPems.size())
{
curl_blob blob;
blob.data = &doOnce.allPems[0];
blob.len = doOnce.allPems.size();
blob.flags = CURL_BLOB_COPY;
HandleCURLcode(curl_easy_setopt(easy, CURLOPT_CAINFO_BLOB, &blob));
}
}
}

View File

@ -2,11 +2,21 @@ client_files += files(
'Common.cpp', 'Common.cpp',
) )
use_system_cert_provider = false
if not enable_http if not enable_http
client_files += files('Null.cpp') client_files += files('Null.cpp')
elif host_platform == 'emscripten' elif host_platform == 'emscripten'
client_files += files('Emscripten.cpp') client_files += files('Emscripten.cpp')
else else
client_files += files('Libcurl.cpp') client_files += files('Libcurl.cpp')
if host_platform == 'windows'
use_system_cert_provider = true
client_files += files('WindowsCertProvider.cpp')
endif
if host_platform == 'android'
use_system_cert_provider = true
client_files += files('AndroidCertProvider.cpp')
endif
endif endif
conf_data.set('NOHTTP', (not enable_http).to_string()) conf_data.set('NOHTTP', (not enable_http).to_string())
conf_data.set('USE_SYSTEM_CERT_PROVIDER', use_system_cert_provider.to_string())

24
src/gui/WindowFrameOps.h Normal file
View File

@ -0,0 +1,24 @@
#pragma once
#include <variant>
struct WindowFrameOps
{
int scale = 1;
bool resizable = false;
bool fullscreen = false;
bool changeResolution = false;
bool forceIntegerScaling = false;
bool blurryScaling = false;
WindowFrameOps Normalize() const
{
return {
fullscreen ? 1 : scale ,
fullscreen ? false : resizable ,
fullscreen ,
fullscreen ? changeResolution : false,
fullscreen ? forceIntegerScaling : false,
blurryScaling ,
};
}
};

View File

@ -529,7 +529,7 @@ void FontEditor::Translate(std::array<std::array<char, MAX_WIDTH>, FONT_H> &pixe
std::array<std::array<char, MAX_WIDTH>, FONT_H> old = pixels; std::array<std::array<char, MAX_WIDTH>, FONT_H> old = pixels;
for(int j = 0; j < FONT_H; j++) for(int j = 0; j < FONT_H; j++)
for(int i = 0; i < MAX_WIDTH; i++) for(int i = 0; i < MAX_WIDTH; i++)
if(i - dx >= 0 && i - dx + 1 < MAX_WIDTH && j - dy >= 0 && j - dy + 1 < FONT_H) if(i - dx >= 0 && i - dx < MAX_WIDTH && j - dy >= 0 && j - dy < FONT_H)
pixels[j][i] = old[j - dy][i - dx]; pixels[j][i] = old[j - dy][i - dx];
else else
pixels[j][i] = 0; pixels[j][i] = 0;

View File

@ -773,20 +773,20 @@ void GameController::ResetSpark()
void GameController::SwitchGravity() void GameController::SwitchGravity()
{ {
gameModel->GetSimulation()->gravityMode = (gameModel->GetSimulation()->gravityMode+1)%4; gameModel->GetSimulation()->gravityMode = (gameModel->GetSimulation()->gravityMode + 1) % NUM_GRAV_MODES;
switch (gameModel->GetSimulation()->gravityMode) switch (gameModel->GetSimulation()->gravityMode)
{ {
case 0: case GRAV_VERTICAL:
gameModel->SetInfoTip("Gravity: Vertical"); gameModel->SetInfoTip("Gravity: Vertical");
break; break;
case 1: case GRAV_OFF:
gameModel->SetInfoTip("Gravity: Off"); gameModel->SetInfoTip("Gravity: Off");
break; break;
case 2: case GRAV_RADIAL:
gameModel->SetInfoTip("Gravity: Radial"); gameModel->SetInfoTip("Gravity: Radial");
break; break;
case 3: case GRAV_CUSTOM:
gameModel->SetInfoTip("Gravity: Custom"); gameModel->SetInfoTip("Gravity: Custom");
break; break;
} }
@ -794,23 +794,23 @@ void GameController::SwitchGravity()
void GameController::SwitchAir() void GameController::SwitchAir()
{ {
gameModel->GetSimulation()->air->airMode = (gameModel->GetSimulation()->air->airMode+1)%5; gameModel->GetSimulation()->air->airMode = (gameModel->GetSimulation()->air->airMode + 1) % NUM_AIR_MODES;
switch (gameModel->GetSimulation()->air->airMode) switch (gameModel->GetSimulation()->air->airMode)
{ {
case 0: case AIR_ON:
gameModel->SetInfoTip("Air: On"); gameModel->SetInfoTip("Air: On");
break; break;
case 1: case AIR_PRESSURE_OFF:
gameModel->SetInfoTip("Air: Pressure Off"); gameModel->SetInfoTip("Air: Pressure Off");
break; break;
case 2: case AIR_VELOCITY_OFF:
gameModel->SetInfoTip("Air: Velocity Off"); gameModel->SetInfoTip("Air: Velocity Off");
break; break;
case 3: case AIR_OFF:
gameModel->SetInfoTip("Air: Off"); gameModel->SetInfoTip("Air: Off");
break; break;
case 4: case AIR_NO_UPDATE:
gameModel->SetInfoTip("Air: No Update"); gameModel->SetInfoTip("Air: No Update");
break; break;
} }
@ -1012,6 +1012,32 @@ int GameController::GetTemperatureScale()
return gameModel->GetTemperatureScale(); return gameModel->GetTemperatureScale();
} }
int GameController::GetEdgeMode()
{
return gameModel->GetEdgeMode();
}
void GameController::SetEdgeMode(int edgeMode)
{
if (edgeMode < 0 || edgeMode >= NUM_EDGE_MODES)
edgeMode = 0;
gameModel->SetEdgeMode(edgeMode);
switch (edgeMode)
{
case EDGE_VOID:
gameModel->SetInfoTip("Edge Mode: Void");
break;
case EDGE_SOLID:
gameModel->SetInfoTip("Edge Mode: Solid");
break;
case EDGE_LOOP:
gameModel->SetInfoTip("Edge Mode: Loop");
break;
}
}
void GameController::SetActiveColourPreset(int preset) void GameController::SetActiveColourPreset(int preset)
{ {
gameModel->SetActiveColourPreset(preset); gameModel->SetActiveColourPreset(preset);

View File

@ -116,6 +116,8 @@ public:
bool GetDebugHUD(); bool GetDebugHUD();
void SetTemperatureScale(int temperatureScale); void SetTemperatureScale(int temperatureScale);
int GetTemperatureScale(); int GetTemperatureScale();
int GetEdgeMode();
void SetEdgeMode(int edgeMode);
void SetDebugFlags(unsigned int flags) { debugFlags = flags; } void SetDebugFlags(unsigned int flags) { debugFlags = flags; }
void SetActiveMenu(int menuID); void SetActiveMenu(int menuID);
std::vector<Menu*> GetMenuList(); std::vector<Menu*> GetMenuList();

View File

@ -51,7 +51,7 @@ GameModel::GameModel():
activeColourPreset(0), activeColourPreset(0),
colourSelector(false), colourSelector(false),
colour(255, 0, 0, 255), colour(255, 0, 0, 255),
edgeMode(0), edgeMode(EDGE_VOID),
ambientAirTemp(R_TEMP + 273.15f), ambientAirTemp(R_TEMP + 273.15f),
decoSpace(0) decoSpace(0)
{ {
@ -91,7 +91,7 @@ GameModel::GameModel():
ren->decorations_enable = prefs.Get("Renderer.Decorations", true); ren->decorations_enable = prefs.Get("Renderer.Decorations", true);
//Load config into simulation //Load config into simulation
edgeMode = prefs.Get("Simulation.EdgeMode", 0); // TODO: EdgeMode enum edgeMode = prefs.Get("Simulation.EdgeMode", (int)EDGE_VOID);
sim->SetEdgeMode(edgeMode); sim->SetEdgeMode(edgeMode);
ambientAirTemp = float(R_TEMP) + 273.15f; ambientAirTemp = float(R_TEMP) + 273.15f;
{ {
@ -1332,10 +1332,10 @@ void GameModel::FrameStep(int frames)
void GameModel::ClearSimulation() void GameModel::ClearSimulation()
{ {
//Load defaults //Load defaults
sim->gravityMode = 0; sim->gravityMode = GRAV_VERTICAL;
sim->customGravityX = 0.0f; sim->customGravityX = 0.0f;
sim->customGravityY = 0.0f; sim->customGravityY = 0.0f;
sim->air->airMode = 0; sim->air->airMode = AIR_ON;
sim->legacy_enable = false; sim->legacy_enable = false;
sim->water_equal_test = false; sim->water_equal_test = false;
sim->SetEdgeMode(edgeMode); sim->SetEdgeMode(edgeMode);

View File

@ -1427,6 +1427,9 @@ void GameView::OnKeyPress(int key, int scan, bool repeat, bool shift, bool ctrl,
c->ReloadSim(); c->ReloadSim();
break; break;
case SDL_SCANCODE_E: case SDL_SCANCODE_E:
if (ctrl)
c->SetEdgeMode(c->GetEdgeMode() + 1);
else
c->OpenElementSearch(); c->OpenElementSearch();
break; break;
case SDL_SCANCODE_F: case SDL_SCANCODE_F:
@ -1459,6 +1462,9 @@ void GameView::OnKeyPress(int key, int scan, bool repeat, bool shift, bool ctrl,
else else
introText = 0; introText = 0;
break; break;
case SDL_SCANCODE_F11:
ui::Engine::Ref().SetFullscreen(!ui::Engine::Ref().GetFullscreen());
break;
case SDL_SCANCODE_H: case SDL_SCANCODE_H:
if(ctrl) if(ctrl)
{ {

View File

@ -2,6 +2,40 @@
#include "Config.h" #include "Config.h"
#include "common/String.h" #include "common/String.h"
inline ByteString VersionInfo()
{
ByteStringBuilder sb;
sb << SAVE_VERSION << "." << MINOR_VERSION << "." << BUILD_NUM << " " << IDENT;
if constexpr (SNAPSHOT)
{
sb << " SNAPSHOT " << SNAPSHOT_ID;
}
else if constexpr (MOD)
{
sb << " MODVER " << SNAPSHOT_ID;
}
if constexpr (LUACONSOLE)
{
sb << " LUACONSOLE";
}
#ifdef REALISTIC
sb << " REALISTIC";
#endif
if constexpr (NOHTTP)
{
sb << " NOHTTP";
}
else if constexpr (ENFORCE_HTTPS)
{
sb << " HTTPS";
}
if constexpr (DEBUG)
{
sb << " DEBUG";
}
return sb.Build();
}
inline ByteString IntroText() inline ByteString IntroText()
{ {
ByteStringBuilder sb; ByteStringBuilder sb;
@ -37,34 +71,6 @@ inline ByteString IntroText()
{ {
sb << "\bgTo use online features such as saving, you need to register at: \brhttps://powdertoy.co.uk/Register.html\n"; sb << "\bgTo use online features such as saving, you need to register at: \brhttps://powdertoy.co.uk/Register.html\n";
} }
sb << "\n" sb << "\n\bt" << VersionInfo();
<< "\bt" << SAVE_VERSION << "." << MINOR_VERSION << "." << BUILD_NUM << " " << IDENT;
if constexpr (SNAPSHOT)
{
sb << " SNAPSHOT " << SNAPSHOT_ID;
}
else if constexpr (MOD)
{
sb << " MODVER " << SNAPSHOT_ID;
}
if constexpr (LUACONSOLE)
{
sb << " LUACONSOLE";
}
#ifdef REALISTIC
sb << " REALISTIC";
#endif
if constexpr (NOHTTP)
{
sb << " NOHTTP";
}
else if constexpr (ENFORCE_HTTPS)
{
sb << " HTTPS";
}
if constexpr (DEBUG)
{
sb << " DEBUG";
}
return sb.Build(); return sb.Build();
} }

View File

@ -10,7 +10,7 @@
class Simulation; class Simulation;
class Brush; class Brush;
class VideoBuffer; class VideoBuffer;
class Particle; struct Particle;
class Tool class Tool
{ {

View File

@ -12,11 +12,7 @@ using namespace ui;
Engine::Engine(): Engine::Engine():
drawingFrequencyLimit(0), drawingFrequencyLimit(0),
Scale(1),
Fullscreen(false),
FrameIndex(0), FrameIndex(0),
altFullscreen(false),
resizable(false),
state_(NULL), state_(NULL),
windowTargetPosition(0, 0), windowTargetPosition(0, 0),
FastQuit(1), FastQuit(1),
@ -335,5 +331,5 @@ void Engine::StopTextInput()
void Engine::TextInputRect(Point position, Point size) void Engine::TextInputRect(Point position, Point size)
{ {
::SetTextInputRect(position.X * Scale, position.Y * Scale, size.X * Scale, size.Y * Scale); ::SetTextInputRect(position.X, position.Y, size.X, size.Y);
} }

View File

@ -5,6 +5,7 @@
#include "common/ExplicitSingleton.h" #include "common/ExplicitSingleton.h"
#include "graphics/Pixel.h" #include "graphics/Pixel.h"
#include "gui/interface/Point.h" #include "gui/interface/Point.h"
#include "gui/WindowFrameOps.h"
#include <climits> #include <climits>
#include "FpsLimit.h" #include "FpsLimit.h"
@ -47,16 +48,6 @@ namespace ui
void SetDrawingFrequencyLimit(int limit) {drawingFrequencyLimit = limit;} void SetDrawingFrequencyLimit(int limit) {drawingFrequencyLimit = limit;}
inline int GetDrawingFrequencyLimit() {return drawingFrequencyLimit;} inline int GetDrawingFrequencyLimit() {return drawingFrequencyLimit;}
void SetFullscreen(bool fullscreen) { Fullscreen = fullscreen; }
inline bool GetFullscreen() { return Fullscreen; }
void SetAltFullscreen(bool altFullscreen) { this->altFullscreen = altFullscreen; }
inline bool GetAltFullscreen() { return altFullscreen; }
void SetForceIntegerScaling(bool forceIntegerScaling) { this->forceIntegerScaling = forceIntegerScaling; }
inline bool GetForceIntegerScaling() { return forceIntegerScaling; }
void SetScale(int scale) { Scale = scale; }
inline int GetScale() { return Scale; }
void SetResizable(bool resizable) { this->resizable = resizable; }
inline bool GetResizable() { return resizable; }
void SetFastQuit(bool fastquit) { FastQuit = fastquit; } void SetFastQuit(bool fastquit) { FastQuit = fastquit; }
inline bool GetFastQuit() {return FastQuit; } inline bool GetFastQuit() {return FastQuit; }
@ -86,16 +77,11 @@ namespace ui
int drawingFrequencyLimit; int drawingFrequencyLimit;
Graphics * g; Graphics * g;
int Scale;
bool GraveExitsConsole; bool GraveExitsConsole;
bool Fullscreen;
unsigned int FrameIndex; unsigned int FrameIndex;
private: private:
FpsLimit fpsLimit; FpsLimit fpsLimit;
bool altFullscreen;
bool forceIntegerScaling = true;
bool resizable;
bool textInput = false; bool textInput = false;
int lastTextEditingStart = INT_MAX; int lastTextEditingStart = INT_MAX;
@ -134,6 +120,20 @@ namespace ui
public: public:
bool MomentumScroll = true; bool MomentumScroll = true;
bool ShowAvatars = true; bool ShowAvatars = true;
}; bool TouchUI = false;
WindowFrameOps windowFrameOps;
void SetScale (int newScale ) { windowFrameOps.scale = newScale; }
void SetFullscreen (bool newFullscreen ) { windowFrameOps.fullscreen = newFullscreen; }
void SetChangeResolution (bool setChangeResolution ) { windowFrameOps.changeResolution = setChangeResolution; }
void SetForceIntegerScaling(bool newForceIntegerScaling) { windowFrameOps.forceIntegerScaling = newForceIntegerScaling; }
void SetResizable (bool newResizable ) { windowFrameOps.resizable = newResizable; }
void SetBlurryScaling (bool newBlurryScaling ) { windowFrameOps.blurryScaling = newBlurryScaling; }
int GetScale () const { return windowFrameOps.scale; }
bool GetFullscreen () const { return windowFrameOps.fullscreen; }
bool GetChangeResolution () const { return windowFrameOps.changeResolution; }
bool GetForceIntegerScaling() const { return windowFrameOps.forceIntegerScaling; }
bool GetResizable () const { return windowFrameOps.resizable; }
bool GetBlurryScaling () const { return windowFrameOps.blurryScaling; }
};
} }

View File

@ -77,9 +77,9 @@ void OptionsController::SetFullscreen(bool fullscreen)
model->SetFullscreen(fullscreen); model->SetFullscreen(fullscreen);
} }
void OptionsController::SetAltFullscreen(bool altFullscreen) void OptionsController::SetChangeResolution(bool newChangeResolution)
{ {
model->SetAltFullscreen(altFullscreen); model->SetChangeResolution(newChangeResolution);
} }
void OptionsController::SetForceIntegerScaling(bool forceIntegerScaling) void OptionsController::SetForceIntegerScaling(bool forceIntegerScaling)
@ -87,6 +87,11 @@ void OptionsController::SetForceIntegerScaling(bool forceIntegerScaling)
model->SetForceIntegerScaling(forceIntegerScaling); model->SetForceIntegerScaling(forceIntegerScaling);
} }
void OptionsController::SetBlurryScaling(bool newBlurryScaling)
{
model->SetBlurryScaling(newBlurryScaling);
}
void OptionsController::SetShowAvatars(bool showAvatars) void OptionsController::SetShowAvatars(bool showAvatars)
{ {
model->SetShowAvatars(showAvatars); model->SetShowAvatars(showAvatars);

View File

@ -25,8 +25,9 @@ public:
void SetEdgeMode(int edgeMode); void SetEdgeMode(int edgeMode);
void SetTemperatureScale(int temperatureScale); void SetTemperatureScale(int temperatureScale);
void SetFullscreen(bool fullscreen); void SetFullscreen(bool fullscreen);
void SetAltFullscreen(bool altFullscreen); void SetChangeResolution(bool newChangeResolution);
void SetForceIntegerScaling(bool forceIntegerScaling); void SetForceIntegerScaling(bool forceIntegerScaling);
void SetBlurryScaling(bool newBlurryScaling);
void SetScale(int scale); void SetScale(int scale);
void SetGraveExitsConsole(bool graveExitsConsole); void SetGraveExitsConsole(bool graveExitsConsole);
void SetResizable(bool resizable); void SetResizable(bool resizable);

View File

@ -191,15 +191,15 @@ void OptionsModel::SetFullscreen(bool fullscreen)
notifySettingsChanged(); notifySettingsChanged();
} }
bool OptionsModel::GetAltFullscreen() bool OptionsModel::GetChangeResolution()
{ {
return ui::Engine::Ref().GetAltFullscreen(); return ui::Engine::Ref().GetChangeResolution();
} }
void OptionsModel::SetAltFullscreen(bool altFullscreen) void OptionsModel::SetChangeResolution(bool newChangeResolution)
{ {
ui::Engine::Ref().SetAltFullscreen(altFullscreen); ui::Engine::Ref().SetChangeResolution(newChangeResolution);
GlobalPrefs::Ref().Set("AltFullscreen", altFullscreen); GlobalPrefs::Ref().Set("AltFullscreen", newChangeResolution);
notifySettingsChanged(); notifySettingsChanged();
} }
@ -215,6 +215,18 @@ void OptionsModel::SetForceIntegerScaling(bool forceIntegerScaling)
notifySettingsChanged(); notifySettingsChanged();
} }
bool OptionsModel::GetBlurryScaling()
{
return ui::Engine::Ref().GetBlurryScaling();
}
void OptionsModel::SetBlurryScaling(bool newBlurryScaling)
{
ui::Engine::Ref().SetBlurryScaling(newBlurryScaling);
GlobalPrefs::Ref().Set("BlurryScaling", newBlurryScaling);
notifySettingsChanged();
}
bool OptionsModel::GetFastQuit() bool OptionsModel::GetFastQuit()
{ {
return ui::Engine::Ref().GetFastQuit(); return ui::Engine::Ref().GetFastQuit();

View File

@ -45,10 +45,12 @@ public:
void SetResizable(bool resizable); void SetResizable(bool resizable);
bool GetFullscreen(); bool GetFullscreen();
void SetFullscreen(bool fullscreen); void SetFullscreen(bool fullscreen);
bool GetAltFullscreen(); bool GetChangeResolution();
void SetAltFullscreen(bool oldFullscreen); void SetChangeResolution(bool newChangeResolution);
bool GetForceIntegerScaling(); bool GetForceIntegerScaling();
void SetForceIntegerScaling(bool forceIntegerScaling); void SetForceIntegerScaling(bool forceIntegerScaling);
bool GetBlurryScaling();
void SetBlurryScaling(bool newBlurryScaling);
bool GetFastQuit(); bool GetFastQuit();
void SetFastQuit(bool fastquit); void SetFastQuit(bool fastquit);
int GetDecoSpace(); int GetDecoSpace();

View File

@ -228,8 +228,9 @@ OptionsView::OptionsView() : ui::Window(ui::Point(-1, -1), ui::Point(320, 340))
}, [this] { }, [this] {
c->SetTemperatureScale(temperatureScale->GetOption().second); c->SetTemperatureScale(temperatureScale->GetOption().second);
}); });
addSeparator(); if (FORCE_WINDOW_FRAME_OPS != forceWindowFrameOpsHandheld)
{ {
addSeparator();
std::vector<std::pair<String, int>> options; std::vector<std::pair<String, int>> options;
int currentScale = ui::Engine::Ref().GetScale(); int currentScale = ui::Engine::Ref().GetScale();
int scaleIndex = 1; int scaleIndex = 1;
@ -252,7 +253,7 @@ OptionsView::OptionsView() : ui::Window(ui::Point(-1, -1), ui::Point(320, 340))
c->SetScale(scale->GetOption().second); c->SetScale(scale->GetOption().second);
}); });
} }
if (ALLOW_WINDOW_FRAME_OPS) if (FORCE_WINDOW_FRAME_OPS == forceWindowFrameOpsNone)
{ {
resizable = addCheckbox(0, "Resizable \bg- allow resizing and maximizing window", "", [this] { resizable = addCheckbox(0, "Resizable \bg- allow resizing and maximizing window", "", [this] {
c->SetResizable(resizable->GetChecked()); c->SetResizable(resizable->GetChecked());
@ -260,13 +261,16 @@ OptionsView::OptionsView() : ui::Window(ui::Point(-1, -1), ui::Point(320, 340))
fullscreen = addCheckbox(0, "Fullscreen \bg- fill the entire screen", "", [this] { fullscreen = addCheckbox(0, "Fullscreen \bg- fill the entire screen", "", [this] {
c->SetFullscreen(fullscreen->GetChecked()); c->SetFullscreen(fullscreen->GetChecked());
}); });
altFullscreen = addCheckbox(1, "Set optimal screen resolution", "", [this] { changeResolution = addCheckbox(1, "Set optimal screen resolution", "", [this] {
c->SetAltFullscreen(altFullscreen->GetChecked()); c->SetChangeResolution(changeResolution->GetChecked());
}); });
forceIntegerScaling = addCheckbox(1, "Force integer scaling \bg- less blurry", "", [this] { forceIntegerScaling = addCheckbox(1, "Force integer scaling \bg- less blurry", "", [this] {
c->SetForceIntegerScaling(forceIntegerScaling->GetChecked()); c->SetForceIntegerScaling(forceIntegerScaling->GetChecked());
}); });
} }
blurryScaling = addCheckbox(0, "Blurry scaling \bg- more blurry, better on very big screens", "", [this] {
c->SetBlurryScaling(blurryScaling->GetChecked());
});
addSeparator(); addSeparator();
if (ALLOW_QUIT) if (ALLOW_QUIT)
{ {
@ -427,7 +431,10 @@ void OptionsView::NotifySettingsChanged(OptionsModel * sender)
customGravityY = sender->GetCustomGravityY(); customGravityY = sender->GetCustomGravityY();
decoSpace->SetOption(sender->GetDecoSpace()); decoSpace->SetOption(sender->GetDecoSpace());
edgeMode->SetOption(sender->GetEdgeMode()); edgeMode->SetOption(sender->GetEdgeMode());
if (scale)
{
scale->SetOption(sender->GetScale()); scale->SetOption(sender->GetScale());
}
if (resizable) if (resizable)
{ {
resizable->SetChecked(sender->GetResizable()); resizable->SetChecked(sender->GetResizable());
@ -436,14 +443,18 @@ void OptionsView::NotifySettingsChanged(OptionsModel * sender)
{ {
fullscreen->SetChecked(sender->GetFullscreen()); fullscreen->SetChecked(sender->GetFullscreen());
} }
if (altFullscreen) if (changeResolution)
{ {
altFullscreen->SetChecked(sender->GetAltFullscreen()); changeResolution->SetChecked(sender->GetChangeResolution());
} }
if (forceIntegerScaling) if (forceIntegerScaling)
{ {
forceIntegerScaling->SetChecked(sender->GetForceIntegerScaling()); forceIntegerScaling->SetChecked(sender->GetForceIntegerScaling());
} }
if (blurryScaling)
{
blurryScaling->SetChecked(sender->GetBlurryScaling());
}
if (fastquit) if (fastquit)
{ {
fastquit->SetChecked(sender->GetFastQuit()); fastquit->SetChecked(sender->GetFastQuit());

View File

@ -15,31 +15,32 @@ class OptionsModel;
class OptionsController; class OptionsController;
class OptionsView: public ui::Window class OptionsView: public ui::Window
{ {
OptionsController * c; OptionsController *c{};
ui::Checkbox * heatSimulation; ui::Checkbox *heatSimulation{};
ui::Checkbox * ambientHeatSimulation; ui::Checkbox *ambientHeatSimulation{};
ui::Checkbox * newtonianGravity; ui::Checkbox *newtonianGravity{};
ui::Checkbox * waterEqualisation; ui::Checkbox *waterEqualisation{};
ui::DropDown * airMode; ui::DropDown *airMode{};
ui::Textbox * ambientAirTemp; ui::Textbox *ambientAirTemp{};
ui::Button * ambientAirTempPreview; ui::Button *ambientAirTempPreview{};
ui::DropDown * gravityMode; ui::DropDown *gravityMode{};
ui::DropDown * edgeMode; ui::DropDown *edgeMode{};
ui::DropDown * temperatureScale; ui::DropDown *temperatureScale{};
ui::DropDown * scale; ui::DropDown *scale{};
ui::Checkbox * resizable; ui::Checkbox *resizable{};
ui::Checkbox * fullscreen; ui::Checkbox *fullscreen{};
ui::Checkbox * altFullscreen; ui::Checkbox *changeResolution{};
ui::Checkbox * forceIntegerScaling; ui::Checkbox *forceIntegerScaling{};
ui::Checkbox * fastquit = nullptr; ui::Checkbox *blurryScaling{};
ui::DropDown * decoSpace; ui::Checkbox *fastquit{};
ui::Checkbox * showAvatars; ui::DropDown *decoSpace{};
ui::Checkbox * momentumScroll; ui::Checkbox *showAvatars{};
ui::Checkbox * mouseClickRequired; ui::Checkbox *momentumScroll{};
ui::Checkbox * includePressure; ui::Checkbox *mouseClickRequired{};
ui::Checkbox * perfectCircle; ui::Checkbox *includePressure{};
ui::Checkbox * graveExitsConsole; ui::Checkbox *perfectCircle{};
ui::ScrollPanel * scrollPanel; ui::Checkbox *graveExitsConsole{};
ui::ScrollPanel *scrollPanel{};
float customGravityX, customGravityY; float customGravityX, customGravityY;
void UpdateAmbientAirTempPreview(float airTemp, bool isValid); void UpdateAmbientAirTempPreview(float airTemp, bool isValid);
void AmbientAirTempToTextBox(float airTemp); void AmbientAirTempToTextBox(float airTemp);

View File

@ -259,7 +259,7 @@ int luacon_elementwrite(lua_State* l)
void luacon_hook(lua_State * l, lua_Debug * ar) void luacon_hook(lua_State * l, lua_Debug * ar)
{ {
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface); auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
if (ar->event == LUA_HOOKCOUNT && Platform::GetTime() - luacon_ci->luaExecutionStart > 3000) if (ar->event == LUA_HOOKCOUNT && int(Platform::GetTime() - luacon_ci->luaExecutionStart) > luacon_ci->luaHookTimeout)
{ {
luaL_error(l, "Error: Script not responding"); luaL_error(l, "Error: Script not responding");
luacon_ci->luaExecutionStart = Platform::GetTime(); luacon_ci->luaExecutionStart = Platform::GetTime();

View File

@ -1,6 +1,7 @@
#include "bzip2/bz2wrap.h" #include "bzip2/bz2wrap.h"
#include "common/VariantIndex.h" #include "common/VariantIndex.h"
#include "Config.h" #include "Config.h"
#include "prefs/GlobalPrefs.h"
#include "LuaScriptInterface.h" #include "LuaScriptInterface.h"
@ -272,6 +273,8 @@ LuaScriptInterface::LuaScriptInterface(GameController * c, GameModel * m):
currentCommand(false), currentCommand(false),
textInputRefcount(0) textInputRefcount(0)
{ {
auto &prefs = GlobalPrefs::Ref();
luaHookTimeout = prefs.Get("LuaHookTimeout", 3000);
luacon_model = m; luacon_model = m;
luacon_controller = c; luacon_controller = c;
luacon_sim = m->GetSimulation(); luacon_sim = m->GetSimulation();
@ -1212,6 +1215,8 @@ void LuaScriptInterface::initSimulationAPI()
SETCONST(l, NCELL); SETCONST(l, NCELL);
SETCONST(l, XRES); SETCONST(l, XRES);
SETCONST(l, YRES); SETCONST(l, YRES);
SETCONST(l, XCNTR);
SETCONST(l, YCNTR);
SETCONST(l, NPART); SETCONST(l, NPART);
SETCONST(l, NT); SETCONST(l, NT);
SETCONST(l, ST); SETCONST(l, ST);
@ -1226,6 +1231,9 @@ void LuaScriptInterface::initSimulationAPI()
SETCONSTF(l, MIN_TEMP); SETCONSTF(l, MIN_TEMP);
SETCONSTF(l, MAX_PRESSURE); SETCONSTF(l, MAX_PRESSURE);
SETCONSTF(l, MIN_PRESSURE); SETCONSTF(l, MIN_PRESSURE);
SETCONST(l, ISTP);
SETCONSTF(l, CFDS);
SETCONSTF(l, MAX_VELOCITY);
SETCONST(l, TOOL_HEAT); SETCONST(l, TOOL_HEAT);
SETCONST(l, TOOL_COOL); SETCONST(l, TOOL_COOL);
@ -1236,6 +1244,7 @@ void LuaScriptInterface::initSimulationAPI()
SETCONST(l, TOOL_MIX); SETCONST(l, TOOL_MIX);
SETCONST(l, TOOL_CYCL); SETCONST(l, TOOL_CYCL);
lua_pushinteger(l, luacon_sim->tools.size()); lua_setfield(l, -2, "TOOL_WIND"); lua_pushinteger(l, luacon_sim->tools.size()); lua_setfield(l, -2, "TOOL_WIND");
SETCONST(l, DECO_DRAW); SETCONST(l, DECO_DRAW);
SETCONST(l, DECO_CLEAR); SETCONST(l, DECO_CLEAR);
SETCONST(l, DECO_ADD); SETCONST(l, DECO_ADD);
@ -1247,6 +1256,43 @@ void LuaScriptInterface::initSimulationAPI()
SETCONST(l, PMAPBITS); SETCONST(l, PMAPBITS);
SETCONST(l, PMAPMASK); SETCONST(l, PMAPMASK);
SETCONST(l, CIRCLE_BRUSH);
SETCONST(l, SQUARE_BRUSH);
SETCONST(l, TRI_BRUSH);
SETCONST(l, BRUSH_NUM);
SETCONST(l, EDGE_VOID);
SETCONST(l, EDGE_SOLID);
SETCONST(l, EDGE_LOOP);
SETCONST(l, NUM_EDGE_MODES);
SETCONST(l, AIR_ON);
SETCONST(l, AIR_PRESSURE_OFF);
SETCONST(l, AIR_VELOCITY_OFF);
SETCONST(l, AIR_OFF);
SETCONST(l, AIR_NO_UPDATE);
SETCONST(l, NUM_AIR_MODES);
SETCONST(l, GRAV_VERTICAL);
SETCONST(l, GRAV_OFF);
SETCONST(l, GRAV_RADIAL);
SETCONST(l, GRAV_CUSTOM);
SETCONST(l, NUM_GRAV_MODES);
lua_newtable(l);
for (int i = 0; i < UI_WALLCOUNT; i++)
{
tpt_lua_pushByteString(l, luacon_sim->wtypes[i].identifier);
lua_pushinteger(l, i);
lua_settable(l, -3);
lua_pushinteger(l, i);
tpt_lua_pushByteString(l, luacon_sim->wtypes[i].identifier);
lua_settable(l, -3);
}
lua_setfield(l, -2, "walls");
SETCONST(l, UI_WALLCOUNT);
//Declare FIELD_BLAH constants //Declare FIELD_BLAH constants
{ {
int particlePropertiesCount = 0; int particlePropertiesCount = 0;
@ -1324,7 +1370,7 @@ void LuaScriptInterface::set_map(int x, int y, int width, int height, float valu
int LuaScriptInterface::simulation_partNeighbours(lua_State * l) int LuaScriptInterface::simulation_partNeighbours(lua_State * l)
{ {
lua_newtable(l); lua_newtable(l);
int id = 0; int id = 1;
int x = lua_tointeger(l, 1), y = lua_tointeger(l, 2), r = lua_tointeger(l, 3), rx, ry, n; int x = lua_tointeger(l, 1), y = lua_tointeger(l, 2), r = lua_tointeger(l, 3), rx, ry, n;
if(lua_gettop(l) == 5) // this is one more than the number of arguments because a table has just been pushed onto the stack with lua_newtable(l); if(lua_gettop(l) == 5) // this is one more than the number of arguments because a table has just been pushed onto the stack with lua_newtable(l);
{ {
@ -2298,7 +2344,7 @@ int LuaScriptInterface::simulation_edgeMode(lua_State * l)
lua_pushnumber(l, luacon_model->GetEdgeMode()); lua_pushnumber(l, luacon_model->GetEdgeMode());
return 1; return 1;
} }
int edgeMode = luaL_optint(l, 1, 0); int edgeMode = luaL_optint(l, 1, EDGE_VOID);
luacon_model->SetEdgeMode(edgeMode); luacon_model->SetEdgeMode(edgeMode);
return 0; return 0;
} }
@ -2311,7 +2357,7 @@ int LuaScriptInterface::simulation_gravityMode(lua_State * l)
lua_pushnumber(l, luacon_sim->gravityMode); lua_pushnumber(l, luacon_sim->gravityMode);
return 1; return 1;
} }
int gravityMode = luaL_optint(l, 1, 0); int gravityMode = luaL_optint(l, 1, GRAV_VERTICAL);
luacon_sim->gravityMode = gravityMode; luacon_sim->gravityMode = gravityMode;
return 0; return 0;
} }
@ -2344,7 +2390,7 @@ int LuaScriptInterface::simulation_airMode(lua_State * l)
lua_pushnumber(l, luacon_sim->air->airMode); lua_pushnumber(l, luacon_sim->air->airMode);
return 1; return 1;
} }
int airMode = luaL_optint(l, 1, 0); int airMode = luaL_optint(l, 1, AIR_ON);
luacon_sim->air->airMode = airMode; luacon_sim->air->airMode = airMode;
return 0; return 0;
} }

View File

@ -212,6 +212,7 @@ public:
static void LuaSetProperty(lua_State* l, StructProperty property, intptr_t propertyAddress, int stackPos); static void LuaSetProperty(lua_State* l, StructProperty property, intptr_t propertyAddress, int stackPos);
static void LuaSetParticleProperty(lua_State* l, int particleID, StructProperty property, intptr_t propertyAddress, int stackPos); static void LuaSetParticleProperty(lua_State* l, int particleID, StructProperty property, intptr_t propertyAddress, int stackPos);
int luaHookTimeout;
ui::Window * Window; ui::Window * Window;
lua_State *l; lua_State *l;
long unsigned int luaExecutionStart = 0; long unsigned int luaExecutionStart = 0;

View File

@ -22,19 +22,25 @@ conf_data.set('USE_UPDATESERVER', (update_server != '').to_string())
enforce_https = get_option('enforce_https') enforce_https = get_option('enforce_https')
allow_quit = true allow_quit = true
allow_window_frame_ops = true force_window_frame_ops = 'forceWindowFrameOpsNone'
allow_data_folder = true allow_data_folder = true
if host_platform == 'emscripten' if host_platform == 'emscripten'
allow_quit = false allow_quit = false
allow_window_frame_ops = false force_window_frame_ops = 'forceWindowFrameOpsEmbedded'
allow_data_folder = false allow_data_folder = false
endif endif
default_touch_ui = false
if host_platform == 'android'
default_touch_ui = true # TODO: some more sophisticated heuristic at runtime instead
force_window_frame_ops = 'forceWindowFrameOpsHandheld'
endif
secure_ciphers_only = get_option('secure_ciphers_only') secure_ciphers_only = get_option('secure_ciphers_only')
if not is_debug and not enforce_https if not is_debug and not enforce_https
error('refusing to build a release binary without enforcing HTTPS, configure with -Denforce_https=true to fix this error') error('refusing to build a release binary without enforcing HTTPS, configure with -Denforce_https=true to fix this error')
endif endif
conf_data.set('ALLOW_QUIT', allow_quit.to_string()) conf_data.set('ALLOW_QUIT', allow_quit.to_string())
conf_data.set('ALLOW_WINDOW_FRAME_OPS', allow_window_frame_ops.to_string()) conf_data.set('FORCE_WINDOW_FRAME_OPS', force_window_frame_ops)
conf_data.set('DEFAULT_TOUCH_UI', default_touch_ui.to_string())
conf_data.set('ALLOW_DATA_FOLDER', allow_data_folder.to_string()) conf_data.set('ALLOW_DATA_FOLDER', allow_data_folder.to_string())
conf_data.set('ENFORCE_HTTPS', enforce_https.to_string()) conf_data.set('ENFORCE_HTTPS', enforce_https.to_string())
conf_data.set('SECURE_CIPHERS_ONLY', secure_ciphers_only.to_string()) conf_data.set('SECURE_CIPHERS_ONLY', secure_ciphers_only.to_string())
@ -49,6 +55,23 @@ conf_data.set('APPID', app_id)
conf_data.set('APPDATA', get_option('app_data')) conf_data.set('APPDATA', get_option('app_data'))
conf_data.set('APPVENDOR', get_option('app_vendor')) conf_data.set('APPVENDOR', get_option('app_vendor'))
if host_platform == 'android'
android_permissions = [
'<uses-permission android:name="android.permission.VIBRATE" />',
]
if enable_http
android_permissions += [
'<uses-permission android:name="android.permission.INTERNET" />',
]
endif
android_properties = []
if is_debug
android_properties += [ 'android:debuggable="true"' ]
endif
conf_data.set('ANDROID_PERMISSIONS', '\n'.join(android_permissions))
conf_data.set('ANDROID_PROPERTIES', '\n'.join(android_properties))
endif
powder_files = files( powder_files = files(
'SDLCompat.cpp', 'SDLCompat.cpp',
'PowderToySDL.cpp', 'PowderToySDL.cpp',

View File

@ -119,7 +119,7 @@ void Air::update_air(void)
{ {
const float advDistanceMult = 0.7f; const float advDistanceMult = 0.7f;
if (airMode != 4) //airMode 4 is no air/pressure update if (airMode != AIR_NO_UPDATE) //airMode 4 is no air/pressure update
{ {
for (auto i=0; i<YCELLS; i++) //reduces pressure/velocity on the edges every frame for (auto i=0; i<YCELLS; i++) //reduces pressure/velocity on the edges every frame
{ {
@ -309,21 +309,21 @@ void Air::update_air(void)
switch (airMode) switch (airMode)
{ {
default: default:
case 0: //Default case AIR_ON: //Default
break; break;
case 1: //0 Pressure case AIR_PRESSURE_OFF: //0 Pressure
dp = 0.0f; dp = 0.0f;
break; break;
case 2: //0 Velocity case AIR_VELOCITY_OFF: //0 Velocity
dx = 0.0f; dx = 0.0f;
dy = 0.0f; dy = 0.0f;
break; break;
case 3: //0 Air case AIR_OFF: //0 Air
dx = 0.0f; dx = 0.0f;
dy = 0.0f; dy = 0.0f;
dp = 0.0f; dp = 0.0f;
break; break;
case 4: //No Update case AIR_NO_UPDATE: //No Update
break; break;
} }
@ -383,7 +383,7 @@ void Air::ApproximateBlockAirMaps()
Air::Air(Simulation & simulation): Air::Air(Simulation & simulation):
sim(simulation), sim(simulation),
airMode(0), airMode(AIR_ON),
ambientAirTemp(R_TEMP + 273.15f) ambientAirTemp(R_TEMP + 273.15f)
{ {
//Simulation should do this. //Simulation should do this.

View File

@ -753,8 +753,8 @@ void Simulation::SetEdgeMode(int newEdgeMode)
edgeMode = newEdgeMode; edgeMode = newEdgeMode;
switch(edgeMode) switch(edgeMode)
{ {
case 0: case EDGE_VOID:
case 2: case EDGE_LOOP:
for(int i = 0; i<XCELLS; i++) for(int i = 0; i<XCELLS; i++)
{ {
bmap[0][i] = 0; bmap[0][i] = 0;
@ -766,7 +766,7 @@ void Simulation::SetEdgeMode(int newEdgeMode)
bmap[i][XCELLS-1] = 0; bmap[i][XCELLS-1] = 0;
} }
break; break;
case 1: case EDGE_SOLID:
int i; int i;
for(i=0; i<XCELLS; i++) for(i=0; i<XCELLS; i++)
{ {
@ -780,7 +780,7 @@ void Simulation::SetEdgeMode(int newEdgeMode)
} }
break; break;
default: default:
SetEdgeMode(0); SetEdgeMode(EDGE_VOID);
} }
} }
@ -1649,7 +1649,7 @@ int Simulation::try_move(int i, int x, int y, int nx, int ny)
int Simulation::do_move(int i, int x, int y, float nxf, float nyf) int Simulation::do_move(int i, int x, int y, float nxf, float nyf)
{ {
int nx = (int)(nxf+0.5f), ny = (int)(nyf+0.5f), result; int nx = (int)(nxf+0.5f), ny = (int)(nyf+0.5f), result;
if (edgeMode == 2) if (edgeMode == EDGE_LOOP)
{ {
bool x_ok = (nx >= CELL && nx < XRES-CELL); bool x_ok = (nx >= CELL && nx < XRES-CELL);
bool y_ok = (ny >= CELL && ny < YRES-CELL); bool y_ok = (ny >= CELL && ny < YRES-CELL);
@ -2078,15 +2078,15 @@ void Simulation::GetGravityField(int x, int y, float particleGrav, float newtonG
switch (gravityMode) switch (gravityMode)
{ {
default: default:
case 0: //normal, vertical gravity case GRAV_VERTICAL: //normal, vertical gravity
pGravX = 0; pGravX = 0;
pGravY = particleGrav; pGravY = particleGrav;
break; break;
case 1: //no gravity case GRAV_OFF: //no gravity
pGravX = 0; pGravX = 0;
pGravY = 0; pGravY = 0;
break; break;
case 2: //radial gravity case GRAV_RADIAL: //radial gravity
{ {
pGravX = 0; pGravX = 0;
pGravY = 0; pGravY = 0;
@ -2100,7 +2100,7 @@ void Simulation::GetGravityField(int x, int y, float particleGrav, float newtonG
} }
} }
break; break;
case 3: //custom gravity case GRAV_CUSTOM: //custom gravity
pGravX = particleGrav * customGravityX; pGravX = particleGrav * customGravityX;
pGravY = particleGrav * customGravityY; pGravY = particleGrav * customGravityY;
break; break;
@ -2866,11 +2866,11 @@ killed:
} }
else else
{ {
if (mv > SIM_MAXVELOCITY) if (mv > MAX_VELOCITY)
{ {
parts[i].vx *= SIM_MAXVELOCITY/mv; parts[i].vx *= MAX_VELOCITY/mv;
parts[i].vy *= SIM_MAXVELOCITY/mv; parts[i].vy *= MAX_VELOCITY/mv;
mv = SIM_MAXVELOCITY; mv = MAX_VELOCITY;
} }
// interpolate to see if there is anything in the way // interpolate to see if there is anything in the way
dx = parts[i].vx*ISTP/mv; dx = parts[i].vx*ISTP/mv;
@ -2887,7 +2887,7 @@ killed:
fin_yf += dy; fin_yf += dy;
fin_x = (int)(fin_xf+0.5f); fin_x = (int)(fin_xf+0.5f);
fin_y = (int)(fin_yf+0.5f); fin_y = (int)(fin_yf+0.5f);
if (edgeMode == 2) if (edgeMode == EDGE_LOOP)
{ {
bool x_ok = (fin_xf >= CELL-.5f && fin_xf < XRES-CELL-.5f); bool x_ok = (fin_xf >= CELL-.5f && fin_xf < XRES-CELL-.5f);
bool y_ok = (fin_yf >= CELL-.5f && fin_yf < YRES-CELL-.5f); bool y_ok = (fin_yf >= CELL-.5f && fin_yf < YRES-CELL-.5f);
@ -2903,7 +2903,7 @@ killed:
// nothing found // nothing found
fin_xf = parts[i].x + parts[i].vx; fin_xf = parts[i].x + parts[i].vx;
fin_yf = parts[i].y + parts[i].vy; fin_yf = parts[i].y + parts[i].vy;
if (edgeMode == 2) if (edgeMode == EDGE_LOOP)
{ {
bool x_ok = (fin_xf >= CELL-.5f && fin_xf < XRES-CELL-.5f); bool x_ok = (fin_xf >= CELL-.5f && fin_xf < XRES-CELL-.5f);
bool y_ok = (fin_yf >= CELL-.5f && fin_yf < YRES-CELL-.5f); bool y_ok = (fin_yf >= CELL-.5f && fin_yf < YRES-CELL-.5f);
@ -2947,7 +2947,7 @@ killed:
parts[i].y += parts[i].vy; parts[i].y += parts[i].vy;
int nx = (int)((float)parts[i].x+0.5f); int nx = (int)((float)parts[i].x+0.5f);
int ny = (int)((float)parts[i].y+0.5f); int ny = (int)((float)parts[i].y+0.5f);
if (edgeMode == 2) if (edgeMode == EDGE_LOOP)
{ {
bool x_ok = (nx >= CELL && nx < XRES-CELL); bool x_ok = (nx >= CELL && nx < XRES-CELL);
bool y_ok = (ny >= CELL && ny < YRES-CELL); bool y_ok = (ny >= CELL && ny < YRES-CELL);
@ -3220,7 +3220,7 @@ killed:
goto movedone; goto movedone;
} }
} }
if (elements[t].Falldown>1 && !grav->IsEnabled() && gravityMode==0 && parts[i].vy>fabsf(parts[i].vx)) if (elements[t].Falldown>1 && !grav->IsEnabled() && gravityMode==GRAV_VERTICAL && parts[i].vy>fabsf(parts[i].vx))
{ {
s = 0; s = 0;
// stagnant is true if FLAG_STAGNANT was set for this particle in previous frame // stagnant is true if FLAG_STAGNANT was set for this particle in previous frame
@ -3944,8 +3944,8 @@ Simulation::Simulation():
gravWallChanged(false), gravWallChanged(false),
CGOL(0), CGOL(0),
GSPEED(1), GSPEED(1),
edgeMode(0), edgeMode(EDGE_VOID),
gravityMode(0), gravityMode(GRAV_VERTICAL),
customGravityX(0), customGravityX(0),
customGravityY(0), customGravityY(0),
legacy_enable(0), legacy_enable(0),

View File

@ -133,6 +133,21 @@ constexpr int NGT_BRAN = 23;
constexpr auto REPLACE_MODE = UINT32_C(0x00000001); constexpr auto REPLACE_MODE = UINT32_C(0x00000001);
constexpr auto SPECIFIC_DELETE = UINT32_C(0x00000002); constexpr auto SPECIFIC_DELETE = UINT32_C(0x00000002);
enum EdgeMode
{
EDGE_VOID, EDGE_SOLID, EDGE_LOOP, NUM_EDGE_MODES
};
enum AirMode
{
AIR_ON, AIR_PRESSURE_OFF, AIR_VELOCITY_OFF, AIR_OFF, AIR_NO_UPDATE, NUM_AIR_MODES
};
enum GravityMode
{
GRAV_VERTICAL, GRAV_OFF, GRAV_RADIAL, GRAV_CUSTOM, NUM_GRAV_MODES
};
struct part_type; struct part_type;
struct part_transition; struct part_transition;

View File

@ -80,9 +80,9 @@ static int update(UPDATE_FUNC_ARGS)
auto rrr = sim->rng.between(0, 359) * 3.14159f / 180.0f; auto rrr = sim->rng.between(0, 359) * 3.14159f / 180.0f;
int rr; int rr;
if (TYP(r) == PT_ISOZ) if (TYP(r) == PT_ISOZ)
rr = sim->rng.between(128, 255) / 127.0f; rr = int(sim->rng.between(128, 255) / 127.0f);
else else
rr = sim->rng.between(128, 355) / 127.0f; rr = int(sim->rng.between(128, 355) / 127.0f);
parts[ID(r)].vx = rr*cosf(rrr); parts[ID(r)].vx = rr*cosf(rrr);
parts[ID(r)].vy = rr*sinf(rrr); parts[ID(r)].vy = rr*sinf(rrr);
sim->pv[y/CELL][x/CELL] -= 15.0f * CFDS; sim->pv[y/CELL][x/CELL] -= 15.0f * CFDS;

View File

@ -147,13 +147,13 @@ int Element_STKM_run_stickman(playerst *playerp, UPDATE_FUNC_ARGS)
switch (sim->gravityMode) switch (sim->gravityMode)
{ {
default: default:
case 0: case GRAV_VERTICAL:
gvy = 1; gvy = 1;
break; break;
case 1: case GRAV_OFF:
gvy = gvx = 0.0f; gvy = gvx = 0.0f;
break; break;
case 2: case GRAV_RADIAL:
{ {
float gravd; float gravd;
gravd = 0.01f - hypotf((parts[i].x - XCNTR), (parts[i].y - YCNTR)); gravd = 0.01f - hypotf((parts[i].x - XCNTR), (parts[i].y - YCNTR));
@ -161,7 +161,7 @@ int Element_STKM_run_stickman(playerst *playerp, UPDATE_FUNC_ARGS)
gvy = ((float)(parts[i].y - YCNTR) / gravd); gvy = ((float)(parts[i].y - YCNTR) / gravd);
} }
break; break;
case 3: case GRAV_CUSTOM:
gvx = sim->customGravityX; gvx = sim->customGravityX;
gvy = sim->customGravityY; gvy = sim->customGravityY;
break; break;

View File

@ -110,7 +110,7 @@ static int update(UPDATE_FUNC_ARGS)
if (TYP(r) == PT_FILT) if (TYP(r) == PT_FILT)
{ {
int vel = parts[ID(r)].ctype - 0x10000000; int vel = parts[ID(r)].ctype - 0x10000000;
if (vel >= 0 && vel < SIM_MAXVELOCITY) if (vel >= 0 && vel < MAX_VELOCITY)
{ {
doDeserialization = true; doDeserialization = true;
Vs = float(vel); Vs = float(vel);

View File

@ -1,6 +0,0 @@
[wrap-file]
directory = tpt-libs-prebuilt-aarch64-android-bionic-static-debug-v20230819222922
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20230819222922/tpt-libs-prebuilt-aarch64-android-bionic-static-debug-v20230819222922.zip
source_filename = tpt-libs-prebuilt-aarch64-android-bionic-static-debug-v20230819222922.zip
source_hash = 0541c47779ac3e0fadeb67093669af3e196faae140c2b04a744fe764cad72393

View File

@ -0,0 +1,6 @@
[wrap-file]
directory = tpt-libs-prebuilt-aarch64-android-bionic-static-debug-v20231003175140
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20231003175140/tpt-libs-prebuilt-aarch64-android-bionic-static-debug-v20231003175140.zip
source_filename = tpt-libs-prebuilt-aarch64-android-bionic-static-debug-v20231003175140.zip
source_hash = 7648a1c16bcc182457207698bbc8d4a3e5c2bc97e195153caf954b69133f8ef4

View File

@ -1,6 +0,0 @@
[wrap-file]
directory = tpt-libs-prebuilt-aarch64-android-bionic-static-release-v20230819222922
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20230819222922/tpt-libs-prebuilt-aarch64-android-bionic-static-release-v20230819222922.zip
source_filename = tpt-libs-prebuilt-aarch64-android-bionic-static-release-v20230819222922.zip
source_hash = b36e77653e3855ec43762fc6024419a943b618ff91ae39d6d0e59bf53403bb78

View File

@ -0,0 +1,6 @@
[wrap-file]
directory = tpt-libs-prebuilt-aarch64-android-bionic-static-release-v20231003175140
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20231003175140/tpt-libs-prebuilt-aarch64-android-bionic-static-release-v20231003175140.zip
source_filename = tpt-libs-prebuilt-aarch64-android-bionic-static-release-v20231003175140.zip
source_hash = ca4aa82d29d1919c91b5d9d605b44476baa6bfbf785ffb0258667400659eaa41

View File

@ -1,6 +0,0 @@
[wrap-file]
directory = tpt-libs-prebuilt-aarch64-darwin-macos-static-debug-v20230819222922
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20230819222922/tpt-libs-prebuilt-aarch64-darwin-macos-static-debug-v20230819222922.zip
source_filename = tpt-libs-prebuilt-aarch64-darwin-macos-static-debug-v20230819222922.zip
source_hash = c3bde6110671d7704a3026269f384d022771a6a1f2573c7953884e99048c20d8

View File

@ -0,0 +1,6 @@
[wrap-file]
directory = tpt-libs-prebuilt-aarch64-darwin-macos-static-debug-v20231003175140
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20231003175140/tpt-libs-prebuilt-aarch64-darwin-macos-static-debug-v20231003175140.zip
source_filename = tpt-libs-prebuilt-aarch64-darwin-macos-static-debug-v20231003175140.zip
source_hash = 12901681aeebdcda7e35db9cf28a084620f448c416b235662dca7cc257a6890b

View File

@ -1,6 +0,0 @@
[wrap-file]
directory = tpt-libs-prebuilt-aarch64-darwin-macos-static-release-v20230819222922
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20230819222922/tpt-libs-prebuilt-aarch64-darwin-macos-static-release-v20230819222922.zip
source_filename = tpt-libs-prebuilt-aarch64-darwin-macos-static-release-v20230819222922.zip
source_hash = 9be581acae1300707505f0d4af0af81fda7de1733f31740f428154488100657e

View File

@ -0,0 +1,6 @@
[wrap-file]
directory = tpt-libs-prebuilt-aarch64-darwin-macos-static-release-v20231003175140
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20231003175140/tpt-libs-prebuilt-aarch64-darwin-macos-static-release-v20231003175140.zip
source_filename = tpt-libs-prebuilt-aarch64-darwin-macos-static-release-v20231003175140.zip
source_hash = 93a190ecd1e5180bbb1864ef7bb358960ee77dfa2f071f9172f2f454af366c98

View File

@ -1,6 +0,0 @@
[wrap-file]
directory = tpt-libs-prebuilt-arm-android-bionic-static-debug-v20230819222922
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20230819222922/tpt-libs-prebuilt-arm-android-bionic-static-debug-v20230819222922.zip
source_filename = tpt-libs-prebuilt-arm-android-bionic-static-debug-v20230819222922.zip
source_hash = 64b0b73af47a4af0eb6eda482b5fbfc4614d69d017fd92cbaea6a6500b6ccd4c

View File

@ -0,0 +1,6 @@
[wrap-file]
directory = tpt-libs-prebuilt-arm-android-bionic-static-debug-v20231003175140
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20231003175140/tpt-libs-prebuilt-arm-android-bionic-static-debug-v20231003175140.zip
source_filename = tpt-libs-prebuilt-arm-android-bionic-static-debug-v20231003175140.zip
source_hash = 82ecadcafda676e9d48a819dda2eddf2faa9a1506063bcf4b069e59a4a245139

View File

@ -1,6 +0,0 @@
[wrap-file]
directory = tpt-libs-prebuilt-arm-android-bionic-static-release-v20230819222922
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20230819222922/tpt-libs-prebuilt-arm-android-bionic-static-release-v20230819222922.zip
source_filename = tpt-libs-prebuilt-arm-android-bionic-static-release-v20230819222922.zip
source_hash = 390aa72c827194fdd1dbfabafceb487472a3a3dcc383bd21296a8bfb508127c1

View File

@ -0,0 +1,6 @@
[wrap-file]
directory = tpt-libs-prebuilt-arm-android-bionic-static-release-v20231003175140
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20231003175140/tpt-libs-prebuilt-arm-android-bionic-static-release-v20231003175140.zip
source_filename = tpt-libs-prebuilt-arm-android-bionic-static-release-v20231003175140.zip
source_hash = ee0fc5475d9cce7e7d375415a1edb5ab2329db0aecff05a9e10fb1a29045f117

View File

@ -1,6 +0,0 @@
[wrap-file]
directory = tpt-libs-prebuilt-wasm32-emscripten-emscripten-static-debug-v20230819222922
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20230819222922/tpt-libs-prebuilt-wasm32-emscripten-emscripten-static-debug-v20230819222922.zip
source_filename = tpt-libs-prebuilt-wasm32-emscripten-emscripten-static-debug-v20230819222922.zip
source_hash = 00a50b3863b9846f5ee3820c55f69aa612a710e1db02f59b9944be43db132ea1

View File

@ -0,0 +1,6 @@
[wrap-file]
directory = tpt-libs-prebuilt-wasm32-emscripten-emscripten-static-debug-v20231003175140
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20231003175140/tpt-libs-prebuilt-wasm32-emscripten-emscripten-static-debug-v20231003175140.zip
source_filename = tpt-libs-prebuilt-wasm32-emscripten-emscripten-static-debug-v20231003175140.zip
source_hash = c75e9928c23b8dc210b2ea4ad608f59c02a672844cd7fee9e8d8507f758c8b1d

View File

@ -1,6 +0,0 @@
[wrap-file]
directory = tpt-libs-prebuilt-wasm32-emscripten-emscripten-static-release-v20230819222922
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20230819222922/tpt-libs-prebuilt-wasm32-emscripten-emscripten-static-release-v20230819222922.zip
source_filename = tpt-libs-prebuilt-wasm32-emscripten-emscripten-static-release-v20230819222922.zip
source_hash = 38bad42affb8de3c5550c5d1e8c196260f3762852f6025c8e2f236305e9679c2

View File

@ -0,0 +1,6 @@
[wrap-file]
directory = tpt-libs-prebuilt-wasm32-emscripten-emscripten-static-release-v20231003175140
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20231003175140/tpt-libs-prebuilt-wasm32-emscripten-emscripten-static-release-v20231003175140.zip
source_filename = tpt-libs-prebuilt-wasm32-emscripten-emscripten-static-release-v20231003175140.zip
source_hash = d8b859257a8e5b87fed5316b6a6ff1415a86dce097c89a07dd25ecb74256f01d

View File

@ -1,6 +0,0 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86-android-bionic-static-debug-v20230819222922
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20230819222922/tpt-libs-prebuilt-x86-android-bionic-static-debug-v20230819222922.zip
source_filename = tpt-libs-prebuilt-x86-android-bionic-static-debug-v20230819222922.zip
source_hash = 4ecd9e0fc21de8ccce5d47b75c9a2116098bd2c5e47a1fc743637991f4aa4d52

View File

@ -0,0 +1,6 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86-android-bionic-static-debug-v20231003175140
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20231003175140/tpt-libs-prebuilt-x86-android-bionic-static-debug-v20231003175140.zip
source_filename = tpt-libs-prebuilt-x86-android-bionic-static-debug-v20231003175140.zip
source_hash = 2a1142ece24e44a3c7a5e7103fa8b5d637978ab16f2455b866c3560391cb036b

View File

@ -1,6 +0,0 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86-android-bionic-static-release-v20230819222922
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20230819222922/tpt-libs-prebuilt-x86-android-bionic-static-release-v20230819222922.zip
source_filename = tpt-libs-prebuilt-x86-android-bionic-static-release-v20230819222922.zip
source_hash = 673ae7e89cc807a5c0f2824a7cea7324d59cb888b73ea11031aea4766c797736

View File

@ -0,0 +1,6 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86-android-bionic-static-release-v20231003175140
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20231003175140/tpt-libs-prebuilt-x86-android-bionic-static-release-v20231003175140.zip
source_filename = tpt-libs-prebuilt-x86-android-bionic-static-release-v20231003175140.zip
source_hash = 1d2db7882c8b25293b516ef132fac6e0f83d169cc279d7433bbe6e62dc4ec951

View File

@ -1,6 +0,0 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86-windows-msvc-dynamic-debug-v20230819222922
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20230819222922/tpt-libs-prebuilt-x86-windows-msvc-dynamic-debug-v20230819222922.zip
source_filename = tpt-libs-prebuilt-x86-windows-msvc-dynamic-debug-v20230819222922.zip
source_hash = ed0a65942a6200b0fd1a567c98a57b0915513edba59d0178d147d6851131fe50

View File

@ -0,0 +1,6 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86-windows-msvc-dynamic-debug-v20231003175140
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20231003175140/tpt-libs-prebuilt-x86-windows-msvc-dynamic-debug-v20231003175140.zip
source_filename = tpt-libs-prebuilt-x86-windows-msvc-dynamic-debug-v20231003175140.zip
source_hash = 2c37f08082b70ee633b4d2664a93b1952c4257029f93befe6136a98e60ba022e

View File

@ -1,6 +0,0 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86-windows-msvc-dynamic-release-v20230819222922
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20230819222922/tpt-libs-prebuilt-x86-windows-msvc-dynamic-release-v20230819222922.zip
source_filename = tpt-libs-prebuilt-x86-windows-msvc-dynamic-release-v20230819222922.zip
source_hash = 790959192dcf11a27cfb2747af80d4ccb1d63fc3ae68ff53392879d1be5c7ecc

View File

@ -0,0 +1,6 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86-windows-msvc-dynamic-release-v20231003175140
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20231003175140/tpt-libs-prebuilt-x86-windows-msvc-dynamic-release-v20231003175140.zip
source_filename = tpt-libs-prebuilt-x86-windows-msvc-dynamic-release-v20231003175140.zip
source_hash = e166842489534ccf53afb178e8b42e438c15ed0adccb4ebd2e7f4a3182ec6bcf

View File

@ -1,6 +0,0 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86-windows-msvc-static-debug-v20230819222922
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20230819222922/tpt-libs-prebuilt-x86-windows-msvc-static-debug-v20230819222922.zip
source_filename = tpt-libs-prebuilt-x86-windows-msvc-static-debug-v20230819222922.zip
source_hash = 5aedb31d4ddf48bbb7cc9f0f9c6add4f371f61afa6d50a3be331497e92a36eee

View File

@ -0,0 +1,6 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86-windows-msvc-static-debug-v20231003175140
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20231003175140/tpt-libs-prebuilt-x86-windows-msvc-static-debug-v20231003175140.zip
source_filename = tpt-libs-prebuilt-x86-windows-msvc-static-debug-v20231003175140.zip
source_hash = aa7b274ccf28dc0bf9b139165d23ab5a2acbd158f8c0dfc219d71515d39dd2e7

View File

@ -1,6 +0,0 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86-windows-msvc-static-release-v20230819222922
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20230819222922/tpt-libs-prebuilt-x86-windows-msvc-static-release-v20230819222922.zip
source_filename = tpt-libs-prebuilt-x86-windows-msvc-static-release-v20230819222922.zip
source_hash = a19ec2bfcb02c36d87a5a5783a06b6a9dfffb2a46276ffc5a6ed21fabf513b52

View File

@ -0,0 +1,6 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86-windows-msvc-static-release-v20231003175140
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20231003175140/tpt-libs-prebuilt-x86-windows-msvc-static-release-v20231003175140.zip
source_filename = tpt-libs-prebuilt-x86-windows-msvc-static-release-v20231003175140.zip
source_hash = 373b849bc92507475b906c79767274b59b3383a2a90e2964423663171483ce3b

View File

@ -1,6 +0,0 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86_64-android-bionic-static-debug-v20230819222922
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20230819222922/tpt-libs-prebuilt-x86_64-android-bionic-static-debug-v20230819222922.zip
source_filename = tpt-libs-prebuilt-x86_64-android-bionic-static-debug-v20230819222922.zip
source_hash = 3dc7d57a802b766ff934c3c6dba7ea5c58d59ae9bccf81d179a767e6f6929ba4

View File

@ -0,0 +1,6 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86_64-android-bionic-static-debug-v20231003175140
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20231003175140/tpt-libs-prebuilt-x86_64-android-bionic-static-debug-v20231003175140.zip
source_filename = tpt-libs-prebuilt-x86_64-android-bionic-static-debug-v20231003175140.zip
source_hash = 5267b97efcbc5070059330af90cec0ae78c257e508975168f9c5578671984f79

View File

@ -1,6 +0,0 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86_64-android-bionic-static-release-v20230819222922
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20230819222922/tpt-libs-prebuilt-x86_64-android-bionic-static-release-v20230819222922.zip
source_filename = tpt-libs-prebuilt-x86_64-android-bionic-static-release-v20230819222922.zip
source_hash = 310bc7fc68f3d23c24ee31f7d6ceb56ca8dd01167134e9fc66afde464a19ed36

View File

@ -0,0 +1,6 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86_64-android-bionic-static-release-v20231003175140
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20231003175140/tpt-libs-prebuilt-x86_64-android-bionic-static-release-v20231003175140.zip
source_filename = tpt-libs-prebuilt-x86_64-android-bionic-static-release-v20231003175140.zip
source_hash = 1db9601b4a745c1a0c9c16133d3cbe66ae0023a99c7004e76494b4b54048bcc5

View File

@ -1,6 +0,0 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86_64-darwin-macos-static-debug-v20230819222922
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20230819222922/tpt-libs-prebuilt-x86_64-darwin-macos-static-debug-v20230819222922.zip
source_filename = tpt-libs-prebuilt-x86_64-darwin-macos-static-debug-v20230819222922.zip
source_hash = 02dc73c4a1732ab8ac5667eca155b896a872ee362e9add53ed950333212bf99e

View File

@ -0,0 +1,6 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86_64-darwin-macos-static-debug-v20231003175140
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20231003175140/tpt-libs-prebuilt-x86_64-darwin-macos-static-debug-v20231003175140.zip
source_filename = tpt-libs-prebuilt-x86_64-darwin-macos-static-debug-v20231003175140.zip
source_hash = 98e751366b6ec9eac5690a25aaf569915f6d3db26102e7640efae39f36a495cb

View File

@ -1,6 +0,0 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86_64-darwin-macos-static-release-v20230819222922
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20230819222922/tpt-libs-prebuilt-x86_64-darwin-macos-static-release-v20230819222922.zip
source_filename = tpt-libs-prebuilt-x86_64-darwin-macos-static-release-v20230819222922.zip
source_hash = 70fe0dc9972a94154e8e3a58546e406d36c1d4049dcdeacddd60f83cbe9e62e4

View File

@ -0,0 +1,6 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86_64-darwin-macos-static-release-v20231003175140
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20231003175140/tpt-libs-prebuilt-x86_64-darwin-macos-static-release-v20231003175140.zip
source_filename = tpt-libs-prebuilt-x86_64-darwin-macos-static-release-v20231003175140.zip
source_hash = 84df15f52d979bd0b703c709145a2731e01e2ccb4ba13966168dace6efea354f

View File

@ -1,6 +0,0 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86_64-linux-gnu-static-debug-v20230819222922
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20230819222922/tpt-libs-prebuilt-x86_64-linux-gnu-static-debug-v20230819222922.zip
source_filename = tpt-libs-prebuilt-x86_64-linux-gnu-static-debug-v20230819222922.zip
source_hash = 5addd00589d97fe47d1d425f58a6e6e66759fbf742fd7e3e0ce704c2a7bb47d5

View File

@ -0,0 +1,6 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86_64-linux-gnu-static-debug-v20231003175140
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20231003175140/tpt-libs-prebuilt-x86_64-linux-gnu-static-debug-v20231003175140.zip
source_filename = tpt-libs-prebuilt-x86_64-linux-gnu-static-debug-v20231003175140.zip
source_hash = 0089fed317eac2545f86259744f72126f249775a1e95539abeece2eaf121a08f

View File

@ -1,6 +0,0 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86_64-linux-gnu-static-release-v20230819222922
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20230819222922/tpt-libs-prebuilt-x86_64-linux-gnu-static-release-v20230819222922.zip
source_filename = tpt-libs-prebuilt-x86_64-linux-gnu-static-release-v20230819222922.zip
source_hash = ce353e62fae0c3ea9756044d2d6257f73462f700f4f419fe09e8324015c8b0bb

View File

@ -0,0 +1,6 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86_64-linux-gnu-static-release-v20231003175140
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20231003175140/tpt-libs-prebuilt-x86_64-linux-gnu-static-release-v20231003175140.zip
source_filename = tpt-libs-prebuilt-x86_64-linux-gnu-static-release-v20231003175140.zip
source_hash = 272a81522aec8a34e61b52a92ab0bef29cf3e4ffdfb343086efa9b410806073a

View File

@ -1,6 +0,0 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86_64-windows-mingw-dynamic-debug-v20230819222922
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20230819222922/tpt-libs-prebuilt-x86_64-windows-mingw-dynamic-debug-v20230819222922.zip
source_filename = tpt-libs-prebuilt-x86_64-windows-mingw-dynamic-debug-v20230819222922.zip
source_hash = 268db7c9f1af6ae97f2324b2189bd52353a9f79fae20bd67c29b13dc70c840e1

View File

@ -0,0 +1,6 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86_64-windows-mingw-dynamic-debug-v20231003175140
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20231003175140/tpt-libs-prebuilt-x86_64-windows-mingw-dynamic-debug-v20231003175140.zip
source_filename = tpt-libs-prebuilt-x86_64-windows-mingw-dynamic-debug-v20231003175140.zip
source_hash = fd097a3c6d1d043fb8475b602330fd2ceb5bf12ac2695ba5e6baa885ac5ce439

View File

@ -1,6 +0,0 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86_64-windows-mingw-dynamic-release-v20230819222922
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20230819222922/tpt-libs-prebuilt-x86_64-windows-mingw-dynamic-release-v20230819222922.zip
source_filename = tpt-libs-prebuilt-x86_64-windows-mingw-dynamic-release-v20230819222922.zip
source_hash = b6c84b87234acbf2c7d8ce53427541e68089e135c15c949f686988b943406933

View File

@ -0,0 +1,6 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86_64-windows-mingw-dynamic-release-v20231003175140
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20231003175140/tpt-libs-prebuilt-x86_64-windows-mingw-dynamic-release-v20231003175140.zip
source_filename = tpt-libs-prebuilt-x86_64-windows-mingw-dynamic-release-v20231003175140.zip
source_hash = 1d3be03fcc47059bd35b751f3a56ccebec94df08d3404465468dbb7168cf68dd

View File

@ -1,6 +0,0 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86_64-windows-mingw-static-debug-v20230819222922
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20230819222922/tpt-libs-prebuilt-x86_64-windows-mingw-static-debug-v20230819222922.zip
source_filename = tpt-libs-prebuilt-x86_64-windows-mingw-static-debug-v20230819222922.zip
source_hash = 19157890ebed425e4d47edf30fc23e795b5ed0753fb87d0412e09485289cd817

View File

@ -0,0 +1,6 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86_64-windows-mingw-static-debug-v20231003175140
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20231003175140/tpt-libs-prebuilt-x86_64-windows-mingw-static-debug-v20231003175140.zip
source_filename = tpt-libs-prebuilt-x86_64-windows-mingw-static-debug-v20231003175140.zip
source_hash = c22edbee65046a45b1e157c28cfca7d875374add7d7d70e62e82a29258e532ac

View File

@ -1,6 +0,0 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86_64-windows-mingw-static-release-v20230819222922
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20230819222922/tpt-libs-prebuilt-x86_64-windows-mingw-static-release-v20230819222922.zip
source_filename = tpt-libs-prebuilt-x86_64-windows-mingw-static-release-v20230819222922.zip
source_hash = 7fcd6561e6355f63112f35179bd9150027880af19ed752fb4d2fbe76953cbb0b

View File

@ -0,0 +1,6 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86_64-windows-mingw-static-release-v20231003175140
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20231003175140/tpt-libs-prebuilt-x86_64-windows-mingw-static-release-v20231003175140.zip
source_filename = tpt-libs-prebuilt-x86_64-windows-mingw-static-release-v20231003175140.zip
source_hash = 9d0d54ec137cfd846e7ba239b1ced30976b7c4d89fde019edd1bce5dc8f0d649

View File

@ -1,6 +0,0 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86_64-windows-msvc-dynamic-debug-v20230819222922
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20230819222922/tpt-libs-prebuilt-x86_64-windows-msvc-dynamic-debug-v20230819222922.zip
source_filename = tpt-libs-prebuilt-x86_64-windows-msvc-dynamic-debug-v20230819222922.zip
source_hash = 699e2a315ee4b562304cb33a9594349afb3118a8c101f2f46c4d7d959e30939f

View File

@ -0,0 +1,6 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86_64-windows-msvc-dynamic-debug-v20231003175140
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20231003175140/tpt-libs-prebuilt-x86_64-windows-msvc-dynamic-debug-v20231003175140.zip
source_filename = tpt-libs-prebuilt-x86_64-windows-msvc-dynamic-debug-v20231003175140.zip
source_hash = abb58a981204af56aad5e4811fd79632f49f9feed219795324732ca83b4c1c2f

View File

@ -1,6 +0,0 @@
[wrap-file]
directory = tpt-libs-prebuilt-x86_64-windows-msvc-dynamic-release-v20230819222922
source_url = https://github.com/The-Powder-Toy/tpt-libs/releases/download/v20230819222922/tpt-libs-prebuilt-x86_64-windows-msvc-dynamic-release-v20230819222922.zip
source_filename = tpt-libs-prebuilt-x86_64-windows-msvc-dynamic-release-v20230819222922.zip
source_hash = 90aab0c8cabef2f917d4c28a1fbc4d412db72ebfe938273f4a83a02479d745b8

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