diff --git a/Makefile b/Makefile
index 5f5077b9d..490862613 100644
--- a/Makefile
+++ b/Makefile
@@ -1,15 +1,15 @@
# Designed for GNU Make
# Compiler settings
-CXXFLAGS?= -Wall -g
+CXXFLAGS?= -g
DMD=gdmd -version=Posix
#DMD=dmd -version=Posix
# Some extra flags for niftool and bsatool
NIFFLAGS=-debug=warnstd -debug=check -debug=statecheck -debug=strict -debug=verbose
-# Compiler settings for Ogre + OIS.
-CF_OIS=$(shell pkg-config --cflags OIS OGRE)
+# Compiler settings for Ogre, OIS and MyGUI
+CF_OIS=$(shell pkg-config --cflags OIS OGRE MyGUI)
OGCC=$(CXX) $(CXXFLAGS) $(CF_OIS)
# Compiler settings for ffmpeg.
@@ -22,7 +22,7 @@ BGCC=$(CXX) $(CXXFLAGS) $(CF_BULLET)
# Ogre C++ files, on the form ogre/cpp_X.cpp. Only the first file is
# passed to the compiler, the rest are dependencies.
-ogre_cpp=ogre framelistener interface overlay bsaarchive
+ogre_cpp=ogre framelistener interface bsaarchive mygui
# FFmpeg files, in the form sound/cpp_X.cpp.
avcodec_cpp=avcodec
@@ -82,10 +82,10 @@ nifobjs/%.o: %.d
$(DMD) $(NIFFLAGS) -c $< -of$@
openmw: openmw.d cpp_ogre.o cpp_avcodec.o cpp_bullet.o $(obj)
- $(DMD) $^ -of$@ -L-lopenal -L-lOgreMain -L-lOIS -L-lavcodec -L-lavformat bullet/libbulletdynamics.a bullet/libbulletcollision.a bullet/libbulletmath.a
+ $(DMD) $^ -of$@ -L-lopenal -L-lOgreMain -L-lOIS -L-lmygui -L-luuid -L-lavcodec -L-lavformat bullet/libbulletdynamics.a bullet/libbulletcollision.a bullet/libbulletmath.a
esmtool: esmtool.d cpp_ogre.o cpp_avcodec.o cpp_bullet.o $(obj)
- $(DMD) $^ -of$@ -L-lopenal -L-lOgreMain -L-lOIS -L-lavcodec -L-lavformat bullet/libbulletdynamics.a bullet/libbulletcollision.a bullet/libbulletmath.a
+ $(DMD) $^ -of$@ -L-lopenal -L-lOgreMain -L-lOIS -L-lmygui -L-luuid -L-lavcodec -L-lavformat bullet/libbulletdynamics.a bullet/libbulletcollision.a bullet/libbulletmath.a
niftool: niftool.d $(obj_nif)
$(DMD) $^ -of$@
diff --git a/MyGUI_Media/Comic.TTF b/MyGUI_Media/Comic.TTF
new file mode 100644
index 000000000..309894baf
Binary files /dev/null and b/MyGUI_Media/Comic.TTF differ
diff --git a/MyGUI_Media/black.png b/MyGUI_Media/black.png
new file mode 100644
index 000000000..69db2911a
Binary files /dev/null and b/MyGUI_Media/black.png differ
diff --git a/MyGUI_Media/core.font b/MyGUI_Media/core.font
new file mode 100644
index 000000000..36da17b0a
--- /dev/null
+++ b/MyGUI_Media/core.font
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MyGUI_Media/core.lang b/MyGUI_Media/core.lang
new file mode 100644
index 000000000..92fc931b2
--- /dev/null
+++ b/MyGUI_Media/core.lang
@@ -0,0 +1,14 @@
+
+
+
+
+ "unassigned, escape, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, -, =, backspace, tab, q, w, e, r, t, y, u, i, o, p, [, ], enter, lcontrol, a, s, d, f, g, h, j, k, l, ;, ', `, lshift, \, z, x, c, v, b, n, m, comma, ., /, rshift, * on numeric keypad, leftalt, space,
+ unassigned, escape, !, @, #, $, %, ^, &, *, (, ), _, +, backspace, tab, Q, W, E, R, T, Y, U, I, O, P, {, }, enter, lcontrol, A, S, D, F, G, H, J, K, L, :, double quotes, ~, lshift, |, Z, X, C, V, B, N, M, <, >, ?, rshift, * on numeric keypad, leftalt, space"
+
+
+
+ 0, 0, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 45, 61, 0, 0, 1081, 1094, 1091, 1082, 1077, 1085, 1075, 1096, 1097, 1079, 1093, 1098, 0, 0, 1092, 1099, 1074, 1072, 1087, 1088, 1086, 1083, 1076, 1078, 1101, 1105, 0, 92, 1103, 1095, 1089, 1084, 1080, 1090, 1100, 1073, 1102, 46, 0, 42, 0, 32,
+ 0, 0, 33, 34, 8470, 59, 37, 58, 63, 42, 40, 41, 95, 43, 0, 0, 1049, 1062, 1059, 1050, 1045, 1053, 1043, 1064, 1065, 1047, 1061, 1066, 0, 0, 1060, 1067, 1042, 1040, 1055, 1056, 1054, 1051, 1044, 1046, 1069, 1025, 0, 47, 1071, 1063, 1057, 1052, 1048, 1058, 1068, 1041, 1070, 44, 0, 42, 0, 32
+
+
+
diff --git a/MyGUI_Media/core.layer b/MyGUI_Media/core.layer
new file mode 100644
index 000000000..8312126b1
--- /dev/null
+++ b/MyGUI_Media/core.layer
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MyGUI_Media/core.png b/MyGUI_Media/core.png
new file mode 100644
index 000000000..d2ef69dcf
Binary files /dev/null and b/MyGUI_Media/core.png differ
diff --git a/MyGUI_Media/core.pointer b/MyGUI_Media/core.pointer
new file mode 100644
index 000000000..8fd51d6a4
--- /dev/null
+++ b/MyGUI_Media/core.pointer
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MyGUI_Media/core.skin b/MyGUI_Media/core.skin
new file mode 100644
index 000000000..82d6cab39
--- /dev/null
+++ b/MyGUI_Media/core.skin
@@ -0,0 +1,1368 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_BasisSkin type="SubSkin" offset = "3 0 18 30" align = "ALIGN_HSTRETCH ALIGN_TOP">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_BasisSkin type="MainSkin" offset = "0 0 50 50" align = "ALIGN_LEFT ALIGN_TOP">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_BasisSkin type="SubSkin" offset = "8 0 27 28" align = "ALIGN_HSTRETCH ALIGN_TOP">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_BasisSkin type="SubSkin" offset = "3 3 10 16" align = "ALIGN_STRETCH">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_BasisSkin type="MainSkin" offset = "0 0 0 0" align = "ALIGN_LEFT ALIGN_TOP"/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MyGUI_Media/core.xml b/MyGUI_Media/core.xml
new file mode 100644
index 000000000..ee4c539f5
--- /dev/null
+++ b/MyGUI_Media/core.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MyGUI_Media/openmw_windows.skin b/MyGUI_Media/openmw_windows.skin
new file mode 100644
index 000000000..769f428f1
--- /dev/null
+++ b/MyGUI_Media/openmw_windows.skin
@@ -0,0 +1,218 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dsss.conf b/dsss.conf
index df7354800..c6a1f99ba 100644
--- a/dsss.conf
+++ b/dsss.conf
@@ -4,7 +4,7 @@
[openmw.d]
# Add libraries and the two C++ object files
-buildflags = -llOgreMain -llopenal -llOIS -llavcodec -llavformat cpp_ogre.o cpp_avcodec.o cpp_bullet.o bullet/libbulletdynamics.a bullet/libbulletcollision.a bullet/libbulletmath.a
+buildflags = -llmygui -llOgreMain -llopenal -llOIS -lluuid -llavcodec -llavformat cpp_ogre.o cpp_avcodec.o cpp_bullet.o bullet/libbulletdynamics.a bullet/libbulletcollision.a bullet/libbulletmath.a
# Make sure the C++ object files are built first
version(Windows) {
@@ -18,7 +18,6 @@ prebuild += dsss clean niftool
-
###########################
# Bsa inspection tool #
###########################
@@ -34,7 +33,7 @@ prebuild += dsss clean niftool
[esmtool.d]
# Because of interdepencies between the ESM code and the resource
# manager, we have to include all the C++ stuff.
-buildflags = -llOgreMain -llopenal -llOIS -llavcodec -llavformat cpp_ogre.o cpp_avcodec.o cpp_bullet.o bullet/libbulletdynamics.a bullet/libbulletcollision.a bullet/libbulletmath.a
+buildflags = -llmygui -llOgreMain -llopenal -llOIS -lluuid -llavcodec -llavformat cpp_ogre.o cpp_avcodec.o cpp_bullet.o bullet/libbulletdynamics.a bullet/libbulletcollision.a bullet/libbulletmath.a
@@ -48,3 +47,5 @@ buildflags = -debug=warnstd -debug=check -debug=statecheck -debug=strict -debug=
prebuild = dsss clean niftool
[bored.d]
+
+
diff --git a/fonts/fntfile.d b/fonts/fntfile.d
new file mode 100644
index 000000000..798095374
--- /dev/null
+++ b/fonts/fntfile.d
@@ -0,0 +1,146 @@
+
+/*
+ Font loader for the Morrowind .FNT/.TEX font file pair. The current
+ code has just been used for testing purposes and to decode the file
+ format. To make it work with MyGUI, we will have to cooperate with a
+ custom sub-class of the MyGUI::Font class in C++.
+ */
+module fonts.fntfile;
+
+import std.stream;
+
+import monster.util.string;
+
+align(1)
+struct FntEntry
+{
+ // Positions, as fractions of the entire texture surface. The
+ // xstart2 etc values are just repeated information. The reason for
+ // this is that the characters are stored as four points, with an
+ // (x,y) coordinate each. Since all the rectangles are aligned with
+ // the image however, this is pretty redundant information.
+
+ float xstart, ystart;
+ float xend;
+ float ystart2, xstart2;
+ float yend;
+ float xend2, yend2;
+
+ float width;
+ float height;
+ int zero1; // Empty heigth? (always zero)
+ float emptyWidth; // Width for empty characters
+ float unk2; // Vertical displacement?
+ int zero2; // Horizontal displacement?
+
+ bool isUsed() { return width != 0; }
+}
+static assert(FntEntry.sizeof == 56);
+
+align(1)
+struct FntFile
+{
+ float size;
+ int unk2, unk3;
+ char[128] texname;
+
+ ubyte[160] filler; // Makes the header exactly 300 bytes long
+
+ FntEntry[255] chars;
+}
+
+align(1)
+union Color
+{
+ ubyte[4] rgba;
+ uint val;
+}
+static assert(Color.sizeof == 4);
+
+// One character
+struct Char
+{
+ Color[][] pixels;
+ bool isUsed;
+ int width, height;
+ char chr;
+}
+
+FntFile fnt;
+Char[255] chars;
+
+// Load a fnt-file
+void loadFont(char[] fntFile)
+{
+ assert(iEnds(fntFile, ".fnt"),
+ "loadFont() can only load .fnt files");
+
+ File s = new File(fntFile);
+ s.readExact(&fnt, fnt.sizeof);
+ s.close();
+
+ // Load the .tex file
+ int texWidth, texHeight;
+ char[] tfile = stripz(fnt.texname)~".tex";
+ // DIRTY hack since we can't do case-insensitive file searching yet
+ if(tfile[0] == 'D') tfile[0] = 'd';
+ s.open(tfile);
+ s.read(texWidth);
+ s.read(texHeight);
+ assert(s.size() == 4*(texWidth*texHeight + 2));
+
+ ubyte[] buf;
+ buf.length = s.size - s.position;
+ s.readExact(buf.ptr, buf.length);
+ delete s;
+
+ // Get the pixel buffer as a series of ints
+ uint[] pixelBuf = cast(uint[]) buf;
+
+ foreach(i, ch; fnt.chars)
+ with(chars[i])
+ {
+ // Store the char, if it is printable
+ if(i > 33 && i < 127)
+ chr = i;
+ else chr = ' ';
+
+ // Store the pixel dimensions
+ isUsed = ch.isUsed;
+ height = cast(int)ch.height;
+ if(isUsed)
+ width = cast(int)ch.width;
+ else
+ width = cast(int)ch.emptyWidth;
+
+ assert(ch.emptyWidth == 0 || ch.emptyWidth == -1 || !isUsed);
+ assert(ch.zero1 == 0);
+ assert(ch.zero2 == 0);
+ assert(ch.xstart2 == ch.xstart);
+ assert(ch.ystart2 == ch.ystart);
+ assert(ch.xend2 == ch.xend);
+ assert(ch.yend2 == ch.yend);
+
+ // If the character is not present, skip to the next one now.
+ if(!isUsed) continue;
+
+ // Get the pixel coordinates of this character
+ int startX = cast(int) (ch.xstart * texWidth);
+ int startY = cast(int) (ch.ystart * texHeight);
+ int endX = cast(int) (ch.xend * texWidth);
+ int endY = cast(int) (ch.yend * texHeight);
+
+ assert(endX-startX == width);
+ assert(endY-startY == height);
+
+ // Set up the pixel array
+ pixels.length = height;
+ foreach(line, ref slice; pixels)
+ {
+ // First pixel in the line
+ int strt = texWidth*(startY+line) + startX;
+ // Get a slice of the pixel data
+ slice = cast(Color[])pixelBuf[strt..strt+width];
+ }
+ }
+}
diff --git a/input/events.d b/input/events.d
index 52074e142..431b0e0bd 100644
--- a/input/events.d
+++ b/input/events.d
@@ -187,7 +187,7 @@ extern(C) void d_handleKey(KC keycode, dchar text = 0)
case Keys.PhysMode: bullet_nextMode(); break;
case Keys.Nighteye: ogre_toggleLight(); break;
- case Keys.Debug: ogre_debug(0); break;
+ case Keys.Debug: break;
case Keys.ScreenShot: takeScreenShot(); break;
case Keys.Pause: togglePause(); break;
case Keys.Exit: exitProgram(); break;
diff --git a/mscripts/fpsticker.mn b/mscripts/fpsticker.mn
index ea69abcc9..443a62213 100644
--- a/mscripts/fpsticker.mn
+++ b/mscripts/fpsticker.mn
@@ -1,29 +1,38 @@
// Small script that prints the FPS to screen with regular intervals.
+class FPSTicker;
import frames;
-// Sleep one frame. This makes sure that we won't start running until
-// the rendering begins. Not critically important, but it prevents the
-// first printed value from being 'nan'.
-fsleep(1);
+// Set the FPS widget text
+native setText(char[][] args...);
-// counter and totalTime (in the 'frames' module) are updated
-// automatically by the system.
-ulong lastFrame = counter;
-float lastTime = totalTime;
+run()
+{
+ // Sleep one frame. This makes sure that we won't start running until
+ // the rendering begins. Not critically important, but it prevents the
+ // first printed value from being 'nan'.
+ fsleep(1);
-float delay = 1.5;
+ setText("hello!");
-while(true)
-{
- sleep(delay);
+ // counter and totalTime (in the 'frames' module) are updated
+ // automatically by the system.
+ ulong lastFrame = counter;
+ float lastTime = totalTime;
+
+ float delay = 1.5;
+
+ while(true)
+ {
+ sleep(delay);
- // Calculate differences since last frame
- ulong fdiff = counter-lastFrame;
- float tdiff = totalTime-lastTime;
+ // Calculate differences since last frame
+ ulong fdiff = counter-lastFrame;
+ float tdiff = totalTime-lastTime;
- print("fps:", fdiff / tdiff);
+ setText("fps: ", fdiff / tdiff);
- lastFrame = counter;
- lastTime = totalTime;
+ lastFrame = counter;
+ lastTime = totalTime;
+ }
}
diff --git a/mscripts/setup.d b/mscripts/setup.d
index 70a0f5ae9..d0f652090 100644
--- a/mscripts/setup.d
+++ b/mscripts/setup.d
@@ -28,6 +28,9 @@ import monster.compiler.scopes : global;
import monster.modules.timer;
import core.config;
+import ogre.bindings;
+
+import std.string;
// Set up the base Monster classes we need in OpenMW
void initMonsterScripts()
@@ -48,8 +51,23 @@ void initMonsterScripts()
config.mo = (new MonsterClass("Config")).getSing();
// Run the fps ticker
- vm.run("fpsticker.mn");
+ //vm.run("fpsticker.mn");
+ auto mc = new MonsterClass("fpsticker.mn");
+ mc.bind("setText", &setFpsText);
+ mc.createObject().call("run");
// Run the test script
vm.run("test.mn");
}
+
+void setFpsText()
+{
+ AIndex[] args = stack.popAArray();
+
+ char[] res;
+
+ foreach(AIndex ind; args)
+ res ~= format("%s", arrays.getRef(ind).carr);
+
+ gui_setFpsText(res.ptr);
+}
diff --git a/ogre/bindings.d b/ogre/bindings.d
index 28266fd46..bcc711253 100644
--- a/ogre/bindings.d
+++ b/ogre/bindings.d
@@ -160,5 +160,5 @@ void ogre_getCameraPos(float *x, float *y, float *z);
void ogre_getCameraOrientation(float *fx, float *fy, float *fz, float *ux, float *uy, float *uz);
void ogre_moveCameraRel(float x, float y, float z);
-// Do some debug action. Check the menu for today's specials!
-void ogre_debug(int i);
+// Test
+void gui_setFpsText(char *str);
diff --git a/ogre/cpp_bsaarchive.cpp b/ogre/cpp_bsaarchive.cpp
index abe2b31ab..96283be51 100644
--- a/ogre/cpp_bsaarchive.cpp
+++ b/ogre/cpp_bsaarchive.cpp
@@ -97,16 +97,33 @@ public:
}
// Gets called once for each of the ogre formats, *.program,
- // *.material etc. We can ignore this.
+ // *.material etc. It's also called by MyGUI to find textures, so we
+ // have to channel it through exists().
FileInfoListPtr findFileInfo(const String& pattern, bool recursive = true,
bool dirs = false)
{
- //std::cout << "findFileInfo(" << pattern << ", " << recursive
- // << ", " << dirs << ")\n";
-
+ /*
+ std::cout << "findFileInfo(" << pattern << ", " << recursive
+ << ", " << dirs << ")\n";
+ */
FileInfoListPtr ptr = FileInfoListPtr(new FileInfoList());
- //std::cout << "BSAArchive::findFileInfo is not implemented!\n";
+
+ // Check if the file exists (only works for single files - wild
+ // cards and recursive search isn't implemented.)
+ if(exists(pattern))
+ {
+ FileInfo fi;
+ fi.archive = this;
+ fi.filename = pattern;
+ fi.path = "";
+ // It apparently doesn't matter that we return bogus
+ // information
+ fi.compressedSize = fi.uncompressedSize = 0;
+
+ ptr->push_back(fi);
+ }
+
return ptr;
}
diff --git a/ogre/cpp_framelistener.cpp b/ogre/cpp_framelistener.cpp
index c8111e920..a2baa276e 100644
--- a/ogre/cpp_framelistener.cpp
+++ b/ogre/cpp_framelistener.cpp
@@ -48,6 +48,10 @@ public:
mKeyboard->capture();
mMouse->capture();
+ // Notify the GUI
+ mGUI->injectFrameEntered(evt.timeSinceLastFrame);
+
+ // Turn over control to the D code
return d_frameStarted(evt.timeSinceLastFrame);
}
};
@@ -75,7 +79,12 @@ public:
<< s.X.abs << ", " << s.Y.abs << ", " << s.Z.abs << ") Rel("
<< s.X.rel << ", " << s.Y.rel << ", " << s.Z.rel << ")\n";
*/
- d_handleMouseMove(&arg.state);
+ // TODO: this should be handled elsewhere later on, most likely in
+ // Monster script.
+ if(guiMode)
+ mGUI->injectMouseMove(arg);
+ else
+ d_handleMouseMove(&arg.state);
return true;
}
@@ -87,13 +96,22 @@ public:
<< s.X.abs << ", " << s.Y.abs << ", " << s.Z.abs << ") Rel("
<< s.X.rel << ", " << s.Y.rel << ", " << s.Z.rel << ")\n";
*/
- d_handleMouseButton(&arg.state, id);
+ if(guiMode)
+ mGUI->injectMousePress(arg, id);
+ else
+ d_handleMouseButton(&arg.state, id);
+ return true;
+ }
+
+ bool mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
+ {
+ if(guiMode)
+ mGUI->injectMouseRelease(arg, id);
return true;
}
// Unused
bool keyReleased( const OIS::KeyEvent &arg ) { return true; }
- bool mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id ) { return true; }
};
MorroFrameListener mFrameListener;
diff --git a/ogre/cpp_interface.cpp b/ogre/cpp_interface.cpp
index 959fc871a..72a6506b3 100644
--- a/ogre/cpp_interface.cpp
+++ b/ogre/cpp_interface.cpp
@@ -147,14 +147,10 @@ extern "C" void ogre_initWindow()
mMouse = static_cast(mInputManager->createInputObject
( OISMouse, bufferedMouse ));
- unsigned int width, height, depth;
- int left, top;
- mWindow->getMetrics(width, height, depth, left, top);
-
// Set mouse region
const MouseState &ms = mMouse->getMouseState();
- ms.width = width;
- ms.height = height;
+ ms.width = mWindow->getWidth();
+ ms.height = mWindow->getHeight();
// Register the input listener
mKeyboard -> setEventCallback( &mInput );
@@ -207,6 +203,9 @@ extern "C" void ogre_makeScene()
g_light->setDiffuseColour(1,0.7,0.3);
g_light->setAttenuation(2000, 0, 0.008, 0);
*/
+
+ // Finally, set up the GUI
+ setupGUI();
}
/*
@@ -447,9 +446,6 @@ public:
}
} dummyLoader;
- // TODO/FIXME/DEBUG (MURDER/DEATH/KILL)
-String LASTNAME;
-
// Load the contents of a mesh
extern "C" void ogre_createMesh(
char* name, // Name of the mesh
@@ -652,9 +648,6 @@ extern "C" void ogre_createMaterial(char *name, // Name to give
// like crap so it's not enabled right now.
//material->setSceneBlending(SBT_TRANSPARENT_ALPHA);
-
- // Temporary, just to store the name of one valid material.
- LASTNAME = material->getName();
}
extern "C" SceneNode *ogre_getDetachedNode()
diff --git a/ogre/cpp_mygui.cpp b/ogre/cpp_mygui.cpp
new file mode 100644
index 000000000..74292cda4
--- /dev/null
+++ b/ogre/cpp_mygui.cpp
@@ -0,0 +1,104 @@
+MyGUI::WidgetPtr FPSText;
+
+MyGUI::WindowPtr window;
+MyGUI::WindowPtr mwindow;
+
+void turnGuiOff(MyGUI::WidgetPtr sender)
+{
+ guiMode = 0;
+ mGUI->hidePointer();
+ if(window)
+ {
+ window->destroySmooth();
+ window = NULL;
+ }
+ if(mwindow)
+ {
+ mwindow->destroySmooth();
+ mwindow = NULL;
+ }
+}
+
+void setupGUI()
+{
+ ResourceGroupManager::getSingleton().
+ addResourceLocation("MyGUI_Media", "FileSystem", "General");
+
+ mGUI = new MyGUI::Gui();
+ mGUI->initialise(mWindow);
+
+ int mWidth = mWindow->getWidth();
+ int mHeight = mWindow->getHeight();
+ int width = 120;
+ int height = 30;
+
+ // FPS Ticker
+ FPSText = mGUI->createWidget
+ ("StaticText",
+ mWidth - width -10, 10, // Position
+ width, height, // Size
+ MyGUI::ALIGN_RIGHT | MyGUI::ALIGN_TOP,
+ "Statistic");
+ FPSText->setTextAlign(MyGUI::ALIGN_RIGHT);
+ FPSText->setColour(Ogre::ColourValue::White);
+ FPSText->setNeedMouseFocus(false);
+
+ // TESTING WINDOW WITH BUTTON
+ guiMode = 1;
+ width = 300;
+ height = 200;
+ window = mGUI->createWidget
+ ("WindowCS",
+ (mWidth-width)/4, (mHeight-height)/4, // Position
+ width, height, // Size
+ MyGUI::ALIGN_DEFAULT, "Overlapped");
+ //window->setColour(Ogre::ColourValue::White);
+ //window->setFontName("ManualFont");
+ window->setCaption("GUI Demo");
+ window->setMinMax(180, 160, 1000, 1000);
+ window->setAlpha(0.7);
+
+ width = 150;
+ height = 30;
+ MyGUI::WidgetPtr tmp;
+ tmp = window->createWidget
+ ("ButtonSmall",
+ 40, 100, // Position
+ width, height, // Size
+ MyGUI::ALIGN_LEFT | MyGUI::ALIGN_TOP,
+ "Main");
+ tmp->setCaption("Press this button");
+ tmp->eventMouseButtonClick = MyGUI::newDelegate(&turnGuiOff);
+
+ // TESTING MORROWIND SKIN
+ width = 300;
+ height = 190;
+ mwindow = mGUI->createWidget
+ ("MW_Window",
+ mWidth-width-120, mHeight-height-160, // Position
+ width, height, // Size
+ MyGUI::ALIGN_DEFAULT, "Overlapped");
+ mwindow->setCaption("Skin test");
+ mwindow->setMinMax(100, 140, 1000, 1000);
+ mwindow->setAlpha(1);
+
+ // TESTING BITMAP FONT
+ /*
+ tmp = mGUI->createWidget
+ ("StaticText",
+ 10, mHeight - height, // Position
+ width, height, // Size
+ MyGUI::ALIGN_LEFT | MyGUI::ALIGN_BOTTOM,
+ "Statistic");
+ tmp->setTextAlign(MyGUI::ALIGN_LEFT);
+ tmp->setColour(Ogre::ColourValue::White);
+ tmp->setFontName("ManualFont");
+ tmp->setCaption("ABC");
+ //*/
+}
+
+extern "C" void gui_setFpsText(char *str)
+{
+ if(FPSText != NULL)
+ FPSText->setCaption(str);
+}
diff --git a/ogre/cpp_ogre.cpp b/ogre/cpp_ogre.cpp
index e408acf06..40d911312 100644
--- a/ogre/cpp_ogre.cpp
+++ b/ogre/cpp_ogre.cpp
@@ -28,12 +28,13 @@
#include
#include
#include
-#include
#include
#include
#include
+#include
+
using namespace Ogre;
RenderWindow* mWindow;
@@ -54,13 +55,17 @@ OIS::InputManager *mInputManager;
OIS::Mouse *mMouse;
OIS::Keyboard *mKeyboard;
+// The global GUI object
+MyGUI::Gui *mGUI;
+int guiMode = 0;
+
// Root node for all objects added to the scene. This is rotated so
// that the OGRE coordinate system matches that used internally in
// Morrowind.
SceneNode *root;
// Include the other parts of the code, and make one big object file.
+#include "cpp_mygui.cpp"
#include "cpp_framelistener.cpp"
#include "cpp_bsaarchive.cpp"
#include "cpp_interface.cpp"
-#include "cpp_overlay.cpp"
diff --git a/ogre/cpp_overlay.cpp b/ogre/cpp_overlay.cpp
deleted file mode 100644
index 0ea80a846..000000000
--- a/ogre/cpp_overlay.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- OpenMW - The completely unofficial reimplementation of Morrowind
- Copyright (C) 2008 Nicolay Korslund
- Email: < korslund@gmail.com >
- WWW: http://openmw.snaptoad.com/
-
- This file (cpp_overlay.cpp) 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/ .
-
- */
-
-OverlayManager *om;
-Overlay *owl;
-PanelOverlayElement *cont;
-
-int visible;
-
-extern "C" void ogre_debug(int32_t i)
-{
- std::cerr << "Running ogre_debug(" << i << ")\n";
-
- if(om)
- {
- if(visible)
- {
- visible = 0;
- owl->hide();
- }
- else
- {
- visible = 1;
- owl->show();
- }
-
- return;
- }
-
- om = OverlayManager::getSingletonPtr();
-
- owl = om->create("HUD");
-
- OverlayElement *e = om->createOverlayElementFromFactory("Panel", "Hopp");
- cont = (PanelOverlayElement*)e;
-
- cont->setDimensions(0.3, 0.5);
- cont->setPosition(0.1, 0.2);
- cont->setMaterialName(LASTNAME);
-
- /*
- * I suggest creating a custom material based on a "live" texture,
- * where we can specify alpha transparency and draw everything
- * ourselves. (Reinvent the wheel at every chance! :)
- */
- MaterialPtr material = MaterialManager::getSingleton().getByName(LASTNAME);
- std::cerr << "Material " << LASTNAME << "\n";
- Pass* pass = material->getTechnique(0)->getPass(0);
- pass->setSceneBlending(SBT_TRANSPARENT_ALPHA);
-
- owl->add2D(cont);
- owl->show();
- visible = 1;
-}