Sanitize the Lua API

Mostly in terms of consistency of spelling (o/ou, z/s, upper/lowercase), placement (which table a function/variable is in), and getter/setter functionality (a ton of settings weren't possible to query). All of this is done, or at least is intended to be done, in a backwards-compatible manner; code that worked without errors in 97.0 should work correctly from now on also.

Also punt off duplicated and deprecated features to eventcompat.lua, renamed to just compat.lua, where they are more concisely implemented and more maintainable than on the C++ side.

Note that this means that functionality added since 97.0 is not necessarily preserved, and also that code that worked with errors may or may not keep working with errors, and it highly likely will not produce the same errors. In the future, errors coming from compat.lua should be attempted to be resolved first and foremost by migrating user code to new APIs.

List of notable, included, but not entirely relevant changes, which should probably have been done in separate commits:

 - add an enum for simulation deco spaces, there still are a few things that need such enums though
 - move clamping to Brush::SetRadius, meaning that nothing can set bogus brush sizes from now on, not even Lua
 - have LuaLuna install constructor functions in the interface table, rather than pollute _G with equivalent callable tables

The old APIs now work in accordance with existing documentation on the Wiki, though they retain weird unintended behaviour, such as accepting fewer arguments than documented. I also intend to give new APIs a thorough look later, and possibly organize C++-side code into separate TUs based on which API table it implements.

A list list of API changes follows. "status" is to be interpreted thus:

 - added: new API, the "related" API may be the limited functionality deprecated equivalent the new one is meant to extend
 - deprecated: retained for compatibility (see above), implemented in compat.lua via the "related" API, possibly meant to be removed from existing documentation, or at least very visibly marked deprecated
 - aliases: retained for compatibility (see above), implemented in compat.lua as an alias to the "related" API, possibly meant to be removed from existing documentation, or at least very visibly marked deprecated
 - renamed: not retained for compatibility because it was added after 97.0, the replacement is the "related" API
 - removed: no replacement available, see "note" for reason
 - unchanged: unchanged but noteworthy

 name                      | status     | related                 | note
---------------------------|------------|-------------------------|--------------
 Button                    | deprecated | ui.button               |
 Checkbox                  | deprecated | ui.checkbox             |
 Label                     | deprecated | ui.label                |
 ProgressBar               | deprecated | ui.progressBar          |
 Slider                    | deprecated | ui.slider               |
 Textbox                   | deprecated | ui.textbox              |
 Window                    | deprecated | ui.window               |
 bz2.COMPRESS_LIMIT        | added      | bz2.compressLimit       | identical
 bz2.COMPRESS_NOMEM        | added      | bz2.compressNomem       | identical
 bz2.DECOMPRESS_BAD        | added      | bz2.decompressBad       | identical
 bz2.DECOMPRESS_EOF        | added      | bz2.decompressEof       | identical
 bz2.DECOMPRESS_LIMIT      | added      | bz2.decompressLimit     | identical
 bz2.DECOMPRESS_NOMEM      | added      | bz2.decompressNomem     | identical
 bz2.DECOMPRESS_TYPE       | added      | bz2.decompressType      | identical
 bz2.compressLimit         | deprecated | bz2.COMPRESS_NOMEM      |
 bz2.compressNomem         | deprecated | bz2.COMPRESS_LIMIT      |
 bz2.compressOk            | removed    |                         | bz2.compress never actually returned this
 bz2.decompressBad         | deprecated | bz2.DECOMPRESS_NOMEM    |
 bz2.decompressEof         | deprecated | bz2.DECOMPRESS_LIMIT    |
 bz2.decompressLimit       | deprecated | bz2.DECOMPRESS_TYPE     |
 bz2.decompressNomem       | deprecated | bz2.DECOMPRESS_BAD      |
 bz2.decompressOk          | removed    |                         | bz2.decompress never actually returned this
 bz2.decompressType        | deprecated | bz2.DECOMPRESS_EOF      |
 elem.FLAG_MOVABLE         | deprecated | sim.FLAG_MOVABLE        |
 elem.FLAG_PHOTDECO        | deprecated | sim.FLAG_PHOTDECO       |
 elem.FLAG_SKIPMOVE        | deprecated | sim.FLAG_SKIPMOVE       |
 elem.FLAG_STAGNANT        | deprecated | sim.FLAG_STAGNANT       |
 elem.PROP_DRAWONCTYPE     | deprecated | 0                       |
 elem.ST_GAS               | deprecated | 0                       |
 elem.ST_LIQUID            | deprecated | 0                       |
 elem.ST_NONE              | deprecated | 0                       |
 elem.ST_SOLID             | deprecated | 0                       |
 elem.getByName            | added      | tpt.element             | only converts names to IDs
 evt.AFTERSIM              | added      | evt.aftersim            | identical
 evt.AFTERSIMDRAW          | added      | evt.aftersimdraw        | identical
 evt.BEFORESIM             | added      | evt.beforesim           | identical
 evt.BEFORESIMDRAW         | added      | evt.beforesimdraw       | identical
 evt.BLUR                  | added      | evt.blur                | identical
 evt.CLOSE                 | added      | evt.close               | identical
 evt.KEYPRESS              | added      | evt.keypress            | identical
 evt.KEYRELEASE            | added      | evt.keyrelease          | identical
 evt.MOUSEDOWN             | added      | evt.mousedown           | identical
 evt.MOUSEMOVE             | added      | evt.mousemove           | identical
 evt.MOUSEUP               | added      | evt.mouseup             | identical
 evt.MOUSEWHEEL            | added      | evt.mousewheel          | identical
 evt.TEXTEDITING           | added      | evt.textediting         | identical
 evt.TEXTINPUT             | added      | evt.textinput           | identical
 evt.TICK                  | added      | evt.tick                | identical
 evt.aftersim              | deprecated | evt.AFTERSIM            |
 evt.aftersimdraw          | deprecated | evt.AFTERSIMDRAW        |
 evt.beforesim             | deprecated | evt.BEFORESIM           |
 evt.beforesimdraw         | deprecated | evt.BEFORESIMDRAW       |
 evt.blur                  | deprecated | evt.BLUR                |
 evt.close                 | deprecated | evt.CLOSE               |
 evt.getModifiers          | added      | evt.getmodifiers        | identical
 evt.getmodifiers          | deprecated | evt.getModifiers        |
 evt.keypress              | deprecated | evt.KEYPRESS            |
 evt.keyrelease            | deprecated | evt.KEYRELEASE          |
 evt.mousedown             | deprecated | evt.MOUSEDOWN           |
 evt.mousemove             | deprecated | evt.MOUSEMOVE           |
 evt.mouseup               | deprecated | evt.MOUSEUP             |
 evt.mousewheel            | deprecated | evt.MOUSEWHEEL          |
 evt.textediting           | deprecated | evt.TEXTEDITING         |
 evt.textinput             | deprecated | evt.TEXTINPUT           |
 evt.tick                  | deprecated | evt.TICK                |
 ren.FIRE_SPARK            | added      |                         | was missing
 ren.colourMode            | deprecated | ren.colorMode           |
 ren.debugHUD              | deprecated | ren.debugHud            |
 ren.decorations           | added      | tpt.decorations_enable  | works with booleans
 ren.fireSize              | added      | tpt.setfire             | also a getter, takes intensity only
 ren.hud                   | added      | tpt.hud                 | works with booleans
 ren.useDisplayPreset      | added      | tpt.display_mode        | identical
 sim.AIR_NOUPDATE          | added      | sim.AIR_NO_UPDATE       | identical
 sim.AIR_NO_UPDATE         | renamed    | sim.AIR_NOUPDATE        |
 sim.AIR_PRESSUREOFF       | added      | sim.AIR_PRESSURE_OFF    | identical
 sim.AIR_PRESSURE_OFF      | renamed    | sim.AIR_PRESSUREOFF     |
 sim.AIR_VELOCITYOFF       | added      | sim.AIR_VELOCITY_OFF    | identical
 sim.AIR_VELOCITY_OFF      | renamed    | sim.AIR_VELOCITYOFF     |
 sim.BRUSH_CIRCLE          | added      | sim.CIRCLE_BRUSH        | identical
 sim.BRUSH_NUM             | renamed    | sim.NUM_DEFAULTBRUSHES  |
 sim.BRUSH_SQUARE          | added      | sim.SQUARE_BRUSH        | identical
 sim.BRUSH_TRIANGLE        | added      | sim.TRI_BRUSH           | identical
 sim.CIRCLE_BRUSH          | renamed    | sim.BRUSH_CIRCLE        |
 sim.FLAG_MOVABLE          | added      | elem.FLAG_MOVABLE       | identical
 sim.FLAG_PHOTDECO         | added      | elem.FLAG_PHOTDECO      | identical
 sim.FLAG_SKIPMOVE         | added      | elem.FLAG_SKIPMOVE      | identical
 sim.FLAG_STAGNANT         | added      | elem.FLAG_STAGNANT      | identical
 sim.MAX_PARTS             | added      | sim.NPART               | identical
 sim.NPART                 | renamed    | sim.MAX_PARTS           |
 sim.NUM_AIRMODES          | added      | sim.NUM_AIR_MODES       | identical
 sim.NUM_AIR_MODES         | renamed    | sim.NUM_AIRMODES        |
 sim.NUM_BRUSHES           | added      |                         | specifies the range of valid ui.brushID inputs
 sim.NUM_DEFAULTBRUSHES    | added      | sim.BRUSH_NUM           | identical
 sim.NUM_EDGEMODES         | added      | sim.NUM_EDGE_MODES      | identical
 sim.NUM_EDGE_MODES        | renamed    | sim.NUM_EDGEMODES       |
 sim.NUM_GRAVMODES         | added      | sim.NUM_GRAV_MODES      | identical
 sim.NUM_GRAV_MODES        | renamed    | sim.NUM_GRAVMODES       |
 sim.NUM_PARTS             | deprecated | sim.partCount           |
 sim.NUM_WALLS             | added      |                         | specifies the range of valid sim.wallMap inputs
 sim.SQUARE_BRUSH          | renamed    | sim.BRUSH_SQUARE        |
 sim.TRI_BRUSH             | renamed    | sim.BRUSH_TRIANGLE      |
 sim.ambientHeatSim        | added      | tpt.ambient_heat        | works with booleans
 sim.canMove               | added      | sim.can_move            | identical
 sim.can_move              | deprecated | sim.canMove             |
 sim.decoColour            | deprecated | sim.decoColor           |
 sim.decoSpace             | added      | tpt.decoSpace           | identical, but a function
 sim.elecMap               | added      | tpt.set_elecmap         | also a getter
 sim.ensureDeterminism     | unchanged  |                         | undocumented
 sim.fanVelocityX          | added      | tpt.set_wallmap         | also a getter, sets fan velocity separately
 sim.fanVelocityY          | added      | tpt.set_wallmap         | also a getter, sets fan velocity separately
 sim.frameRender           | added      | sim.framerender         | identical
 sim.framerender           | deprecated | sim.frameRender         |
 sim.golSpeedRatio         | added      | sim.gspeed              | identical
 sim.gravMap               | deprecated | various                 |
 sim.gravityField          | added      | sim.graMap              | gravity simulation output
 sim.gravityMass           | added      | sim.graMap              | also a getter, gravity simulation input
 sim.gspeed                | deprecated | sim.golSpeedRatio       |
 sim.hash                  | unchanged  |                         | undocumented
 sim.heatSim               | added      | tpt.heat                | works with booleans
 sim.neighbours            | deprecated | sim.neighbors           |
 sim.newtonianGravity      | added      | tpt.newtonian_gravity   | works with booleans
 sim.partCount             | added      | tpt.NUM_PARTS           | identical, but a function
 sim.partNeighbours        | deprecated | see sim.partNeighbors   |
 sim.paused                | added      | tpt.set_pause           | works with booleans
 sim.randomSeed            | added      | sim.randomseed          | identical, undocumented
 sim.randomseed            | renamed    | sim.randomSeed          | undocumented
 sim.resetGravityField     | added      | tpt.reset_gravity_field | identical
 sim.resetSpark            | added      | tpt.reset_spark         | identical
 sim.resetVelocity         | added      | tpt.reset_velocity      | identical
 sim.wallMap               | added      | tpt.set_wallmap         | also a getter, doesn't set fan velocity
 sim.waterEqualisation     | deprecated | sim.waterEqualization   |
 sim.waterEqualization     | unchanged  |                         | still works with ints, not worth the trouble
 socket.getTime            | added      | socket.gettime          | identical
 socket.gettime            | deprecated | socket.getTime          |
 tpt.active_menu           | deprecated | ui.activeMenu           |
 tpt.ambient_heat          | deprecated | sim.ambientHeatSim      |
 tpt.brushID               | deprecated | ui.brushID              |
 tpt.brushx                | deprecated | ui.brushRadius          |
 tpt.brushy                | deprecated | ui.brushRadius          |
 tpt.create                | deprecated | various                 |
 tpt.debug                 | added      | tpt.setdebug            | identical
 tpt.decoSpace             | deprecated | sim.decoSpace           |
 tpt.decorations_enable    | deprecated | ren.decorations         |
 tpt.delete                | deprecated | various                 |
 tpt.display_mode          | deprecated | ren.useDisplayPreset    |
 tpt.drawCap               | added      | tpt.setdrawcap          | identical
 tpt.drawline              | deprecated | gfx.drawLine            |
 tpt.drawpixel             | deprecated | gfx.drawPixel           |
 tpt.drawrect              | deprecated | gfx.drawRect            |
 tpt.drawtext              | deprecated | gfx.drawText            |
 tpt.el                    | deprecated | various                 |
 tpt.element               | deprecated | various                 |
 tpt.element_func          | deprecated | elem.property           |
 tpt.eltransition          | deprecated | various                 |
 tpt.fillrect              | deprecated | gfx.fillRect            |
 tpt.fpsCap                | added      | tpt.setfpscap           | identical
 tpt.getPartIndex          | deprecated | various                 |
 tpt.getUserName           | added      | tpt.get_name            | identical
 tpt.get_clipboard         | deprecated | plat.clipboardCopy      |
 tpt.get_elecmap           | deprecated | sim.elecMap             |
 tpt.get_name              | deprecated | tpt.getUserName         |
 tpt.get_numOfParts        | deprecated | sim.partCount           |
 tpt.get_property          | deprecated | sim.partProperty        |
 tpt.get_wallmap           | deprecated | sim.wallMap             |
 tpt.graphics_func         | deprecated | elem.property           |
 tpt.heat                  | deprecated | sim.heatSim             |
 tpt.hud                   | deprecated | ren.hud                 |
 tpt.menu_enabled          | deprecated | ui.menuEnabled          |
 tpt.mousex                | deprecated | ui.mousePosition        |
 tpt.mousey                | deprecated | ui.mousePosition        |
 tpt.newtonian_gravity     | deprecated | sim.newtonianGravity    |
 tpt.next_getPartIndex     | deprecated | various                 |
 tpt.num_menus             | deprecated | ui.numMenus             |
 tpt.parts                 | deprecated | various                 |
 tpt.perfectCircleBrush    | deprecated | ui.perfectCircleBrush   |
 tpt.reset_gravity_field   | deprecated | sim.resetGravityField   |
 tpt.reset_spark           | deprecated | sim.resetSpark          |
 tpt.reset_velocity        | deprecated | sim.resetVelocity       |
 tpt.selecteda             | deprecated | ui.activeTool           |
 tpt.selectedl             | deprecated | ui.activeTool           |
 tpt.selectedr             | deprecated | ui.activeTool           |
 tpt.selectedreplace       | deprecated | ui.activeTool           |
 tpt.set_clipboard         | deprecated | plat.clipboardPaste     |
 tpt.set_console           | deprecated | ui.console              |
 tpt.set_elecmap           | deprecated | sim.elecMap             |
 tpt.set_gravity           | deprecated | sim.gravityMass         |
 tpt.set_pause             | deprecated | sim.paused              |
 tpt.set_pressure          | deprecated | sim.pressure            |
 tpt.set_property          | deprecated | sim.partProperty        |
 tpt.set_wallmap           | deprecated | sim.wallMap             |
 tpt.setdebug              | deprecated | tpt.debug               |
 tpt.setdrawcap            | deprecated | tpt.drawCap             |
 tpt.setfire               | deprecated | ren.fireSize            |
 tpt.setfpscap             | deprecated | tpt.fpsCap              |
 tpt.setwindowsize         | deprecated | ui.windowSize           |
 tpt.start_getPartIndex    | deprecated | various                 |
 tpt.textwidth             | deprecated | gfx.textSize            |
 tpt.toggle_pause          | deprecated | sim.paused              |
 tpt.watertest             | deprecated | sim.waterEqualization   |
 ui.MOUSEUP_BLUR           | added      | ui.MOUSE_UP_BLUR        | identical
 ui.MOUSEUP_DRAWEND        | added      | ui.MOUSE_UP_DRAW_END    | identical
 ui.MOUSEUP_NORMAL         | added      | ui.MOUSE_UP_NORMAL      | identical
 ui.MOUSE_UP_BLUR          | deprecated | ui.MOUSEUP_BLUR         |
 ui.MOUSE_UP_DRAW_END      | deprecated | ui.MOUSEUP_DRAWEND      |
 ui.MOUSE_UP_NORMAL        | deprecated | ui.MOUSEUP_NORMAL       |
 ui.NUM_TOOLINDICES        | added      |                         | specifies the range of valid ui.activeTool inputs
 ui.activeMenu             | added      | tpt.active_menu         | identical
 ui.activeTool             | added      | tpt.selectedl, ...      | identical, but a function
 ui.brushID                | added      | tpt.brushID             | identical, but a function
 ui.brushRadius            | added      | tpt.brushx, tpt.brushy  | identical, but a function
 ui.button                 | added      | Slider:new              | standalone function
 ui.checkbox               | added      | Textbox:new             | standalone function
 ui.console                | added      | tpt.set_console         | works with booleans
 ui.label                  | added      | ProgressBar:new         | standalone function
 ui.menuEnabled            | added      | tpt.menu_enabled        | identical
 ui.mousePosition          | added      | tpt.mousex, tpt.mousey  | identical, but a function
 ui.numMenus               | added      | tpt.num_menus           | identical
 ui.perfectCircleBrush     | added      | tpt.perfectCircleBrush  | identical
 ui.progressBar            | added      | Window:new              | standalone function
 ui.slider                 | added      | Button:new              | standalone function
 ui.textbox                | added      | Label:new               | standalone function
 ui.window                 | added      | Checkbox:new            | standalone function
 ui.windowSize             | added      | tpt.setwindowsize       | also a getter
This commit is contained in:
Tamás Bálint Misius 2024-01-17 12:33:50 +01:00
parent 5e60b53a3b
commit 8e6faddd2f
No known key found for this signature in database
GPG Key ID: 5B472A12F6ECA9F2
31 changed files with 1669 additions and 2315 deletions

View File

@ -42,10 +42,13 @@ constexpr float AIR_PLOSS = 0.9999f;
constexpr int NGOL = 24;
constexpr int CIRCLE_BRUSH = 0;
constexpr int SQUARE_BRUSH = 1;
constexpr int TRI_BRUSH = 2;
constexpr int BRUSH_NUM = 3;
enum DefaultBrushes
{
BRUSH_CIRCLE,
BRUSH_SQUARE,
BRUSH_TRIANGLE,
NUM_DEFAULTBRUSHES,
};
//Photon constants
constexpr int SURF_RANGE = 10;

View File

@ -41,6 +41,8 @@ class Renderer: public RasterDrawMethods<Renderer>
friend struct RasterDrawMethods<Renderer>;
float fireIntensity = 1;
public:
Vec2<int> Size() const
{
@ -97,6 +99,10 @@ public:
void DrawSigns();
void render_gravlensing(const Video &source);
void render_fire();
float GetFireIntensity() const
{
return fireIntensity;
}
void prepare_alpha(int size, float intensity);
void render_parts();
void draw_grav_zones();

View File

@ -142,9 +142,10 @@ float glow_alphaf[11][11];
float blur_alphaf[7][7];
void Renderer::prepare_alpha(int size, float intensity)
{
fireIntensity = intensity;
//TODO: implement size
int x,y,i,j;
float multiplier = 255.0f*intensity;
float multiplier = 255.0f*fireIntensity;
memset(temp, 0, sizeof(temp));
for (x=0; x<CELL; x++)

View File

@ -52,6 +52,14 @@ void Brush::InitOutline()
void Brush::SetRadius(ui::Point newRadius)
{
if (newRadius.X < 0)
newRadius.X = 0;
if (newRadius.Y < 0)
newRadius.Y = 0;
if (newRadius.X > 200)
newRadius.X = 200;
if (newRadius.Y > 200)
newRadius.Y = 200;
radius = newRadius;
InitOutline();
}
@ -67,14 +75,6 @@ void Brush::AdjustSize(int delta, bool logarithmic, bool keepX, bool keepY)
newSize = oldSize + ui::Point(delta * std::max(oldSize.X / 5, 1), delta * std::max(oldSize.Y / 5, 1));
else
newSize = oldSize + ui::Point(delta, delta);
if (newSize.X < 0)
newSize.X = 0;
if (newSize.Y < 0)
newSize.Y = 0;
if (newSize.X > 200)
newSize.X = 200;
if (newSize.Y > 200)
newSize.Y = 200;
if (keepY)
SetRadius(ui::Point(newSize.X, oldSize.Y));

View File

@ -785,7 +785,7 @@ void GameController::ResetSpark()
void GameController::SwitchGravity()
{
gameModel->GetSimulation()->gravityMode = (gameModel->GetSimulation()->gravityMode + 1) % NUM_GRAV_MODES;
gameModel->GetSimulation()->gravityMode = (gameModel->GetSimulation()->gravityMode + 1) % NUM_GRAVMODES;
switch (gameModel->GetSimulation()->gravityMode)
{
@ -806,23 +806,23 @@ void GameController::SwitchGravity()
void GameController::SwitchAir()
{
gameModel->GetSimulation()->air->airMode = (gameModel->GetSimulation()->air->airMode + 1) % NUM_AIR_MODES;
gameModel->GetSimulation()->air->airMode = (gameModel->GetSimulation()->air->airMode + 1) % NUM_AIRMODES;
switch (gameModel->GetSimulation()->air->airMode)
{
case AIR_ON:
gameModel->SetInfoTip("Air: On");
break;
case AIR_PRESSURE_OFF:
case AIR_PRESSUREOFF:
gameModel->SetInfoTip("Air: Pressure Off");
break;
case AIR_VELOCITY_OFF:
case AIR_VELOCITYOFF:
gameModel->SetInfoTip("Air: Velocity Off");
break;
case AIR_OFF:
gameModel->SetInfoTip("Air: Off");
break;
case AIR_NO_UPDATE:
case AIR_NOUPDATE:
gameModel->SetInfoTip("Air: No Update");
break;
}
@ -1031,7 +1031,7 @@ int GameController::GetEdgeMode()
void GameController::SetEdgeMode(int edgeMode)
{
if (edgeMode < 0 || edgeMode >= NUM_EDGE_MODES)
if (edgeMode < 0 || edgeMode >= NUM_EDGEMODES)
edgeMode = 0;
gameModel->SetEdgeMode(edgeMode);

View File

@ -126,6 +126,7 @@ public:
int GetEdgeMode();
void SetEdgeMode(int edgeMode);
void SetDebugFlags(unsigned int flags) { debugFlags = flags; }
unsigned int GetDebugFlags() const { return debugFlags; }
void SetActiveMenu(int menuID);
std::vector<Menu*> GetMenuList();
int GetNumMenus(bool onlyEnabled);

View File

@ -54,16 +54,16 @@ GameModel::GameModel():
colour(255, 0, 0, 255),
edgeMode(EDGE_VOID),
ambientAirTemp(R_TEMP + 273.15f),
decoSpace(0)
decoSpace(DECOSPACE_SRGB)
{
sim = new Simulation();
sim->useLuaCallbacks = true;
ren = new Renderer(sim);
activeTools = regularToolset;
activeTools = &regularToolset[0];
std::fill(decoToolset, decoToolset+4, (Tool*)NULL);
std::fill(regularToolset, regularToolset+4, (Tool*)NULL);
std::fill(decoToolset.begin(), decoToolset.end(), nullptr);
std::fill(regularToolset.begin(), regularToolset.end(), nullptr);
//Default render prefs
ren->SetRenderMode({
@ -93,7 +93,7 @@ GameModel::GameModel():
ren->decorations_enable = prefs.Get("Renderer.Decorations", true);
//Load config into simulation
edgeMode = prefs.Get("Simulation.EdgeMode", (int)EDGE_VOID);
edgeMode = prefs.Get("Simulation.EdgeMode", NUM_EDGEMODES, EDGE_VOID);
sim->SetEdgeMode(edgeMode);
ambientAirTemp = float(R_TEMP) + 273.15f;
{
@ -104,9 +104,9 @@ GameModel::GameModel():
}
}
sim->air->ambientAirTemp = ambientAirTemp;
decoSpace = prefs.Get("Simulation.DecoSpace", 0); // TODO: DecoSpace enum
decoSpace = prefs.Get("Simulation.DecoSpace", NUM_DECOSPACES, DECOSPACE_SRGB);
sim->SetDecoSpace(decoSpace);
int ngrav_enable = prefs.Get("Simulation.NewtonianGravity", 0); // TODO: NewtonianGravity enum
int ngrav_enable = prefs.Get("Simulation.NewtonianGravity", NUM_GRAVMODES, GRAV_VERTICAL);
if (ngrav_enable)
sim->grav->start_grav_async();
sim->aheat_enable = prefs.Get("Simulation.AmbientHeat", 0); // TODO: AmbientHeat enum
@ -228,7 +228,7 @@ void GameModel::BuildMenus()
if(activeMenu != -1)
lastMenu = activeMenu;
ByteString activeToolIdentifiers[4];
std::array<ByteString, NUM_TOOLINDICES> activeToolIdentifiers;
if(regularToolset[0])
activeToolIdentifiers[0] = regularToolset[0]->Identifier;
if(regularToolset[1])
@ -881,17 +881,17 @@ void GameModel::SetActiveMenu(int menuID)
if(menuID == SC_DECO)
{
if(activeTools != decoToolset)
if(activeTools != &decoToolset[0])
{
activeTools = decoToolset;
activeTools = &decoToolset[0];
notifyActiveToolsChanged();
}
}
else
{
if(activeTools != regularToolset)
if(activeTools != &regularToolset[0])
{
activeTools = regularToolset;
activeTools = &regularToolset[0];
notifyActiveToolsChanged();
}
}

View File

@ -6,6 +6,9 @@
#include <deque>
#include <memory>
#include <optional>
#include <array>
constexpr auto NUM_TOOLINDICES = 4;
class Menu;
class Tool;
@ -72,8 +75,8 @@ private:
std::unique_ptr<SaveFile> currentFile;
Tool * lastTool;
Tool ** activeTools;
Tool * decoToolset[4];
Tool * regularToolset[4];
std::array<Tool *, NUM_TOOLINDICES> decoToolset;
std::array<Tool *, NUM_TOOLINDICES> regularToolset;
User currentUser;
float toolStrength;
std::deque<HistoryEntry> history;
@ -192,6 +195,10 @@ public:
Brush &GetBrush();
Brush *GetBrushByID(int i);
int GetBrushID();
int BrushListSize() const
{
return int(brushList.size());
}
void SetBrushID(int i);
void SetVote(int direction);

View File

@ -8,6 +8,7 @@
#include "graphics/Renderer.h"
#include "gui/Style.h"
#include "simulation/ElementDefs.h"
#include "simulation/SimulationData.h"
#include "client/Client.h"
#include "gui/dialogues/ConfirmPrompt.h"
#include "gui/dialogues/InformationMessage.h"
@ -120,11 +121,11 @@ OptionsView::OptionsView() : ui::Window(ui::Point(-1, -1), ui::Point(320, 340))
c->SetWaterEqualisation(waterEqualisation->GetChecked());
});
airMode = addDropDown("Air simulation mode", {
{ "On", 0 },
{ "Pressure off", 1 },
{ "Velocity off", 2 },
{ "Off", 3 },
{ "No update", 4 },
{ "On", AIR_ON },
{ "Pressure off", AIR_PRESSUREOFF },
{ "Velocity off", AIR_VELOCITYOFF },
{ "Off", AIR_OFF },
{ "No update", AIR_NOUPDATE },
}, [this] {
c->SetAirMode(airMode->GetOption().second);
});
@ -210,10 +211,10 @@ OptionsView::OptionsView() : ui::Window(ui::Point(-1, -1), ui::Point(320, 340))
}
};
gravityMode = addDropDown("Gravity simulation mode", {
{ "Vertical", 0 },
{ "Off", 1 },
{ "Radial", 2 },
{ "Custom", 3 },
{ "Vertical", GRAV_VERTICAL },
{ "Off", GRAV_OFF },
{ "Radial", GRAV_RADIAL },
{ "Custom", GRAV_CUSTOM },
}, [this] {
c->SetGravityMode(gravityMode->GetOption().second);
if (gravityMode->GetOption().second == 3)
@ -222,9 +223,9 @@ OptionsView::OptionsView() : ui::Window(ui::Point(-1, -1), ui::Point(320, 340))
}
});
edgeMode = addDropDown("Edge mode", {
{ "Void", 0 },
{ "Solid", 1 },
{ "Loop", 2 },
{ "Void", EDGE_VOID },
{ "Solid", EDGE_SOLID },
{ "Loop", EDGE_LOOP },
}, [this] {
c->SetEdgeMode(edgeMode->GetOption().second);
});
@ -317,10 +318,10 @@ OptionsView::OptionsView() : ui::Window(ui::Point(-1, -1), ui::Point(320, 340))
currentY += 4; // and then undo the undo
}
decoSpace = addDropDown("Colour space used by decoration tools", {
{ "sRGB", 0 },
{ "Linear", 1 },
{ "Gamma 2.2", 2 },
{ "Gamma 1.8", 3 },
{ "sRGB", DECOSPACE_SRGB },
{ "Linear", DECOSPACE_LINEAR },
{ "Gamma 2.2", DECOSPACE_GAMMA22 },
{ "Gamma 1.8", DECOSPACE_GAMMA18 },
}, [this] {
c->SetDecoSpace(decoSpace->GetOption().second);
});

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
#include "LuaScriptInterface.h"
#include "gui/interface/Button.h"
const char LuaButton::className[] = "Button";
const char LuaButton::className[] = "button";
#define method(class, name) {#name, &class::name}
Luna<LuaButton>::RegType LuaButton::methods[] = {

View File

@ -2,7 +2,7 @@
#include "LuaScriptInterface.h"
#include "gui/interface/Checkbox.h"
const char LuaCheckbox::className[] = "Checkbox";
const char LuaCheckbox::className[] = "checkbox";
#define method(class, name) {#name, &class::name}
Luna<LuaCheckbox>::RegType LuaCheckbox::methods[] = {

View File

@ -2,7 +2,7 @@
#include "LuaLabel.h"
#include "gui/interface/Label.h"
const char LuaLabel::className[] = "Label";
const char LuaLabel::className[] = "label";
#define method(class, name) {#name, &class::name}
Luna<LuaLabel>::RegType LuaLabel::methods[] = {

View File

@ -11,21 +11,15 @@ public:
static void Register(lua_State *L)
{
lua_getglobal(L, "interface");
int ui = lua_gettop(L);
lua_newtable(L);
int methods = lua_gettop(L);
// push global table to the stack, so we can add the component APIs to it
lua_pushglobaltable(L);
luaL_newmetatable(L, T::className);
int metatable = lua_gettop(L);
// store method table in globals so that
// scripts can add functions written in Lua.
lua_pushstring(L, T::className);
lua_pushvalue(L, methods);
lua_settable(L, -4);
lua_pushliteral(L, "__metatable");
lua_pushvalue(L, methods);
lua_settable(L, metatable); // hide metatable from Lua getmetatable()
@ -42,16 +36,6 @@ public:
lua_pushcfunction(L, gc_T);
lua_settable(L, metatable);
lua_newtable(L); // mt for method table
int mt = lua_gettop(L);
lua_pushliteral(L, "__call");
lua_pushcfunction(L, new_T);
lua_pushliteral(L, "new");
lua_pushvalue(L, -2); // dup new_T function
lua_settable(L, methods); // add new_T to method table
lua_settable(L, mt); // mt.__call = new_T
lua_setmetatable(L, methods);
// fill method table with methods from class T
for (RegType *l = T::methods; l->name; l++)
{
@ -62,7 +46,11 @@ public:
lua_settable(L, methods);
}
lua_pop(L, 3); // pop global table, metatable, and method table
lua_pop(L, 2); // pop metatable, and method table
lua_pushcfunction(L, new_T);
lua_setfield(L, ui, T::className);
lua_pop(L, 1);
}
// get userdata from Lua stack and return pointer to T object
@ -126,7 +114,6 @@ private:
{
if (!lua_gettop(L))
return 0;
lua_remove(L, 1); // use classname:new(), instead of classname.new()
T *obj = new T(L); // call constructor for T objects
userdataType *ud = static_cast<userdataType*>(lua_newuserdata(L, sizeof(userdataType)));

View File

@ -2,7 +2,7 @@
#include "LuaScriptInterface.h"
#include "gui/interface/ProgressBar.h"
const char LuaProgressBar::className[] = "ProgressBar";
const char LuaProgressBar::className[] = "progressBar";
#define method(class, name) {#name, &class::name}
Luna<LuaProgressBar>::RegType LuaProgressBar::methods[] = {

View File

@ -1,114 +0,0 @@
#pragma once
#include "simulation/Particle.h"
#include "simulation/ElementDefs.h"
#include "common/String.h"
#include "LuaCompat.h"
#include <variant>
class GameModel;
class GameController;
class Simulation;
class CommandInterface;
class Graphics;
class Renderer;
extern GameModel * luacon_model;
extern GameController * luacon_controller;
extern Simulation * luacon_sim;
extern bool *luacon_currentCommand;
extern String *luacon_lastError;
extern bool luacon_hasLastError;
class LuaSmartRef;
extern int *lua_el_mode;
extern LuaSmartRef *lua_el_func, *lua_gr_func;
extern int getPartIndex_curIdx;
extern int tptProperties; //Table for some TPT properties
extern int tptPropertiesVersion;
extern int tptElements; //Table for TPT element names
extern int tptParts, tptPartsMeta, tptElementTransitions, tptPartsCData, tptPartMeta, cIndex;
extern LuaSmartRef *tptPart;
void luacon_hook(lua_State *L, lua_Debug *ar);
String luacon_geterror();
void luacon_close();
void initLegacyProps();
int luacon_partsread(lua_State* l);
int luacon_partswrite(lua_State* l);
int luacon_partread(lua_State* l);
int luacon_partwrite(lua_State* l);
int luacon_elementread(lua_State* l);
int luacon_elementwrite(lua_State* l);
int luacon_transitionread(lua_State* l);
int luacon_transitionwrite(lua_State* l);
//int process_command_lua(pixel *vid_buf, char *console, char *console_error);
//tpt. api
int luatpt_getelement(lua_State *l);
int luatpt_create(lua_State* l);
int luatpt_setpause(lua_State* l);
int luatpt_togglepause(lua_State* l);
int luatpt_togglewater(lua_State* l);
int luatpt_setconsole(lua_State* l);
int luatpt_log(lua_State* l);
int luatpt_set_pressure(lua_State* l);
int luatpt_set_gravity(lua_State* l);
int luatpt_reset_gravity_field(lua_State* l);
int luatpt_reset_velocity(lua_State* l);
int luatpt_reset_spark(lua_State* l);
int luatpt_set_property(lua_State* l);
int luatpt_get_property(lua_State* l);
int luatpt_set_wallmap(lua_State* l);
int luatpt_get_wallmap(lua_State* l);
int luatpt_set_elecmap(lua_State* l);
int luatpt_get_elecmap(lua_State* l);
int luatpt_textwidth(lua_State* l);
int luatpt_get_name(lua_State* l);
int luatpt_delete(lua_State* l);
int luatpt_get_numOfParts(lua_State* l);
int luatpt_start_getPartIndex(lua_State* l);
int luatpt_next_getPartIndex(lua_State* l);
int luatpt_getPartIndex(lua_State* l);
int luatpt_hud(lua_State* l);
int luatpt_gravity(lua_State* l);
int luatpt_airheat(lua_State* l);
int luatpt_active_menu(lua_State* l);
int luatpt_menu_enabled(lua_State* l);
int luatpt_num_menus(lua_State* l);
int luatpt_decorations_enable(lua_State* l);
int luatpt_heat(lua_State* l);
int luatpt_cmode_set(lua_State* l);
int luatpt_setfire(lua_State* l);
int luatpt_setdebug(lua_State* l);
int luatpt_setfpscap(lua_State* l);
int luatpt_setdrawcap(lua_State* l);
int luatpt_getscript(lua_State* l);
int luatpt_setwindowsize(lua_State* l);
int luatpt_screenshot(lua_State* l);
int luatpt_record(lua_State* l);
int luatpt_perfectCircle(lua_State* l);

File diff suppressed because it is too large Load Diff

View File

@ -44,7 +44,6 @@ class LuaScriptInterface: public TPTScriptInterface
//Simulation
void initSimulationAPI();
static void set_map(int x, int y, int width, int height, float value, int mapType);
static int simulation_partNeighbours(lua_State * l);
static int simulation_partChangeType(lua_State * l);
static int simulation_partCreate(lua_State * l);
@ -53,11 +52,6 @@ class LuaScriptInterface: public TPTScriptInterface
static int simulation_partID(lua_State * l);
static int simulation_partKill(lua_State * l);
static int simulation_partExists(lua_State * l);
static int simulation_pressure(lua_State * l);
static int simulation_velocityX(lua_State * l);
static int simulation_velocityY(lua_State * l);
static int simulation_gravMap(lua_State * l);
static int simulation_ambientHeat(lua_State * l);
static int simulation_createParts(lua_State * l);
static int simulation_createLine(lua_State * l);
static int simulation_createBox(lua_State * l);
@ -122,7 +116,6 @@ class LuaScriptInterface: public TPTScriptInterface
static int renderer_colourMode(lua_State * l);
static int renderer_decorations(lua_State * l);
static int renderer_grid(lua_State * l);
static int renderer_debugHUD(lua_State * l);
static int renderer_showBrush(lua_State * l);
static int renderer_depth3d(lua_State * l);
static int renderer_zoomEnabled(lua_State *l);
@ -199,9 +192,6 @@ class LuaScriptInterface: public TPTScriptInterface
std::vector<LuaSmartRef> gameControllerEventHandlers;
public:
int tpt_index(lua_State *l);
int tpt_newIndex(lua_State *l);
static void LuaGetProperty(lua_State* l, StructProperty property, intptr_t propertyAddress);
static void LuaSetProperty(lua_State* l, StructProperty property, intptr_t propertyAddress, int stackPos);
static void LuaSetParticleProperty(lua_State* l, int particleID, StructProperty property, intptr_t propertyAddress, int stackPos);

View File

@ -2,7 +2,7 @@
#include "LuaScriptInterface.h"
#include "gui/interface/Slider.h"
const char LuaSlider::className[] = "Slider";
const char LuaSlider::className[] = "slider";
#define method(class, name) {#name, &class::name}
Luna<LuaSlider>::RegType LuaSlider::methods[] = {

View File

@ -23,7 +23,7 @@ namespace LuaSocket
lua_newtable(l);
struct luaL_Reg socketMethods[] = {
{ "sleep", LuaSocket::Sleep },
{ "gettime", LuaSocket::GetTime },
{ "getTime", LuaSocket::GetTime },
{ NULL, NULL },
};
luaL_register(l, NULL, socketMethods);

View File

@ -2,7 +2,7 @@
#include "LuaScriptInterface.h"
#include "gui/interface/Textbox.h"
const char LuaTextbox::className[] = "Textbox";
const char LuaTextbox::className[] = "textbox";
#define method(class, name) {#name, &class::name}
Luna<LuaTextbox>::RegType LuaTextbox::methods[] = {

View File

@ -10,7 +10,7 @@
#include "gui/interface/Engine.h"
#include "graphics/Graphics.h"
const char LuaWindow::className[] = "Window";
const char LuaWindow::className[] = "window";
#define method(class, name) {#name, &class::name}
Luna<LuaWindow>::RegType LuaWindow::methods[] = {

View File

@ -0,0 +1,699 @@
bz2.compressLimit = bz2.COMPRESS_LIMIT
bz2.compressNomem = bz2.COMPRESS_NOMEM
bz2.decompressBad = bz2.DECOMPRESS_BAD
bz2.decompressEof = bz2.DECOMPRESS_EOF
bz2.decompressLimit = bz2.DECOMPRESS_LIMIT
bz2.decompressNomem = bz2.DECOMPRESS_NOMEM
bz2.decompressType = bz2.DECOMPRESS_TYPE
elem.FLAG_MOVABLE = sim.FLAG_MOVABLE
elem.FLAG_PHOTDECO = sim.FLAG_PHOTDECO
elem.FLAG_SKIPMOVE = sim.FLAG_SKIPMOVE
elem.FLAG_STAGNANT = sim.FLAG_STAGNANT
elem.PROP_DRAWONCTYPE = 0
elem.ST_GAS = 0
elem.ST_LIQUID = 0
elem.ST_NONE = 0
elem.ST_SOLID = 0
event.aftersimdraw = event.AFTERSIMDRAW
event.aftersim = event.AFTERSIM
event.beforesimdraw = event.BEFORESIMDRAW
event.beforesim = event.BEFORESIM
event.blur = event.BLUR
event.close = event.CLOSE
event.getmodifiers = event.getModifiers
event.keypress = event.KEYPRESS
event.keyrelease = event.KEYRELEASE
event.mousedown = event.MOUSEDOWN
event.mousemove = event.MOUSEMOVE
event.mouseup = event.MOUSEUP
event.mousewheel = event.MOUSEWHEEL
event.textediting = event.TEXTEDITING
event.textinput = event.TEXTINPUT
event.tick = event.TICK
ren.colourMode = ren.colorMode
sim.can_move = sim.canMove
sim.decoColour = sim.decoColor
sim.framerender = sim.frameRender
sim.gspeed = sim.golSpeedRatio
sim.neighbours = sim.neighbors
sim.partNeighbours = sim.partNeighbors
sim.randomseed = sim.randomSeed
sim.waterEqualisation = sim.waterEqualization
tpt.active_menu = ui.activeMenu
tpt.display_mode = ren.useDisplayPreset
tpt.get_clipboard = plat.clipboardCopy
tpt.get_name = tpt.getUserName
tpt.menu_enabled = ui.menuEnabled
tpt.num_menus = ui.numMenus
tpt.perfectCircleBrush = ui.perfectCircleBrush
tpt.reset_gravity_field = sim.resetGravityField
tpt.reset_spark = sim.resetSpark
tpt.reset_velocity = sim.resetVelocity
tpt.set_clipboard = plat.clipboardPaste
tpt.setdrawcap = tpt.drawCap
tpt.setfpscap = tpt.fpsCap
ui.MOUSE_UP_BLUR = ui.MOUSEUP_BLUR
ui.MOUSE_UP_DRAW_END = ui.MOUSEUP_DRAWEND
ui.MOUSE_UP_NORMAL = ui.MOUSEUP_NORMAL
if socket then
socket.gettime = socket.getTime
end
local function fake_boolean_wrapper(func, true_is_1)
return function(param)
if not param then
return func() and 1 or 0
end
local enable
if true_is_1 then
enable = param == 1
else
enable = param ~= 0
end
func(enable)
end
end
tpt.set_console = fake_boolean_wrapper(ui.console , true )
tpt.ambient_heat = fake_boolean_wrapper(sim.ambientHeatSim , true )
tpt.heat = fake_boolean_wrapper(sim.heatSim , false)
tpt.set_pause = fake_boolean_wrapper(sim.paused , false)
tpt.decorations_enable = fake_boolean_wrapper(ren.decorations , false)
tpt.hud = fake_boolean_wrapper(ren.hud , false)
tpt.newtonian_gravity = fake_boolean_wrapper(sim.newtonianGravity, false)
ren.debugHUD = fake_boolean_wrapper(ren.debugHud , false)
function tpt.setdebug(flags)
-- correct usage passed 0 to 1 arguments
tpt.debug(flags or 0)
end
function sim.gravMap(x, y, ...)
-- correct usage passed 2, 3, or 5 arguments
if select("#", ...) == 0 then
-- 2-argument calls are handled here
local gx, gy = sim.gravityField(x, y)
return math.sqrt(gx * gx + gy * gy)
end
-- sim.gravityMass is compatible with 3- and 5-argument calls
sim.gravityMass(x, y, ...)
end
function tpt.set_wallmap(x, y, ...)
-- correct usage passed 3, 5, or 7 arguments
if select("#", ...) == 5 then
-- 7-argument calls are handled here
local w, h, fvx, fvy, v = ...
sim.wallMap(x, y, w, h, v)
sim.fanVelocityX(x, y, w, h, fvx)
sim.fanVelocityY(x, y, w, h, fvy)
return
end
-- sim.wallMap is compatible with 3- and 5-argument calls
sim.wallMap(x, y, ...)
end
function tpt.get_wallmap(x, y)
-- correct usage passed 0 to 2 arguments
return sim.wallMap(x or 0, y or 0)
end
function tpt.set_elecmap(...)
-- correct usage passed 0 to 5 arguments
local x1, y1, width, height
local argc = select("#", ...)
if argc == 5 then
-- only the 5-argument calls enabled area mode
x1, y1, width, height = ...
else
x1, y1 = ...
x1 = x1 or 0
y1 = y1 or 0
width, height = 1, 1
end
-- value was always the last argument
local value = argc > 0 and select(argc, ...) or 0
-- sim.elecMap is used with a 5-argument call
sim.elecMap(x1, y1, width, height, value)
end
function tpt.get_elecmap(x, y)
-- correct usage passed 0 to 2 arguments
return sim.elecMap(x or 0, y or 0)
end
function tpt.set_pressure(x1, y1, width, height, value)
-- correct usage passed 0 to 5 arguments
return sim.pressure(x1 or 0, y1 or 0, width or sim.XCELLS, height or sim.YCELLS, value or 0)
end
function tpt.set_gravity(x1, y1, width, height, value)
-- correct usage passed 0 to 5 arguments
sim.gravityMass(x1 or 0, y1 or 0, width or sim.XCELLS, height or sim.YCELLS, value or 0)
end
function tpt.setwindowsize(scale, fullscreen)
-- correct usage passed 0 to 2 arguments
ui.windowSize(scale or 1, (fullscreen or 0) == 1)
end
function tpt.setfire(intensity)
-- correct usage passed 0 to 1 arguments
ren.fireSize(intensity or 1)
end
local old_ui_ctor
do
local ctor_mt = {}
function ctor_mt:__call(...)
return self.new(...)
end
function ctor_mt:__newindex()
error("table is read-only", 2)
end
function old_ui_ctor(func)
return setmetatable({ new = function(_, ...)
return func(...)
end }, ctor_mt)
end
end
Slider = old_ui_ctor(ui.slider )
Textbox = old_ui_ctor(ui.textbox )
ProgressBar = old_ui_ctor(ui.progressBar)
Window = old_ui_ctor(ui.window )
Button = old_ui_ctor(ui.button )
Label = old_ui_ctor(ui.label )
Checkbox = old_ui_ctor(ui.checkbox )
function tpt.register_step(f)
event.register(event.tick, f)
end
function tpt.unregister_step(f)
event.unregister(event.tick, f)
end
do
local registered_mouseclicks = {}
function tpt.register_mouseclick(f)
if registered_mouseclicks[f] then return end
local mousex = -1
local mousey = -1
local mousedown = -1
local function mousedownfunc(x, y, button)
--replicate hack in original function
if button == 3 then
button = 4
end
mousex = x
mousey = y
mousedown = button
return f(x, y, button, 1, 0)
end
local function mouseupfunc(x, y, button, evt)
--ignore automatic mouseup event sent when switching windows
if mousedown == -1 and evt == 1 then
return
end
--replicate hack in original function
if button == 3 then
button = 4
end
local evtType = 2
if evt == 1 then
evtType = 4
elseif evt == 2 then
evtType = 5
end
--zoom window cancel
--Original function would have started returning 0 for mousetick events
--(until the actual mousedown), but we don't replicate that here
if evt ~= 2 then
mousedown = -1
end
return f(x, y, button, evtType, 0)
end
local function mousemovefunc(x, y, dx, dy)
mousex = x
mousey = y
end
local function mousewheelfunc(x, y, d)
return f(x, y, 0, 0, d)
end
local function tickfunc()
if mousedown ~= -1 then
return f(mousex, mousey, mousedown, 3, 0)
end
end
event.register(event.mousedown, mousedownfunc)
event.register(event.mouseup, mouseupfunc)
event.register(event.mousemove, mousemovefunc)
event.register(event.mousewheel, mousewheelfunc)
event.register(event.tick, tickfunc)
local funcs = {mousedownfunc, mouseupfunc, mousemovefunc, mousewheelfunc, tickfunc}
registered_mouseclicks[f] = funcs
end
tpt.register_mouseevent = tpt.register_mouseclick
function tpt.unregister_mouseclick(f)
if not registered_mouseclicks[f] then return end
local funcs = registered_mouseclicks[f]
event.unregister(event.mousedown, funcs[1])
event.unregister(event.mouseup, funcs[2])
event.unregister(event.mousemove, funcs[3])
event.unregister(event.mousewheel, funcs[4])
event.unregister(event.tick, funcs[5])
registered_mouseclicks[f] = nil
end
tpt.unregister_mouseevent = tpt.unregister_mouseclick
end
do
local registered_keypresses = {}
local keyMapping = {}
-- lctrl, rctlr, lshift, rshift, lalt, ralt
keyMapping[225] = 304
keyMapping[229] = 303
keyMapping[224] = 306
keyMapping[228] = 305
keyMapping[226] = 308
keyMapping[230] = 307
--up, down, right, left
keyMapping[82] = 273
keyMapping[81] = 274
keyMapping[79] = 275
keyMapping[80] = 276
-- shift mapping for US keyboard layout
local shiftMapping = {
["`"] = "~",
["1"] = "!",
["2"] = "@",
["3"] = "#",
["4"] = "$",
["5"] = "%",
["6"] = "^",
["7"] = "&",
["8"] = "*",
["9"] = "(",
["0"] = ")",
["-"] = "_",
["="] = "+",
["["] = "{",
["]"] = "}",
["\\"] = "|",
[";"] = ":",
["'"] = "\"",
[","] = "<",
["."] = ">",
["/"] = "?"
}
function tpt.register_keypress(f)
if registered_keypresses[f] then return end
local function keypress(key, scan, rep, shift, ctrl, alt)
if rep then return end
local mod = event.getmodifiers()
-- attempt to convert to string representation
local err, keyStr = pcall(string.char, key)
if not err then keyStr = "" end
if keyStr ~= "" and shift then
keyStr = shiftMapping[keyStr] and shiftMapping[keyStr] or string.upper(keyStr)
end
-- key mapping for common keys, extremely incomplete
if keyMapping[scan] then key = keyMapping[scan] end
return f(keyStr, key, mod, 1)
end
local function keyrelease(key, scan, rep, shift, ctrl, alt)
local mod = event.getmodifiers()
-- attempt to convert to string representation
local err, keyStr = pcall(string.char, key)
if not err then keyStr = "" end
-- key mapping for common keys, extremely incomplete
if keyMapping[scan] then key = keyMapping[scan] end
return f(keyStr, key, mod, 2)
end
event.register(event.keypress, keypress)
event.register(event.keyrelease, keyrelease)
local funcs = { keypress, keyrelease }
registered_keypresses[f] = funcs
end
tpt.register_keyevent = tpt.register_keypress
function tpt.unregister_keypress(f)
if not registered_keypresses[f] then return end
local funcs = registered_keypresses[f]
event.unregister(event.keypress, funcs[1])
event.unregister(event.keyrelease, funcs[2])
registered_keypresses[f] = nil
end
tpt.unregister_keyevent = tpt.unregister_keypress
end
function tpt.element_func(f, element, replace)
if f == nil then f = false end
elem.property(element, "Update", f, replace)
end
function tpt.graphics_func(f, element)
if f == nil then f = false end
elem.property(element, "Graphics", f)
end
function tpt.getscript(id, name, run)
if not (id == 1 and name == "autorun.lua" and run == 1) then
error("only use tpt.getscript to install the script manager")
end
tpt.installScriptManager()
end
tpt.drawpixel = gfx.drawPixel
function tpt.drawrect(x, y, w, h, r, g, b, a)
gfx.drawRect(x, y, w + 1, h + 1, r, g, b, a)
end
function tpt.fillrect(x, y, w, h, r, g, b, a)
gfx.fillRect(x + 1, y + 1, w - 1, h - 1, r, g, b, a)
end
tpt.drawline = gfx.drawLine
tpt.drawtext = gfx.drawText
function tpt.textwidth(str)
local width = gfx.textSize(str)
return width - 1
end
function tpt.toggle_pause()
sim.paused(not sim.paused())
return tpt.set_pause()
end
function tpt.watertest()
sim.waterEqualization(not sim.waterEqualization())
return sim.waterEqualization()
end
do
local index = -1
function tpt.start_getPartIndex()
index = -1
end
function tpt.next_getPartIndex()
while true do
index = index + 1
if index >= sim.MAX_PARTS then
index = -1
return false
end
if sim.partExists(index) then
break
end
end
return true
end
function tpt.getPartIndex()
return index
end
end
function tpt.get_numOfParts()
return sim.NUM_PARTS
end
function tpt.element(thing)
if type(thing) == "string" then
local id = elem.getByName(thing)
if id == -1 then
error("Unrecognised element " .. thing, 2)
end
return id
end
return elem.property(thing, "Name")
end
function tpt.create(x, y, thing)
if type(thing) ~= "number" then
thing = tpt.element(thing or "dust")
end
return sim.partCreate(-1, x, y, thing)
end
function tpt.delete(x, y)
if y then
local id = sim.partID(x, y)
if id then
sim.partKill(id)
end
return
end
sim.partKill(x)
end
do
local el_names = {
[ "name" ] = "Name" ,
[ "colour" ] = "Colour" ,
[ "color" ] = "Color" ,
[ "menu" ] = "MenuVisible" ,
[ "menusection" ] = "MenuSection" ,
[ "enabled" ] = "Enabled" ,
[ "advection" ] = "Advection" ,
[ "airdrag" ] = "AirDrag" ,
[ "airloss" ] = "AirLoss" ,
[ "loss" ] = "Loss" ,
[ "collision" ] = "Collision" ,
[ "gravity" ] = "Gravity" ,
[ "newtoniangravity" ] = "NewtonianGravity",
[ "diffusion" ] = "Diffusion" ,
[ "hotair" ] = "HotAir" ,
[ "falldown" ] = "Falldown" ,
[ "flammable" ] = "Flammable" ,
[ "explosive" ] = "Explosive" ,
[ "meltable" ] = "Meltable" ,
[ "hardness" ] = "Hardness" ,
[ "weight" ] = "Weight" ,
[ "heat" ] = "Temperature" ,
[ "hconduct" ] = "HeatConduct" ,
[ "description" ] = "Description" ,
[ "state" ] = "State" ,
[ "properties" ] = "Properties" ,
}
local el_mt = {}
function el_mt:__index(key)
return elem.property(self.id, el_names[key])
end
function el_mt:__newindex(key, value)
elem.property(self.id, el_names[key], value)
end
local eltransition_names = {
[ "presLowValue" ] = "LowPressure" ,
[ "presLowType" ] = "LowPressureTransition" ,
[ "presHighValue" ] = "HighPressure" ,
[ "presHighType" ] = "HighPressureTransition" ,
[ "tempLowValue" ] = "LowTemperature" ,
[ "tempLowType" ] = "LowTemperatureTransition" ,
[ "tempHighValue" ] = "HighTemperature" ,
[ "tempHighType" ] = "HighTemperatureTransition",
}
local eltransition_mt = {}
function eltransition_mt:__index(key)
return elem.property(self.id, eltransition_names[key])
end
function eltransition_mt:__newindex(key, value)
elem.property(self.id, eltransition_names[key], value)
end
tpt.el = {}
tpt.eltransition = {}
for i = 1, sim.PT_NUM do
if elem.exists(i) then
local name = elem.property(i, "Name"):lower()
tpt.el [name] = setmetatable({ id = i }, el_mt )
tpt.eltransition[name] = setmetatable({ id = i }, eltransition_mt)
end
end
local part_mt = {}
local last_id
function part_mt:__index(key)
if not sim.partExists(last_id) then
error("dead particle", 2)
end
if key == "id" then
return last_id
end
return sim.partProperty(last_id, key)
end
function part_mt:__newindex(key, value)
if not sim.partExists(last_id) then
error("dead particle", 2)
end
sim.partProperty(last_id, key, value)
end
local part_proxy = setmetatable({}, part_mt)
local parts_mt = {}
function parts_mt:__index(key)
last_id = key
return part_proxy
end
function parts_mt:__newindex()
error("table is read-only", 2)
end
tpt.parts = setmetatable({}, parts_mt)
end
function tpt.set_property(prop, value, ...)
if type(value) == "string" then
value = tpt.element(value)
end
local argc = select("#", ...)
local filter = argc > 0 and select(argc, ...)
local have_filter = type(filter) == "string"
if not have_filter then
-- fast path for the common cases; the slow path covers these too though
if argc == 1 then
sim.partProperty(..., prop, value)
return
end
if argc == 2 then
local i = sim.partID(...)
if i then
sim.partProperty(i, prop, value)
end
return
end
end
filter = have_filter and tpt.element(filter)
do
-- is this a region?
local x, y, w, h = ...
if type(x) ~= "number" or argc >= 4 then
if argc < 4 then -- we're here because type(x) ~= "number", use default x, y, w, h
x, y, w, h = 0, 0, sim.XRES, sim.YRES
end
for i in sim.parts() do
local ix, iy = sim.partPosition(i)
ix = math.floor(ix + 0.5)
iy = math.floor(iy + 0.5)
if ix >= x and iy >= y and ix < x + w and iy < y + h and (not filter or sim.partProperty(i, "type") == filter) then
sim.partProperty(i, prop, value)
end
end
return
end
end
local x, y = ...
local i
if type(y) == "number" then
i = sim.pmap(x, y)
if i and filter and sim.partProperty(i, "type") ~= filter then
i = nil
end
if not i then
i = sim.photons(x, y)
if i and filter and sim.partProperty(i, "type") ~= filter then
i = nil
end
end
else
i = x
end
if i and filter and sim.partProperty(i, "type") ~= filter then
i = nil
end
if i then
sim.partProperty(i, prop, value)
end
end
function tpt.get_property(prop, x, y)
local i
if type(y) == "number" then
i = sim.partID(x, y)
else
i = sim.partExists(x) and x
end
if i then
if prop == "id" then
return i
end
else
if prop == "type" then
return 0
end
end
return sim.partProperty(i, prop)
end
local sim_mt = {}
function sim_mt:__index(key)
if key == "NUM_PARTS" then
return sim.partCount()
end
end
function sim_mt:__newindex(key)
if key == "NUM_PARTS" then
error("property is read-only", 2)
end
rawset(self, key, value)
end
setmetatable(sim, sim_mt)
local tpt_mt = {}
function tpt_mt:__index(key)
if key == "selectedl" then
return ui.activeTool(0)
elseif key == "mousex" then
local x, y = ui.mousePosition()
return x
elseif key == "mousey" then
local x, y = ui.mousePosition()
return y
elseif key == "selectedr" then
return ui.activeTool(1)
elseif key == "selecteda" then
return ui.activeTool(2)
elseif key == "selectedreplace" then
return ui.activeTool(3)
elseif key == "brushID" then
return ui.brushID()
elseif key == "brushx" then
local w, h = ui.brushRadius()
return w
elseif key == "brushy" then
local w, h = ui.brushRadius()
return h
elseif key == "decoSpace" then
return sim.decoSpace()
end
end
function tpt_mt:__newindex(key, value)
if key == "selectedl" then
return ui.activeTool(0, value)
elseif key == "mousex" then
error("property is read-only", 2)
elseif key == "mousey" then
error("property is read-only", 2)
elseif key == "selectedr" then
return ui.activeTool(1, value)
elseif key == "selecteda" then
return ui.activeTool(2, value)
elseif key == "selectedreplace" then
return ui.activeTool(3, value)
elseif key == "brushID" then
return ui.brushID(value)
elseif key == "brushx" then
local w, h = ui.brushRadius()
ui.brushRadius(value, h)
elseif key == "brushy" then
local w, h = ui.brushRadius()
ui.brushRadius(w, value)
elseif key == "decoSpace" then
return sim.decoSpace(value)
end
rawset(self, key, value)
end
setmetatable(tpt, tpt_mt)

View File

@ -1,258 +0,0 @@
if not event then
return
end
local deprecated_scripts = {}
local timer = nil
local function print_deprecation_warnings()
if not timer or timer <= 0 then
event.unregister(event.tick, print_deprecation_warnings)
else
timer = timer - 1
return
end
local deprecated = {}
for k,v in pairs(deprecated_scripts) do
table.insert(deprecated, k)
end
local start_message = #deprecated == 1 and "This script is" or "These scripts are"
print(start_message.." using a legacy event api and should be updated: ")
print("\""..table.concat(deprecated, "\", \"").."\"")
end
tpt.DEPRECATION_WARNINGS = false
local function deprecationwarning()
if not tpt.DEPRECATION_WARNINGS then return end
local calling_file_info = debug.getinfo(3, "S")
if calling_file_info then
calling_file_info = calling_file_info["short_src"]
if calling_file_info then
deprecated_scripts[calling_file_info] = true
if not timer then
timer = 5
event.register(event.tick, print_deprecation_warnings)
end
end
end
end
function tpt.register_step(f)
deprecationwarning()
event.register(event.tick, f)
end
function tpt.unregister_step(f)
deprecationwarning()
event.unregister(event.tick, f)
end
local registered_mouseclicks = {}
function tpt.register_mouseclick(f)
deprecationwarning()
if registered_mouseclicks[f] then return end
local mousex = -1
local mousey = -1
local mousedown = -1
local function mousedownfunc(x, y, button)
--replicate hack in original function
if button == 3 then
button = 4
end
mousex = x
mousey = y
mousedown = button
return f(x, y, button, 1, 0)
end
local function mouseupfunc(x, y, button, evt)
--ignore automatic mouseup event sent when switching windows
if mousedown == -1 and evt == 1 then
return
end
--replicate hack in original function
if button == 3 then
button = 4
end
local evtType = 2
if evt == 1 then
evtType = 4
elseif evt == 2 then
evtType = 5
end
--zoom window cancel
--Original function would have started returning 0 for mousetick events
--(until the actual mousedown), but we don't replicate that here
if evt ~= 2 then
mousedown = -1
end
return f(x, y, button, evtType, 0)
end
local function mousemovefunc(x, y, dx, dy)
mousex = x
mousey = y
end
local function mousewheelfunc(x, y, d)
return f(x, y, 0, 0, d)
end
local function tickfunc()
if mousedown ~= -1 then
return f(mousex, mousey, mousedown, 3, 0)
end
end
event.register(event.mousedown, mousedownfunc)
event.register(event.mouseup, mouseupfunc)
event.register(event.mousemove, mousemovefunc)
event.register(event.mousewheel, mousewheelfunc)
event.register(event.tick, tickfunc)
local funcs = {mousedownfunc, mouseupfunc, mousemovefunc, mousewheelfunc, tickfunc}
registered_mouseclicks[f] = funcs
end
tpt.register_mouseevent = tpt.register_mouseclick
function tpt.unregister_mouseclick(f)
if not registered_mouseclicks[f] then return end
local funcs = registered_mouseclicks[f]
event.unregister(event.mousedown, funcs[1])
event.unregister(event.mouseup, funcs[2])
event.unregister(event.mousemove, funcs[3])
event.unregister(event.mousewheel, funcs[4])
event.unregister(event.tick, funcs[5])
registered_mouseclicks[f] = nil
end
tpt.unregister_mouseevent = tpt.unregister_mouseclick
local registered_keypresses = {}
function tpt.register_keypress(f)
deprecationwarning()
if registered_keypresses[f] then return end
local keyMapping = {}
-- lctrl, rctlr, lshift, rshift, lalt, ralt
keyMapping[225] = 304
keyMapping[229] = 303
keyMapping[224] = 306
keyMapping[228] = 305
keyMapping[226] = 308
keyMapping[230] = 307
--up, down, right, left
keyMapping[82] = 273
keyMapping[81] = 274
keyMapping[79] = 275
keyMapping[80] = 276
-- shift mapping for US keyboard layout
local shiftMapping = {
["`"] = "~",
["1"] = "!",
["2"] = "@",
["3"] = "#",
["4"] = "$",
["5"] = "%",
["6"] = "^",
["7"] = "&",
["8"] = "*",
["9"] = "(",
["0"] = ")",
["-"] = "_",
["="] = "+",
["["] = "{",
["]"] = "}",
["\\"] = "|",
[";"] = ":",
["'"] = "\"",
[","] = "<",
["."] = ">",
["/"] = "?"
}
local function keypress(key, scan, rep, shift, ctrl, alt)
if rep then return end
local mod = event.getmodifiers()
-- attempt to convert to string representation
err, keyStr = pcall(string.char, key)
if not err then keyStr = "" end
if keyStr ~= "" and shift then
keyStr = shiftMapping[keyStr] and shiftMapping[keyStr] or string.upper(keyStr)
end
-- key mapping for common keys, extremely incomplete
if keyMapping[scan] then key = keyMapping[scan] end
return f(keyStr, key, mod, 1)
end
local function keyrelease(key, scan, rep, shift, ctrl, alt)
local mod = event.getmodifiers()
-- attempt to convert to string representation
err, keyStr = pcall(string.char, key)
if not err then keyStr = "" end
-- key mapping for common keys, extremely incomplete
if keyMapping[scan] then key = keyMapping[scan] end
return f(keyStr, key, mod, 2)
end
event.register(event.keypress, keypress)
event.register(event.keyrelease, keyrelease)
local funcs = { keypress, keyrelease }
registered_keypresses[f] = funcs
end
tpt.register_keyevent = tpt.register_keypress
function tpt.unregister_keypress(f)
if not registered_keypresses[f] then return end
local funcs = registered_keypresses[f]
event.unregister(event.keypress, funcs[1])
event.unregister(event.keyrelease, funcs[2])
registered_keypresses[f] = nil
end
tpt.unregister_keyevent = tpt.unregister_keypress
function tpt.element_func(f, element, replace)
deprecationwarning()
if f == nil then f = false end
elem.property(element, "Update", f, replace)
end
function tpt.graphics_func(f, element)
deprecationwarning()
if f == nil then f = false end
elem.property(element, "Graphics", f)
end
function tpt.getscript(id, name, run)
if not (id == 1 and name == "autorun.lua" and run == 1) then
error("only use tpt.getscript to install the script manager")
end
tpt.installScriptManager()
end
tpt.drawpixel = gfx.drawPixel
function tpt.drawrect(x, y, w, h, r, g, b, a)
gfx.drawRect(x, y, w + 1, h + 1, r, g, b, a)
end
function tpt.fillrect(x, y, w, h, r, g, b, a)
gfx.fillRect(x + 1, y + 1, w - 1, h - 1, r, g, b, a)
end
tpt.drawline = gfx.drawLine
tpt.drawtext = gfx.drawText

View File

@ -1 +1 @@
luaconsole_files += to_array.process('eventcompat.lua', extra_args: 'eventcompat_lua')
luaconsole_files += to_array.process('compat.lua', extra_args: 'compat_lua')

View File

@ -1,5 +1,4 @@
luaconsole_files = files(
'LegacyLuaAPI.cpp',
'LuaButton.cpp',
'LuaCheckbox.cpp',
'LuaCompat.c',

View File

@ -64,10 +64,10 @@ public:
}
template<class Enum, class EnumBase = int>
Enum Get(ByteString path, Enum maxValue, Enum defaultValue) const
Enum Get(ByteString path, Enum numValues, Enum defaultValue) const
{
EnumBase value = Get(path, EnumBase(defaultValue));
if (value < 0 || value >= EnumBase(maxValue))
if (value < 0 || value >= EnumBase(numValues))
{
value = EnumBase(defaultValue);
}

View File

@ -119,7 +119,7 @@ void Air::update_air(void)
{
const float advDistanceMult = 0.7f;
if (airMode != AIR_NO_UPDATE) //airMode 4 is no air/pressure update
if (airMode != AIR_NOUPDATE) //airMode 4 is no air/pressure update
{
for (auto i=0; i<YCELLS; i++) //reduces pressure/velocity on the edges every frame
{
@ -311,10 +311,10 @@ void Air::update_air(void)
default:
case AIR_ON: //Default
break;
case AIR_PRESSURE_OFF: //0 Pressure
case AIR_PRESSUREOFF: //0 Pressure
dp = 0.0f;
break;
case AIR_VELOCITY_OFF: //0 Velocity
case AIR_VELOCITYOFF: //0 Velocity
dx = 0.0f;
dy = 0.0f;
break;
@ -323,7 +323,7 @@ void Air::update_air(void)
dy = 0.0f;
dp = 0.0f;
break;
case AIR_NO_UPDATE: //No Update
case AIR_NOUPDATE: //No Update
break;
}

View File

@ -159,25 +159,11 @@ SimulationSample Simulation::GetSample(int x, int y)
void Simulation::SetDecoSpace(int newDecoSpace)
{
switch (newDecoSpace)
if (newDecoSpace < 0 || newDecoSpace >= NUM_DECOSPACES)
{
case 0: // sRGB
default: // anything stupid
deco_space = 0;
break;
case 1: // linear
deco_space = 1;
break;
case 2: // Gamma = 2.2
deco_space = 2;
break;
case 3: // Gamma = 1.8
deco_space = 3;
break;
newDecoSpace = DECOSPACE_SRGB;
}
deco_space = newDecoSpace;
}
int Simulation::Tool(int x, int y, int tool, int brushX, int brushY, float strength)
@ -506,24 +492,24 @@ void Simulation::ApplyDecoration(int x, int y, int colR_, int colG_, int colB_,
float pb = ((float)((part.dcolour )&0xFF)) / 255.f;
switch (deco_space)
{
case 0: // sRGB
case DECOSPACE_SRGB:
pa = (pa <= 0.04045f) ? (pa / 12.92f) : pow((pa + 0.055f) / 1.055f, 2.4f);
pr = (pr <= 0.04045f) ? (pr / 12.92f) : pow((pr + 0.055f) / 1.055f, 2.4f);
pg = (pg <= 0.04045f) ? (pg / 12.92f) : pow((pg + 0.055f) / 1.055f, 2.4f);
pb = (pb <= 0.04045f) ? (pb / 12.92f) : pow((pb + 0.055f) / 1.055f, 2.4f);
break;
case 1: // linear
case DECOSPACE_LINEAR:
break;
case 2: // Gamma = 2.2
case DECOSPACE_GAMMA22:
pa = pow(pa, 2.2f);
pr = pow(pr, 2.2f);
pg = pow(pg, 2.2f);
pb = pow(pb, 2.2f);
break;
case 3: // Gamma = 1.8
case DECOSPACE_GAMMA18:
pa = pow(pa, 1.8f);
pr = pow(pr, 1.8f);
pg = pow(pg, 1.8f);
@ -544,24 +530,24 @@ void Simulation::ApplyDecoration(int x, int y, int colR_, int colG_, int colB_,
tb = tbs / num;
switch (deco_space)
{
case 0: // sRGB
case DECOSPACE_SRGB:
ta = (ta <= 0.0031308f) ? (ta * 12.92f) : (1.055f * pow(ta, 1.f / 2.4f) - 0.055f);
tr = (tr <= 0.0031308f) ? (tr * 12.92f) : (1.055f * pow(tr, 1.f / 2.4f) - 0.055f);
tg = (tg <= 0.0031308f) ? (tg * 12.92f) : (1.055f * pow(tg, 1.f / 2.4f) - 0.055f);
tb = (tb <= 0.0031308f) ? (tb * 12.92f) : (1.055f * pow(tb, 1.f / 2.4f) - 0.055f);
break;
case 1: // linear
case DECOSPACE_LINEAR:
break;
case 2: // Gamma = 2.2
case DECOSPACE_GAMMA22:
ta = pow(ta, 1.f / 2.2f);
tr = pow(tr, 1.f / 2.2f);
tg = pow(tg, 1.f / 2.2f);
tb = pow(tb, 1.f / 2.2f);
break;
case 3: // Gamma = 1.8
case DECOSPACE_GAMMA18:
ta = pow(ta, 1.f / 1.8f);
tr = pow(tr, 1.f / 1.8f);
tg = pow(tg, 1.f / 1.8f);

View File

@ -3910,7 +3910,7 @@ Simulation::Simulation():
framerender(0),
pretty_powder(0),
sandcolour_frame(0),
deco_space(0)
deco_space(DECOSPACE_SRGB)
{
int tportal_rx[] = {-1, 0, 1, 1, 1, 0,-1,-1};
int tportal_ry[] = {-1,-1,-1, 0, 1, 1, 1, 0};

View File

@ -146,17 +146,26 @@ constexpr auto SPECIFIC_DELETE = UINT32_C(0x00000002);
enum EdgeMode
{
EDGE_VOID, EDGE_SOLID, EDGE_LOOP, NUM_EDGE_MODES
EDGE_VOID, EDGE_SOLID, EDGE_LOOP, NUM_EDGEMODES
};
enum AirMode
{
AIR_ON, AIR_PRESSURE_OFF, AIR_VELOCITY_OFF, AIR_OFF, AIR_NO_UPDATE, NUM_AIR_MODES
AIR_ON, AIR_PRESSUREOFF, AIR_VELOCITYOFF, AIR_OFF, AIR_NOUPDATE, NUM_AIRMODES
};
enum GravityMode
{
GRAV_VERTICAL, GRAV_OFF, GRAV_RADIAL, GRAV_CUSTOM, NUM_GRAV_MODES
GRAV_VERTICAL, GRAV_OFF, GRAV_RADIAL, GRAV_CUSTOM, NUM_GRAVMODES
};
enum DecoSpace
{
DECOSPACE_SRGB,
DECOSPACE_LINEAR,
DECOSPACE_GAMMA22,
DECOSPACE_GAMMA18,
NUM_DECOSPACES,
};
struct CustomGOLData