Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 34 additions & 23 deletions vm-rust/src/player/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use super::{
keyboard_events::{player_key_down, player_key_up},
player_alloc_datum, player_call_script_handler, player_dispatch_global_event,
player_is_playing, reserve_player_mut, reserve_player_ref,
score::{concrete_sprite_hit_test, get_concrete_sprite_rect, get_sprite_at},
score::{concrete_sprite_hit_test, get_concrete_sprite_rect, get_interactable_sprite_at, get_sprite_at},
PlayerVMExecutionItem, ScriptError, ScriptReceiver, PLAYER_TX,
};

Expand Down Expand Up @@ -692,33 +692,44 @@ pub async fn run_player_command(command: PlayerVMCommand) -> Result<DatumRef, Sc
}

let hovered_sprite = player.hovered_sprite;
let sprite_num = get_sprite_at(player, x, y, false);
if let Some(sprite_num) = sprite_num {
player.hovered_sprite = Some(sprite_num as i16);
}
let sprite_num = get_interactable_sprite_at(player, x, y);
player.hovered_sprite = sprite_num.map(|n| n as i16);
(sprite_num, hovered_sprite)
});
if let Some(sprite_num) = sprite_num {
let hovered_sprite = hovered_sprite.unwrap_or(-1);
if hovered_sprite != sprite_num as i16 {
if hovered_sprite != -1 {
match sprite_num {
Some(sprite_num) => {
let prev = hovered_sprite.unwrap_or(-1);
if prev != sprite_num as i16 {
if prev != -1 {
player_dispatch_event_to_sprite(
&"mouseLeave".to_string(),
&vec![],
prev as u16,
);
}
player_dispatch_event_to_sprite(
&"mouseLeave".to_string(),
&"mouseEnter".to_string(),
&vec![],
hovered_sprite as u16,
)
sprite_num as u16,
);
} else {
player_dispatch_event_to_sprite(
&"mouseWithin".to_string(),
&vec![],
sprite_num as u16,
);
}
}
None => {
if let Some(prev) = hovered_sprite {
if prev != -1 {
player_dispatch_event_to_sprite(
&"mouseLeave".to_string(),
&vec![],
prev as u16,
);
}
}
player_dispatch_event_to_sprite(
&"mouseEnter".to_string(),
&vec![],
sprite_num as u16,
);
} else {
player_dispatch_event_to_sprite(
&"mouseWithin".to_string(),
&vec![],
sprite_num as u16,
);
}
}
}
Expand Down
45 changes: 39 additions & 6 deletions vm-rust/src/player/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -593,12 +593,20 @@ pub async fn player_dispatch_event_beginsprite(
return Ok(Vec::new());
}

if frame_instances.len() > 0 {
let _ = player_invoke_frame_and_movie_scripts(
handler_name,
args,
)
.await;
// Dispatch beginSprite to channel 0 (frame script) behavior instances directly
for (_channel_number, behavior) in frame_instances {
let receivers = vec![behavior.clone()];
if let Err(err) = player_invoke_targeted_event(handler_name, args, Some(receivers).as_ref()).await {
if err.code == ScriptErrorCode::Abort {
return Ok(vec![]);
}
web_sys::console::error_1(
&format!("Error in {} for frame script: {}", handler_name, err.message).into()
);
reserve_player_mut(|player| {
player.on_script_error(&err);
});
}
}

// Dispatch to sprite behaviors (number > 0)
Expand Down Expand Up @@ -862,6 +870,31 @@ pub async fn dispatch_event_to_all_behaviors(
player.current_score_context = ScoreRef::Stage;
});
}

// Dispatch to channel 0 (frame script) behaviors
// Per ScummVM, the script channel instance receives frame events (enterFrame/exitFrame)
// but NOT sprite events (beginSprite/endSprite).
for (_channel_number, behaviors) in frame_behaviors {
for behavior in behaviors {
let receivers = vec![behavior.clone()];
if let Err(err) = player_invoke_event_to_instances(handler_name, args, &receivers).await {
if err.code == ScriptErrorCode::Abort {
reserve_player_mut(|player| {
player.is_dispatching_events = false;
player.current_score_context = ScoreRef::Stage;
});
return;
}
web_sys::console::error_1(
&format!("Error in {} for frame script: {}", handler_name, err.message).into()
);
reserve_player_mut(|player| {
player.on_script_error(&err);
});
}
}
}

// Dispatch event to frame/movie scripts
if let Err(err) = player_invoke_frame_and_movie_scripts(handler_name, args).await {
if err.code != ScriptErrorCode::Abort {
Expand Down
Loading