This page contains notes for the game Bookworm Adventures Volume 2.
|
|
To do: |
The scripts/common directory has the following uncompiled Lua scripts.
App.lua:
class App;
def gApp;
def gCApp;
function App:Init(theCObj)
{
def mCObj = theCObj;
gApp = self;
gCApp = theCObj;
}
function App:WrapWidget(theClass, theDefaultClass, theCObj)
{
if (theClass == nil)
theClass = theDefaultClass;
local aNewObj = theClass:new(theCObj);
return aNewObj;}
function App:CreateLuaWidget(theClass)
{
return WrapWidget(theClass, LuaWidget,
mCObj:CreateLuaWidget());
}
function App:CreateHyperlinkWidget(theId, theListener, theClass)
{
return WrapWidget(theClass, LuaHyperlinkWidget,
mCObj:CreateLuaHyperlinkWidget(theId, theListener.mCObj));
}
function App:CreateLabelWidget(theListener, theClass)
{
return WrapWidget(theClass, LuaLabelWidget,
mCObj:CreateLuaLabelWidget());
}
function App:CreateButtonWidget(theId, theListener, theClass)
{
return WrapWidget(theClass, LuaButtonWidget,
mCObj:CreateLuaButtonWidget(theId, theListener.mCObj));
}
function App:CreateCheckboxWidget(theUncheckedImage, theCheckedImage, theId, theListener, theClass)
{
return WrapWidget(theClass, LuaCheckboxWidget,
mCObj:CreateLuaCheckboxWidget(theUncheckedImage, theCheckedImage, theId, theListener.mCObj));
}
function App:CreateScrollbarWidget(theId, theListener, theClass)
{
return WrapWidget(theClass, LuaScrollbarWidget,
mCObj:CreateLuaScrollbarWidget(theId, theListener.mCObj));
}
function App:CreateEditWidget(theId, theListener, theClass)
{
return WrapWidget(theClass, LuaEditWidget,
mCObj:CreateLuaEditWidget(theId, theListener.mCObj));
}
function App:CreateListWidget(theId, theFont, theListener, theClass)
{
return WrapWidget(theClass, LuaListWidget,
mCObj:CreateLuaListWidget(theId, theFont, theListener.mCObj));
}
function App:CreateDialog(theComponentImage, theButtonComponentImage,
theId, isModal, theDialogHeader, theDialogLines, theDialogFooter, theButtonMode, theClass)
{
local aWidget = WrapWidget(theClass, LuaWidget,
mCObj:CreateLuaDialog(theComponentImage, theButtonComponentImage,
theId, isModal, theDialogHeader, theDialogLines, theDialogFooter, theButtonMode));
gCApp:AddDialog(aWidget.mCObj);
return aWidget;
}
function App:DialogButtonPress(theDialogId, theButtonId)
{
}
function App:DialogButtonDepress(theDialogId, theButtonId)
{
mCObj:KillDialog(theDialogId);
}
RegisterLinkedClass("App", App);
ClassLink.lua:
def gLinkedClassConstructors = {};
def gLinkedClasses = {};
def gLinkedObjectTable = {};
def gLinkedDynCallTable = {};
def gLinkedClassNames = {};
function RegisterLinkedClass(theClassName, theClass)
{
//print("RegisterLinkedClass: "..theClassName);
gLinkedClasses[theClassName] = theClass;
}
function RegisterLinkedConstructor(theClassName, theConstructor)
{
gLinkedClassConstructors[theClassName] = theConstructor;
}
function CreateLinkedObject(theClassName, theCObj)
{
if (gLinkedObjectTable[theCObj] != nil)
return;
gLinkedClassNames[theCObj] = theClassName;
local aClass = gLinkedClasses[theClassName];
if (aClass)
{
gLinkedDynCallTable.a = aClass["new"];
local aLuaObject = gLinkedDynCallTable@aClass:a(theCObj);
gLinkedObjectTable[theCObj] = aLuaObject;
}
else
{
local aConstructor = gLinkedClassConstructors[theClassName];
local aLuaObject = aConstructor(theCObj);
gLinkedObjectTable[theCObj] = aLuaObject;
}
}
function SetLinkedObject(theCObj, theLuaObject)
{
:gLinkedObjectTable[theCObj] = theLuaObject;
}
function DeleteLinkedObject(theCObj)
{
local anObj = :gLinkedObjectTable[theCObj];
if (anObj == nil)
return;
//print("DeleteLinkedObject: class = "..gLinkedClassNames[theCObj]..", address = "..tostring(theCObj));
gLinkedClassNames[theCObj] = nil;
if (table.contains(anObj, "CObjDeleted"))
anObj:CObjDeleted();
:gLinkedObjectTable[theCObj] = nil;
}
function CallLinkedMethod(theCObject, theMethodName, ...)
{
local aLuaObject = gLinkedObjectTable[theCObject];
:gLinkedDynCallTable.a = aLuaObject[theMethodName];
return gLinkedDynCallTable@aLuaObject:a(unpack(arg));
}
function GetLinkedLuaObject(theCObject)
{
return gLinkedObjectTable[theCObject];
}
Common.lua:
require("ClassLink.lua");
require("LuaApp.lua");
require("LuaWidget.lua");
require("DProps.lua");
require("LuaCommonWidgets.lua");
require("Consts.lua");
require("QRand.lua");
function Color(r, g, b, a)
{
if (a == nil)
return {r=r, g=g, b=b, a=255};
else
return {r=r, g=g, b=b, a=a};
}
function IColor(r, g, b, a)
{
if (a ~= nil)
return (a*0x1000000)+(r*0x10000)+(g*0x100)+b;
else
return (0xFF000000)+(r*0x10000)+(g*0x100)+b;
}
function Rect(x, y, width, height)
{
return {mX=x, mY=y, mWidth=width, mHeight=height};
}
function RectContains(theRect, x, y)
{
return ((x >= theRect.mX) && (y >= theRect.mY) &&
(x < theRect.mX + theRect.mWidth) && (y < theRect.mY + theRect.mHeight));
}
function RectUnpack(theRect)
{
return theRect.mX, theRect.mY, theRect.mWidth, theRect.mHeight;
}
function RectIntersects(theRect1, theRect2)
{
return !((theRect2.mX + theRect2.mWidth <= theRect1.mX) ||
(theRect2.mY + theRect2.mHeight <= theRect1.mY) ||
(theRect2.mX >= theRect1.mX + theRect1.mWidth) ||
(theRect2.mY >= theRect1.mY + theRect1.mHeight));
}
function RectIntersection(theRect1, theRect2)
{
local x1 = Math.max(theRect1.mX, theRect2.mX);
local x2 = Math.min(theRect1.mX + theRect1.mWidth, theRect2.mX + theRect2.mWidth);
local y1 = Math.max(theRect1.mY, theRect2.mY);
local y2 = Math.min(theRect1.mY + theRect1.mHeight, theRect2.mY + theRect2.mHeight);
if (x2 - x1 < 0 || y2 - y1 < 0)
return Rect(0,0,0,0);
else
return Rect(x1, y1, x2 - x1, y2 - y1);
}
function Point(x, y) { return {mX = x, mY = y}; }
function Vector(x, y) { return {mX = x, mY = y}; }
function VecDotProd(vec1, vec2) { return vec1.mX*vec2.mX + vec1.mY*vec2.mY; }
function VecMagnitude(theVec) { return Math.sqrt(VecDotProd(theVec, theVec)); }
function VecNormalize(theVec) { local aMag = VecMagnitude(theVec); return VecScale(theVec, 1/aMag); }
function VecScale(theVec, theScale) { return { mX = theVec.mX*theScale, mY = theVec.mY*theScale }; }
function RandFloat()
{
return (Rand()%100000000)/100000000.0;
}
function DupTable(theTable)
{
local aNewTab = {};
for aKey, aVal in theTable
{
aNewTab[aKey] = aVal;
}
return aNewTab;
}
function GetDirectoryFromPos(thePos)
{
local aFileName = string.sub(thePos[0], 1);
local aSlashPos = 0;
for (i < string.len(aFileName))
if (string.sub(aFileName, i, 1) == "\\")
aSlashPos = i;
return string.sub(aFileName, 0, aSlashPos);
}
function URLEncode(theString)
{
local aHexChars = "0123456789ABCDEF";
local aString = "";
if (theString == nil) return aString;
for (i < string.len(theString))
{
local aPattern = string.sub(theString,i,1);
if (string.find(aPattern, "[%w]") == nil) aPattern = "%"..aPattern; // escape non-alphanumeric characters
if (string.sub(theString,i,1) == " ")
aString = aString.."+";
else if (string.find("?&%+\r\n\t", aPattern) != nil)
{
aString = aString.."%";
aString = aString..string.sub(aHexChars,bit.band(int(string.byte(theString,i)/16),0xF),1);
aString = aString..string.sub(aHexChars,bit.band(int(string.byte(theString,i)),0xF),1);
}
else
{
aString = aString..string.sub(theString,i,1);
}
}
return aString;
}
Consts.lua:
def KEYCODE = {};
setprot(KEYCODE);
const KEYCODE.TAB = 0x09;
const KEYCODE.RETURN = 0x0D;
const KEYCODE.SHIFT = 0x10;
const KEYCODE.CONTROL = 0x11;
const KEYCODE.MENU = 0x12;
const KEYCODE.ALT = 0x12;
const KEYCODE.ESCAPE = 0x1B;
const KEYCODE.PGUP = 0x21;
const KEYCODE.PGDN = 0x22;
const KEYCODE.END = 0x23;
const KEYCODE.HOME = 0x24;
const KEYCODE.LEFT = 0x25;
const KEYCODE.UP = 0x26;
const KEYCODE.RIGHT = 0x27;
const KEYCODE.DOWN = 0x28;
const KEYCODE.INSERT = 0x2D;
const KEYCODE.DELETE = 0x2E;
def D3DIMAGEFLAGS = {};
setprot(D3DIMAGEFLAGS);
const D3DIMAGEFLAGS.MinimizeNumSubdivisions = 0x0001;
const D3DIMAGEFLAGS.Use64By64Subdivisions = 0x0002;
const D3DIMAGEFLAGS.UseA4R4G4B4 = 0x0004;
const D3DIMAGEFLAGS.UseA8R8G8B8 = 0x0008;
def CURSOR = {};
setprot(CURSOR);
const CURSOR.POINTER = 0;
const CURSOR.HAND = 1;
const CURSOR.DRAGGING = 2;
const CURSOR.TEXT = 3;
const CURSOR.CIRCLE_SLASH = 4;
const CURSOR.SIZEALL = 5;
const CURSOR.SIZENESW = 6;
const CURSOR.SIZENS = 7;
const CURSOR.SIZENWSE = 8;
const CURSOR.SIZEWE = 9;
const CURSOR.WAIT = 10;
const CURSOR.NONE = 11;
const CURSOR.CUSTOM = 12;
def DIALOG = {};
setprot(DIALOG);
def DIALOG.BUTTONS = {};
setprot(DIALOG.BUTTONS);
const DIALOG.BUTTONS.NONE = 0;
const DIALOG.BUTTONS.YES_NO = 1;
const DIALOG.BUTTONS.OK_CANCEL = 2;
const DIALOG.BUTTONS.FOOTER = 3;
def DIALOG.ID = {};
setprot(DIALOG.ID);
const DIALOG.ID.YES = 1000;
const DIALOG.ID.NO = 1001;
const DIALOG.ID.OK = 1000;
const DIALOG.ID.CANCEL = 1001;
const DIALOG.ID.FOOTER = 1000;
def DRAWMODE = {};
setprot(DRAWMODE);
const DRAWMODE.NORMAL = 0;
const DRAWMODE.ADDITIVE = 1;
DProps.lua:
class DProps : LuaWidget;
class DPropsShared
{
def mWidgetTypes = {};
def mWidgetTypeOrder = {};
def mObjects = {};
def mWidgetToLuaWidget = {};
def mCurAddWidgetType;
def mLastAddWidgetX;
def mLastAddWidgetY;
def mGridOn;
def mGridSizeX;
def mGridSizeY;
def mGridOfsX;
def mGridOfsY;
}
function DPropsShared:Load()
{
mLastAddWidgetX = gCApp:RegistryRead("LastAddWidgetX");
mLastAddWidgetY = gCApp:RegistryRead("LastAddWidgetY");
mGridOn = gCApp:RegistryRead("GridOn", false);
mGridSizeX = gCApp:RegistryRead("GridSizeX", 8);
mGridSizeY = gCApp:RegistryRead("GridSizeY", 8);
mGridOfsX = gCApp:RegistryRead("GridOfsX", 0);
mGridOfsY = gCApp:RegistryRead("GridOfsY", 0);
}
function DPropsShared:Save()
{
gCApp:RegistryWrite("LastAddWidgetX", mLastAddWidgetX);
gCApp:RegistryWrite("LastAddWidgetY", mLastAddWidgetY);
gCApp:RegistryWrite("GridOn", mGridOn);
gCApp:RegistryWrite("GridSizeX", mGridSizeX);
gCApp:RegistryWrite("GridSizeY", mGridSizeY);
gCApp:RegistryWrite("GridOfsX", mGridOfsX);
gCApp:RegistryWrite("GridOfsY", mGridOfsY);
}
DProps.mShared = DPropsShared:new();
DProps.mEditing = false;
function dptrack(thePos, theTrackInfo)
{
local anObj = theTrackInfo[0];
// Get object tab
local anObjTab = DProps.mShared.mObjects[anObj];
// Get file table
local aFileTab = anObjTab.mFiles[thePos[0]];
if (aFileTab == nil)
{
aFileTab = {};
anObjTab.mFiles[thePos[0]] = aFileTab;
}
// Store setting information
aFileTab[thePos[1]] = {theTrackInfo[1], theTrackInfo[2], theTrackInfo[3], theTrackInfo[4]};
// Get props table
for (aPropNum < *theTrackInfo[3])
{
anObjTab.mProps[theTrackInfo[3][aPropNum]] = theTrackInfo[4][aPropNum];
local aPropsPos = anObjTab.mPropsPos[theTrackInfo[3][aPropNum]];
if (aPropsPos != nil)
anObjTab.mFiles[aPropsPos[0]][aPropsPos[1]] = nil; // Remove the old entry
anObjTab.mPropsPos[theTrackInfo[3][aPropNum]] = thePos;
}
}
function DProps.AddWidgetType(theName, theClass, theImage, theImageNum)
{
if (*DProps.mShared.mWidgetTypeOrder == 0)
DProps.mShared.mCurAddWidgetType = theName;
if (DProps.mShared.mWidgetTypes[theName] == nil)
DProps.mShared.mWidgetTypeOrder[*DProps.mShared.mWidgetTypeOrder] = theName;
DProps.mShared.mWidgetTypes[theName] =
{mName=theName, mClass=theClass, mImage=theImage, mImageNum=theImageNum};
}
function DProps.WidgetCreated(theWidget)
{
local aCWidget = theWidget.mCObj:GetWidget();
DProps.mShared.mWidgetToLuaWidget[aCWidget] = theWidget;
local anObjTab = {mProps={}, mPropsPos={}, mFiles={}, mDrawOrder=0};
DProps.mShared.mObjects[theWidget] = anObjTab;
}
function DProps.WidgetDeleted(theWidget)
{
DProps.mShared.mObjects[theWidget] = nil;
local aCWidget = theWidget.mCObj:GetWidget();
DProps.mShared.mWidgetToLuaWidget[aCWidget] = nil;
}
//////////////////////////////////////////////////////////////////////////
function DProps.DProps_Loader(theCObj)
{
DProps.mShared:Load();
require("DProps_Editor.lua");
return DProps:new(theCObj);
}
RegisterLinkedConstructor("DPropsWidget", DProps.DProps_Loader);
LuaApp.lua:
class LuaApp;
def gApp;
def gCApp;
function LuaApp:Init(theCObj)
{
def mCObj = theCObj;
gApp = self;
gCApp = theCObj;
}
function LuaApp:WrapWidget(theClass, theDefaultClass, theCObj)
{
if (theClass == nil)
theClass = theDefaultClass;
local aNewObj = theClass:new(theCObj);
return aNewObj;}
function LuaApp:CreateLuaWidget(theClass)
{
return WrapWidget(theClass, LuaWidget,
mCObj:CreateLuaWidget());
}
function LuaApp:CreateHyperlinkWidget(theId, theListener, theClass)
{
return WrapWidget(theClass, LuaHyperlinkWidget,
mCObj:CreateLuaHyperlinkWidget(theId, theListener.mCObj));
}
function LuaApp:CreateTextWidget(theClass)
{
return WrapWidget(theClass, LuaTextWidget,
mCObj:CreateLuaTextWidget());
}
function LuaApp:CreateButtonWidget(theId, theListener, theClass)
{
return WrapWidget(theClass, LuaButtonWidget,
mCObj:CreateLuaButtonWidget(theId, theListener.mCObj));
}
function LuaApp:CreateCheckboxWidget(theUncheckedImage, theCheckedImage, theId, theListener, theClass)
{
return WrapWidget(theClass, LuaCheckboxWidget,
mCObj:CreateLuaCheckboxWidget(theUncheckedImage, theCheckedImage, theId, theListener.mCObj));
}
function LuaApp:CreateScrollbarWidget(theId, theListener, theClass)
{
return WrapWidget(theClass, LuaScrollbarWidget,
mCObj:CreateLuaScrollbarWidget(theId, theListener.mCObj));
}
function LuaApp:CreateEditWidget(theId, theListener, theClass)
{
return WrapWidget(theClass, LuaEditWidget,
mCObj:CreateLuaEditWidget(theId, theListener.mCObj));
}
function LuaApp:CreateListWidget(theId, theFont, theListener, theClass)
{
return WrapWidget(theClass, LuaListWidget,
mCObj:CreateLuaListWidget(theId, theFont, theListener.mCObj));
}
function LuaApp:CreateDialog(theComponentImage, theButtonComponentImage,
theId, isModal, theDialogHeader, theDialogLines, theDialogFooter, theButtonMode, theClass)
{
local aWidget = WrapWidget(theClass, LuaWidget,
mCObj:CreateLuaDialog(theComponentImage, theButtonComponentImage,
theId, isModal, theDialogHeader, theDialogLines, theDialogFooter, theButtonMode));
gCApp:AddDialog(aWidget.mCObj);
return aWidget;
}
function LuaApp:DialogButtonPress(theDialogId, theButtonId)
{
}
function LuaApp:DialogButtonDepress(theDialogId, theButtonId)
{
mCObj:KillDialog(theDialogId);
}
function LuaApp:DebugKeyDown(theKey)
{
return mCObj:DebugKeyDown(theKey);
}
RegisterLinkedClass("LuaApp", LuaApp);
LuaCommonWidgets.lua:
//////////////////////////////////////////////////////////////////////////
class LuaDialog : LuaWidget(theCObj)
{
super:Init(theCObj);
}
function LuaDialog:Create(theComponentImage, theButtonComponentImage,
theId, isModal, theDialogHeader, theDialogLines, theDialogFooter, theButtonMode)
{
local aWidget = gApp:CreateDialog(theComponentImage, theButtonComponentImage,
theId, isModal, theDialogHeader, theDialogLines, theDialogFooter, theButtonMode, self);
gCApp:GetWidgetManager():AddWidget(aWidget.mCObj);
return aWidget;
}
//////////////////////////////////////////////////////////////////////////
class LuaButtonWidget : LuaWidget(theCObj)
{
super:Init(theCObj);
}
function LuaButtonWidget:Create(theId, theParent)
{
local aWidget = gApp:CreateButtonWidget(theId, theParent, self);
theParent:AddWidget(aWidget);
return aWidget;
}
function LuaButtonWidget:SetLabel(theStr)
{
mCObj:SetLabel(theStr);
}
function LuaButtonWidget:SetLabel_DYN(thePos, theStr)
{
SetLabel(theStr);
dptrack(thePos, {self, SetLabel, 0, {"Label"}, {theStr}});
}
function LuaButtonWidget.DPGetDefaultSize()
{
return 80, 24;
}
function LuaButtonWidget.DPGetCreateDefault(thePos, theParent, theX, theY, theWidth, theHeight)
{
local aWidget = LuaButtonWidget:Create(-1, theParent);
thePos[1]++;
aWidget:SetLabel_DYN(thePos, "Button");
thePos[1]++;
aWidget:Resize_DYN(thePos, theX, theY, theWidth, theHeight);
return aWidget, {"local aButton = LuaButtonWidget:Create(-1, self);",
"aButton:SetLabel_DYN(__POS, \"Button\");",
"aButton:Resize_DYN(__POS, " .. theX .. ", " .. theY .. ", " .. theWidth .. ", " .. theHeight .. ");"};
}
//////////////////////////////////////////////////////////////////////////
class LuaCheckboxWidget : LuaWidget(theCObj)
{
super:Init(theCObj);
}
function LuaCheckboxWidget:Create(theId, theParent)
{
local aWidget = gApp:CreateCheckboxWidget(nil, nil, theId, theParent, self);
theParent:AddWidget(aWidget);
return aWidget;
}
function LuaCheckboxWidget.DPGetDefaultSize()
{
return 16, 16;
}
function LuaCheckboxWidget:SetChecked(checked)
{
mCObj:SetChecked(checked);
}
function LuaCheckboxWidget:SetChecked_DYN(thePos, checked)
{
SetChecked(checked);
dptrack(thePos, {self, SetChecked, 0, {"Checked"}, {checked}});
}
function LuaCheckboxWidget.DPGetCreateDefault(thePos, theParent, theX, theY, theWidth, theHeight)
{
local aWidget = LuaCheckboxWidget:Create(-1, theParent);
thePos[1]++;
aWidget:Resize_DYN(thePos, theX, theY, theWidth, theHeight);
thePos[1]++;
aWidget:SetChecked_DYN(thePos, false);
return aWidget, {"local aCheckbox = LuaCheckboxWidget:Create(-1, self);",
"aCheckbox:SetChecked_DYN(__POS, false);",
"aCheckbox:Resize_DYN(__POS, " .. theX .. ", " .. theY .. ", " .. theWidth .. ", " .. theHeight .. ");"};
}
//////////////////////////////////////////////////////////////////////////
class LuaEditWidget : LuaWidget(theCObj)
{
super:Init(theCObj);
}
function LuaEditWidget:Create(theId, theParent)
{
local aWidget = gApp:CreateEditWidget(theId, theParent, self);
theParent:AddWidget(aWidget);
return aWidget;
}
function LuaEditWidget.DPGetDefaultSize()
{
return 80, 24;
}
function LuaEditWidget.DPGetCreateDefault(thePos, theParent, theX, theY, theWidth, theHeight)
{
local aWidget = LuaEditWidget:Create(-1, theParent);
thePos[1]++;
aWidget:Resize_DYN(thePos, theX, theY, theWidth, theHeight);
return aWidget, {"local aEdit = LuaEditWidget:Create(-1, self);",
"aEdit:Resize_DYN(__POS, " .. theX .. ", " .. theY .. ", " .. theWidth .. ", " .. theHeight .. ");"};
}
//////////////////////////////////////////////////////////////////////////
class LuaListWidget : LuaWidget(theCObj)
{
super:Init(theCObj);
}
function LuaListWidget:Create(theId, theParent)
{
local aWidget = gApp:CreateListWidget(theId, nil, theParent, self);
theParent:AddWidget(aWidget);
return aWidget;
}
function LuaListWidget.DPGetDefaultSize()
{
return 80, 64;
}
function LuaListWidget.DPGetCreateDefault(thePos, theParent, theX, theY, theWidth, theHeight)
{
local aWidget = LuaListWidget:Create(-1, theParent);
thePos[1]++;
aWidget:Resize_DYN(thePos, theX, theY, theWidth, theHeight);
return aWidget, {"local aList = LuaListWidget:Create(-1, self);",
"aList:Resize_DYN(__POS, " .. theX .. ", " .. theY .. ", " .. theWidth .. ", " .. theHeight .. ");"};
}
//////////////////////////////////////////////////////////////////////////
class LuaTextWidget : LuaWidget(theCObj)
{
super:Init(theCObj);
}
function LuaTextWidget:Create(theParent)
{
local aWidget = gApp:CreateTextWidget(self);
theParent:AddWidget(aWidget);
return aWidget;
}
function LuaTextWidget:IsPointVisible(theX, theY)
{
// Allow us to select it if we're editing
return DProps.mEditing;
}
function LuaTextWidget:SetLabel(theStr)
{
mCObj:SetLabel(theStr);
}
function LuaTextWidget:SetLabel_DYN(thePos, theStr)
{
SetLabel(theStr);
dptrack(thePos, {self, SetLabel, 0, {"Label"}, {theStr}});
}
function LuaTextWidget:SetLineSpacing(theLineSpacing)
{
mCObj:SetLineSpacing(theLineSpacing);
}
function LuaTextWidget:SetLineSpacing_DYN(thePos, theLineSpacing)
{
SetLineSpacing(theLineSpacing);
dptrack(thePos, {self, SetLineSpacing, 0, {"Line Spacing"}, {theLineSpacing}});
}
function LuaTextWidget:SetJustification(theJustification)
{
mCObj:SetJustification(theJustification);
}
function LuaTextWidget:SetJustification_DYN(thePos, theJustification)
{
SetJustification(theJustification);
dptrack(thePos, {self, SetJustification, 0, {"Justification"}, {theJustification}});
}
function LuaTextWidget.DPGetDefaultSize()
{
return 128, 16;
}
function LuaTextWidget.DPGetCreateDefault(thePos, theParent, theX, theY, theWidth, theHeight)
{
local aWidget = LuaTextWidget:Create(theParent);
thePos[1]++;
aWidget:SetLabel_DYN(thePos, "Text");
thePos[1]++;
aWidget:SetLineSpacing_DYN(thePos, -1);
thePos[1]++;
aWidget:SetJustification_DYN(thePos, -1);
thePos[1]++;
aWidget:Resize_DYN(thePos, theX, theY, theWidth, theHeight);
thePos[1]++;
aWidget:SetColors_DYN(thePos, {0xFFFFFFFF});
return aWidget, {"local aText = LuaTextWidget:Create(self);",
"aText:SetLabel_DYN(__POS, \"Text\");",
"aText:SetLineSpacing_DYN(__POS, -1);",
"aText:SetJustification_DYN(__POS, -1);",
"aText:Resize_DYN(__POS, " .. theX .. ", " .. theY .. ", " .. theWidth .. ", " .. theHeight .. ");",
"aText:SetColors_DYN(__POS, {0xFFFFFFFF});"};
}
//////////////////////////////////////////////////////////////////////////
class LuaScrollbarWidget : LuaWidget(theCObj)
{
super:Init(theCObj);
}
function LuaScrollbarWidget:Create(theId, theParent)
{
local aWidget = gApp:CreateScrollbarWidget(theId, theParent, self);
theParent:AddWidget(aWidget);
return aWidget;
}
function LuaScrollbarWidget:ResizeScrollbar(theX, theY, theWidth, theHeight)
{
mCObj:ResizeScrollbar(theX, theY, theWidth, theHeight);
}
function LuaScrollbarWidget:ResizeScrollbar_DYN(thePos, theX, theY, theWidth, theHeight)
{
ResizeScrollbar(theX, theY, theWidth, theHeight);
dptrack(thePos, {self, LuaScrollbarWidget.ResizeScrollbar, 0, {"X", "Y", "Width", "Height"}, {theX, theY, theWidth, theHeight}});
}
function LuaScrollbarWidget.DPGetDefaultSize()
{
return 16, 64;
}
function LuaScrollbarWidget.DPGetCreateDefault(thePos, theParent, theX, theY, theWidth, theHeight)
{
local aWidget = LuaScrollbarWidget:Create(-1, theParent);
thePos[1]++;
aWidget:ResizeScrollbar_DYN(thePos, theX, theY, theWidth, theHeight);
return aWidget, {"local aScrollbar = LuaScrollbarWidget:Create(-1, self);",
"aScrollbar:ResizeScrollbar_DYN(__POS, " .. theX .. ", " .. theY .. ", " .. theWidth .. ", " .. theHeight .. ");"};
}
//////////////////////////////////////////////////////////////////////////
class LuaHorzScrollbarWidget : LuaScrollbarWidget(theCObj)
{
super:Init(theCObj);
}
function LuaHorzScrollbarWidget:Create(theId, theParent)
{
local aWidget = gApp:CreateScrollbarWidget(theId, theParent, self);
theParent:AddWidget(aWidget);
aWidget.mCObj:SetHorizontal(true);
return aWidget;
}
function LuaHorzScrollbarWidget.DPGetDefaultSize()
{
return 64, 16;
}
function LuaHorzScrollbarWidget.DPGetCreateDefault(thePos, theParent, theX, theY, theWidth, theHeight)
{
local aWidget = LuaHorzScrollbarWidget:Create(-1, theParent);
thePos[1]++;
aWidget:ResizeScrollbar_DYN(thePos, theX, theY, theWidth, theHeight);
return aWidget, {"local aScrollbar = LuaHorzScrollbarWidget:Create(-1, self);",
"aScrollbar:ResizeScrollbar_DYN(__POS, " .. theX .. ", " .. theY .. ", " .. theWidth .. ", " .. theHeight .. ");"};
}
//////////////////////////////////////////////////////////////////////////
class LuaHyperlinkWidget : LuaWidget(theCObj)
{
super:Init(theCObj);
}
function LuaHyperlinkWidget:Create(theId, theParent)
{
local aWidget = gApp:CreateHyperlinkWidget(theId, theParent, self);
theParent:AddWidget(aWidget);
return aWidget;
}
function LuaHyperlinkWidget:SetLabel(theStr)
{
mCObj:SetLabel(theStr);
}
function LuaHyperlinkWidget:SetLabel_DYN(thePos, theStr)
{
SetLabel(theStr);
dptrack(thePos, {self, SetLabel, 0, {"Label"}, {theStr}});
}
function LuaHyperlinkWidget.DPGetDefaultSize()
{
return 128, 20;
}
function LuaHyperlinkWidget.DPGetCreateDefault(thePos, theParent, theX, theY, theWidth, theHeight)
{
local aWidget = LuaHyperlinkWidget:Create(-1, theParent);
thePos[1]++;
aWidget:SetLabel_DYN(thePos, "Hyperlink");
thePos[1]++;
aWidget:Resize_DYN(thePos, theX, theY, theWidth, theHeight);
thePos[1]++;
aWidget:SetColors_DYN(thePos, {0xFFFFFF00, 0xFFFFFFFF});
return aWidget, {"local aHyperlink = LuaHyperlinkWidget:Create(-1, self);",
"aHyperlink:SetLabel_DYN(__POS, \"Hyperlink\");",
"aHyperlink:Resize_DYN(__POS, " .. theX .. ", " .. theY .. ", " .. theWidth .. ", " .. theHeight .. ");",
"aHyperlink:SetColors_DYN(__POS, {0xFFFFFF00, 0xFFFFFFFF});"};
}
//////////////////////////////////////////////////////////////////////////
DProps.AddWidgetType("Button", LuaButtonWidget, nil, 0);
DProps.AddWidgetType("Checkbox", LuaCheckboxWidget, nil, 1);
DProps.AddWidgetType("Edit", LuaEditWidget, nil, 2);
DProps.AddWidgetType("List", LuaListWidget, nil, 3);
DProps.AddWidgetType("Text", LuaTextWidget, nil, 4);
DProps.AddWidgetType("Horz Scrollbar", LuaHorzScrollbarWidget, nil, 5);
DProps.AddWidgetType("Vert Scrollbar", LuaScrollbarWidget, nil, 6);
DProps.AddWidgetType("Hyperlink", LuaHyperlinkWidget, nil, 7);
//////////////////////////////////////////////////////////////////////////
RegisterLinkedClass("LuaButtonWidget", LuaButtonWidget);
LuaWidget.lua:
class LuaWidget(theCObj)
{
def mCObj = theCObj;
def mUpdateCnt = 0;
def mChildren = {};
setprot(mChildren, "l");
DProps.WidgetCreated(self);
:SetLinkedObject(theCObj, self);
theCObj:RegisterObject();
}
function LuaWidget:Create(theParent)
{
local aWidget = gApp:CreateLuaWidget(self);
theParent:AddWidget(aWidget);
return aWidget;
}
function LuaWidget:CObjDeleted()
{
DProps.WidgetDeleted(self);
}
//////////////////////////////////////////////////////////////////////////
function LuaWidget:Update()
{
mUpdateCnt++;
mCObj:Update();
}
function LuaWidget:Draw(g)
{
mCObj:Draw();
}
function LuaWidget:DrawOverlay(g)
{
mCObj:DrawOverlay();
}
function LuaWidget:IsPointVisible(theX, theY)
{
return true;
}
function LuaWidget:MouseEnter()
{
mCObj:MouseEnter();
}
function LuaWidget:MouseLeave()
{
mCObj:MouseLeave();
}
function LuaWidget:MouseMove(theX, theY)
{
mCObj:MouseMove(theX, theY);
}
function LuaWidget:MouseDrag(theX, theY)
{
mCObj:MouseDrag(theX, theY);
}
function LuaWidget:MouseDown(theX, theY, theBtnNum, theClickCount)
{
mCObj:MouseDown(theX, theY, theBtnNum, theClickCount);
}
function LuaWidget:MouseUp(theX, theY, theBtnNum, theClickCount)
{
mCObj:MouseUp(theX, theY, theBtnNum, theClickCount);
}
function LuaWidget:MouseWheel(theDelta)
{
mCObj:MouseWheel(theDelta);
}
function LuaWidget:KeyChar(theChar)
{
mCObj:KeyChar(theChar);
}
function LuaWidget:KeyDown(theKey)
{
mCObj:KeyDown(theKey);
}
function LuaWidget:KeyUp(theKey)
{
mCObj:KeyUp(theKey);
}
function LuaWidget:GotFocus()
{
mCObj:GotFocus();
}
function LuaWidget:LostFocus()
{
mCObj:LostFocus();
}
function LuaWidget:WantsFocus()
{
return mCObj:WantsFocus();
}
///
function LuaWidget:CheckboxChecked(theId, checked)
{
mCObj:CheckboxChecked(theId, checked);
}
function LuaWidget:ButtonPress(theBtnId, theClickCount)
{
mCObj:ButtonPress(theBtnId, theClickCount);
}
function LuaWidget:ButtonDepress(theBtnId)
{
mCObj:ButtonDepress(theBtnId);
}
function LuaWidget:ButtonMouseEnter(theId)
{
mCObj:ButtonMouseEnter(theId);
}
function LuaWidget:ButtonMouseLeave(theId)
{
mCObj:ButtonMouseLeave(theId);
}
function LuaWidget:ButtonMouseMove(theId, theX, theY)
{
mCObj:ButtonMouseMove(theId, theX, theY);
}
function LuaWidget:ButtonDownTick(theId, theClickCount)
{
mCObj:ButtonDownTick(theId, theClickCount);
}
function LuaWidget:ScrollPosition(theId, thePosition)
{
mCObj:ScrollPosition(theId, thePosition);
}
function LuaWidget:EditWidgetText(theId, theString)
{
mCObj:EditWidgetText(theId, theString);
}
function LuaWidget:AllowKey(theId, theKey)
{
return mCObj:AllowKey(theId, theKey);
}
function LuaWidget:AllowChar(theId, theChar)
{
return mCObj:AllowChar(theId, theChar);
}
function LuaWidget:AllowText(theId, theText)
{
return mCObj:AllowText(theId, theText);
}
function LuaWidget:ListClicked(theId, theIdx, theClickCount)
{
mCObj:ListClicked(theId, theIdx, theClickCount);
}
function LuaWidget:ListClosed(theId)
{
mCObj:ListClosed(theId);
}
function LuaWidget:ListHiliteChanged(theId, theOldIdx, theNewIdx)
{
mCObj:ListHiliteChanged(theId, theOldIdx, theNewIdx);
}
//////////////////////////////////////////////////////////////////////////
function LuaWidget:Resize(theX, theY, theWidth, theHeight)
{
mCObj:Resize(theX, theY, theWidth, theHeight);
}
function LuaWidget:Resize_DYN(thePos, theX, theY, theWidth, theHeight)
{
Resize(theX, theY, theWidth, theHeight);
dptrack(thePos, {self, LuaWidget.Resize, 0, {"X", "Y", "Width", "Height"}, {theX, theY, theWidth, theHeight}});
}
function LuaWidget:Move(theX, theY)
{
mCObj:Resize(theX, theY, mCObj:GetWidth(), mCObj:GetHeight());
}
function LuaWidget:SetColors(theColors)
{
mCObj:SetColors(theColors);
}
function LuaWidget:SetColors_DYN(thePos, theColors)
{
mCObj:SetColors(theColors);
dptrack(thePos, {self, LuaWidget.SetColors, 0, {"Colors"}, {theColors}});
}
function LuaWidget:AddWidget(theWidget)
{
if (table.contains(theWidget.mCObj, "GetID"))
mChildren[theWidget.mCObj:GetID()] = theWidget;
mCObj:AddWidget(theWidget.mCObj);
}
function LuaWidget:RemoveWidget(theWidget)
{
if (table.contains(theWidget.mCObj, "GetID"))
mChildren[theWidget.mCObj:GetID()] = nil;
mCObj:RemoveWidget(theWidget.mCObj);
}
//////////////////////////////////////////////////////////////////////////
RegisterLinkedClass("LuaWidget", LuaWidget);
QRand.lua:
//def mQRand = QRand:new(0.25, 0.5, 0.75, 0.1);
class QRand(...)
{
def mUpdateCnt = 0;
def mWeights = {};
def mLastHitUpdate = {};
def mPrevLastHitUpdate = {};
def mCurSway = {};
def mLastIndex = -1;
SetWeights(unpack(arg));
}
function QRand:SetWeights(...)
{
if (arg.n == 1)
{
mWeights[0] = 1.0 - arg[0];
mWeights[1] = arg[0];
}
else
{
local aTotal = 0.0;
for (anArgNum < arg.n)
{
mWeights[anArgNum] = arg[anArgNum];
aTotal += mWeights[anArgNum];
}
for (aWeightNum < *mWeights)
mWeights[aWeightNum] /= aTotal;
}
for (i = *mLastHitUpdate, *mWeights-1, 1)
{
mLastHitUpdate[i] = 0;
mPrevLastHitUpdate[i] = 0;
}
}
function QRand:Next()
{
mUpdateCnt++;
//local aStr = "";
local aTotalWeight = 0.0;
for (aResultNum,aWeight in mWeights)
{
if (aWeight != 0)
{
local anAvgLength = 1.0 / aWeight;
local aPctOff = 1.0 + (((mUpdateCnt - mLastHitUpdate[aResultNum]) - anAvgLength) / anAvgLength);
local aPrevPctOff = 1.0 + (((mUpdateCnt - mPrevLastHitUpdate[aResultNum]) - anAvgLength*2) / (anAvgLength*2));
local aSway = aWeight * math.max(math.min(aPctOff*0.75 + aPrevPctOff*0.25, 3.0), 0.333);
//aSway = aWeight; // Comment this in to get a normal random number generator
mCurSway[aResultNum] = aSway;
aTotalWeight += aSway;
//aStr = aStr .. aSway .. " ";
}
else
mCurSway[aResultNum] = 0;
}
local aRand = math.random() * aTotalWeight;
local anIdx = 0;
while (aRand > mCurSway[anIdx])
{
aRand -= mCurSway[anIdx];
anIdx++;
}
mPrevLastHitUpdate[anIdx] = mLastHitUpdate[anIdx];
mLastHitUpdate[anIdx] = mUpdateCnt;
mLastIndex = anIdx;
return anIdx;
}