Add support for two different inverse modes

- Inverse mode invert (default) will invert the color in shader.
- Inverse mode swap will simply swap the foreground and background
  colors. This is the default behavior of libtsm and GodotXterm v3.
This commit is contained in:
Leroy Hopson 2024-02-07 23:03:11 +13:00
parent 930f3ef352
commit 8c30bec861
No known key found for this signature in database
GPG key ID: D2747312A6DB51AA
3 changed files with 41 additions and 1 deletions

View file

@ -31,6 +31,14 @@ void Terminal::_bind_methods()
ClassDB::bind_method(D_METHOD("set_max_scrollback", "max_scrollback"), &Terminal::set_max_scrollback);
ClassDB::add_property("Terminal", PropertyInfo(Variant::INT, "max_scrollback"), "set_max_scrollback", "get_max_scrollback");
// Inverse mode.
BIND_ENUM_CONSTANT(INVERSE_MODE_INVERT);
BIND_ENUM_CONSTANT(INVERSE_MODE_SWAP);
ClassDB::bind_method(D_METHOD("get_inverse_mode"), &Terminal::get_inverse_mode);
ClassDB::bind_method(D_METHOD("set_inverse_mode", "inverse_mode"), &Terminal::set_inverse_mode);
ClassDB::add_property("Terminal", PropertyInfo(Variant::INT, "inverse_mode", PROPERTY_HINT_ENUM, "Invert,Swap"), "set_inverse_mode", "get_inverse_mode");
// Blink.
ClassDB::add_property_group("Terminal", "Blink", "blink_");
@ -53,6 +61,8 @@ Terminal::Terminal()
blink_on_time = 0.6;
blink_off_time = 0.3;
inverse_mode = InverseMode::INVERSE_MODE_INVERT;
if (tsm_screen_new(&screen, NULL, NULL))
{
ERR_PRINT("Failed to create tsm screen.");
@ -199,6 +209,9 @@ int Terminal::_draw_cb(struct tsm_screen *con,
? term->palette[attr->bccode]
: Color(attr->br / 255.0f, attr->bg / 255.0f, attr->bb / 255.0f);
if (attr->inverse && term->inverse_mode == InverseMode::INVERSE_MODE_SWAP)
std::swap(fgcol, bgcol);
// Draw background.
term->back_image->set_pixel(posx, posy, bgcol);
@ -490,4 +503,18 @@ void Terminal::set_blink_off_time(const float time)
float Terminal::get_blink_off_time() const
{
return blink_off_time;
}
void Terminal::set_inverse_mode(const int mode) {
inverse_mode = static_cast<InverseMode>(mode);
bool inverse_enabled = inverse_mode == InverseMode::INVERSE_MODE_INVERT;
back_material->set_shader_parameter("inverse_enabled", inverse_enabled);
fore_material->set_shader_parameter("inverse_enabled", inverse_enabled);
refresh();
}
int Terminal::get_inverse_mode() const {
return static_cast<int>(inverse_mode);
}

View file

@ -34,6 +34,11 @@ namespace godot
BLINK = 1 << 1,
};
enum InverseMode {
INVERSE_MODE_INVERT,
INVERSE_MODE_SWAP,
};
Terminal();
~Terminal();
@ -52,6 +57,9 @@ namespace godot
void set_blink_off_time(const float p_blink_off_time);
float get_blink_off_time() const;
void set_inverse_mode(const int mode);
int get_inverse_mode() const;
void write(Variant data);
protected:
@ -66,6 +74,8 @@ namespace godot
float blink_on_time;
float blink_off_time;
InverseMode inverse_mode;
RenderingServer *rs;
tsm_screen *screen;
@ -118,3 +128,5 @@ namespace godot
};
} // namespace godot
VARIANT_ENUM_CAST(Terminal::InverseMode);

View file

@ -13,6 +13,7 @@ uniform vec2 cell_size;
uniform vec2 grid_size;
uniform sampler2D attributes;
uniform bool inverse_enabled = true;
#ifdef BACKGROUND
uniform vec4 background_color;
@ -46,7 +47,7 @@ void fragment() {
color = texture(TEXTURE, UV);
#endif
if (has_attribute(sample_uv, FLAG_INVERSE)) {
if (has_attribute(sample_uv, FLAG_INVERSE) && inverse_enabled) {
color = vec4(1.0 - color.rgb, color.a);
}