Add Lua function gui.setlayermask

This change adds a Lua function called gui.setlayermask, which allows Lua
scripts to procedurally modify which render layers are visible. It takes
two arguments: one integer bitfield representing the visibility states for
the main GPU, and the other representing the sub GPU. For example: 0b11111
shows all layers, 0b00000 hides all layers, 0b00001 shows only layer 0
(BG0), 0b10000 shows only layer 5 (OBJ), etc.

Since display layer state is coupled to the frontend, and since frontends
are entirely separate between platforms (i.e., on Windows, toggling
display layer state requires updating the GUI state asl well), this
function is only supported and tested on the Windows build. On MacOS and
Linux, gui.setlayermask will simply return 0 without doing anything.
This commit is contained in:
Alex Forsythe 2019-05-03 21:51:07 -05:00
parent 851274b3e8
commit cc9335eea6
3 changed files with 43 additions and 1 deletions

View File

@ -968,3 +968,28 @@ void TwiddleLayer(UINT ctlid, int core, int layer)
gpu->SetLayerEnableState(layer, newLayerState);
MainWindow->checkMenu(ctlid, newLayerState);
}
void SetLayerMasks(int mainEngineMask, int subEngineMask)
{
static const size_t numCores = sizeof(CommonSettings.dispLayers) / sizeof(CommonSettings.dispLayers[0]);
static const size_t numLayers = sizeof(CommonSettings.dispLayers[0]) / sizeof(CommonSettings.dispLayers[0][0]);
static const UINT ctlids[numCores][numLayers] = {
{IDM_MBG0, IDM_MBG1, IDM_MBG2, IDM_MBG3, IDM_MOBJ},
{IDM_SBG0, IDM_SBG1, IDM_SBG2, IDM_SBG3, IDM_SOBJ},
};
for (int core = 0; core < 2; core++)
{
GPUEngineBase *gpu = (GPUEngineID)core == GPUEngineID_Main ? (GPUEngineBase *)GPU->GetEngineMain() : (GPUEngineBase *)GPU->GetEngineSub();
const int mask = core == 0 ? mainEngineMask : subEngineMask;
for (size_t layer = 0; layer < numLayers; layer++)
{
const bool newLayerState = (mask >> layer) & 0x01 != 0;
if (newLayerState != CommonSettings.dispLayers[core][layer])
{
gpu->SetLayerEnableState(layer, newLayerState);
MainWindow->checkMenu(ctlids[core][layer], newLayerState);
}
}
}
}

View File

@ -105,5 +105,6 @@ FORCEINLINE void ServiceDisplayThreadInvocations()
void UpdateWndRects(HWND hwnd, RECT* newClientRect = NULL);
void TwiddleLayer(UINT ctlid, int core, int layer);
void SetLayerMasks(int mainEngineMask, int subEngineMask);
#endif

View File

@ -28,6 +28,7 @@
#include "frontend/windows/main.h"
#include "frontend/windows/video.h"
#include "frontend/windows/resource.h"
#include "frontend/windows/display.h"
#else
// TODO: define appropriate types for menu
typedef void* PlatformMenu;
@ -3278,6 +3279,20 @@ DEFINE_LUA_FUNCTION(gui_settransparency, "transparency_4_to_0")
return 0;
}
// gui.setlayermask(int top, int bottom)
// enables or disables display layers for each screen according to the bitfields provided
// e.g. 31 (11111) shows all layers; 0 (00000) hides all layers; 16 (10000) shows only the object layer (layer 4)
// this function is only supported by the windows frontend.
DEFINE_LUA_FUNCTION(gui_setlayermask, "top,bottom")
{
#if defined(WIN32)
lua_Integer top = luaL_checkint(L, 1);
lua_Integer bottom = luaL_checkint(L, 2);
SetLayerMasks(top, bottom);
#endif
return 0;
}
// takes a screenshot and returns it in gdstr format
// example: gd.createFromGdStr(gui.gdscreenshot()):png("outputimage.png")
DEFINE_LUA_FUNCTION(gui_gdscreenshot, "[whichScreen='both']")
@ -3849,7 +3864,7 @@ DEFINE_LUA_FUNCTION(emu_registermenustart, "func")
DEFINE_LUA_FUNCTION(emu_set3dtransform, "mode, matrix")
{
extern int freelookMode;
extern int freelookMode;
extern s32 freelookMatrix[16];
int mode = luaL_checkinteger(L,1);
@ -4861,6 +4876,7 @@ static const struct luaL_reg guilib [] =
{"transparency", gui_settransparency},
{"popup", gui_popup},
{"parsecolor", gui_parsecolor},
{"setlayermask", gui_setlayermask},
{"gdscreenshot", gui_gdscreenshot},
{"gdoverlay", gui_gdoverlay},
{"redraw", emu_redraw}, // some people might think of this as more of a GUI function