Skip to content

Commit

Permalink
Final work on scripting before next release
Browse files Browse the repository at this point in the history
  • Loading branch information
ZILtoid1991 committed Oct 1, 2023
1 parent a906873 commit a40d564
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 45 deletions.
50 changes: 44 additions & 6 deletions assets/test4.lua
Original file line number Diff line number Diff line change
@@ -1,12 +1,50 @@
Globalstate = 0
Titlescreen = true

--Script entry point
function Main(luastate)
Globalstate = luastate
local sprtLayer = getLayer(16)
addSprite(sprtLayer, getBitmapResource("Titlescreen"), 0, 0, 0, 0, 0, 255, 1024, 1024, 0)
end
--Horrible tone generator, using the engine's own RNG
function OnNextNote()
function OnNextNote_Title()
local r = rng_Seed()
local audioModule = getAudioModule(0)
--Melody 1
midiCMD(audioModule, 0x40803c00 + ((r % 18) * 256), 0xFFFF0000, 0x00000000, 0x00000000)
r = rng_Seed()
--Melody 2
midiCMD(audioModule, 0x40813000 + ((r % 20) * 256), 0xFFFF0000, 0x00000000, 0x00000000)
r = rng_Seed()
--Bass
if (r % 12) > 5 then
r = rng_Seed()
midiCMD(audioModule, 0x40821600 + ((r % 12) * 256), 0xFFFF0000, 0x00000000, 0x00000000)
end
--Rhythm
r = rng_Seed()
--Cymbals
if (r % 20) == 0 then
midiCMD(audioModule, 0x40836000, 0xFFFF0000, 0x00000000, 0x00000000)
else
midiCMD(audioModule, 0x40846000, 0xFFFF0000, 0x00000000, 0x00000000)
end
--Kick
if (r % 7) == 0 then
midiCMD(audioModule, 0x40852000, 0xFFFF0000, 0x00000000, 0x00000000)
end
--Snare
if (r % 9) == 0 then
midiCMD(audioModule, 0x40856000, 0xFFFF0000, 0x00000000, 0x00000000)
end

if Titlescreen then
timer_register(Globalstate, 250, "OnNextNote_Title")
end
end

function NextBus()

function ToSelection()
Titlescreen = false
end

function PrevBus()

end
9 changes: 9 additions & 0 deletions dub.sdl
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,15 @@ subPackage {
sourcePaths "./test3/"
importPaths "./test3/"
}
/* subPackage {
name "test4"
dependency "pixelperfectengine" version="*"
targetType "executable"
targetPath "./bin-$ARCH-$PLATFORM/"
lflags "/PDB:.\\bin-$ARCH-$PLATFORM\\pixelperfectengine_test4.pdb" platform="windows"
sourcePaths "./test4/"
importPaths "./test4/"
} */
subPackage {
name "test5"
dependency "pixelperfectengine" version="*"
Expand Down
27 changes: 22 additions & 5 deletions pixelperfectengine/src/pixelperfectengine/scripting/lua.d
Original file line number Diff line number Diff line change
Expand Up @@ -136,17 +136,18 @@ extern(C) public int registerDFunction(alias Func)(lua_State* state) nothrow
return 1;
}
}

/**
* Registers a D delegate to be called from Lua.
* Registers a D member function to be called from Lua.
* Code is modified from MrcSnm's example found in the HipremeEngine.
* Params:
* state = The Lua state to handle the data from the Lua side of things.
* Template params:
* Func = The function to be registered.
* Note: When calling a D delegate from Lua, the first parameter is always a light user data
* containing the class instance that the delegate should be executed on.
* Note: When calling a D member function from Lua, the first parameter is always a light user data
* containing the class instance that the member function should be executed on.
*/
extern (C) public int registerDDelegate(alias Func)(lua_State* state) nothrow
extern (C) public int registerDMemberFunc(alias Func)(lua_State* state) nothrow
if(isSomeFunction!(Func)) {
import std.traits:Parameters, ReturnType;
alias ClassType = __traits(parent, Func);
Expand All @@ -156,6 +157,10 @@ extern (C) public int registerDDelegate(alias Func)(lua_State* state) nothrow
ClassType c;
try {
c = luaGetFromIndex!ClassType(state, stackCounter);
if (c is null) {
luaL_error(state, "Wrong lightweight userdata was passed to member function!");
return 1;
}
foreach_reverse(ref param; params) {
stackCounter--;
param = luaGetFromIndex!(typeof(param))(state, stackCounter);
Expand Down Expand Up @@ -260,6 +265,14 @@ public struct LuaVar {
public this(T)(T val) @safe pure nothrow {
static if (is(T == void*) || is(T == LuaTable*)) {
dataPtr = val;
} else static if (is(T == class) || is(T == interface)) {
void __workaround() @system pure nothrow {
dataPtr = cast(void*)val;
}
void _workaround() @trusted pure nothrow {
__workaround();
}
_workaround();
} else static if (isIntegral!T || isBoolean!T) {
dataInt = val;
} else static if (isFloatingPoint!T) {
Expand Down Expand Up @@ -499,6 +512,7 @@ public class LuaScript {
throw new LuaException(LUA_ERRMEM, "Memory error!");
}
registerLibForScripting(state);
/* lua_register(state, "getLuaState", &registerDFunction!(function void*(){return this.getLuaState_internal();})); */
}
///Automatically deallocates the lua_State variable.
~this() {
Expand All @@ -508,13 +522,16 @@ public class LuaScript {
public lua_State* getState() @nogc nothrow pure {
return state;
}
/* protected void* getLuaState_internal() @nogc nothrow {
return cast(void*)state;
} */
/**
* Executes the main function of the scipt.
* Returns: A LuaVar variable with the appropriate return value if there was any.
* Throws: A LuaException if the execution ran into an error, or the function isn't found.
*/
public LuaVar runMain() {
return callLuaFunc!(LuaVar)(state, "main");
return callLuaFunc!(LuaVar)(state, "Main", cast(void*)state);
}
extern(C)
private static const(char*) reader(lua_State* st, void* data, size_t* size) nothrow {
Expand Down
78 changes: 50 additions & 28 deletions pixelperfectengine/src/pixelperfectengine/scripting/lualib.d
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,24 @@ public void registerLibForScripting(lua_State* state) {
lua_register(state, "setLayerRenderingMode", &registerDFunction!setLayerRenderingMode);
lua_register(state, "scrollLayer", &registerDFunction!(scrollLayer));
lua_register(state, "relScrollLayer", &registerDFunction!(relScrollLayer));
lua_register(state, "getLayerScrollX", &registerDDelegate!(Layer.getSX));
lua_register(state, "getLayerScrollY", &registerDDelegate!(Layer.getSY));
lua_register(state, "getLayerScrollX", &registerDMemberFunc!(Layer.getSX));
lua_register(state, "getLayerScrollY", &registerDMemberFunc!(Layer.getSY));
lua_register(state, "addTile", &registerDMemberFunc!(ITileLayer.addTile));
//lua_register(state, "setTileMaterial", &registerDFunction!(setTileMaterial));

lua_register(state, "readMapping", &registerDFunction!readMapping);
lua_register(state, "tileByPixel", &registerDFunction!tileByPixel);
lua_register(state, "writeMapping", &registerDFunction!writeMapping);
lua_register(state, "getTileWidth", &registerDDelegate!(ITileLayer.getTileWidth));
lua_register(state, "getTileHeight", &registerDDelegate!(ITileLayer.getTileHeight));
lua_register(state, "getMapWidth", &registerDDelegate!(ITileLayer.getMX));
lua_register(state, "getMapHeight", &registerDDelegate!(ITileLayer.getMY));
lua_register(state, "getTileWidth", &registerDDelegate!(ITileLayer.getTX));
lua_register(state, "getTileHeight", &registerDDelegate!(ITileLayer.getTY));
lua_register(state, "clearTilemap", &registerDDelegate!(ITileLayer.clearTilemap));
lua_register(state, "addTile", &registerDDelegate!(ITileLayer.addTile));
lua_register(state, "getTile", &registerDDelegate!(ITileLayer.getTile));
lua_register(state, "removeTile", &registerDDelegate!(ITileLayer.removeTile));
lua_register(state, "getTileWidth", &registerDMemberFunc!(ITileLayer.getTileWidth));
lua_register(state, "getTileHeight", &registerDMemberFunc!(ITileLayer.getTileHeight));
lua_register(state, "getMapWidth", &registerDMemberFunc!(ITileLayer.getMX));
lua_register(state, "getMapHeight", &registerDMemberFunc!(ITileLayer.getMY));
lua_register(state, "getTileWidth", &registerDMemberFunc!(ITileLayer.getTX));
lua_register(state, "getTileHeight", &registerDMemberFunc!(ITileLayer.getTY));
lua_register(state, "clearTilemap", &registerDMemberFunc!(ITileLayer.clearTilemap));
lua_register(state, "addTile", &registerDMemberFunc!(ITileLayer.addTile));
lua_register(state, "getTile", &registerDMemberFunc!(ITileLayer.getTile));
lua_register(state, "removeTile", &registerDMemberFunc!(ITileLayer.removeTile));

lua_register(state, "ttl_setA", &registerDFunction!ttl_setA);
lua_register(state, "ttl_setB", &registerDFunction!ttl_setB);
Expand All @@ -63,23 +65,33 @@ public void registerLibForScripting(lua_State* state) {

lua_register(state, "moveSprite", &registerDFunction!(moveSprite));
lua_register(state, "relMoveSprite", &registerDFunction!(relMoveSprite));
lua_register(state, "getSpriteCoordinate", &registerDDelegate!(ISpriteLayer.getSpriteCoordinate));
lua_register(state, "getSpriteCoordinate", &registerDMemberFunc!(ISpriteLayer.getSpriteCoordinate));
lua_register(state, "setSpriteSlice", &registerDFunction!setSpriteSlice);
lua_register(state, "getSpriteSlice", &registerDDelegate!(ISpriteLayer.getSlice));
lua_register(state, "addSprite", &registerDDelegate!(ISpriteLayer.addSprite));
lua_register(state, "removeSprite", &registerDDelegate!(ISpriteLayer.removeSprite));
lua_register(state, "getPaletteID", &registerDDelegate!(ISpriteLayer.getPaletteID));
lua_register(state, "setPaletteID", &registerDDelegate!(ISpriteLayer.setPaletteID));
lua_register(state, "scaleSpriteHoriz", &registerDDelegate!(ISpriteLayer.scaleSpriteHoriz));
lua_register(state, "scaleSpriteVert", &registerDDelegate!(ISpriteLayer.scaleSpriteVert));
lua_register(state, "getScaleSpriteHoriz", &registerDDelegate!(ISpriteLayer.getScaleSpriteHoriz));
lua_register(state, "getScaleSpriteVert", &registerDDelegate!(ISpriteLayer.getScaleSpriteVert));
lua_register(state, "getSpriteSlice", &registerDMemberFunc!(ISpriteLayer.getSlice));
lua_register(state, "addSprite", &registerDMemberFunc!(ISpriteLayer.addSprite));
lua_register(state, "removeSprite", &registerDMemberFunc!(ISpriteLayer.removeSprite));
lua_register(state, "getPaletteID", &registerDMemberFunc!(ISpriteLayer.getPaletteID));
lua_register(state, "setPaletteID", &registerDMemberFunc!(ISpriteLayer.setPaletteID));
lua_register(state, "scaleSpriteHoriz", &registerDMemberFunc!(ISpriteLayer.scaleSpriteHoriz));
lua_register(state, "scaleSpriteVert", &registerDMemberFunc!(ISpriteLayer.scaleSpriteVert));
lua_register(state, "getScaleSpriteHoriz", &registerDMemberFunc!(ISpriteLayer.getScaleSpriteHoriz));
lua_register(state, "getScaleSpriteVert", &registerDMemberFunc!(ISpriteLayer.getScaleSpriteVert));

lua_register(state, "getBitmapWidth", &registerDDelegate!(ABitmap.width));
lua_register(state, "getBitmapHeight", &registerDDelegate!(ABitmap.height));
lua_register(state, "getBitmapWidth", &registerDMemberFunc!(ABitmap.width));
lua_register(state, "getBitmapHeight", &registerDMemberFunc!(ABitmap.height));

lua_register(state, "getBitmapResource", &registerDFunction!getBitmapResource);
lua_register(state, "loadBitmapResource", &registerDFunction!loadBitmapResource);

lua_register(state, "getAudioModule", &registerDFunction!getAudioModule);
lua_register(state, "midiCMD", &registerDFunction!midiCMD);

lua_register(state, "rng_Seed", &registerDFunction!rng_Seed);
lua_register(state, "rng_Dice", &registerDFunction!rng_Dice);

lua_register(state, "timer_resume", &registerDFunction!timer_resume);
lua_register(state, "timer_suspend", &registerDFunction!timer_suspend);
lua_register(state, "timer_register", &registerDFunction!timer_register);
}
package void scrollLayer(Layer l, LuaVar x, LuaVar y) {
l.scroll(cast(int)x, cast(int)y);
Expand Down Expand Up @@ -335,7 +347,7 @@ package int loadBitmapResource(string path, string resID, int paletteOffset) {
}
return 0;
}
package int setTileMaterial(int layerID, int tileID, string resID, int paletteSh) {
/* package int setTileMaterial(int layerID, int tileID, string resID, int paletteSh) {
ITileLayer itl = cast(ITileLayer)mainRaster.layerMap[layerID];
if (itl !is null) {
try {
Expand All @@ -347,11 +359,21 @@ package int setTileMaterial(int layerID, int tileID, string resID, int paletteSh
} else {
return 1;
}
}
} */

package ulong rngSeed() @nogc nothrow {
package ulong rng_Seed() @nogc nothrow {
return rng.seed();
}
package ulong rngDice(uint s) @nogc nothrow {
package ulong rng_Dice(uint s) @nogc nothrow {
return rng.dice(s);
}

package void timer_suspend() {
timer.suspendTimer;
}
package void timer_resume() {
timer.resumeTimer;
}
package void timer_register(void* state, uint ms, string func) {
timer.register(delegate void(Duration){callLuaFunc!void(cast(lua_State*)state, func);}, msecs(ms));
}
2 changes: 2 additions & 0 deletions pixelperfectengine/src/pixelperfectengine/system/timer.d
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ public class CoarseTimer {
timeSuspend = MonoTime.currTime;
}
}
alias suspend = suspendTimer;
/**
* Resumes timer and shifts all entries by given time delta.
*/
Expand All @@ -109,4 +110,5 @@ public class CoarseTimer {
}
}
}
alias resume = resumeTimer;
}
32 changes: 26 additions & 6 deletions test4/app.d
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ import pixelperfectengine.audio.base.midiseq; //MIDI sequencer
import pixelperfectengine.map.mapformat;
//Other imports that might be important. Uncomment any you feel you'll need.
/* import pixelperfectengine.system.common; */
import pixelperfectengine.scripting.lua;
import pixelperfectengine.scripting.globals;


///Our main function, needed for the program to operate.
///You can add `string[] args` if your either really need or really want.
Expand Down Expand Up @@ -86,8 +89,8 @@ public class GameApp : SystemEventListener, InputListener {
///Contains pointer to the game field, so we can easily interact with it.
SpriteLayer gameField;
///Contains the random number generator and its state.
RandomNumberGenerator rng;
ConfigurationProfile cfg;
//RandomNumberGenerator rng;
//ConfigurationProfile cfg;
//Audio related stuff goes here.
//Note: some of the audio stuff is preliminary. It works, but cannot handle certain cases, such as sample rate mismatches, or device disconnection.
//Sequencer is untested as of now due to a lack of time and manpower.
Expand All @@ -114,23 +117,40 @@ public class GameApp : SystemEventListener, InputListener {
textLayer.paletteOffset = 512; //Sets the palette offset to 512. You might want to change this to the value to the place where you loaded your GUI palette
textLayer.masterVal = 127; //Sets the master value for the alpha blending, making this layer semi-transparent initially.

cfg = new ConfigurationProfile(); //Creates and loads the configuration profile.
//cfg = new ConfigurationProfile(); //Creates and loads the configuration profile.
//Comment the next part out, if you're having too much trouble with audio working, since you still can add sound later on.
//audio related part begin
AudioDeviceHandler.initAudioDriver(OS_PREFERRED_DRIVER); //Initializes the driver
AudioSpecs as = AudioSpecs(predefinedFormats[PredefinedFormats.FP32], cfg.audioFrequency, 0, 2, cfg.audioBufferLen,
AudioSpecs as = AudioSpecs(predefinedFormats[PredefinedFormats.FP32], 48_000, 0, 2, cfg.audioBufferLen,
Duration.init); //Sets up a default audio specification
adh = new AudioDeviceHandler(as, cfg.audioBufferLen, cfg.audioBufferLen / cfg.audioFrameLen); //Creates a new AudioDeviceHandler and sets up the basics
adh = new AudioDeviceHandler(as, 1024, 1024 / 128); //Creates a new AudioDeviceHandler and sets up the basics
adh.initAudioDevice(-1); //Initializes the default device
modMan = new ModuleManager(adh); //Initializes the module manager
modCfg = new ModuleConfig(modMan); //Initializes the module configurator
modCfg.loadConfigFromFile("yourAudioConfiguration.sdl");//This line loads an audio configuration file (make sure you have a valid one - create one with the ADK/test1!)
modCfg.loadConfigFromFile("../assets/test4_audio.sdl");//This line loads an audio configuration file (make sure you have a valid one - create one with the ADK/test1!)
modCfg.compile(false); //Compiles the current module configuration.
midiSeq = new SequencerM1(modMan.moduleList, modCfg.midiRouting, modCfg.midiGroups);
modMan.runAudioThread(); //Runs the audio thread.
//audio related part end

//<Put other initialization code here>
{
import pixelperfectengine.system.input.scancode;
ih.addBinding(BindingCode(ScanCode.UP, 0, Devicetype.Keyboard, 0, KeyModifier.LockKeys), InputBinding("up"));
ih.addBinding(BindingCode(ScanCode.DOWN, 0, Devicetype.Keyboard, 0, KeyModifier.LockKeys), InputBinding("down"));
ih.addBinding(BindingCode(ScanCode.LEFT, 0, Devicetype.Keyboard, 0, KeyModifier.LockKeys), InputBinding("left"));
ih.addBinding(BindingCode(ScanCode.RIGHT, 0, Devicetype.Keyboard, 0, KeyModifier.LockKeys), InputBinding("right"));
ih.addBinding(BindingCode(ScanCode.SPACE, 0, Devicetype.Keyboard, 0, KeyModifier.LockKeys), InputBinding("space"));
ih.addBinding(BindingCode(ScanCode.LALT, 0, Devicetype.Keyboard, 0, KeyModifier.LockKeys), InputBinding("leftalt"));

ih.addBinding(BindingCode(11, 0, Devicetype.Joystick), InputBinding("up"));
ih.addBinding(BindingCode(12, 0, Devicetype.Joystick), InputBinding("down"));
ih.addBinding(BindingCode(13, 0, Devicetype.Joystick), InputBinding("left"));
ih.addBinding(BindingCode(14, 0, Devicetype.Joystick), InputBinding("right"));
ih.addBinding(BindingCode(1, 0, Devicetype.Joystick), InputBinding("space"));
ih.addBinding(BindingCode(2, 0, Devicetype.Joystick), InputBinding("leftalt"));
}

}
void whereTheMagicHappens() {
while (stateFlags.isRunning) {
Expand Down

0 comments on commit a40d564

Please sign in to comment.