Preparation for console

git-svn-id: https://openmw.svn.sourceforge.net/svnroot/openmw/trunk@103 ea6a568a-9f4f-0410-981a-c910a81bb256
actorid
nkorslund 16 years ago
parent 714b724bf2
commit 1b01de4294

@ -38,7 +38,7 @@ bullet_cpp_files=$(bullet_cpp:%=bullet/cpp_%.cpp)
# All object files needed by openmw and esmtool # All object files needed by openmw and esmtool
src := $(wildcard bsa/*.d) $(wildcard bullet/*.d) $(wildcard core/*.d) \ src := $(wildcard bsa/*.d) $(wildcard bullet/*.d) $(wildcard core/*.d) \
$(wildcard esm/*.d) $(wildcard input/*.d) $(wildcard nif/*.d) $(wildcard ogre/*.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) $(wildcard mscripts/*.d)
src := $(src) monster/monster.d \ src := $(src) monster/monster.d \
$(wildcard monster/vm/*.d) \ $(wildcard monster/vm/*.d) \

@ -35,8 +35,11 @@ extern(C):
// Initialize the dynamic world. Returns non-zero if an error occurs. // Initialize the dynamic world. Returns non-zero if an error occurs.
int bullet_init(); int bullet_init();
// Switch to the next physics mode // Set physics modes
void bullet_nextMode(); void bullet_nextMode();
void bullet_walk();
void bullet_fly();
void bullet_ghost();
// Warp the player to a specific location. // Warp the player to a specific location.
void bullet_movePlayer(float x, float y, float z); void bullet_movePlayer(float x, float y, float z);

@ -206,29 +206,45 @@ extern "C" int32_t bullet_init()
return 0; 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 // Switch to the next physics mode
extern "C" void bullet_nextMode() extern "C" void bullet_nextMode()
{ {
g_physMode++;
if(g_physMode > PHYS_GHOST)
g_physMode = PHYS_WALK;
switch(g_physMode) switch(g_physMode)
{ {
case PHYS_WALK: case PHYS_WALK:
cout << "Entering walking mode\n"; bullet_fly();
break; break;
case PHYS_FLY: case PHYS_FLY:
cout << "Entering flying mode\n"; bullet_ghost();
break; break;
case PHYS_GHOST: case PHYS_GHOST:
cout << "Entering ghost mode\n"; bullet_walk();
break; break;
} }
} }
// Warp the player to a specific location. We do not bother setting // 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) extern "C" void bullet_movePlayer(float x, float y, float z)
{ {
btTransform tr; btTransform tr;

@ -164,7 +164,7 @@ struct NPC
skipRecord(); skipRecord();
makeProto("Person"); makeProto();
// Clean this up a little later, eg. no point in storing the // Clean this up a little later, eg. no point in storing the
// structs outside the function any longer. Same goes for most of // structs outside the function any longer. Same goes for most of

@ -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.monster;
import monster.vm.mclass; import monster.vm.mclass;
import ogre.bindings; import gui.bindings;
import std.string; import std.string;
// Widget class and gui module // Widget class and gui module
@ -57,7 +57,7 @@ class MWidget
isLayout = true; isLayout = true;
prefix = format("%s", cast(void*)this); 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) if(widget is null)
fail("Layout " ~ layout ~ " is empty"); fail("Layout " ~ layout ~ " is empty");
@ -91,7 +91,7 @@ class MWidget
name = prefix ~ name; name = prefix ~ name;
// Get the child widget // Get the child widget
auto pt = gui_getChild(widget, name.ptr); auto pt = gui_getChild(widget, name.toStringz());
if(pt is null) if(pt is null)
fail("Widget has no child named " ~ name); fail("Widget has no child named " ~ name);
@ -163,7 +163,7 @@ void setCaption()
foreach(AIndex ind; args) foreach(AIndex ind; args)
res ~= format("%s", arrays.getRef(ind).carr); res ~= format("%s", arrays.getRef(ind).carr);
gui_setCaption(getOwner(), res.ptr); gui_setCaption(getOwner(), toStringz(res));
} }
void setNeedMouseFocus() void setNeedMouseFocus()
{ gui_setNeedMouseFocus(getOwner(), stack.popBool); } { gui_setNeedMouseFocus(getOwner(), stack.popBool); }
@ -211,9 +211,9 @@ void text()
int y = stack.popInt(); int y = stack.popInt();
int x = stack.popInt(); int x = stack.popInt();
char[] skin = stack.popString8(); char[] skin = stack.popString8();
WidgetPtr ptr = gui_createText(skin.ptr, WidgetPtr ptr = gui_createText(skin.toStringz(),
x,y,w,h, x,y,w,h,
layer.ptr); layer.toStringz());
assert(widgetType(ptr) == "StaticText"); assert(widgetType(ptr) == "StaticText");
MWidget mw = new MWidget(ptr); MWidget mw = new MWidget(ptr);
stack.pushObject(mw.mo); stack.pushObject(mw.mo);

@ -213,7 +213,7 @@ void initializeInput()
{ {
// Move the player into place. TODO: This isn't really input-related // Move the player into place. TODO: This isn't really input-related
// at all, and should be moved. // at all, and should be moved.
with(playerData.position) with(*playerData.position)
{ {
ogre_moveCamera(position[0], position[1], position[2]); ogre_moveCamera(position[0], position[1], position[2]);
ogre_setCameraRotation(rotation[0], rotation[1], rotation[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); bullet_getPlayerPos(&x, &y, &z);
ogre_moveCamera(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 // Tell the sound scene that the player has moved
sndCumTime += time; sndCumTime += time;
if(sndCumTime > sndRefresh) if(sndCumTime > sndRefresh)

@ -1180,12 +1180,26 @@ class ExprStatement : Statement
// Require a terminating semicolon or line break // Require a terminating semicolon or line break
bool term = true; 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) void parse(ref TokenArray toks)
{ {
if(toks.length == 0) if(left is null)
fail("Expected statement, found end of stream."); {
loc = toks[0].loc; if(toks.length == 0)
left = Expression.identify(toks); fail("Expected statement, found end of stream.");
left = Expression.identify(toks);
}
loc = left.loc;
Token tok; Token tok;
@ -1219,7 +1233,8 @@ class ExprStatement : Statement
void resolve(Scope sc) void resolve(Scope sc)
{ {
left.resolve(sc); if(!leftSet)
left.resolve(sc);
loc = left.loc; loc = left.loc;
type = left.type; type = left.type;

@ -989,26 +989,66 @@ class FunctionCallExpr : Expression
fail("Parameter list expected ')'", toks); fail("Parameter list expected ')'", toks);
} }
// Special version of getParams that allow 'console-mode' grammar.
this(Expression func, ref TokenArray toks) 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); assert(func !is null);
fname = func; fname = func;
loc = fname.loc; loc = fname.loc;
// Parse the parameter list // Parse the parameter list. The 'console' parameter determines
getParams(toks, params, named); // 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; /* Might be used for D-like implicit function calling, eg. someFunc;
or (obj.prop) or (obj.prop)
this(Expression func) {} 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); } void parse(ref TokenArray toks) { assert(0); }
@ -1176,7 +1216,7 @@ class FunctionCallExpr : Expression
} }
// Evaluate the parameters // Evaluate the parameters
void evalParams() private void evalParams()
{ {
// Again, let's handle the vararg case separately // Again, let's handle the vararg case separately
if(isVararg) if(isVararg)
@ -1253,9 +1293,10 @@ class FunctionCallExpr : Expression
{ {
if(isCast) if(isCast)
{ {
// This is a type cast, not a function call.
// Just evaluate the expression. CastExpression takes care // Just evaluate the expression. CastExpression takes care
// of everything automatically. // of everything automatically.
assert(params.length == 1); assert(params.length == 1);
assert(params[0] !is null); assert(params[0] !is null);
params[0].eval(); params[0].eval();

@ -534,8 +534,8 @@ class DotOperator : OperatorExpr
type = member.type; type = member.type;
// Make sure we only call static members when the owner is a // Make sure we only call static members when the owner is a
// type. // type or a package.
if(ot.isMeta && !member.isStatic) if((ot.isMeta || ot.isPackage) && !member.isStatic)
fail("Can only access static members for " ~ owner.toString, fail("Can only access static members for " ~ owner.toString,
loc); loc);
} }

@ -1702,11 +1702,21 @@ class TypeofType : ReplacerType
// D. // D.
class GenericType : InternalType class GenericType : InternalType
{ {
static GenericType sing;
this() { name = "var"; } this() { name = "var"; }
static bool canParse(TokenArray toks) static bool canParse(TokenArray toks)
{ return isNext(toks, TT.Var); } { return isNext(toks, TT.Var); }
static GenericType getSingleton()
{
if(sing is null)
sing = new GenericType;
return sing;
}
override: override:
bool isVar() { return true; } bool isVar() { return true; }

@ -576,6 +576,7 @@ class MemberExpr : Expression
isNext(toks, TT.Singleton) || isNext(toks, TT.Singleton) ||
isNext(toks, TT.State) || isNext(toks, TT.State) ||
isNext(toks, TT.Clone) || isNext(toks, TT.Clone) ||
isNext(toks, TT.Var) ||
isNext(toks, TT.Const); isNext(toks, TT.Const);
} }
@ -803,6 +804,13 @@ class MemberExpr : Expression
if(name.type == TT.Const || name.type == TT.Clone) if(name.type == TT.Const || name.type == TT.Clone)
fail("Cannot use " ~ name.str ~ " as a variable", name.loc); 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 // Look ourselves up in the local scope, and include imported
// scopes. // scopes.
look = sc.lookupImport(name); look = sc.lookupImport(name);
@ -851,6 +859,9 @@ class MemberExpr : Expression
void evalAsm() void evalAsm()
{ {
if(type.isVar)
fail("Cannot use 'var' as an expression", loc);
// Hairy. But does the trick for now. // Hairy. But does the trick for now.
if(dotImport !is null && recurse) if(dotImport !is null && recurse)
{ {
@ -1011,6 +1022,7 @@ class VarDeclStatement : Statement
{ {
VarDeclaration[] vars; VarDeclaration[] vars;
bool reqSemi; bool reqSemi;
Type preKnownType = null;
// Pass 'true' to the constructor to require a semi-colon (used eg // Pass 'true' to the constructor to require a semi-colon (used eg
// in for loops) // in for loops)
@ -1019,6 +1031,12 @@ class VarDeclStatement : Statement
reqSemi = rs; reqSemi = rs;
} }
// Used from the console, when the type is already known
this(Type type)
{
preKnownType = type;
}
static bool canParse(TokenArray toks) static bool canParse(TokenArray toks)
{ {
if(Type.canParseRem(toks) && if(Type.canParseRem(toks) &&
@ -1030,7 +1048,12 @@ class VarDeclStatement : Statement
void parse(ref TokenArray toks) void parse(ref TokenArray toks)
{ {
VarDeclaration varDec; VarDeclaration varDec;
varDec = new VarDeclaration;
if(preKnownType !is null)
varDec = new VarDeclaration(preKnownType);
else
varDec = new VarDeclaration;
varDec.parse(toks); varDec.parse(toks);
vars ~= varDec; vars ~= varDec;
loc = varDec.var.name.loc; loc = varDec.var.name.loc;

@ -134,19 +134,16 @@ class Console
void putln(char[] str) { put(str, true); } void putln(char[] str) { put(str, true); }
Statement[] parse(TokenArray toks) Statement[] parse(TokenArray toks, Scope sc)
{ {
Statement b = null; Statement b;
Statement[] res; Statement[] res;
repeat: repeat:
if(VarDeclStatement.canParse(toks)) b = null;
{
if(!allowVar) fail("Variable declaration not allowed here"); if(CodeBlock.canParse(toks)) b = new CodeBlock;
b = new VarDeclStatement;
}
else if(CodeBlock.canParse(toks)) b = new CodeBlock;
else if(IfStatement.canParse(toks)) b = new IfStatement; else if(IfStatement.canParse(toks)) b = new IfStatement;
else if(DoWhileStatement.canParse(toks)) b = new DoWhileStatement; else if(DoWhileStatement.canParse(toks)) b = new DoWhileStatement;
else if(WhileStatement.canParse(toks)) b = new WhileStatement; else if(WhileStatement.canParse(toks)) b = new WhileStatement;
@ -154,11 +151,24 @@ class Console
else if(ForeachStatement.canParse(toks)) b = new ForeachStatement; else if(ForeachStatement.canParse(toks)) b = new ForeachStatement;
else if(ImportStatement.canParse(toks)) b = new ImportStatement(true); else if(ImportStatement.canParse(toks)) b = new ImportStatement(true);
// If this is not one of the above, default to an expression if(b !is null)
// statement. {
else b = new ExprStatement; // 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;
// Parse and resolve in one operation.
es.parseResolve(toks, sc, allowVar);
}
b.parse(toks); assert(b !is null);
res ~= b; res ~= b;
// Are there more tokens waiting for us? // Are there more tokens waiting for us?
@ -269,51 +279,58 @@ class Console
if(tokArr.length == 0) if(tokArr.length == 0)
return CR.Empty; return CR.Empty;
// Phase II, parse // Phase II & III, parse and resolve
TokenArray toks = tokArr.arrayCopy(); TokenArray toks = tokArr.arrayCopy();
Statement[] sts = parse(toks); Statement[] sts = parse(toks, sc);
delete toks; delete toks;
assert(sts.length >= 1); assert(sts.length >= 1);
// First, background the current thread (if any) and bring up // 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; store = cthread;
if(store !is null) if(store !is null)
store.background(); store.background();
assert(trd !is null); assert(trd !is null);
trd.foreground(); trd.foreground();
// We have to push ourselves on the function stack, or call() // We have to push ourselves on the function stack, or
// will see that it's empty and kill the thread upon exit // Function.call() will see that it's empty and kill the thread
// upon exit
trd.fstack.pushExt("Console"); trd.fstack.pushExt("Console");
// The rest must be performed separately for each statement on // The rest must be performed separately for each statement on
// the line. // the line.
foreach(st; sts) foreach(st; sts)
{ {
// Phase III, resolve
st.resolve(sc);
// Phase IV, compile // Phase IV, compile
tasm.newFunc(); tasm.newFunc();
// Is it an expression? ExprStatement es;
auto es = cast(ExprStatement)st;
if(es !is null) // Is it an special console statement?
auto cs = cast(ConsoleStatement)st;
if(cs !is null)
{ {
// Yes. But is the type usable? // Yes. Is the client an expression?
if(es.left.type.canCastTo(ArrayType.getString()) es = cast(ExprStatement)cs.client;
&& es.right is null) if(es !is null)
{ {
// Yup. Get the type, and cast the expression to string. // Ok. But is the type usable?
scope auto ce = new if(es.left.type.canCastTo(ArrayType.getString())
CastExpression(es.left, ArrayType.getString()); && es.right is null)
ce.eval(); {
// 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 // No expression is being used, so compile the statement
// normally.
if(es is null) if(es is null)
st.compile(); st.compile();
@ -336,28 +353,31 @@ class Console
// function frame, ie. the same way we treat function // function frame, ie. the same way we treat function
// parameters. We do this by giving the variables negative // parameters. We do this by giving the variables negative
// indices. // indices.
auto vs = cast(VarDeclStatement)st; if(cs !is null)
if(vs !is null)
{ {
// Add the new vars to the list auto vs = cast(VarDeclStatement)cs.client;
foreach(v; vs.vars) if(vs !is null)
{
varList ~= v.var;
// 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; // Add the new vars to the list
v.number = place; foreach(v; vs.vars)
{
varList ~= v.var;
// 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();
} }
// 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; bool defaultLogToStdout = false;
// If true, all function stack operations (pushes and pops) are logged // 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; 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.remove(this);
list = null; list = null;
assert(isDead); assert(isDead);
static if(logThreads)
dbg.log(format("------ killing thread=%s ------", getIndex));
} }
// Stop the execution of a thread and cancel any scheduling. // Stop the execution of a thread and cancel any scheduling.

@ -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;

@ -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

@ -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 monster.modules.timer;
import core.config; import core.config;
import ogre.gui; import gui.gui;
import scene.player;
import std.string; import std.string;
import std.stdio;
// Set up the base Monster classes we need in OpenMW // Set up the base Monster classes we need in OpenMW
void initMonsterScripts() void initMonsterScripts()
@ -45,6 +47,9 @@ void initMonsterScripts()
// Get the Config singleton object // Get the Config singleton object
config.mo = vm.load("Config").getSing(); config.mo = vm.load("Config").getSing();
// Set up the player object.
playerData.setup();
// Set up the GUI Monster module // Set up the GUI Monster module
setupGUIScripts(); setupGUIScripts();
} }
@ -62,7 +67,6 @@ void runGUIScripts()
// This should probably not be here: // This should probably not be here:
import monster.vm.dbg; import monster.vm.dbg;
import std.string;
extern(C): extern(C):
void dbg_trace(char*str) { dbg.trace(toString(str)); } 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. // Insert a raw RGBA image into the texture system.
//void ogre_insertTexture(char *name, int width, int height, void *data); //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 // Set up logging first
new LogManager; new LogManager;
Log *log = LogManager::getSingleton().createLog("default"); Log *log = LogManager::getSingleton().createLog("Ogre.log");
if(debugOut) if(debugOut)
// Full log detail // Full log detail

@ -24,7 +24,9 @@ extern "C" int32_t gui_getWidth(MyGUI::WidgetPtr p)
// Set various properties of a given widget // Set various properties of a given widget
extern "C" void gui_setCaption(MyGUI::WidgetPtr p, char* s) 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) extern "C" void gui_setNeedMouseFocus(MyGUI::WidgetPtr p, int32_t b)
{ p->setNeedMouseFocus(b); } { p->setNeedMouseFocus(b); }

@ -30,6 +30,7 @@ import std.file;
import ogre.ogre; import ogre.ogre;
import ogre.bindings; import ogre.bindings;
import gui.bindings;
import bullet.bullet; import bullet.bullet;

@ -453,7 +453,7 @@ class CellData
{ {
// Create a creature, based on current player level. // Create a creature, based on current player level.
LiveCreature ls; LiveCreature ls;
ls.m = l.instCreature(playerData.level); ls.m = l.instCreature(*playerData.level);
if(ls.m != null) if(ls.m != null)
{ {
// Note that this clones a creature object, not a // Note that this clones a creature object, not a
@ -565,7 +565,7 @@ class CellData
if(door && !playerData.posSet) if(door && !playerData.posSet)
{ {
playerData.posSet = true; playerData.posSet = true;
playerData.position = *pos; *playerData.position = *pos;
} }
} }
} // End of while(hasMoreSubs) } // End of while(hasMoreSubs)

@ -24,6 +24,7 @@
module scene.player; module scene.player;
import ogre.ogre; import ogre.ogre;
import monster.monster;
/* /*
* Contains essential data about the player and other current game * Contains essential data about the player and other current game
@ -34,14 +35,30 @@ PlayerData playerData;
struct PlayerData struct PlayerData
{ {
// Position and rotation. The rotation is not updated continuously, MonsterObject *mo;
// only the position.
Placement position; Placement *position;
int *level;
// Just an example value, we use it for resolving leveled lists
// (lists that determine eg. what creatures to put in a cave based // Set up the player object. This is still pretty hackish and
// on what level the player is.) // temporary.
short level = 5; 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 // Temp. way of selecting start point - used in celldata
bool posSet = false; bool posSet = false;

Loading…
Cancel
Save