Compare commits

...

3 Commits

Author SHA1 Message Date
Logan McNaughton 6c2ae4dc5a update mac signing command (#801) 2026-04-23 20:01:01 +02:00
Logan McNaughton 0a884e85df Fix macos sandboxing (#800)
* Fix macos sandboxing

* more

* more

* more

* more

* more

* more

* more
2026-04-23 19:32:53 +02:00
Logan McNaughton 47098f60dd use timer for message lengths (#799)
* use timer for message lengths

* more

* more

* more

* more

* more

* more
2026-04-23 18:00:15 +02:00
18 changed files with 156 additions and 85 deletions
+10 -5
View File
@@ -64,7 +64,6 @@ jobs:
matrix.llvm }}.tar.xz
- name: Build
run: |
cargo build --no-default-features -v --target=${{ matrix.target }}
cargo build --release -v --target=${{ matrix.target }}
mkdir output
cp target/${{ matrix.target }}/release/gopher64 output/gopher64-${{ matrix.arch }}
@@ -114,7 +113,6 @@ jobs:
}}.exe
- name: Build
run: |
cargo build --no-default-features -v --target=${{ matrix.target }}
cargo build --release -v --target=${{ matrix.target }}
mkdir output
cp target/${{ matrix.target }}/release/gopher64.exe output/gopher64-${{ matrix.arch }}.exe
@@ -184,10 +182,14 @@ jobs:
run: |
cargo install cargo-bundle
brew install molten-vk
cargo build --no-default-features -v --target=${{ matrix.target }}
cargo build --release --no-default-features -v --target=${{ matrix.target }}
mv target/${{ matrix.target }}/release/gopher64 target/${{ matrix.target }}/release/gopher64-cli
cargo bundle --release --target=${{ matrix.target }} --format osx
cp target/${{ matrix.target }}/release/gopher64-cli target/${{ matrix.target }}/release/bundle/osx/Gopher64.app/Contents/MacOS/gopher64-cli
install_name_tool -change /opt/homebrew/opt/freetype/lib/libfreetype.6.dylib \
@executable_path/../Frameworks/libfreetype.6.dylib target/${{ matrix.target }}/release/bundle/osx/Gopher64.app/Contents/MacOS/gopher64
install_name_tool -change /opt/homebrew/opt/freetype/lib/libfreetype.6.dylib \
@executable_path/../Frameworks/libfreetype.6.dylib target/${{ matrix.target }}/release/bundle/osx/Gopher64.app/Contents/MacOS/gopher64-cli
install_name_tool -change /opt/homebrew/opt/libpng/lib/libpng16.16.dylib \
@executable_path/../Frameworks/libpng16.16.dylib target/${{ matrix.target }}/release/bundle/osx/Gopher64.app/Contents/Frameworks/libfreetype.6.dylib
env:
@@ -206,8 +208,11 @@ jobs:
- name: Sign Bundle Release
if: ${{ github.ref_type == 'tag' }}
run: |
cp data/macos/embedded.provisionprofile target/${{ matrix.target }}/release/bundle/osx/Gopher64.app/Contents/embedded.provisionprofile
codesign -f --entitlements data/macos/entitlements_prod.plist --deep --timestamp --options runtime -s "${{ secrets.APPLE_DEVELOPER_ID }}" target/${{ matrix.target }}/release/bundle/osx/Gopher64.app
codesign -f --timestamp --options runtime -s "${{ secrets.APPLE_DEVELOPER_ID }}" target/${{ matrix.target }}/release/bundle/osx/Gopher64.app/Contents/Frameworks/libpng16.16.dylib
codesign -f --timestamp --options runtime -s "${{ secrets.APPLE_DEVELOPER_ID }}" target/${{ matrix.target }}/release/bundle/osx/Gopher64.app/Contents/Frameworks/libfreetype.6.dylib
codesign -f --timestamp --options runtime -s "${{ secrets.APPLE_DEVELOPER_ID }}" target/${{ matrix.target }}/release/bundle/osx/Gopher64.app/Contents/Frameworks/libMoltenVK.dylib
codesign -f --entitlements data/macos/entitlements_child.plist --timestamp --options runtime -s "${{ secrets.APPLE_DEVELOPER_ID }}" target/${{ matrix.target }}/release/bundle/osx/Gopher64.app/Contents/MacOS/gopher64-cli
codesign -f --entitlements data/macos/entitlements_prod.plist --timestamp --options runtime -s "${{ secrets.APPLE_DEVELOPER_ID }}" target/${{ matrix.target }}/release/bundle/osx/Gopher64.app
zip -r gopher64-${{ matrix.arch }}.zip target/${{ matrix.target }}/release/bundle/osx/Gopher64.app
xcrun notarytool submit --wait --apple-id "${{ secrets.APPLE_ID }}" --team-id "${{ secrets.APPLE_DEVELOPER_ID }}" --password "${{ secrets.APPLE_APP_PASSWORD }}" gopher64-${{ matrix.arch }}.zip
xcrun stapler staple target/${{ matrix.target }}/release/bundle/osx/Gopher64.app
Generated
+26 -25
View File
@@ -2111,7 +2111,7 @@ dependencies = [
[[package]]
name = "gopher64"
version = "1.1.17"
version = "1.1.18"
dependencies = [
"bindgen",
"cc",
@@ -2400,11 +2400,12 @@ dependencies = [
[[package]]
name = "i-slint-backend-linuxkms"
version = "1.16.0"
version = "1.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "580bb55cd14cb12bd9169920661235797f4c8220318d0071e971fce345e28488"
checksum = "3224c3aa9f3ea568daf38389d0f7ace164eda4d6f1851042eb83750ac43e1a65"
dependencies = [
"calloop 0.14.4",
"cfg_aliases",
"drm",
"gbm",
"glutin",
@@ -2420,9 +2421,9 @@ dependencies = [
[[package]]
name = "i-slint-backend-selector"
version = "1.16.0"
version = "1.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ed4d0e693f83dbe68fea69b8ebebda8b245f34350d83e5f8fd62c0333d938b8"
checksum = "f93c9c4203e0a2c5c396b8f1686160816f73e9b9cadaf3915aa3b888a83448aa"
dependencies = [
"cfg-if",
"i-slint-backend-linuxkms",
@@ -2434,9 +2435,9 @@ dependencies = [
[[package]]
name = "i-slint-backend-winit"
version = "1.16.0"
version = "1.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90f7fddf48d12b366f352f8fb78d59665c490cf279786772f1d1592e143edd0d"
checksum = "f4df6ec88d452e3c22e418d20c96bc1ccbc9509e81e6596426d3388bf226a5f9"
dependencies = [
"accesskit",
"accesskit_winit",
@@ -2476,9 +2477,9 @@ dependencies = [
[[package]]
name = "i-slint-common"
version = "1.16.0"
version = "1.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f44bc19b68be0295354769bc456ccca1c8cb5a38c4cbb5566b0b3fdb918921b"
checksum = "40cae5cd0a81ce044029ac303256e025f98a4c59495b5189fc22b588da094e01"
dependencies = [
"derive_more",
"fontique",
@@ -2489,9 +2490,9 @@ dependencies = [
[[package]]
name = "i-slint-compiler"
version = "1.16.0"
version = "1.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dba63c5a2774a878478572a0b48b2af4895323d1dc969432c690362f0ab67d5c"
checksum = "a7b7f9834faf2a62cc36f01decc7c683e66bb0861b53511723c3da9ad914d9bb"
dependencies = [
"annotate-snippets",
"by_address",
@@ -2522,9 +2523,9 @@ dependencies = [
[[package]]
name = "i-slint-core"
version = "1.16.0"
version = "1.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8bac8ed92f61140aa03e426b28cd135e252c82891bc1ed88f2f799ba367f21c8"
checksum = "89e4a57afd78d8a1f599a78781dc1413af68545b2bc5ba5e143ecf022c75d5f3"
dependencies = [
"auto_enums",
"bitflags 2.11.1",
@@ -2570,9 +2571,9 @@ dependencies = [
[[package]]
name = "i-slint-core-macros"
version = "1.16.0"
version = "1.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "315b38ab2265294fedd11a578468ab146fd579a5765d68d42824a060a4772fc4"
checksum = "7931356d5238281e6be994ec15241fb2d9e66359776d53b4bd6b2fdd9c257c6e"
dependencies = [
"quote",
"serde_json",
@@ -2581,9 +2582,9 @@ dependencies = [
[[package]]
name = "i-slint-renderer-skia"
version = "1.16.0"
version = "1.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9cd39e5a129ba4c30d18159c344e756e81d4ea2d0ab3dc5c9834d47339d3e580"
checksum = "d4030ff9eeb1b99fdf9b47472f3a7a582f3bcb57207c9bc07505dc6998abdcbc"
dependencies = [
"bytemuck",
"cfg-if",
@@ -2618,9 +2619,9 @@ dependencies = [
[[package]]
name = "i-slint-renderer-software"
version = "1.16.0"
version = "1.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a8fa9e24ad40900de052eda07ee1dbbe0d66efcb25742d81296b1ba9d28c9d0"
checksum = "ee8a21285f3a81a8e1b1e7c385eefe89bf9487f53fabfd5b238c68bc895d6013"
dependencies = [
"bytemuck",
"clru",
@@ -5340,9 +5341,9 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
[[package]]
name = "slint"
version = "1.16.0"
version = "1.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "364a1e8fae7f1969224acc59ba729f06aeaf808123796389eae458c396119ef0"
checksum = "d46bc502cc6b113bfd1a7e9a0876532a9454ff4ee905afe09784eaa2ec3f3f33"
dependencies = [
"const-field-offset",
"i-slint-backend-selector",
@@ -5361,9 +5362,9 @@ dependencies = [
[[package]]
name = "slint-build"
version = "1.16.0"
version = "1.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec94124d27a1b691fd8613c653bae47ece44cb469af11ce0edf645acf458ae61"
checksum = "a73854b9adf81fa1600b46df488ffc3796400e8e9b40d504a94a36b55c8f3d0a"
dependencies = [
"derive_more",
"fontique",
@@ -5374,9 +5375,9 @@ dependencies = [
[[package]]
name = "slint-macros"
version = "1.16.0"
version = "1.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2f2659f0896ccf5921a1b0af835c4d5285a3292bfcf36cb9bf9e4fbcbe874fc"
checksum = "6d5884e06072c329da7096ad1367eb83b98c78e5313f7ac90d66f90d4acc62ee"
dependencies = [
"i-slint-compiler",
"proc-macro2",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "gopher64"
version = "1.1.17"
version = "1.1.18"
edition = "2024"
rust-version = "1.95.0"
Binary file not shown.
+10
View File
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.inherit</key>
<true/>
</dict>
</plist>
+27 -22
View File
@@ -82,6 +82,7 @@ typedef struct {
typedef struct {
std::string message;
uint64_t milliseconds;
Vulkan::ImageHandle image;
} Message;
@@ -102,7 +103,6 @@ uint64_t sync_signal;
static TTF_Font *message_font;
static std::queue<Message> messages;
static uint64_t message_timer;
static TTF_Font *achievement_challenge_indicator_font;
static std::vector<const char *> achievement_challenge_indicators;
@@ -114,8 +114,6 @@ static bool display_challenge_indicator;
static bool display_fps;
static Vulkan::ImageHandle fps_image;
#define MESSAGE_TIME 3000 // 3 seconds
typedef struct {
float SourceSize[4];
float OutputSize[4];
@@ -169,7 +167,7 @@ bool sdl_event_filter(void *userdata, SDL_Event *event) {
break;
case SDL_SCANCODE_F8:
if (messages.empty())
SDL_RunOnMainThread(ra_display_inprogress_achievements, nullptr, true);
SDL_RunOnMainThread(ra_display_inprogress_achievements, nullptr, false);
break;
case SDL_SCANCODE_F9:
display_challenge_indicator = !display_challenge_indicator;
@@ -177,7 +175,7 @@ bool sdl_event_filter(void *userdata, SDL_Event *event) {
std::format("Challenge indicators: {}",
display_challenge_indicator ? "ON" : "OFF")
.c_str(),
false);
MESSAGE_SHORT);
break;
case SDL_SCANCODE_F12:
callback.reset_game = true;
@@ -334,7 +332,6 @@ void rdp_init(void *_window, GFX_INFO _gfx_info, const void *font,
crop_letterbox = false;
messages = std::queue<Message>();
message_timer = 0;
display_challenge_indicator = true;
achievement_challenge_indicators.clear();
@@ -444,6 +441,13 @@ static void draw_fps(CommandBufferHandle cmd, VkViewport vp) {
cmd->draw(3);
}
static void pop_message(void *userdata) { messages.pop(); }
static uint32_t pop_message_callback(void *userdata, SDL_TimerID timerID,
uint32_t interval) {
SDL_RunOnMainThread(pop_message, NULL, false);
return 0;
}
static void render_frame(Vulkan::Device &device) {
RDP::ScanoutOptions options = {};
options.persist_frame_on_invalid_input = true;
@@ -519,6 +523,7 @@ static void render_frame(Vulkan::Device &device) {
if (!message->image) {
message->image = create_message_image(device, vp.width, message_font,
message->message.c_str());
SDL_AddTimer(message->milliseconds, pop_message_callback, NULL);
}
cmd->set_texture(0, 0, message->image->get_view(),
Vulkan::StockSampler::NearestClamp);
@@ -529,11 +534,6 @@ static void render_frame(Vulkan::Device &device) {
cmd->set_viewport(vp);
cmd->draw(3);
if (SDL_GetTicks() > message_timer) {
messages.pop();
message_timer = SDL_GetTicks() + MESSAGE_TIME;
}
} else if (achievement_progress_indicator_image) {
draw_indicator(cmd, achievement_progress_indicator_image, vp);
} else if (achievement_challenge_indicator_image &&
@@ -608,16 +608,18 @@ void rdp_load_state(const uint8_t *state) {
memcpy(&rdp_device, state, sizeof(RDP_DEVICE));
}
static void push_onscreen_message(void *message) {
if (messages.empty())
message_timer = SDL_GetTicks() + MESSAGE_TIME;
messages.push({std::string((const char *)message), Vulkan::ImageHandle()});
static void push_onscreen_message(void *data) {
Message *message = (Message *)data;
messages.push(*message);
delete message;
}
void rdp_onscreen_message(const char *message, bool long_message) {
SDL_RunOnMainThread(push_onscreen_message, (void *)message, true);
if (long_message)
SDL_RunOnMainThread(push_onscreen_message, (void *)message, true);
void rdp_onscreen_message(const char *message, MESSAGE_LENGTH milliseconds) {
Message *data = new Message;
data->message = message;
data->milliseconds = static_cast<uint64_t>(milliseconds);
data->image = Vulkan::ImageHandle();
SDL_RunOnMainThread(push_onscreen_message, data, false);
}
uint32_t pixel_size(uint32_t pixel_type, uint32_t area) {
@@ -849,17 +851,20 @@ uint64_t rdp_process_commands() {
return interrupt_timer;
}
void rdp_set_fps_callback(void *userdata) {
static void rdp_set_fps_callback(void *userdata) {
FPS_DATA *data = (FPS_DATA *)userdata;
fps_image = create_message_image(
wsi->get_device(), 0, achievement_challenge_indicator_font,
std::format("FPS: {} VI/S: {}", data->fps, data->vis).c_str());
delete data;
}
void rdp_set_fps(uint32_t fps, uint32_t vis) {
if (display_fps) {
FPS_DATA data = {fps, vis};
SDL_RunOnMainThread(rdp_set_fps_callback, &data, true);
FPS_DATA *data = new FPS_DATA;
data->fps = fps;
data->vis = vis;
SDL_RunOnMainThread(rdp_set_fps_callback, data, false);
}
}
+7 -1
View File
@@ -37,6 +37,12 @@ typedef struct {
uint32_t save_state_slot;
} CALL_BACK;
typedef enum {
MESSAGE_VERY_SHORT = 500,
MESSAGE_SHORT = 3000,
MESSAGE_LONG = 6000,
} MESSAGE_LENGTH;
void rdp_init(void *_window, GFX_INFO _gfx_info, const void *font,
size_t font_size, uint32_t save_state_slot);
void rdp_close();
@@ -45,7 +51,7 @@ void rdp_update_screen();
void rdp_render_frame();
CALL_BACK rdp_check_callback();
uint64_t rdp_process_commands();
void rdp_onscreen_message(const char *message, bool long_message);
void rdp_onscreen_message(const char *message, MESSAGE_LENGTH milliseconds);
void rdp_new_processor(GFX_INFO _gfx_info);
void rdp_check_framebuffers(uint32_t address, uint32_t length);
size_t rdp_state_size();
+8 -8
View File
@@ -137,7 +137,7 @@ void ra_welcome() {
char *error_message = rc_client_get_userdata(g_client);
if (error_message) {
snprintf(buffer, sizeof(buffer), "RA Error: %s", error_message);
rdp_onscreen_message(buffer, true);
rdp_onscreen_message(buffer, MESSAGE_LONG);
free(error_message);
rc_client_set_userdata(g_client, NULL);
return;
@@ -160,7 +160,7 @@ void ra_welcome() {
snprintf(buffer + message_length, sizeof(buffer) - message_length,
"Game has no achievements");
}
rdp_onscreen_message(buffer, true);
rdp_onscreen_message(buffer, MESSAGE_LONG);
}
void ra_load_game(const uint8_t *rom, size_t rom_size, void *userdata) {
@@ -187,14 +187,14 @@ static void leaderboard_submitted(const rc_client_leaderboard_t *leaderboard) {
snprintf(buffer, sizeof(buffer), "Leaderboard submitted: %s - %s",
leaderboard->title, leaderboard->tracker_value);
rdp_onscreen_message(buffer, false);
rdp_onscreen_message(buffer, MESSAGE_SHORT);
}
static void achievement_triggered(const rc_client_achievement_t *achievement) {
char buffer[512];
snprintf(buffer, sizeof(buffer), "Unlocked: %s", achievement->title);
rdp_onscreen_message(buffer, false);
rdp_onscreen_message(buffer, MESSAGE_SHORT);
}
static void game_completed(rc_client_t *client) {
@@ -204,7 +204,7 @@ static void game_completed(rc_client_t *client) {
snprintf(buffer, sizeof(buffer), "%s: %s",
rc_client_get_hardcore_enabled(client) ? "Mastered" : "Completed",
game->title);
rdp_onscreen_message(buffer, false);
rdp_onscreen_message(buffer, MESSAGE_SHORT);
}
static void subset_completed(const rc_client_subset_t *subset,
@@ -214,7 +214,7 @@ static void subset_completed(const rc_client_subset_t *subset,
snprintf(buffer, sizeof(buffer), "Subset %s: %s",
rc_client_get_hardcore_enabled(client) ? "mastered" : "completed",
subset->title);
rdp_onscreen_message(buffer, false);
rdp_onscreen_message(buffer, MESSAGE_SHORT);
}
static void server_error(const rc_client_server_error_t *server_error) {
@@ -222,7 +222,7 @@ static void server_error(const rc_client_server_error_t *server_error) {
snprintf(buffer, sizeof(buffer), "RA server error: %s",
server_error->error_message);
rdp_onscreen_message(buffer, false);
rdp_onscreen_message(buffer, MESSAGE_SHORT);
}
static const char *get_leaderboard_title(const char *display) {
@@ -393,7 +393,7 @@ void ra_display_inprogress_achievements(void *userdata) {
}
}
if (buffer_length > 0) {
rdp_onscreen_message(buffer, false);
rdp_onscreen_message(buffer, MESSAGE_SHORT);
}
rc_client_destroy_achievement_list(list);
}
+1 -1
View File
@@ -79,7 +79,7 @@ pub fn init(
if !device.cheats.cheats.is_empty() {
device.cheats.enabled = true;
ui::video::onscreen_message("Cheats enabled", false);
ui::video::onscreen_message("Cheats enabled", ui::video::MESSAGE_LENGTH_MESSAGE_SHORT);
}
}
+12 -3
View File
@@ -190,21 +190,30 @@ pub fn pak_switch_event(device: &mut device::Device) {
write: device::controller::mempak::write,
pak_type: new_pak_type,
});
ui::video::onscreen_message("MemPak selected", false);
ui::video::onscreen_message(
"MemPak selected",
ui::video::MESSAGE_LENGTH_MESSAGE_SHORT,
);
} else if new_pak_type == PakType::RumblePak {
channel.pak_handler = Some(device::controller::PakHandler {
read: device::controller::rumble::read,
write: device::controller::rumble::write,
pak_type: new_pak_type,
});
ui::video::onscreen_message("RumblePak selected", false);
ui::video::onscreen_message(
"RumblePak selected",
ui::video::MESSAGE_LENGTH_MESSAGE_SHORT,
);
} else if new_pak_type == PakType::TransferPak {
channel.pak_handler = Some(device::controller::PakHandler {
read: device::controller::transferpak::read,
write: device::controller::transferpak::write,
pak_type: new_pak_type,
});
ui::video::onscreen_message("TransferPak selected", false);
ui::video::onscreen_message(
"TransferPak selected",
ui::video::MESSAGE_LENGTH_MESSAGE_SHORT,
);
}
channel.change_pak = PakType::None;
}
+4 -1
View File
@@ -227,7 +227,10 @@ pub fn init(device: &mut device::Device) {
device.cpu.clock_rate = if !device.cpu.overclock {
93750000
} else {
ui::video::onscreen_message("Overclocking enabled, setting clock rate to 125 MHz", false);
ui::video::onscreen_message(
"Overclocking enabled, setting clock rate to 125 MHz",
ui::video::MESSAGE_LENGTH_MESSAGE_SHORT,
);
125000000
};
+1 -1
View File
@@ -166,7 +166,7 @@ pub fn reset_event(device: &mut device::Device) {
device::pif::reset_pif(device, true);
ui::video::onscreen_message("Game reset", false);
ui::video::onscreen_message("Game reset", ui::video::MESSAGE_LENGTH_MESSAGE_SHORT);
}
fn exception_general(device: &mut device::Device, vector_offset: u32) {
+4 -1
View File
@@ -150,7 +150,10 @@ pub fn vertical_interrupt_event(device: &mut device::Device) {
if device.netplay.is_none() && paused {
if retroachievements::get_hardcore() {
ui::video::onscreen_message("Cannot pause in RA hardcore mode", false);
ui::video::onscreen_message(
"Cannot pause in RA hardcore mode",
ui::video::MESSAGE_LENGTH_MESSAGE_SHORT,
);
} else {
ui::video::pause_loop(device.vi.frame_time);
}
+9 -3
View File
@@ -146,7 +146,10 @@ pub fn get_input(device: &mut device::Device, channel: usize) -> ui::input::Inpu
.remove(&netplay.player_data[channel].count);
if std::time::Instant::now() > timeout {
ui::video::onscreen_message("Lost connection to netplay server", false);
ui::video::onscreen_message(
"Lost connection to netplay server",
ui::video::MESSAGE_LENGTH_MESSAGE_SHORT,
);
input = Some(InputEvent {
input: 0,
plugin: 0,
@@ -191,14 +194,17 @@ fn process_incoming(netplay: &mut Netplay) {
}
if current_status != netplay.status {
if ((current_status & 0x1) ^ (netplay.status & 0x1)) != 0 {
ui::video::onscreen_message("Netplay desync detected", true);
ui::video::onscreen_message(
"Netplay desync detected",
ui::video::MESSAGE_LENGTH_MESSAGE_LONG,
);
}
for dis in 1..5 {
if ((current_status & (0x1 << dis)) ^ (netplay.status & (0x1 << dis))) != 0
{
ui::video::onscreen_message(
&format!("Player {dis} disconnected"),
false,
ui::video::MESSAGE_LENGTH_MESSAGE_SHORT,
);
}
}
+8 -5
View File
@@ -95,13 +95,16 @@ pub fn create_savestate(device: &device::Device) {
"Savestate created in slot {}",
device.ui.storage.save_state_slot
),
false,
ui::video::MESSAGE_LENGTH_MESSAGE_SHORT,
);
}
pub fn load_savestate(device: &mut device::Device) {
if retroachievements::get_hardcore() {
ui::video::onscreen_message("Cannot load savestate in RA hardcore mode", false);
ui::video::onscreen_message(
"Cannot load savestate in RA hardcore mode",
ui::video::MESSAGE_LENGTH_MESSAGE_SHORT,
);
return;
}
let savestate = std::fs::read(&device.ui.storage.paths.savestate_file_path);
@@ -216,7 +219,7 @@ pub fn load_savestate(device: &mut device::Device) {
"Savestate loaded from slot {}",
device.ui.storage.save_state_slot
),
false,
ui::video::MESSAGE_LENGTH_MESSAGE_SHORT,
);
} else {
ui::video::onscreen_message(
@@ -224,7 +227,7 @@ pub fn load_savestate(device: &mut device::Device) {
"Failed to load savestate from slot {}",
device.ui.storage.save_state_slot
),
false,
ui::video::MESSAGE_LENGTH_MESSAGE_SHORT,
);
}
} else {
@@ -233,7 +236,7 @@ pub fn load_savestate(device: &mut device::Device) {
"Could not find savestate in slot {}",
device.ui.storage.save_state_slot
),
false,
ui::video::MESSAGE_LENGTH_MESSAGE_SHORT,
);
}
}
+2 -2
View File
@@ -55,7 +55,7 @@ pub fn lower_audio_volume(ui: &mut ui::Ui) {
}
ui::video::onscreen_message(
&format!("Audio volume: {:.0}%", ui.audio.gain * 100.0),
false,
ui::video::MESSAGE_LENGTH_MESSAGE_VERY_SHORT,
);
}
@@ -69,7 +69,7 @@ pub fn raise_audio_volume(ui: &mut ui::Ui) {
}
ui::video::onscreen_message(
&format!("Audio volume: {:.0}%", ui.audio.gain * 100.0),
false,
ui::video::MESSAGE_LENGTH_MESSAGE_VERY_SHORT,
);
}
+22 -3
View File
@@ -321,8 +321,17 @@ fn controller_window(
let deadzone = handle.get_deadzone();
tokio::spawn(async move {
let mut command =
tokio::process::Command::new(std::env::current_exe().unwrap());
let cli_path = std::env::current_exe()
.unwrap()
.parent()
.unwrap()
.join(format!("{}-cli", env!("CARGO_PKG_NAME")));
let cmd_path = if cfg!(target_os = "macos") && cli_path.exists() {
cli_path
} else {
std::env::current_exe().unwrap()
};
let mut command = tokio::process::Command::new(cmd_path);
command.args([
"--configure-input-profile",
&profile_name,
@@ -485,7 +494,17 @@ pub fn run_rom(
weak.upgrade_in_event_loop(move |handle| handle.set_game_running(true))
.unwrap();
let mut command = tokio::process::Command::new(std::env::current_exe().unwrap());
let cli_path = std::env::current_exe()
.unwrap()
.parent()
.unwrap()
.join(format!("{}-cli", env!("CARGO_PKG_NAME")));
let cmd_path = if cfg!(target_os = "macos") && cli_path.exists() {
cli_path
} else {
std::env::current_exe().unwrap()
};
let mut command = tokio::process::Command::new(cmd_path);
command.args([
"--overclock",
&game_settings.overclock.to_string(),
+4 -3
View File
@@ -1,4 +1,5 @@
#![allow(non_snake_case)]
#![allow(non_camel_case_types)]
include!(concat!(env!("OUT_DIR"), "/parallel_bindings.rs"));
use crate::{device, retroachievements, ui};
@@ -215,7 +216,7 @@ pub fn check_callback(device: &mut device::Device) -> (bool, bool) {
if device.ui.storage.save_state_slot != callback.save_state_slot {
onscreen_message(
&format!("Switching savestate slot to {}", callback.save_state_slot),
false,
ui::video::MESSAGE_LENGTH_MESSAGE_SHORT,
);
device.ui.storage.save_state_slot = callback.save_state_slot;
device
@@ -247,10 +248,10 @@ pub fn check_framebuffers(address: u32, length: u32) {
unsafe { rdp_check_framebuffers(address, length) }
}
pub fn onscreen_message(message: &str, long_message: bool) {
pub fn onscreen_message(message: &str, milliseconds: MESSAGE_LENGTH) {
unsafe {
let c_message = std::ffi::CString::new(message).unwrap();
rdp_onscreen_message(c_message.as_ptr(), long_message)
rdp_onscreen_message(c_message.as_ptr(), milliseconds)
};
}