Skip to content

Commit dd5849c

Browse files
committed
Add game speed controls to the embedded game window
1 parent fc523ec commit dd5849c

File tree

6 files changed

+134
-2
lines changed

6 files changed

+134
-2
lines changed

core/config/engine.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,18 @@
3838
#include "core/version.h"
3939
#include "servers/rendering/rendering_device.h"
4040

41+
void Engine::_update_time_scale() {
42+
double wanted_time_scale = time_scale_override_enabled
43+
? time_scale_override * time_scale_base
44+
: time_scale_base;
45+
46+
if (_time_scale == wanted_time_scale) {
47+
return;
48+
}
49+
50+
_time_scale = wanted_time_scale;
51+
}
52+
4153
void Engine::set_physics_ticks_per_second(int p_ips) {
4254
ERR_FAIL_COND_MSG(p_ips <= 0, "Engine iterations per second must be greater than 0.");
4355
ips = p_ips;
@@ -113,6 +125,11 @@ uint32_t Engine::get_frame_delay() const {
113125

114126
void Engine::set_time_scale(double p_scale) {
115127
_time_scale = p_scale;
128+
if (time_scale_base == p_scale) {
129+
return;
130+
}
131+
time_scale_base = p_scale;
132+
_update_time_scale();
116133
}
117134

118135
double Engine::get_time_scale() const {
@@ -404,6 +421,38 @@ bool Engine::is_embedded_in_editor() const {
404421
return embedded_in_editor;
405422
}
406423

424+
void Engine::set_time_scale_base(double p_scale) {
425+
print_line(p_scale);
426+
time_scale_base = p_scale;
427+
}
428+
429+
void Engine::set_time_scale_override(double p_scale) {
430+
print_line("p_scale", p_scale);
431+
if (time_scale_override == p_scale) {
432+
return;
433+
}
434+
time_scale_override = p_scale;
435+
if (is_time_scale_override_enabled()) {
436+
_update_time_scale();
437+
}
438+
}
439+
440+
double Engine::get_time_scale_override() {
441+
return time_scale_override;
442+
}
443+
444+
void Engine::set_time_scale_override_enabled(bool p_enabled) {
445+
if (time_scale_override_enabled == p_enabled) {
446+
return;
447+
}
448+
time_scale_override_enabled = p_enabled;
449+
_update_time_scale();
450+
}
451+
452+
bool Engine::is_time_scale_override_enabled() {
453+
return time_scale_override_enabled;
454+
}
455+
407456
Engine::Engine() {
408457
singleton = this;
409458
}

core/config/engine.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,13 @@ class Engine {
101101

102102
bool freeze_time_scale = false;
103103

104+
double time_scale_base;
105+
double time_scale_override;
106+
bool time_scale_override_enabled;
107+
108+
protected:
109+
void _update_time_scale();
110+
104111
public:
105112
static Engine *get_singleton();
106113

@@ -210,6 +217,12 @@ class Engine {
210217
void set_embedded_in_editor(bool p_enabled);
211218
bool is_embedded_in_editor() const;
212219

220+
void set_time_scale_override(double p_scale);
221+
void set_time_scale_base(double p_scale);
222+
double get_time_scale_override();
223+
void set_time_scale_override_enabled(bool p_enabled);
224+
bool is_time_scale_override_enabled();
225+
213226
Engine();
214227
virtual ~Engine();
215228
};

editor/plugins/game_view_plugin.cpp

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,6 @@ void GameView::_sessions_changed() {
240240
active_sessions++;
241241
}
242242
}
243-
244243
_update_debugger_buttons();
245244

246245
#ifdef MACOS_ENABLED
@@ -419,6 +418,7 @@ void GameView::_update_debugger_buttons() {
419418

420419
suspend_button->set_disabled(empty);
421420
camera_override_button->set_disabled(empty);
421+
speed_state_button->set_disabled(empty);
422422

423423
PopupMenu *menu = camera_override_menu->get_popup();
424424

@@ -431,6 +431,9 @@ void GameView::_update_debugger_buttons() {
431431
camera_override_button->set_pressed(false);
432432
}
433433
next_frame_button->set_disabled(!suspend_button->is_pressed());
434+
435+
time_scale_index = DEFUALT_TIME_SCALE_INDEX;
436+
_update_time_scales();
434437
}
435438

436439
void GameView::_handle_shortcut_requested(int p_embed_action) {
@@ -511,6 +514,37 @@ void GameView::_size_mode_button_pressed(int size_mode) {
511514
_update_embed_window_size();
512515
}
513516

517+
void GameView::_update_time_scales() {
518+
Array message;
519+
message.append(time_scale_index != DEFUALT_TIME_SCALE_INDEX);
520+
message.append(time_scale_range[time_scale_index]);
521+
Array sessions = debugger->get_sessions();
522+
for (int i = 0; i < sessions.size(); i++) {
523+
if (Object::cast_to<EditorDebuggerSession>(sessions[i])->is_active()) {
524+
Ref<EditorDebuggerSession> session = sessions[i];
525+
session->send_message("scene:speed_changed", message);
526+
}
527+
}
528+
Color text_color;
529+
if (time_scale_index == DEFUALT_TIME_SCALE_INDEX) {
530+
text_color = Color(1.0f, 1.0f, 1.0f);
531+
} else if (time_scale_index > DEFUALT_TIME_SCALE_INDEX) {
532+
text_color = Color(0.0f, 1.0f, 0.0f);
533+
} else if (time_scale_index < DEFUALT_TIME_SCALE_INDEX) {
534+
text_color = Color(1.0f, 1.0f, 0.0f);
535+
}
536+
speed_state_button->add_theme_color_override("font_color", text_color);
537+
speed_state_button->set_text(vformat("%0.2fx", time_scale_range[time_scale_index]));
538+
}
539+
540+
void GameView::_speed_state_menu_pressed(int p_id) {
541+
if (time_scale_index == p_id) {
542+
return;
543+
}
544+
time_scale_index = p_id;
545+
_update_time_scales();
546+
}
547+
514548
GameView::EmbedAvailability GameView::_get_embed_available() {
515549
if (!DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_WINDOW_EMBEDDING)) {
516550
return EMBED_NOT_AVAILABLE_FEATURE_NOT_SUPPORTED;
@@ -995,6 +1029,20 @@ GameView::GameView(Ref<GameViewDebugger> p_debugger, EmbeddedProcessBase *p_embe
9951029
next_frame_button->set_accessibility_name(TTRC("Next Frame"));
9961030
next_frame_button->set_shortcut(ED_SHORTCUT("editor/next_frame_embedded_project", TTRC("Next Frame"), Key::F10));
9971031

1032+
speed_state_button = memnew(MenuButton);
1033+
main_menu_hbox->add_child(speed_state_button);
1034+
speed_state_button->set_text(TTRC("1.00x"));
1035+
speed_state_button->set_theme_type_variation("FlatButton");
1036+
speed_state_button->set_tooltip_text(TTRC("Reset the game speed."));
1037+
speed_state_button->set_accessibility_name(TTRC("Speed State"));
1038+
speed_state_button->set_custom_minimum_size(Vector2(48, 0));
1039+
1040+
PopupMenu *menu = speed_state_button->get_popup();
1041+
menu->connect(SceneStringName(id_pressed), callable_mp(this, &GameView::_speed_state_menu_pressed));
1042+
for (float f : time_scale_range) {
1043+
menu->add_item(TTRC(vformat("%0.2fx", f)));
1044+
}
1045+
9981046
main_menu_hbox->add_child(memnew(VSeparator));
9991047

10001048
node_type_button[RuntimeNodeSelect::NODE_TYPE_NONE] = memnew(Button);
@@ -1079,7 +1127,7 @@ GameView::GameView(Ref<GameViewDebugger> p_debugger, EmbeddedProcessBase *p_embe
10791127
camera_override_menu->set_tooltip_text(TTRC("Camera Override Options"));
10801128
camera_override_menu->set_accessibility_name(TTRC("Camera Override Options"));
10811129

1082-
PopupMenu *menu = camera_override_menu->get_popup();
1130+
menu = camera_override_menu->get_popup();
10831131
menu->connect(SceneStringName(id_pressed), callable_mp(this, &GameView::_camera_override_menu_id_pressed));
10841132
menu->add_item(TTRC("Reset 2D Camera"), CAMERA_RESET_2D);
10851133
menu->add_item(TTRC("Reset 3D Camera"), CAMERA_RESET_3D);

editor/plugins/game_view_plugin.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,12 @@ class GameView : public VBoxContainer {
157157
EmbeddedProcessBase *embedded_process = nullptr;
158158
Label *state_label = nullptr;
159159

160+
int const DEFUALT_TIME_SCALE_INDEX = 5;
161+
Array time_scale_range = { 0.0625f, 0.125f, 0.25f, 0.5f, 0.75f, 1.0f, 1.25f, 1.5f, 1.75f, 2.0f, 4.0f, 8.0f, 16.0f };
162+
int time_scale_index = DEFUALT_TIME_SCALE_INDEX;
163+
164+
MenuButton *speed_state_button = nullptr;
165+
160166
void _sessions_changed();
161167

162168
void _update_debugger_buttons();
@@ -170,6 +176,9 @@ class GameView : public VBoxContainer {
170176
void _embed_options_menu_menu_id_pressed(int p_id);
171177
void _size_mode_button_pressed(int size_mode);
172178

179+
void _update_time_scales();
180+
void _speed_state_menu_pressed(int p_id);
181+
173182
void _play_pressed();
174183
static void _instance_starting_static(int p_idx, List<String> &r_arguments);
175184
void _instance_starting(int p_idx, List<String> &r_arguments);

scene/debugger/scene_debugger.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,17 @@ Error SceneDebugger::_msg_next_frame(const Array &p_args) {
183183
return OK;
184184
}
185185

186+
Error SceneDebugger::_msg_speed_changed(const Array &p_args) {
187+
bool enabled = Engine::get_singleton()->is_time_scale_override_enabled();
188+
double time_scale = Engine::get_singleton()->get_time_scale();
189+
if (!enabled) {
190+
Engine::get_singleton()->set_time_scale_base(time_scale);
191+
}
192+
Engine::get_singleton()->set_time_scale_override_enabled(p_args[0]);
193+
Engine::get_singleton()->set_time_scale_override(p_args[1]);
194+
return OK;
195+
}
196+
186197
Error SceneDebugger::_msg_debug_mute_audio(const Array &p_args) {
187198
ERR_FAIL_COND_V(p_args.is_empty(), ERR_INVALID_DATA);
188199
bool do_mute = p_args[0];
@@ -457,6 +468,7 @@ void SceneDebugger::_init_message_handlers() {
457468
message_handlers["clear_selection"] = _msg_clear_selection;
458469
message_handlers["suspend_changed"] = _msg_suspend_changed;
459470
message_handlers["next_frame"] = _msg_next_frame;
471+
message_handlers["speed_changed"] = _msg_speed_changed;
460472
message_handlers["debug_mute_audio"] = _msg_debug_mute_audio;
461473
message_handlers["override_cameras"] = _msg_override_cameras;
462474
message_handlers["transform_camera_2d"] = _msg_transform_camera_2d;

scene/debugger/scene_debugger.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ class SceneDebugger {
8686
static Error _msg_clear_selection(const Array &p_args);
8787
static Error _msg_suspend_changed(const Array &p_args);
8888
static Error _msg_next_frame(const Array &p_args);
89+
static Error _msg_speed_changed(const Array &p_args);
8990
static Error _msg_debug_mute_audio(const Array &p_args);
9091
static Error _msg_override_cameras(const Array &p_args);
9192
static Error _msg_transform_camera_2d(const Array &p_args);

0 commit comments

Comments
 (0)