Open source Star Ruler 2 source code!

This commit is contained in:
Lucas de Vries
2018-07-17 14:15:37 +02:00
commit cc307720ff
4342 changed files with 2365070 additions and 0 deletions
+17
View File
@@ -0,0 +1,17 @@
void drawLitModel(const Model& model, const Material@ material, const recti& position, const quaterniond& rotation, double scale = 1.0, const vec3f& lightPos = vec3f(), const Color& lightColor = colors::White) {
Light@ light = ::light[0];
light.position = vec3f(position.center.x, -100.f, position.center.y);
if(!lightPos.zero)
light.position = lightPos;
light.diffuse = lightColor;
light.specular = light.diffuse;
light.radius = 1000.f;
light.att_quadratic = 1.f/(500.0*500.0);
light.enable();
light.enable();
model.draw(material, position, rotation, scale);
resetLights();
}
+150
View File
@@ -0,0 +1,150 @@
import elements.BaseGuiElement;
import util.gui_options;
interface EngineOption {
void apply();
void reset();
};
mixin class IsEngineBoolOption {
string Setting;
void set_setting(string val) {
Setting = val;
reset();
}
void apply() {
setSettingBool(Setting, get());
}
void reset() {
set(getSettingBool(Setting));
}
};
mixin class IsEngineDoubleOption {
string Setting;
void set_setting(string val) {
Setting = val;
setMin(getSettingMinDouble(Setting));
setMax(getSettingMaxDouble(Setting));
reset();
}
void apply() {
setSettingDouble(Setting, get());
}
void reset() {
set(getSettingDouble(Setting));
}
};
mixin class IsEngineIntegerOption {
string Setting;
void set_setting(string val) {
Setting = val;
setMin(getSettingMinInt(Setting));
setMax(getSettingMaxInt(Setting));
reset();
}
void apply() {
setSettingInt(Setting, get());
}
void reset() {
set(getSettingInt(Setting));
}
};
class GuiEngineToggle : GuiToggleOption, EngineOption, IsEngineBoolOption {
GuiEngineToggle(BaseGuiElement@ parent, const recti& pos, const string&in text, string& settingname) {
super(parent, pos, text);
setting = settingname;
}
GuiEngineToggle(BaseGuiElement@ parent, Alignment@ pos, const string& text, string& settingname) {
super(parent, pos, text);
setting = settingname;
}
};
class GuiEngineSlider : GuiSliderOption, EngineOption, IsEngineDoubleOption {
GuiEngineSlider(BaseGuiElement@ parent, const recti& pos, const string&in text, string& settingname) {
super(parent, pos, text);
setting = settingname;
}
GuiEngineSlider(BaseGuiElement@ parent, Alignment@ pos, const string& text, string& settingname) {
super(parent, pos, text);
setting = settingname;
}
};
class GuiEngineNumber : GuiNumberOption, EngineOption, IsEngineIntegerOption {
GuiEngineNumber(BaseGuiElement@ parent, const recti& pos, const string&in text, string& settingname) {
super(parent, pos, text);
setting = settingname;
}
GuiEngineNumber(BaseGuiElement@ parent, Alignment@ pos, const string& text, string& settingname) {
super(parent, pos, text);
setting = settingname;
}
};
class GuiEngineDecimal : GuiNumberOption, EngineOption, IsEngineDoubleOption {
GuiEngineDecimal(BaseGuiElement@ parent, const recti& pos, const string&in text, string& settingname) {
super(parent, pos, text);
setting = settingname;
}
GuiEngineDecimal(BaseGuiElement@ parent, Alignment@ pos, const string& text, string& settingname) {
super(parent, pos, text);
setting = settingname;
}
};
class GuiEngineDropdown : GuiDropdownOption, EngineOption, IsEngineIntegerOption {
array<int> values;
GuiEngineDropdown(BaseGuiElement@ parent, const recti& pos, const string&in text, string& settingname) {
super(parent, pos, text);
setting = settingname;
}
GuiEngineDropdown(BaseGuiElement@ parent, Alignment@ pos, const string& text, string& settingname) {
super(parent, pos, text);
setting = settingname;
}
void addItem(const string& name, int value) {
values.insertLast(value);
box.addItem(name);
}
void setMin(int v) {
//Ignored
}
void setMax(int v) {
//Ignored
}
int get() {
return values[clamp(box.selected, 0, values.length-1)];
}
void set(int val) {
for(uint i = 0, cnt = values.length; i < cnt; ++i) {
if(val == values[i]) {
box.selected = i;
return;
}
}
}
};
+196
View File
@@ -0,0 +1,196 @@
import elements.BaseGuiElement;
import util.gui_options;
import settings.game_settings;
interface GameOption {
void apply(SettingsContainer&);
void load(SettingsContainer&);
void reset();
};
uint MASK_CONFIG = 0x71 << 16;
mixin class IsGameBoolOption {
uint Setting;
bool DefaultSetting;
bool DefaultValue;
void set_defaultValue(bool val) {
DefaultSetting = val;
DefaultValue = val;
}
void set_setting(int val) {
Setting = val;
}
void apply(SettingsContainer& gs) {
bool v = get();
if(Setting & MASK_CONFIG != 0) {
if(v != DefaultSetting)
gs.setNamed(config::getName(Setting & ~MASK_CONFIG), v ? 1.0 : 0.0);
else
gs.clearNamed(config::getName(Setting & ~MASK_CONFIG));
}
else
gs[Setting] = v ? 1.0 : 0.0;
}
void load(SettingsContainer& gs) {
if(Setting & MASK_CONFIG != 0)
set(gs.getNamed(config::getName(Setting & ~MASK_CONFIG), DefaultValue ? 1.0 : 0.0) != 0);
else
set(gs[Setting] != 0);
}
void reset() {
set(DefaultValue);
}
};
mixin class IsGameDoubleOption {
uint Setting;
double Default;
void set_defaultValue(double val) {
Default = val;
}
void set_setting(int val) {
Setting = val;
}
void apply(SettingsContainer& gs) {
double v = get();
if(Setting & MASK_CONFIG != 0) {
if(v != Default)
gs.setNamed(config::getName(Setting & ~MASK_CONFIG), v);
else
gs.clearNamed(config::getName(Setting & ~MASK_CONFIG));
}
else
gs[Setting] = v;
}
void load(SettingsContainer& gs) {
if(Setting & MASK_CONFIG != 0)
set(gs.getNamed(config::getName(Setting & ~MASK_CONFIG), Default));
else
set(gs[Setting]);
}
void reset() {
set(Default);
}
};
uint config(const string& name) {
return MASK_CONFIG | config::getIndex(name);
}
class GuiGameToggle : GuiToggleOption, GameOption, IsGameBoolOption {
GuiGameToggle(BaseGuiElement@ parent, const recti& pos, const string&in text, int settingid) {
super(parent, pos, text);
setting = settingid;
}
GuiGameToggle(BaseGuiElement@ parent, Alignment@ pos, const string& text, int settingid) {
super(parent, pos, text);
setting = settingid;
}
};
class GuiGameSlider : GuiSliderOption, GameOption, IsGameDoubleOption {
GuiGameSlider(BaseGuiElement@ parent, const recti& pos, const string&in text, int settingid) {
super(parent, pos, text);
setting = settingid;
}
GuiGameSlider(BaseGuiElement@ parent, Alignment@ pos, const string& text, int settingid) {
super(parent, pos, text);
setting = settingid;
}
};
class GuiGameOccurance : GuiOccuranceOption, GameOption, IsGameDoubleOption {
GuiGameOccurance(BaseGuiElement@ parent, const recti& pos, const string&in text, int settingid) {
super(parent, pos, text);
setting = settingid;
}
GuiGameOccurance(BaseGuiElement@ parent, Alignment@ pos, const string& text, int settingid) {
super(parent, pos, text);
setting = settingid;
}
void set_defaultValue(double val) {
defaultValue = val;
Default = val;
}
};
class GuiGameFrequency : GuiFrequencyOption, GameOption, IsGameDoubleOption {
GuiGameFrequency(BaseGuiElement@ parent, const recti& pos, const string&in text, int settingid) {
super(parent, pos, text);
setting = settingid;
}
GuiGameFrequency(BaseGuiElement@ parent, Alignment@ pos, const string& text, int settingid) {
super(parent, pos, text);
setting = settingid;
}
void set_defaultValue(double val) {
defaultValue = val;
Default = val;
}
};
class GuiGameNumber : GuiNumberOption, GameOption, IsGameDoubleOption {
GuiGameNumber(BaseGuiElement@ parent, const recti& pos, const string&in text, int settingid) {
super(parent, pos, text);
setting = settingid;
}
GuiGameNumber(BaseGuiElement@ parent, Alignment@ pos, const string& text, int settingid) {
super(parent, pos, text);
setting = settingid;
}
};
class GuiGameDropdown : GuiDropdownOption, GameOption, IsGameDoubleOption {
array<double> values;
GuiGameDropdown(BaseGuiElement@ parent, const recti& pos, const string&in text, int settingid) {
super(parent, pos, text);
setting = settingid;
}
GuiGameDropdown(BaseGuiElement@ parent, Alignment@ pos, const string& text, int settingid) {
super(parent, pos, text);
setting = settingid;
}
void addOption(const string& text, double value) {
box.addItem(text);
values.insertLast(value);
}
void set(double value) {
uint sel = 0;
for(uint i = 0, cnt = values.length; i < cnt; ++i) {
if(values[i] == value) {
sel = i;
break;
}
}
box.selected = sel;
}
double get() {
if(uint(box.selected) >= values.length)
return 0.0;
return values[box.selected];
}
};
+357
View File
@@ -0,0 +1,357 @@
import elements.BaseGuiElement;
import elements.GuiCheckbox;
import elements.GuiText;
import elements.GuiScrollbar;
import elements.GuiSpinbox;
import elements.GuiTextbox;
import elements.GuiDropdown;
class GuiToggleOption : BaseGuiElement {
GuiCheckbox@ check;
GuiToggleOption(BaseGuiElement@ parent, Alignment@ pos, const string& text) {
super(parent, pos);
_GuiToggleOption(text);
}
GuiToggleOption(BaseGuiElement@ parent, const recti& pos, const string&in text) {
super(parent, pos);
_GuiToggleOption(text);
}
void _GuiToggleOption(const string& text) {
@check = GuiCheckbox(this, Alignment_Fill(), text);
updateAbsolutePosition();
}
bool onGuiEvent(const GuiEvent& event) {
if(event.caller is check && event.type == GUI_Changed) {
emitChanged();
if(check.checked)
check.textColor = colors::White;
else
check.textColor = Color(0x888888ff);
return true;
}
return BaseGuiElement::onGuiEvent(event);
}
bool get() {
return check.checked;
}
void set(bool value) {
check.checked = value;
if(check.checked)
check.textColor = colors::White;
else
check.textColor = Color(0x888888ff);
}
};
funcdef void settingChanged();
class GuiSliderOption : BaseGuiElement {
GuiScrollbar@ bar;
GuiText@ label;
GuiText@ value;
settingChanged@ onChanged;
GuiSliderOption(BaseGuiElement@ parent, const recti& pos, const string&in text) {
super(parent, pos);
_GuiSliderOption(text);
}
GuiSliderOption(BaseGuiElement@ parent, Alignment@ pos, const string& text) {
super(parent, pos);
_GuiSliderOption(text);
}
void _GuiSliderOption(const string& text) {
@label = GuiText(this, recti(), text);
@label.alignment = Alignment(Left, Top, Left+0.4f, Bottom);
@value = GuiText(this, recti());
@value.alignment = Alignment(Right-74, Top, Right-0.0f-4, Bottom);
value.horizAlign = 1.0;
@bar = GuiScrollbar(this, recti());
@bar.alignment = Alignment(Left+0.4f+4, Top+1, Right-0.0f-78, Bottom-1);
bar.up.visible = false;
bar.down.visible = false;
bar.orientation = SO_Horizontal;
updateAbsolutePosition();
}
bool onGuiEvent(const GuiEvent& event) {
if(event.caller is bar && event.type == GUI_Changed) {
value.text = toString(bar.pos, 1);
if(onChanged !is null)
onChanged();
emitChanged();
return true;
}
return BaseGuiElement::onGuiEvent(event);
}
double get() {
return round(bar.pos * 10.0) / 10.0;
}
void set(double val) {
bar.pos = val;
value.text = toString(bar.pos, 1);
}
void setMin(double val) {
bar.start = val;
}
void setMax(double val) {
bar.end = val;
bar.page = 0.0;
bar.bar = (bar.end - bar.start) / 10.0;
bar.scroll = 0.1;
}
};
class GuiOccuranceOption : BaseGuiElement {
GuiScrollbar@ bar;
GuiCheckbox@ label;
GuiText@ value;
double defaultValue = 1.0;
GuiOccuranceOption(BaseGuiElement@ parent, const recti& pos, const string&in text) {
super(parent, pos);
_(text);
}
GuiOccuranceOption(BaseGuiElement@ parent, Alignment@ pos, const string& text) {
super(parent, pos);
_(text);
}
void _(const string& text) {
@label = GuiCheckbox(this, recti(), text);
@label.alignment = Alignment(Left, Top, Left+0.4f, Bottom);
@value = GuiText(this, recti());
@value.alignment = Alignment(Right-74, Top, Right-0.0f-4, Bottom);
value.horizAlign = 1.0;
@bar = GuiScrollbar(this, recti());
@bar.alignment = Alignment(Left+0.4f+4, Top+1, Right-0.0f-78, Bottom-1);
bar.up.visible = false;
bar.down.visible = false;
bar.orientation = SO_Horizontal;
updateAbsolutePosition();
label.emitClicked();
}
bool onGuiEvent(const GuiEvent& event) {
if(event.caller is bar && event.type == GUI_Changed) {
value.text = toString(bar.pos*100.0, 0)+"%";
label.checked = bar.pos != 0.0;
label.emitClicked();
emitChanged();
return true;
}
if(event.caller is label) {
Color color;
FontType font = FT_Normal;
double v = get();
if(!label.checked) {
color = Color(0x888888ff);
}
else if(v > defaultValue*1.1) {
font = FT_Bold;
color = colors::Green;
}
else if(v < defaultValue*0.9) {
font = FT_Bold;
color = colors::Red;
}
label.textColor = color;
value.color = color;
label.font = font;
value.font = font;
if(event.type == GUI_Changed) {
emitChanged();
return true;
}
}
return BaseGuiElement::onGuiEvent(event);
}
double get() {
return label.checked ? round(bar.pos*100.0) / 100.0 : 0.0;
}
void set(double val) {
bar.pos = val;
value.text = toString(bar.pos*100.0, 0)+"%";
label.checked = val != 0.0;
label.emitClicked();
}
void setMin(double val) {
bar.start = val;
}
void setMax(double val) {
bar.end = val;
bar.bar = 0.25;
bar.page = 0.0;
bar.scroll = 0.1;
}
};
class GuiFrequencyOption : GuiSliderOption {
double defaultValue = 1.0;
GuiFrequencyOption(BaseGuiElement@ parent, const recti& pos, const string&in text) {
super(parent, pos, text);
}
GuiFrequencyOption(BaseGuiElement@ parent, Alignment@ pos, const string& text) {
super(parent, pos, text);
}
double get() {
return round(bar.pos*100.0) / 100.0;
}
bool onGuiEvent(const GuiEvent& event) {
if(event.caller is bar && event.type == GUI_Changed) {
value.text = toString(bar.pos*100.0, 0)+"%";
Color color;
FontType font = FT_Normal;
double v = get();
if(v > defaultValue*1.1) {
font = FT_Bold;
color = colors::Green;
}
else if(v < defaultValue*0.9) {
font = FT_Bold;
color = colors::Red;
}
label.color = color;
label.font = font;
value.color = color;
value.font = font;
emitChanged();
return true;
}
return BaseGuiElement::onGuiEvent(event);
}
void set(double val) {
bar.pos = val;
bar.emitChanged();
}
};
class GuiNumberOption : BaseGuiElement {
GuiSpinbox@ value;
GuiText@ label;
bool changed = false;
GuiNumberOption(BaseGuiElement@ parent, const recti& pos, const string&in text) {
super(parent, pos);
_GuiNumberOption(text);
}
GuiNumberOption(BaseGuiElement@ parent, Alignment@ pos, const string& text) {
super(parent, pos);
_GuiNumberOption(text);
}
void _GuiNumberOption(const string& text) {
@label = GuiText(this, recti(), text);
@label.alignment = Alignment(Left, Top, Left+0.4f, Bottom);
@value = GuiSpinbox(this, recti());
@value.alignment = Alignment(Left+0.4f+2, Top+2, Right-0.0f-2, Bottom-2);
value.min = 0.0;
updateAbsolutePosition();
}
bool onGuiEvent(const GuiEvent& event) {
if(event.caller is value){
if(event.type == GUI_Changed) {
emitChanged();
return true;
}
}
return BaseGuiElement::onGuiEvent(event);
}
void set_step(double step) {
value.step = step;
}
void set_decimals(int dec) {
value.decimals = dec;
}
double get() {
return value.value;
}
void set(double val) {
value.value = val;
}
void setMin(double val) {
value.min = val;
}
void setMax(double val) {
value.max = val;
}
};
class GuiDropdownOption : BaseGuiElement {
GuiDropdown@ box;
GuiText@ label;
bool changed = false;
GuiDropdownOption(BaseGuiElement@ parent, const recti& pos, const string&in text) {
super(parent, pos);
_GuiDropdownOption(text);
}
GuiDropdownOption(BaseGuiElement@ parent, Alignment@ pos, const string& text) {
super(parent, pos);
_GuiDropdownOption(text);
}
void _GuiDropdownOption(const string& text) {
@label = GuiText(this, recti(), text);
@label.alignment = Alignment(Left, Top, Left+0.4f, Bottom);
@box = GuiDropdown(this, recti());
@box.alignment = Alignment(Left+0.5f+2, Top, Right-0.0f-2, Bottom);
updateAbsolutePosition();
}
bool onGuiEvent(const GuiEvent& event) {
if(event.caller is box){
if(event.type == GUI_Changed) {
emitChanged();
return true;
}
}
return BaseGuiElement::onGuiEvent(event);
}
};
+211
View File
@@ -0,0 +1,211 @@
import elements.BaseGuiElement;
import elements.MarkupTooltip;
import elements.GuiMarkupText;
import util.game_options;
import elements.GuiText;
class SettingsPage {
GameOption@[] options;
BaseGuiElement@ cur;
uint lineHeight = 34;
uint linePadding = 4;
uint line = 0;
bool half = false;
void clear() {
options.length = 0;
@cur = null;
lineHeight = 30;
line = 0;
}
void create(BaseGuiElement@ pane, SettingsContainer@ gs = null) {
clear();
@cur = pane;
makeSettings();
reset();
if(gs !is null)
load(gs);
}
Alignment@ nextAlignment(bool halfWidth = false) {
if(!halfWidth && half) {
half = false;
++line;
}
Alignment align(Left+8, Top+linePadding+line*lineHeight, Right-24, Top+line*lineHeight + lineHeight);
if(halfWidth) {
if(half) {
align.left.percent = 0.5f;
++line;
}
else {
align.right.percent = 0.5f;
}
half = !half;
}
else {
++line;
half = false;
}
return align;
}
void emptyline() {
line += 1;
if(half) {
half = false;
line += 1;
}
}
GuiText@ Title(const string& title, FontType font = FT_Medium, Alignment@ align = null) {
if(align is null)
@align = nextAlignment();
GuiText ele(cur, align, title);
ele.font = font;
ele.stroke = colors::Black;
return ele;
}
GuiMarkupText@ Description(const string& text, uint lines = 1) {
auto@ align = nextAlignment();
align.bottom.pixels += lineHeight * lines-1;
line += lines-1;
GuiMarkupText ele(cur, align);
ele.text = text;
return ele;
}
GuiGameToggle@ Toggle(const string& text, const string& configName, Alignment@ align = null, const string& tooltip = "", bool halfWidth=false) {
return Toggle(text, config(configName), config::get(configName) != 0.0, align, tooltip, halfWidth);
}
GuiGameToggle@ Toggle(const string& text, uint setting, bool value, Alignment@ align = null, const string& tooltip = "", bool halfWidth=false) {
if(align is null)
@align = nextAlignment(halfWidth);
GuiGameToggle ele(cur, align, text, setting);
if(tooltip.length != 0)
setMarkupTooltip(ele, tooltip, width=300);
ele.set(value);
ele.defaultValue = value;
options.insertLast(ele);
return ele;
}
GuiGameSlider@ Slider(const string& text, uint setting, double value, double min, double max, Alignment@ align = null) {
if(align is null)
@align = nextAlignment();
GuiGameSlider ele(cur, align, text, setting);
ele.defaultValue = value;
ele.set(value);
ele.setMin(min);
ele.setMax(max);
options.insertLast(ele);
return ele;
}
GuiGameNumber@ Number(const string& text, const string& configName, int decimals = 0, double step = 1.0, Alignment@ align = null, double min=0.0, double max=INFINITY, bool halfWidth=false, const string& tooltip = "") {
return Number(text, config(configName), config::get(configName), decimals, step, align, min, max, halfWidth, tooltip);
}
GuiGameNumber@ Number(const string& text, uint setting, double value, int decimals = 0, double step = 1.0, Alignment@ align = null, double min=0.0, double max=INFINITY, bool halfWidth=false, const string& tooltip = "") {
if(align is null)
@align = nextAlignment(halfWidth);
GuiGameNumber ele(cur, align, text, setting);
ele.decimals = decimals;
ele.step = step;
ele.defaultValue = value;
ele.setMin(min);
ele.setMax(max);
ele.set(value);
if(tooltip.length != 0)
setMarkupTooltip(ele, tooltip, width=300);
options.insertLast(ele);
return ele;
}
GuiGameOccurance@ Occurance(const string& text, const string& configName, double min = 0.0, double max = 2.0, Alignment@ align = null, const string& tooltip = "") {
return Occurance(text, config(configName), config::get(configName), min, max, align, tooltip);
}
GuiGameOccurance@ Occurance(const string& text, uint setting, double value, double min = 0.0, double max = 2.0, Alignment@ align = null, const string& tooltip = "") {
if(align is null)
@align = nextAlignment();
GuiGameOccurance ele(cur, align, text, setting);
ele.defaultValue = value;
ele.set(value);
ele.setMin(min);
ele.setMax(max);
if(tooltip.length != 0)
setMarkupTooltip(ele, tooltip, width=300);
options.insertLast(ele);
return ele;
}
GuiGameFrequency@ Frequency(const string& text, const string& configName, double min = 0.0, double max = 2.0, Alignment@ align = null) {
return Frequency(text, config(configName), config::get(configName), min, max, align);
}
GuiGameFrequency@ Frequency(const string& text, uint setting, double value, double min = 0.0, double max = 2.0, Alignment@ align = null) {
if(align is null)
@align = nextAlignment();
GuiGameFrequency ele(cur, align, text, setting);
ele.defaultValue = value;
ele.set(value);
ele.setMin(min);
ele.setMax(max);
options.insertLast(ele);
return ele;
}
GuiGameDropdown@ Dropdown(const string& text, const string& configName, Alignment@ align = null) {
return Dropdown(text, config(configName), config::get(configName), align);
}
GuiGameDropdown@ Dropdown(const string& text, uint setting, double value, Alignment@ align = null) {
if(align is null)
@align = nextAlignment();
GuiGameDropdown ele(cur, align, text, setting);
ele.defaultValue = value;
ele.set(value);
options.insertLast(ele);
return ele;
}
void makeSettings() {
throw("SettingsPage does not implement makeSettings().");
}
void reset() {
uint cnt = options.length;
for(uint i = 0; i < cnt; ++i)
options[i].reset();
}
void load(SettingsContainer& gs) {
uint cnt = options.length;
for(uint i = 0; i < cnt; ++i)
options[i].load(gs);
}
void apply(SettingsContainer& gs) {
uint cnt = options.length;
for(uint i = 0; i < cnt; ++i)
options[i].apply(gs);
}
};
class GameSettingsPage : SettingsPage {
Color color;
string header;
Sprite icon;
GameSettingsPage() {
GAME_SETTINGS_PAGES.insertLast(this);
}
};
array<GameSettingsPage@> GAME_SETTINGS_PAGES;