mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-04 02:45:35 +00:00
Preparation for console
git-svn-id: https://openmw.svn.sourceforge.net/svnroot/openmw/trunk@103 ea6a568a-9f4f-0410-981a-c910a81bb256
This commit is contained in:
parent
714b724bf2
commit
1b01de4294
25 changed files with 470 additions and 127 deletions
2
Makefile
2
Makefile
|
@ -38,7 +38,7 @@ bullet_cpp_files=$(bullet_cpp:%=bullet/cpp_%.cpp)
|
|||
# All object files needed by openmw and esmtool
|
||||
src := $(wildcard bsa/*.d) $(wildcard bullet/*.d) $(wildcard core/*.d) \
|
||||
$(wildcard esm/*.d) $(wildcard input/*.d) $(wildcard nif/*.d) $(wildcard ogre/*.d) \
|
||||
$(wildcard scene/*.d) $(wildcard sound/*.d) $(wildcard util/*.d)
|
||||
$(wildcard scene/*.d) $(wildcard sound/*.d) $(wildcard util/*.d) $(wildcard gui/*.d)
|
||||
src := $(src) $(wildcard mscripts/*.d)
|
||||
src := $(src) monster/monster.d \
|
||||
$(wildcard monster/vm/*.d) \
|
||||
|
|
|
@ -35,8 +35,11 @@ extern(C):
|
|||
// Initialize the dynamic world. Returns non-zero if an error occurs.
|
||||
int bullet_init();
|
||||
|
||||
// Switch to the next physics mode
|
||||
// Set physics modes
|
||||
void bullet_nextMode();
|
||||
void bullet_walk();
|
||||
void bullet_fly();
|
||||
void bullet_ghost();
|
||||
|
||||
// Warp the player to a specific location.
|
||||
void bullet_movePlayer(float x, float y, float z);
|
||||
|
|
|
@ -206,29 +206,45 @@ extern "C" int32_t bullet_init()
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Set physics modes
|
||||
extern "C" void bullet_walk()
|
||||
{
|
||||
g_physMode = PHYS_WALK;
|
||||
cout << "Walk mode\n";
|
||||
}
|
||||
|
||||
extern "C" void bullet_fly()
|
||||
{
|
||||
g_physMode = PHYS_FLY;
|
||||
cout << "Fly mode\n";
|
||||
}
|
||||
|
||||
extern "C" void bullet_ghost()
|
||||
{
|
||||
g_physMode = PHYS_GHOST;
|
||||
cout << "Ghost mode\n";
|
||||
}
|
||||
|
||||
// Switch to the next physics mode
|
||||
extern "C" void bullet_nextMode()
|
||||
{
|
||||
g_physMode++;
|
||||
if(g_physMode > PHYS_GHOST)
|
||||
g_physMode = PHYS_WALK;
|
||||
|
||||
switch(g_physMode)
|
||||
{
|
||||
case PHYS_WALK:
|
||||
cout << "Entering walking mode\n";
|
||||
bullet_fly();
|
||||
break;
|
||||
case PHYS_FLY:
|
||||
cout << "Entering flying mode\n";
|
||||
bullet_ghost();
|
||||
break;
|
||||
case PHYS_GHOST:
|
||||
cout << "Entering ghost mode\n";
|
||||
bullet_walk();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Warp the player to a specific location. We do not bother setting
|
||||
// rotation, since it's completely irrelevant for collision detection.
|
||||
// rotation, since it's completely irrelevant for collision detection,
|
||||
// and doubly so since the collision mesh is a sphere.
|
||||
extern "C" void bullet_movePlayer(float x, float y, float z)
|
||||
{
|
||||
btTransform tr;
|
||||
|
|
|
@ -164,7 +164,7 @@ struct NPC
|
|||
|
||||
skipRecord();
|
||||
|
||||
makeProto("Person");
|
||||
makeProto();
|
||||
|
||||
// Clean this up a little later, eg. no point in storing the
|
||||
// structs outside the function any longer. Same goes for most of
|
||||
|
|
53
gui/bindings.d
Normal file
53
gui/bindings.d
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
OpenMW - The completely unofficial reimplementation of Morrowind
|
||||
Copyright (C) 2008 Nicolay Korslund
|
||||
Email: < korslund@gmail.com >
|
||||
WWW: http://openmw.snaptoad.com/
|
||||
|
||||
This file (bindings.d) is part of the OpenMW package.
|
||||
|
||||
OpenMW is distributed as free software: you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License
|
||||
version 3, as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
version 3 along with this program. If not, see
|
||||
http://www.gnu.org/licenses/ .
|
||||
|
||||
*/
|
||||
|
||||
module gui.bindings;
|
||||
|
||||
extern(C):
|
||||
|
||||
// GUI functions. Under development. The corresponding C++ functions
|
||||
// are in ogre/cpp_mygui.cpp
|
||||
|
||||
typedef void* WidgetPtr;
|
||||
void gui_setupGUI(int debugOut);
|
||||
void gui_toggleGui();
|
||||
void gui_setCellName(char *str);
|
||||
|
||||
// Get the widget type, as a string
|
||||
char *gui_widgetType(WidgetPtr);
|
||||
|
||||
// Get the height or width of a widget. If the argument is null,
|
||||
// return the size of the screen.
|
||||
int gui_getHeight(WidgetPtr);
|
||||
int gui_getWidth(WidgetPtr);
|
||||
|
||||
// Set various properties of a given widget
|
||||
void gui_setCaption(WidgetPtr, char*);
|
||||
void gui_setNeedMouseFocus(WidgetPtr, int);
|
||||
void gui_setTextColor(WidgetPtr, float,float,float);
|
||||
void gui_setCoord(WidgetPtr, int,int,int,int);
|
||||
|
||||
// Various ways to get or create widgets
|
||||
WidgetPtr gui_loadLayout(char *file, char *prefix, WidgetPtr parent);
|
||||
WidgetPtr gui_getChild(WidgetPtr, char*);
|
||||
WidgetPtr gui_createText(char *skin, int x, int y, int w, int h, char *layer);
|
|
@ -21,11 +21,11 @@
|
|||
|
||||
*/
|
||||
|
||||
module ogre.gui;
|
||||
module gui.gui;
|
||||
|
||||
import monster.monster;
|
||||
import monster.vm.mclass;
|
||||
import ogre.bindings;
|
||||
import gui.bindings;
|
||||
import std.string;
|
||||
|
||||
// Widget class and gui module
|
||||
|
@ -57,7 +57,7 @@ class MWidget
|
|||
isLayout = true;
|
||||
prefix = format("%s", cast(void*)this);
|
||||
|
||||
widget = gui_loadLayout(layout.ptr, prefix.ptr, parent);
|
||||
widget = gui_loadLayout(layout.toStringz(), prefix.toStringz(), parent);
|
||||
if(widget is null)
|
||||
fail("Layout " ~ layout ~ " is empty");
|
||||
|
||||
|
@ -91,7 +91,7 @@ class MWidget
|
|||
name = prefix ~ name;
|
||||
|
||||
// Get the child widget
|
||||
auto pt = gui_getChild(widget, name.ptr);
|
||||
auto pt = gui_getChild(widget, name.toStringz());
|
||||
|
||||
if(pt is null)
|
||||
fail("Widget has no child named " ~ name);
|
||||
|
@ -163,7 +163,7 @@ void setCaption()
|
|||
foreach(AIndex ind; args)
|
||||
res ~= format("%s", arrays.getRef(ind).carr);
|
||||
|
||||
gui_setCaption(getOwner(), res.ptr);
|
||||
gui_setCaption(getOwner(), toStringz(res));
|
||||
}
|
||||
void setNeedMouseFocus()
|
||||
{ gui_setNeedMouseFocus(getOwner(), stack.popBool); }
|
||||
|
@ -211,9 +211,9 @@ void text()
|
|||
int y = stack.popInt();
|
||||
int x = stack.popInt();
|
||||
char[] skin = stack.popString8();
|
||||
WidgetPtr ptr = gui_createText(skin.ptr,
|
||||
WidgetPtr ptr = gui_createText(skin.toStringz(),
|
||||
x,y,w,h,
|
||||
layer.ptr);
|
||||
layer.toStringz());
|
||||
assert(widgetType(ptr) == "StaticText");
|
||||
MWidget mw = new MWidget(ptr);
|
||||
stack.pushObject(mw.mo);
|
|
@ -213,7 +213,7 @@ void initializeInput()
|
|||
{
|
||||
// Move the player into place. TODO: This isn't really input-related
|
||||
// at all, and should be moved.
|
||||
with(playerData.position)
|
||||
with(*playerData.position)
|
||||
{
|
||||
ogre_moveCamera(position[0], position[1], position[2]);
|
||||
ogre_setCameraRotation(rotation[0], rotation[1], rotation[2]);
|
||||
|
@ -305,6 +305,11 @@ extern(C) int d_frameStarted(float time, int guiMode)
|
|||
bullet_getPlayerPos(&x, &y, &z);
|
||||
ogre_moveCamera(x,y,z);
|
||||
|
||||
// Store it in the player object
|
||||
playerData.position.position[0] = x;
|
||||
playerData.position.position[1] = y;
|
||||
playerData.position.position[2] = z;
|
||||
|
||||
// Tell the sound scene that the player has moved
|
||||
sndCumTime += time;
|
||||
if(sndCumTime > sndRefresh)
|
||||
|
|
|
@ -1180,12 +1180,26 @@ class ExprStatement : Statement
|
|||
// Require a terminating semicolon or line break
|
||||
bool term = true;
|
||||
|
||||
// True if 'left' was set in the constructor
|
||||
bool leftSet = false;
|
||||
|
||||
this(Expression lft=null)
|
||||
{
|
||||
left = lft;
|
||||
if(left !is null)
|
||||
leftSet = true;
|
||||
}
|
||||
|
||||
void parse(ref TokenArray toks)
|
||||
{
|
||||
if(toks.length == 0)
|
||||
fail("Expected statement, found end of stream.");
|
||||
loc = toks[0].loc;
|
||||
left = Expression.identify(toks);
|
||||
if(left is null)
|
||||
{
|
||||
if(toks.length == 0)
|
||||
fail("Expected statement, found end of stream.");
|
||||
left = Expression.identify(toks);
|
||||
}
|
||||
|
||||
loc = left.loc;
|
||||
|
||||
Token tok;
|
||||
|
||||
|
@ -1219,7 +1233,8 @@ class ExprStatement : Statement
|
|||
|
||||
void resolve(Scope sc)
|
||||
{
|
||||
left.resolve(sc);
|
||||
if(!leftSet)
|
||||
left.resolve(sc);
|
||||
|
||||
loc = left.loc;
|
||||
type = left.type;
|
||||
|
|
|
@ -989,26 +989,66 @@ class FunctionCallExpr : Expression
|
|||
fail("Parameter list expected ')'", toks);
|
||||
}
|
||||
|
||||
|
||||
this(Expression func, ref TokenArray toks)
|
||||
// Special version of getParams that allow 'console-mode' grammar.
|
||||
static void getParamsConsole(ref TokenArray toks,
|
||||
out ExprArray parms,
|
||||
out NamedParam[] named)
|
||||
{
|
||||
parms = null;
|
||||
named = null;
|
||||
|
||||
// The param list is terminated by a semicolon or a newline
|
||||
while(!isSep(toks))
|
||||
{
|
||||
if(toks.length == 0)
|
||||
fail("Unexpected end of stream");
|
||||
|
||||
// Named paramter?
|
||||
if(toks.length >= 3 && toks[1].type == TT.Equals)
|
||||
{
|
||||
NamedParam np;
|
||||
|
||||
reqNext(toks, TT.Identifier, np.name);
|
||||
reqNext(toks, TT.Equals);
|
||||
np.value = Expression.identify(toks);
|
||||
|
||||
named ~= np;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Normal parameter
|
||||
if(named.length)
|
||||
fail("Cannot use non-named parameters after a named one",
|
||||
toks[0].loc);
|
||||
|
||||
parms ~= Expression.identify(toks);
|
||||
}
|
||||
|
||||
// Allow optional commas between parameters
|
||||
isNext(toks, TT.Comma);
|
||||
}
|
||||
}
|
||||
|
||||
this(Expression func, ref TokenArray toks, bool console=false)
|
||||
{
|
||||
assert(func !is null);
|
||||
fname = func;
|
||||
loc = fname.loc;
|
||||
|
||||
// Parse the parameter list
|
||||
getParams(toks, params, named);
|
||||
// Parse the parameter list. The 'console' parameter determines
|
||||
// whether we're using normal grammar rules:
|
||||
// func(param1,param2)
|
||||
// or console rules
|
||||
// func param1 param2
|
||||
if(console)
|
||||
getParamsConsole(toks, params, named);
|
||||
else
|
||||
getParams(toks, params, named);
|
||||
}
|
||||
|
||||
/* Might be used for D-like implicit function calling, eg. someFunc;
|
||||
or (obj.prop)
|
||||
this(Expression func) {}
|
||||
|
||||
We might also allow a special free-form function call syntax, eg.
|
||||
func 1 2 3
|
||||
|
||||
where parens and commas are optional, and the list is terminated by
|
||||
isSep (newline or ;). This is useful mostly for console mode.
|
||||
*/
|
||||
|
||||
void parse(ref TokenArray toks) { assert(0); }
|
||||
|
@ -1176,7 +1216,7 @@ class FunctionCallExpr : Expression
|
|||
}
|
||||
|
||||
// Evaluate the parameters
|
||||
void evalParams()
|
||||
private void evalParams()
|
||||
{
|
||||
// Again, let's handle the vararg case separately
|
||||
if(isVararg)
|
||||
|
@ -1253,9 +1293,10 @@ class FunctionCallExpr : Expression
|
|||
{
|
||||
if(isCast)
|
||||
{
|
||||
// This is a type cast, not a function call.
|
||||
|
||||
// Just evaluate the expression. CastExpression takes care
|
||||
// of everything automatically.
|
||||
|
||||
assert(params.length == 1);
|
||||
assert(params[0] !is null);
|
||||
params[0].eval();
|
||||
|
|
|
@ -534,8 +534,8 @@ class DotOperator : OperatorExpr
|
|||
type = member.type;
|
||||
|
||||
// Make sure we only call static members when the owner is a
|
||||
// type.
|
||||
if(ot.isMeta && !member.isStatic)
|
||||
// type or a package.
|
||||
if((ot.isMeta || ot.isPackage) && !member.isStatic)
|
||||
fail("Can only access static members for " ~ owner.toString,
|
||||
loc);
|
||||
}
|
||||
|
|
|
@ -1702,11 +1702,21 @@ class TypeofType : ReplacerType
|
|||
// D.
|
||||
class GenericType : InternalType
|
||||
{
|
||||
static GenericType sing;
|
||||
|
||||
this() { name = "var"; }
|
||||
|
||||
static bool canParse(TokenArray toks)
|
||||
{ return isNext(toks, TT.Var); }
|
||||
|
||||
static GenericType getSingleton()
|
||||
{
|
||||
if(sing is null)
|
||||
sing = new GenericType;
|
||||
|
||||
return sing;
|
||||
}
|
||||
|
||||
override:
|
||||
bool isVar() { return true; }
|
||||
|
||||
|
|
|
@ -576,6 +576,7 @@ class MemberExpr : Expression
|
|||
isNext(toks, TT.Singleton) ||
|
||||
isNext(toks, TT.State) ||
|
||||
isNext(toks, TT.Clone) ||
|
||||
isNext(toks, TT.Var) ||
|
||||
isNext(toks, TT.Const);
|
||||
}
|
||||
|
||||
|
@ -803,6 +804,13 @@ class MemberExpr : Expression
|
|||
if(name.type == TT.Const || name.type == TT.Clone)
|
||||
fail("Cannot use " ~ name.str ~ " as a variable", name.loc);
|
||||
|
||||
if(name.type == TT.Var)
|
||||
{
|
||||
type = GenericType.getSingleton();
|
||||
vtype = VType.Special;
|
||||
return;
|
||||
}
|
||||
|
||||
// Look ourselves up in the local scope, and include imported
|
||||
// scopes.
|
||||
look = sc.lookupImport(name);
|
||||
|
@ -851,6 +859,9 @@ class MemberExpr : Expression
|
|||
|
||||
void evalAsm()
|
||||
{
|
||||
if(type.isVar)
|
||||
fail("Cannot use 'var' as an expression", loc);
|
||||
|
||||
// Hairy. But does the trick for now.
|
||||
if(dotImport !is null && recurse)
|
||||
{
|
||||
|
@ -1011,6 +1022,7 @@ class VarDeclStatement : Statement
|
|||
{
|
||||
VarDeclaration[] vars;
|
||||
bool reqSemi;
|
||||
Type preKnownType = null;
|
||||
|
||||
// Pass 'true' to the constructor to require a semi-colon (used eg
|
||||
// in for loops)
|
||||
|
@ -1019,6 +1031,12 @@ class VarDeclStatement : Statement
|
|||
reqSemi = rs;
|
||||
}
|
||||
|
||||
// Used from the console, when the type is already known
|
||||
this(Type type)
|
||||
{
|
||||
preKnownType = type;
|
||||
}
|
||||
|
||||
static bool canParse(TokenArray toks)
|
||||
{
|
||||
if(Type.canParseRem(toks) &&
|
||||
|
@ -1030,7 +1048,12 @@ class VarDeclStatement : Statement
|
|||
void parse(ref TokenArray toks)
|
||||
{
|
||||
VarDeclaration varDec;
|
||||
varDec = new VarDeclaration;
|
||||
|
||||
if(preKnownType !is null)
|
||||
varDec = new VarDeclaration(preKnownType);
|
||||
else
|
||||
varDec = new VarDeclaration;
|
||||
|
||||
varDec.parse(toks);
|
||||
vars ~= varDec;
|
||||
loc = varDec.var.name.loc;
|
||||
|
|
|
@ -134,19 +134,16 @@ class Console
|
|||
|
||||
void putln(char[] str) { put(str, true); }
|
||||
|
||||
Statement[] parse(TokenArray toks)
|
||||
Statement[] parse(TokenArray toks, Scope sc)
|
||||
{
|
||||
Statement b = null;
|
||||
Statement b;
|
||||
Statement[] res;
|
||||
|
||||
repeat:
|
||||
|
||||
if(VarDeclStatement.canParse(toks))
|
||||
{
|
||||
if(!allowVar) fail("Variable declaration not allowed here");
|
||||
b = new VarDeclStatement;
|
||||
}
|
||||
else if(CodeBlock.canParse(toks)) b = new CodeBlock;
|
||||
b = null;
|
||||
|
||||
if(CodeBlock.canParse(toks)) b = new CodeBlock;
|
||||
else if(IfStatement.canParse(toks)) b = new IfStatement;
|
||||
else if(DoWhileStatement.canParse(toks)) b = new DoWhileStatement;
|
||||
else if(WhileStatement.canParse(toks)) b = new WhileStatement;
|
||||
|
@ -154,11 +151,24 @@ class Console
|
|||
else if(ForeachStatement.canParse(toks)) b = new ForeachStatement;
|
||||
else if(ImportStatement.canParse(toks)) b = new ImportStatement(true);
|
||||
|
||||
// If this is not one of the above, default to an expression
|
||||
// statement.
|
||||
else b = new ExprStatement;
|
||||
if(b !is null)
|
||||
{
|
||||
// Parse and resolve
|
||||
b.parse(toks);
|
||||
b.resolve(sc);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If this is not one of the above, default to a console
|
||||
// statement.
|
||||
auto es = new ConsoleStatement;
|
||||
b = es;
|
||||
|
||||
b.parse(toks);
|
||||
// Parse and resolve in one operation.
|
||||
es.parseResolve(toks, sc, allowVar);
|
||||
}
|
||||
|
||||
assert(b !is null);
|
||||
res ~= b;
|
||||
|
||||
// Are there more tokens waiting for us?
|
||||
|
@ -269,51 +279,58 @@ class Console
|
|||
if(tokArr.length == 0)
|
||||
return CR.Empty;
|
||||
|
||||
// Phase II, parse
|
||||
// Phase II & III, parse and resolve
|
||||
TokenArray toks = tokArr.arrayCopy();
|
||||
Statement[] sts = parse(toks);
|
||||
Statement[] sts = parse(toks, sc);
|
||||
delete toks;
|
||||
assert(sts.length >= 1);
|
||||
|
||||
// First, background the current thread (if any) and bring up
|
||||
// our own.
|
||||
// our own. This is necessary in order to keep the stack
|
||||
// variables we make.
|
||||
store = cthread;
|
||||
if(store !is null)
|
||||
store.background();
|
||||
assert(trd !is null);
|
||||
trd.foreground();
|
||||
|
||||
// We have to push ourselves on the function stack, or call()
|
||||
// will see that it's empty and kill the thread upon exit
|
||||
// We have to push ourselves on the function stack, or
|
||||
// Function.call() will see that it's empty and kill the thread
|
||||
// upon exit
|
||||
trd.fstack.pushExt("Console");
|
||||
|
||||
// The rest must be performed separately for each statement on
|
||||
// the line.
|
||||
foreach(st; sts)
|
||||
{
|
||||
// Phase III, resolve
|
||||
st.resolve(sc);
|
||||
|
||||
// Phase IV, compile
|
||||
tasm.newFunc();
|
||||
|
||||
// Is it an expression?
|
||||
auto es = cast(ExprStatement)st;
|
||||
if(es !is null)
|
||||
ExprStatement es;
|
||||
|
||||
// Is it an special console statement?
|
||||
auto cs = cast(ConsoleStatement)st;
|
||||
if(cs !is null)
|
||||
{
|
||||
// Yes. But is the type usable?
|
||||
if(es.left.type.canCastTo(ArrayType.getString())
|
||||
&& es.right is null)
|
||||
// Yes. Is the client an expression?
|
||||
es = cast(ExprStatement)cs.client;
|
||||
if(es !is null)
|
||||
{
|
||||
// Yup. Get the type, and cast the expression to string.
|
||||
scope auto ce = new
|
||||
CastExpression(es.left, ArrayType.getString());
|
||||
ce.eval();
|
||||
// Ok. But is the type usable?
|
||||
if(es.left.type.canCastTo(ArrayType.getString())
|
||||
&& es.right is null)
|
||||
{
|
||||
// Yup. Get the type, and cast the expression to string.
|
||||
scope auto ce = new
|
||||
CastExpression(es.left, ArrayType.getString());
|
||||
ce.eval();
|
||||
}
|
||||
else es = null;
|
||||
}
|
||||
else es = null;
|
||||
}
|
||||
|
||||
// No expression is being used, so compile the statement
|
||||
// normally.
|
||||
if(es is null)
|
||||
st.compile();
|
||||
|
||||
|
@ -336,28 +353,31 @@ class Console
|
|||
// function frame, ie. the same way we treat function
|
||||
// parameters. We do this by giving the variables negative
|
||||
// indices.
|
||||
auto vs = cast(VarDeclStatement)st;
|
||||
if(vs !is null)
|
||||
if(cs !is null)
|
||||
{
|
||||
// Add the new vars to the list
|
||||
foreach(v; vs.vars)
|
||||
auto vs = cast(VarDeclStatement)cs.client;
|
||||
if(vs !is null)
|
||||
{
|
||||
varList ~= v.var;
|
||||
// Add the new vars to the list
|
||||
foreach(v; vs.vars)
|
||||
{
|
||||
varList ~= v.var;
|
||||
|
||||
// Add the size as well
|
||||
varSize += v.var.type.getSize;
|
||||
// Add the size as well
|
||||
varSize += v.var.type.getSize;
|
||||
}
|
||||
|
||||
// Recalculate all the indices backwards from zero
|
||||
int place = 0;
|
||||
foreach_reverse(v; varList)
|
||||
{
|
||||
place -= v.type.getSize;
|
||||
v.number = place;
|
||||
}
|
||||
|
||||
// Reset the scope stack counters
|
||||
sc.reset();
|
||||
}
|
||||
|
||||
// Recalculate all the indices backwards from zero
|
||||
int place = 0;
|
||||
foreach_reverse(v; varList)
|
||||
{
|
||||
place -= v.type.getSize;
|
||||
v.number = place;
|
||||
}
|
||||
|
||||
// Reset the scope stack counters
|
||||
sc.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -443,3 +463,71 @@ class Console
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Statement that handles variable declarations, function calls and
|
||||
// expression statements in consoles. Since these are gramatically
|
||||
// similar, we need the type to determine which
|
||||
class ConsoleStatement : Statement
|
||||
{
|
||||
// Used for variables and expression statements
|
||||
Statement client;
|
||||
|
||||
// Used for function calls
|
||||
FunctionCallExpr func;
|
||||
|
||||
void parseResolve(ref TokenArray toks, Scope sc, bool allowVar)
|
||||
{
|
||||
assert(toks.length != 0);
|
||||
|
||||
// Get the first expression
|
||||
auto first = Expression.identify(toks);
|
||||
|
||||
// And the type right away
|
||||
first.resolve(sc);
|
||||
auto type = first.type;
|
||||
assert(type !is null);
|
||||
|
||||
// Type? If so, it's a variable declaration
|
||||
if((type.isMeta || type.isVar) && allowVar)
|
||||
{
|
||||
if(type.isMeta) type = type.getBase();
|
||||
|
||||
client = new VarDeclStatement(type);
|
||||
}
|
||||
|
||||
// Function?
|
||||
else if(type.isFunc)
|
||||
func = new FunctionCallExpr(first, toks, true);
|
||||
|
||||
// It's an expression statement
|
||||
else
|
||||
client = new ExprStatement(first);
|
||||
|
||||
if(client !is null)
|
||||
{
|
||||
client.parse(toks);
|
||||
client.resolve(sc);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(func !is null);
|
||||
func.resolve(sc);
|
||||
}
|
||||
}
|
||||
|
||||
override:
|
||||
void parse(ref TokenArray) { assert(0); }
|
||||
void resolve(Scope sc) { assert(0); }
|
||||
|
||||
void compile()
|
||||
{
|
||||
if(client !is null)
|
||||
{
|
||||
client.compile();
|
||||
return;
|
||||
}
|
||||
|
||||
assert(func !is null);
|
||||
func.evalPop();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,9 +116,13 @@ long execLimit = 10000000;
|
|||
bool defaultLogToStdout = false;
|
||||
|
||||
// If true, all function stack operations (pushes and pops) are logged
|
||||
// with dbg.log().
|
||||
// with dbg.log(), and all logged messages are indented according to
|
||||
// the current fstack level.
|
||||
bool logFStack = true;
|
||||
|
||||
// If true, log when threads are put into the background/forground.
|
||||
bool logThreads = true;
|
||||
|
||||
/*********************************************************
|
||||
|
||||
|
||||
|
|
|
@ -167,6 +167,9 @@ struct Thread
|
|||
list.remove(this);
|
||||
list = null;
|
||||
assert(isDead);
|
||||
|
||||
static if(logThreads)
|
||||
dbg.log(format("------ killing thread=%s ------", getIndex));
|
||||
}
|
||||
|
||||
// Stop the execution of a thread and cancel any scheduling.
|
||||
|
|
31
mscripts/console.mn
Normal file
31
mscripts/console.mn
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
OpenMW - The completely unofficial reimplementation of Morrowind
|
||||
Copyright (C) 2008 Nicolay Korslund
|
||||
Email: < korslund@gmail.com >
|
||||
WWW: http://openmw.snaptoad.com/
|
||||
|
||||
This file (console.mn) is part of the OpenMW package.
|
||||
|
||||
OpenMW is distributed as free software: you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License
|
||||
version 3, as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
version 3 along with this program. If not, see
|
||||
http://www.gnu.org/licenses/ .
|
||||
|
||||
*/
|
||||
|
||||
class Console
|
||||
|
||||
|
||||
// This class contains all the functions available to the ingame
|
||||
// console.
|
||||
|
||||
import io;
|
||||
import game;
|
25
mscripts/game/npc.mn
Normal file
25
mscripts/game/npc.mn
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
OpenMW - The completely unofficial reimplementation of Morrowind
|
||||
Copyright (C) 2008 Nicolay Korslund
|
||||
Email: < korslund@gmail.com >
|
||||
WWW: http://openmw.snaptoad.com/
|
||||
|
||||
This file (npc.mn) is part of the OpenMW package.
|
||||
|
||||
OpenMW is distributed as free software: you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License
|
||||
version 3, as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
version 3 along with this program. If not, see
|
||||
http://www.gnu.org/licenses/ .
|
||||
|
||||
*/
|
||||
|
||||
class NPC : Person
|
||||
|
27
mscripts/game/player.mn
Normal file
27
mscripts/game/player.mn
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
OpenMW - The completely unofficial reimplementation of Morrowind
|
||||
Copyright (C) 2008 Nicolay Korslund
|
||||
Email: < korslund@gmail.com >
|
||||
WWW: http://openmw.snaptoad.com/
|
||||
|
||||
This file (player.mn) is part of the OpenMW package.
|
||||
|
||||
OpenMW is distributed as free software: you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License
|
||||
version 3, as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
version 3 along with this program. If not, see
|
||||
http://www.gnu.org/licenses/ .
|
||||
|
||||
*/
|
||||
|
||||
singleton player : Person
|
||||
|
||||
name="Player Name"
|
||||
level = 5 // Just an example value
|
|
@ -28,9 +28,11 @@ import monster.compiler.scopes : global;
|
|||
import monster.modules.timer;
|
||||
|
||||
import core.config;
|
||||
import ogre.gui;
|
||||
import gui.gui;
|
||||
import scene.player;
|
||||
|
||||
import std.string;
|
||||
import std.stdio;
|
||||
|
||||
// Set up the base Monster classes we need in OpenMW
|
||||
void initMonsterScripts()
|
||||
|
@ -45,6 +47,9 @@ void initMonsterScripts()
|
|||
// Get the Config singleton object
|
||||
config.mo = vm.load("Config").getSing();
|
||||
|
||||
// Set up the player object.
|
||||
playerData.setup();
|
||||
|
||||
// Set up the GUI Monster module
|
||||
setupGUIScripts();
|
||||
}
|
||||
|
@ -62,7 +67,6 @@ void runGUIScripts()
|
|||
|
||||
// This should probably not be here:
|
||||
import monster.vm.dbg;
|
||||
import std.string;
|
||||
|
||||
extern(C):
|
||||
void dbg_trace(char*str) { dbg.trace(toString(str)); }
|
||||
|
|
|
@ -164,28 +164,3 @@ void ogre_moveCameraRel(float x, float y, float z);
|
|||
|
||||
// Insert a raw RGBA image into the texture system.
|
||||
//void ogre_insertTexture(char *name, int width, int height, void *data);
|
||||
|
||||
// GUI functions. Under development.
|
||||
typedef void* WidgetPtr;
|
||||
void gui_setupGUI(int debugOut);
|
||||
void gui_toggleGui();
|
||||
void gui_setCellName(char *str);
|
||||
|
||||
// Get the widget type, as a string
|
||||
char *gui_widgetType(WidgetPtr);
|
||||
|
||||
// Get the height or width of a widget. If the argument is null,
|
||||
// return the size of the screen.
|
||||
int gui_getHeight(WidgetPtr);
|
||||
int gui_getWidth(WidgetPtr);
|
||||
|
||||
// Set various properties of a given widget
|
||||
void gui_setCaption(WidgetPtr, char*);
|
||||
void gui_setNeedMouseFocus(WidgetPtr, int);
|
||||
void gui_setTextColor(WidgetPtr, float,float,float);
|
||||
void gui_setCoord(WidgetPtr, int,int,int,int);
|
||||
|
||||
// Various ways to get or create widgets
|
||||
WidgetPtr gui_loadLayout(char *file, char *prefix, WidgetPtr parent);
|
||||
WidgetPtr gui_getChild(WidgetPtr, char*);
|
||||
WidgetPtr gui_createText(char *skin, int x, int y, int w, int h, char *layer);
|
||||
|
|
|
@ -48,7 +48,7 @@ extern "C" int32_t ogre_configure(
|
|||
{
|
||||
// Set up logging first
|
||||
new LogManager;
|
||||
Log *log = LogManager::getSingleton().createLog("default");
|
||||
Log *log = LogManager::getSingleton().createLog("Ogre.log");
|
||||
|
||||
if(debugOut)
|
||||
// Full log detail
|
||||
|
|
|
@ -24,7 +24,9 @@ extern "C" int32_t gui_getWidth(MyGUI::WidgetPtr p)
|
|||
|
||||
// Set various properties of a given widget
|
||||
extern "C" void gui_setCaption(MyGUI::WidgetPtr p, char* s)
|
||||
{ p->setCaption(s); }
|
||||
{
|
||||
p->setCaption(s);
|
||||
}
|
||||
|
||||
extern "C" void gui_setNeedMouseFocus(MyGUI::WidgetPtr p, int32_t b)
|
||||
{ p->setNeedMouseFocus(b); }
|
||||
|
|
1
openmw.d
1
openmw.d
|
@ -30,6 +30,7 @@ import std.file;
|
|||
|
||||
import ogre.ogre;
|
||||
import ogre.bindings;
|
||||
import gui.bindings;
|
||||
|
||||
import bullet.bullet;
|
||||
|
||||
|
|
|
@ -453,7 +453,7 @@ class CellData
|
|||
{
|
||||
// Create a creature, based on current player level.
|
||||
LiveCreature ls;
|
||||
ls.m = l.instCreature(playerData.level);
|
||||
ls.m = l.instCreature(*playerData.level);
|
||||
if(ls.m != null)
|
||||
{
|
||||
// Note that this clones a creature object, not a
|
||||
|
@ -565,7 +565,7 @@ class CellData
|
|||
if(door && !playerData.posSet)
|
||||
{
|
||||
playerData.posSet = true;
|
||||
playerData.position = *pos;
|
||||
*playerData.position = *pos;
|
||||
}
|
||||
}
|
||||
} // End of while(hasMoreSubs)
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
module scene.player;
|
||||
|
||||
import ogre.ogre;
|
||||
import monster.monster;
|
||||
|
||||
/*
|
||||
* Contains essential data about the player and other current game
|
||||
|
@ -34,14 +35,30 @@ PlayerData playerData;
|
|||
|
||||
struct PlayerData
|
||||
{
|
||||
// Position and rotation. The rotation is not updated continuously,
|
||||
// only the position.
|
||||
Placement position;
|
||||
MonsterObject *mo;
|
||||
|
||||
// Just an example value, we use it for resolving leveled lists
|
||||
// (lists that determine eg. what creatures to put in a cave based
|
||||
// on what level the player is.)
|
||||
short level = 5;
|
||||
Placement *position;
|
||||
int *level;
|
||||
|
||||
// Set up the player object. This is still pretty hackish and
|
||||
// temporary.
|
||||
void setup()
|
||||
{
|
||||
assert(mo is null);
|
||||
mo = vm.load("game.player").createObject;
|
||||
level = mo.getIntPtr("level");
|
||||
|
||||
// Still an ugly hack
|
||||
position = cast(Placement*)mo.getFloatPtr("x");
|
||||
}
|
||||
|
||||
/*
|
||||
char[] getName()
|
||||
{
|
||||
assert(mo !is null);
|
||||
return mo.getString8("name");
|
||||
}
|
||||
*/
|
||||
|
||||
// Temp. way of selecting start point - used in celldata
|
||||
bool posSet = false;
|
||||
|
|
Loading…
Reference in a new issue