From b2d54a619e42296c34b79dc04007e5f379851129 Mon Sep 17 00:00:00 2001 From: Nicolay Korslund Date: Thu, 8 Jul 2010 15:23:35 +0200 Subject: [PATCH] Implemented all MW window layouts --- .gitignore | 2 + CMakeLists.txt | 101 ++-- apps/mygui_dev/CMakeLists.txt | 4 +- apps/mygui_dev/layout.hpp | 125 +++++ apps/mygui_dev/main.cpp | 97 +++- apps/mygui_dev/manager.hpp | 58 +++ apps/mygui_dev/mw_layouts.hpp | 188 ++++++++ .../openmw_resources/openmw_box.skin.xml | 16 +- .../openmw_resources/openmw_button.skin.xml | 16 +- .../openmw_resources/openmw_hud_box.skin.xml | 2 +- .../openmw_hud_energybar.skin.xml | 6 +- .../openmw_resources/openmw_mainmenu_skin.xml | 12 +- .../openmw_resources/openmw_windows.skin.xml | 34 +- old_d_version/gui/bindings.d | 62 --- old_d_version/gui/cpp_mygui.cpp | 436 ------------------ old_d_version/gui/gui.d | 321 ------------- 16 files changed, 551 insertions(+), 929 deletions(-) create mode 100644 apps/mygui_dev/layout.hpp create mode 100644 apps/mygui_dev/manager.hpp create mode 100644 apps/mygui_dev/mw_layouts.hpp delete mode 100644 old_d_version/gui/bindings.d delete mode 100644 old_d_version/gui/gui.d diff --git a/.gitignore b/.gitignore index 8f48283fa..c38aabac4 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,5 @@ mwcompiler mwinterpreter clientconsole MyGUI.log +mygui_test +mygui_test.png diff --git a/CMakeLists.txt b/CMakeLists.txt index f89cb85f7..12a9ef83b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,22 +9,22 @@ set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/) # source directory: apps set(GAME - apps/openmw/main.cpp + apps/openmw/main.cpp apps/openmw/engine.cpp) set(GAME_HEADER apps/openmw/engine.hpp) source_group(game FILES ${GAME} ${GAME_HEADER}) set(GAMEREND - apps/openmw/mwrender/mwscene.cpp + apps/openmw/mwrender/mwscene.cpp apps/openmw/mwrender/cellimp.cpp apps/openmw/mwrender/interior.cpp apps/openmw/mwrender/sky.cpp) set(GAMEREND_HEADER - apps/openmw/mwrender/cell.hpp - apps/openmw/mwrender/cellimp.hpp + apps/openmw/mwrender/cell.hpp + apps/openmw/mwrender/cellimp.hpp apps/openmw/mwrender/mwscene.hpp - apps/openmw/mwrender/interior.hpp + apps/openmw/mwrender/interior.hpp apps/openmw/mwrender/playerpos.hpp apps/openmw/mwrender/sky.hpp) source_group(apps\\openmw\\mwrender FILES ${GAMEREND} ${GAMEREND_HEADER}) @@ -87,87 +87,88 @@ set(APPS_HEADER ${GAME_HEADER} ${GAMEREND_HEADER} ${GAMEINPUT_HEADER} ${GAMESCRI ${GAMESOUND_HEADER} ${GAMEGUI_HEADER} ${GAMEWORLD_HEADER}) # source directory: components +set(COMP_DIR ${CMAKE_SOURCE_DIR}/components) set(BSA - components/bsa/bsa_archive.cpp - components/bsa/bsa_file.cpp) + ${COMP_DIR}/bsa/bsa_archive.cpp + ${COMP_DIR}/bsa/bsa_file.cpp) set(BSA_HEADER - components/bsa/bsa_archive.hpp - components/bsa/bsa_file.hpp) + ${COMP_DIR}/bsa/bsa_archive.hpp + ${COMP_DIR}/bsa/bsa_file.hpp) source_group(components\\bsa FILES ${BSA} ${BSA_HEADER}) set(NIF - components/nif/nif_file.cpp) + ${COMP_DIR}/nif/nif_file.cpp) set(NIF_HEADER - components/nif/controlled.hpp - components/nif/effect.hpp - components/nif/nif_types.hpp - components/nif/record.hpp - components/nif/controller.hpp - components/nif/extra.hpp - components/nif/node.hpp - components/nif/record_ptr.hpp - components/nif/data.hpp - components/nif/nif_file.hpp - components/nif/property.hpp) + ${COMP_DIR}/nif/controlled.hpp + ${COMP_DIR}/nif/effect.hpp + ${COMP_DIR}/nif/nif_types.hpp + ${COMP_DIR}/nif/record.hpp + ${COMP_DIR}/nif/controller.hpp + ${COMP_DIR}/nif/extra.hpp + ${COMP_DIR}/nif/node.hpp + ${COMP_DIR}/nif/record_ptr.hpp + ${COMP_DIR}/nif/data.hpp + ${COMP_DIR}/nif/nif_file.hpp + ${COMP_DIR}/nif/property.hpp) source_group(components\\nif FILES ${NIF} ${NIF_HEADER}) set(NIFOGRE - components/nifogre/ogre_nif_loader.cpp) + ${COMP_DIR}/nifogre/ogre_nif_loader.cpp) set(NIFOGRE_HEADER - components/nifogre/ogre_nif_loader.hpp) + ${COMP_DIR}/nifogre/ogre_nif_loader.hpp) source_group(components\\nifogre FILES ${NIFOGRE} ${NIFOGRE_HEADER}) set(ESM_STORE - components/esm_store/store.cpp) + ${COMP_DIR}/esm_store/store.cpp) set(ESM_STORE_HEADER - components/esm_store/cell_store.hpp - components/esm_store/reclists.hpp - components/esm_store/store.hpp) + ${COMP_DIR}/esm_store/cell_store.hpp + ${COMP_DIR}/esm_store/reclists.hpp + ${COMP_DIR}/esm_store/store.hpp) source_group(components\\esm_store FILES ${ESM_STORE} ${ESM_STORE_HEADER}) -file(GLOB ESM_HEADER components/esm/*.hpp) +file(GLOB ESM_HEADER ${COMP_DIR}/esm/*.hpp) source_group(components\\esm FILES ${ESM_HEADER}) set(OGRE - ${CMAKE_SOURCE_DIR}/components/engine/ogre/renderer.cpp) + ${COMP_DIR}/engine/ogre/renderer.cpp) set(OGRE_HEADER - ${CMAKE_SOURCE_DIR}/components/engine/ogre/renderer.hpp) + ${COMP_DIR}/engine/ogre/renderer.hpp) source_group(components\\engine\\ogre FILES ${OGRE} ${OGRE_HEADER}) set(INPUT - components/engine/input/oismanager.cpp) + ${COMP_DIR}/engine/input/oismanager.cpp) set(INPUT_HEADER - components/engine/input/oismanager.hpp - components/engine/input/listener.hpp - components/engine/input/func_binder.hpp - components/engine/input/dispatch_map.hpp - components/engine/input/dispatcher.hpp - components/engine/input/poller.hpp) + ${COMP_DIR}/engine/input/oismanager.hpp + ${COMP_DIR}/engine/input/listener.hpp + ${COMP_DIR}/engine/input/func_binder.hpp + ${COMP_DIR}/engine/input/dispatch_map.hpp + ${COMP_DIR}/engine/input/dispatcher.hpp + ${COMP_DIR}/engine/input/poller.hpp) source_group(components\\engine\\input FILES ${INPUT} ${INPUT_HEADER}) set(COMMANDSERVER - components/commandserver/command.hpp - components/commandserver/server.hpp - components/commandserver/server.cpp) + ${COMP_DIR}/commandserver/command.hpp + ${COMP_DIR}/commandserver/server.hpp + ${COMP_DIR}/commandserver/server.cpp) source_group(components\\commandserver FILES ${COMMANDSERVER}) set(MISC - components/misc/stringops.cpp - components/misc/fileops.cpp) + ${COMP_DIR}/misc/stringops.cpp + ${COMP_DIR}/misc/fileops.cpp) set(MISC_HEADER - components/misc/fileops.hpp - components/misc/slice_array.hpp - components/misc/stringops.hpp - components/misc/tsdeque.hpp) + ${COMP_DIR}/misc/fileops.hpp + ${COMP_DIR}/misc/slice_array.hpp + ${COMP_DIR}/misc/stringops.hpp + ${COMP_DIR}/misc/tsdeque.hpp) source_group(components\\misc FILES ${MISC} ${MISC_HEADER}) -file(GLOB COMPILER components/compiler/*.cpp) -file(GLOB COMPILER_HEADER components/compiler/*.hpp) +file(GLOB COMPILER ${COMP_DIR}/compiler/*.cpp) +file(GLOB COMPILER_HEADER ${COMP_DIR}/compiler/*.hpp) source_group(components\\compiler FILES ${COMPILER} ${COMPILER_HEADER}) -file(GLOB INTERPRETER components/interpreter/*.cpp) -file(GLOB INTERPRETER_HEADER components/interpreter/*.hpp) +file(GLOB INTERPRETER ${COMP_DIR}/interpreter/*.cpp) +file(GLOB INTERPRETER_HEADER ${COMP_DIR}/interpreter/*.hpp) source_group(components\\interpreter FILES ${INTERPRETER} ${INTERPRETER_HEADER}) set(COMPONENTS ${BSA} ${NIF} ${NIFOGRE} ${ESM_STORE} ${OGRE} ${INPUT} ${MISC} diff --git a/apps/mygui_dev/CMakeLists.txt b/apps/mygui_dev/CMakeLists.txt index 9d3c3790f..2d1a2beb9 100644 --- a/apps/mygui_dev/CMakeLists.txt +++ b/apps/mygui_dev/CMakeLists.txt @@ -1,7 +1,7 @@ add_executable(mygui_test main.cpp - ${OGRE} - ${OGRE_HEADER} + ${BSA} ${BSA_HEADER} + ${OGRE} ${OGRE_HEADER} ) target_link_libraries(mygui_test ${OGRE_LIBRARIES} diff --git a/apps/mygui_dev/layout.hpp b/apps/mygui_dev/layout.hpp new file mode 100644 index 000000000..4d0a7e663 --- /dev/null +++ b/apps/mygui_dev/layout.hpp @@ -0,0 +1,125 @@ +#ifndef ENGINE_MYGUI_LAYOUT_H +#define ENGINE_MYGUI_LAYOUT_H + +#include +#include + +namespace GUI +{ + /** The Layout class is an utility class used to load MyGUI layouts + from xml files, and to manipulate member widgets. + */ + class Layout + { + public: + Layout(const std::string & _layout, MyGUI::WidgetPtr _parent = nullptr) + : mMainWidget(nullptr) + { initialise(_layout, _parent); } + virtual ~Layout() { shutdown(); } + + template + void getWidget(T * & _widget, const std::string & _name, bool _throw = true) + { + _widget = nullptr; + for (MyGUI::VectorWidgetPtr::iterator iter=mListWindowRoot.begin(); + iter!=mListWindowRoot.end(); ++iter) + { + MyGUI::WidgetPtr find = (*iter)->findWidget(mPrefix + _name); + if (nullptr != find) + { + T * cast = find->castType(false); + if (nullptr != cast) + _widget = cast; + else if (_throw) + { + MYGUI_EXCEPT("Error cast : dest type = '" << T::getClassTypeName() + << "' source name = '" << find->getName() + << "' source type = '" << find->getTypeName() << "' in layout '" << mLayoutName << "'"); + } + return; + } + } + MYGUI_ASSERT( ! _throw, "widget name '" << _name << "' in layout '" << mLayoutName << "' not found."); + } + + void initialise(const std::string & _layout, + MyGUI::WidgetPtr _parent = nullptr) + { + const std::string MAIN_WINDOW = "_Main"; + mLayoutName = _layout; + + if (mLayoutName.empty()) + mMainWidget = _parent; + else + { + mPrefix = MyGUI::utility::toString(this, "_"); + mListWindowRoot = MyGUI::LayoutManager::getInstance().loadLayout(mLayoutName, mPrefix, _parent); + + const std::string main_name = mPrefix + MAIN_WINDOW; + for (MyGUI::VectorWidgetPtr::iterator iter=mListWindowRoot.begin(); iter!=mListWindowRoot.end(); ++iter) + { + if ((*iter)->getName() == main_name) + { + mMainWidget = (*iter); + break; + } + } + MYGUI_ASSERT(mMainWidget, "root widget name '" << MAIN_WINDOW << "' in layout '" << mLayoutName << "' not found."); + } + } + + void shutdown() + { + for (VectorBasePtr::iterator iter=mListBase.begin(); iter!=mListBase.end(); ++iter) { + delete (*iter); + } + mListBase.clear(); + + MyGUI::LayoutManager::getInstance().unloadLayout(mListWindowRoot); + mListWindowRoot.clear(); + } + + void setCoord(int x, int y, int w, int h) + { + mMainWidget->setCoord(x,y,w,h); + } + + void setVisible(bool b) + { + mMainWidget->setVisible(b); + } + + void setText(const std::string& name, const std::string& caption) + { + MyGUI::WidgetPtr pt; + getWidget(pt, name); + pt->setCaption(caption); + } + + void setTextColor(const std::string& name, float r, float g, float b) + { + MyGUI::WidgetPtr pt; + getWidget(pt, name); + MyGUI::StaticText *st = dynamic_cast(pt); + if(st != NULL) + st->setTextColour(MyGUI::Colour(b,g,r)); + } + + void setImage(const std::string& name, const std::string& imgName) + { + MyGUI::StaticImagePtr pt; + getWidget(pt, name); + pt->setImageTexture(imgName); + } + + protected: + + MyGUI::WidgetPtr mMainWidget; + std::string mPrefix; + std::string mLayoutName; + MyGUI::VectorWidgetPtr mListWindowRoot; + typedef std::vector VectorBasePtr; + VectorBasePtr mListBase; + }; +} +#endif diff --git a/apps/mygui_dev/main.cpp b/apps/mygui_dev/main.cpp index 027585363..1b11951ba 100644 --- a/apps/mygui_dev/main.cpp +++ b/apps/mygui_dev/main.cpp @@ -1,13 +1,45 @@ #include +#include +#include using namespace std; -#include -#include -using namespace MyGUI; +#include "manager.hpp" +#include "layout.hpp" +#include "mw_layouts.hpp" #include #include +#include + +// Frame listener +struct Listener : public Ogre::FrameListener +{ + bool exit; + float total; + int step; + + Listener() : exit(false), total(0.0), step(0) {} + + bool frameStarted(const Ogre::FrameEvent &evt) + { + total += evt.timeSinceLastFrame; + + // Countdown to exit + const int MAX = 5; + if(total >= step) + { + step++; + if(stepinitialise(ogre.getWindow(), ogre.getScene()); - - // Create GUI - Gui *gui = new Gui(); - gui->initialise(); + Listener listener; + ogre.getRoot()->addFrameListener(&listener); - // Add the Morrowind windows resources + cout << "Adding data path and BSA\n"; + // Add the Morrowind window resources Ogre::ResourceGroupManager::getSingleton(). addResourceLocation("resources/mygui/", "FileSystem", "General"); + // And add the BSA, since most of the window bitmaps are located + // there + addBSA("data/Morrowind.bsa"); + + // Make sure you load the data paths BEFORE you initialize the + // GUI. MyGUI depends on finding core.xml in resources/mygui/. + cout << "Setting up MyGUI\n"; + GUI::MyGUIManager gui(ogre.getWindow(), ogre.getScene()); + + int w = ogre.getWindow()->getWidth(); + int h = ogre.getWindow()->getHeight(); + + cout << "Setting up the window layouts\n"; + MWGUI::HUD hud(w,h); + MWGUI::MapWindow map; + MWGUI::MainMenu menu(w,h); + MWGUI::StatsWindow stats; + + hud.setVisible(true); + map.setVisible(true); + menu.setVisible(false); + stats.setVisible(true); + + cout << "Starting rendering loop\n"; + ogre.start(); + ogre.screenshot("mygui_test.png"); + + cout << "Done.\n"; return 0; } + +/// Old D function +/* +extern "C" MyGUI::WidgetPtr gui_createText(const char *skin, + int32_t x, int32_t y, + int32_t w, int32_t h, + const char *layer) +{ + return mGUI->createWidget + (skin, + x,y,w,h, + MyGUI::ALIGN_LEFT | MyGUI::ALIGN_TOP, + layer); +} +*/ diff --git a/apps/mygui_dev/manager.hpp b/apps/mygui_dev/manager.hpp new file mode 100644 index 000000000..2771c666a --- /dev/null +++ b/apps/mygui_dev/manager.hpp @@ -0,0 +1,58 @@ +#ifndef ENGINE_MYGUI_MANAGER_H +#define ENGINE_MYGUI_MANAGER_H + +#include +#include +#include + +namespace GUI +{ + class MyGUIManager + { + MyGUI::OgrePlatform *mPlatform; + MyGUI::Gui *mGui; + + public: + MyGUIManager() : mPlatform(NULL), mGui(NULL) {} + MyGUIManager(Ogre::RenderWindow *wnd, Ogre::SceneManager *mgr, bool logging=false) + { setup(wnd,mgr,logging); } + ~MyGUIManager() { shutdown(); } + + void setup(Ogre::RenderWindow *wnd, Ogre::SceneManager *mgr, bool logging=false) + { + assert(wnd); + assert(mgr); + + using namespace MyGUI; + + // Enable/disable MyGUI logging to stdout. (Logging to MyGUI.log + // is still enabled.) In order to do this we have to initialize + // the log manager before the main gui system itself, otherwise + // the main object will get the chance to spit out a few messages + // before we can able to disable it. + LogManager::initialise(); + LogManager::setSTDOutputEnabled(logging); + + // Set up OGRE platform. We might make this more generic later. + mPlatform = new OgrePlatform(); + mPlatform->initialise(wnd, mgr); + + // Create GUI + mGui = new Gui(); + mGui->initialise(); + } + + void shutdown() + { + if(mGui) delete mGui; + if(mPlatform) + { + mPlatform->shutdown(); + delete mPlatform; + } + mGui = NULL; + mPlatform = NULL; + } + }; +} +#endif diff --git a/apps/mygui_dev/mw_layouts.hpp b/apps/mygui_dev/mw_layouts.hpp new file mode 100644 index 000000000..03e9fa007 --- /dev/null +++ b/apps/mygui_dev/mw_layouts.hpp @@ -0,0 +1,188 @@ +#ifndef MWGUI_LAYOUTS_H +#define MWGUI_LAYOUTS_H + +#include "layout.hpp" + +namespace MWGUI +{ + class HUD : public GUI::Layout + { + public: + HUD(int width, int height) + : Layout("openmw_hud_layout.xml") + { + setCoord(0,0, width, height); + + // Energy bars + getWidget(health, "Health"); + getWidget(magicka, "Magicka"); + getWidget(stamina, "Stamina"); + + // Item and spell images and status bars + getWidget(weapImage, "WeapImage"); + getWidget(weapStatus, "WeapStatus"); + getWidget(spellImage, "SpellImage"); + getWidget(spellStatus, "SpellStatus"); + + getWidget(effectBox, "EffectBox"); + getWidget(effect1, "Effect1"); + + getWidget(minimap, "MiniMap"); + getWidget(compass, "Compass"); + + getWidget(crosshair, "Crosshair"); + + compass->setImageTexture("compass.dds"); + crosshair->setImageTexture("target.dds"); + + // These are just demo values, you should replace these with + // real calls from outside the class later. + setStats(60, 100, + 30, 100, + 80, 100); + setWeapIcon("icons\\w\\tx_knife_iron.dds"); + setWeapStatus(90, 100); + setSpellIcon("icons\\s\\b_tx_s_rstor_health.dds"); + setSpellStatus(65, 100); + setEffect("icons\\s\\tx_s_chameleon.dds"); + } + + void setStats(int h, int hmax, int m, int mmax, int s, int smax) + { + health->setProgressRange(hmax); + health->setProgressPosition(h); + magicka->setProgressRange(mmax); + magicka->setProgressPosition(m); + stamina->setProgressRange(smax); + stamina->setProgressPosition(s); + } + + void setWeapIcon(const char *str) + { weapImage->setImageTexture(str); } + void setSpellIcon(const char *str) + { spellImage->setImageTexture(str); } + + void setWeapStatus(int s, int smax) + { + weapStatus->setProgressRange(smax); + weapStatus->setProgressPosition(s); + } + void setSpellStatus(int s, int smax) + { + spellStatus->setProgressRange(smax); + spellStatus->setProgressPosition(s); + } + + void setEffect(const char *img) + { effect1->setImageTexture(img); } + + MyGUI::ProgressPtr health, magicka, stamina; + + MyGUI::StaticImagePtr weapImage, spellImage; + MyGUI::ProgressPtr weapStatus, spellStatus; + + MyGUI::WidgetPtr effectBox; + MyGUI::StaticImagePtr effect1; + + MyGUI::StaticImagePtr minimap; + MyGUI::StaticImagePtr compass; + + MyGUI::StaticImagePtr crosshair; + }; + + class MapWindow : public GUI::Layout + { + public: + MapWindow() + : Layout("openmw_map_window_layout.xml") + { + setCoord(500,0,320,300); + setText("WorldButton", "World"); + setImage("Compass", "compass.dds"); + + // Obviously you should override this later on + setCellName("No Cell Loaded"); + } + + void setCellName(const std::string& cellName) + { + mMainWidget->setCaption(cellName); + } + }; + + class MainMenu : public GUI::Layout + { + public: + MainMenu(int w, int h) + : Layout("openmw_mainmenu_layout.xml") + { + setCoord(0,0,w,h); + } + }; + + class StatsWindow : public GUI::Layout + { + public: + void setBar(const char* name, const char* tname, int val, int max) + { + MyGUI::ProgressPtr pt; + getWidget(pt, name); + pt->setProgressRange(max); + pt->setProgressPosition(val); + + std::stringstream out; + out << val << "/" << max; + setText(tname, out.str().c_str()); + } + + StatsWindow() + : Layout("openmw_stats_window_layout.xml") + { + setCoord(0,0,498, 342); + + setText("Health_str", "Health"); + setText("Magicka_str", "Magicka"); + setText("Fatigue_str", "Fatigue"); + + setText("Level_str", "Level"); + setText("Race_str", "Race"); + setText("Class_str", "Class"); + + setText("Attrib1", "Strength"); + setText("Attrib2", "Intelligence"); + setText("Attrib3", "Willpower"); + setText("Attrib4", "Agility"); + setText("Attrib5", "Speed"); + setText("Attrib6", "Endurance"); + setText("Attrib7", "Personality"); + setText("Attrib8", "Luck"); + + // These are just demo values, you should replace these with + // real calls from outside the class later. + setPlayerName("ThePlayer"); + + setText("LevelText", "5"); + setText("RaceText", "Wood Elf"); + setText("ClassText", "Pilgrim"); + + setBar("HBar", "HBarT", 60, 100); + setBar("MBar", "MBarT", 30, 100); + setBar("FBar", "FBarT", 80, 100); + + setText("AttribVal1", "30"); + setText("AttribVal2", "40"); + setText("AttribVal3", "30"); + setText("AttribVal4", "75"); + setText("AttribVal5", "50"); + setText("AttribVal6", "40"); + setText("AttribVal7", "50"); + setText("AttribVal8", "40"); + } + + void setPlayerName(const std::string& playerName) + { + mMainWidget->setCaption(playerName); + } + }; +} +#endif diff --git a/extern/mygui_3.0.1/openmw_resources/openmw_box.skin.xml b/extern/mygui_3.0.1/openmw_resources/openmw_box.skin.xml index 683c9c146..c1952794c 100644 --- a/extern/mygui_3.0.1/openmw_resources/openmw_box.skin.xml +++ b/extern/mygui_3.0.1/openmw_resources/openmw_box.skin.xml @@ -5,42 +5,42 @@ as around the sections of the stats window, or around popup info windows --> - + - + - + - + - + - + - + - + diff --git a/extern/mygui_3.0.1/openmw_resources/openmw_button.skin.xml b/extern/mygui_3.0.1/openmw_resources/openmw_button.skin.xml index b38790c38..fbc5aeb59 100644 --- a/extern/mygui_3.0.1/openmw_resources/openmw_button.skin.xml +++ b/extern/mygui_3.0.1/openmw_resources/openmw_button.skin.xml @@ -2,42 +2,42 @@ - + - + - + - + - + - + - + - + diff --git a/extern/mygui_3.0.1/openmw_resources/openmw_hud_box.skin.xml b/extern/mygui_3.0.1/openmw_resources/openmw_hud_box.skin.xml index 1f91c66b5..bf1b0056a 100644 --- a/extern/mygui_3.0.1/openmw_resources/openmw_hud_box.skin.xml +++ b/extern/mygui_3.0.1/openmw_resources/openmw_hud_box.skin.xml @@ -2,7 +2,7 @@ - + diff --git a/extern/mygui_3.0.1/openmw_resources/openmw_hud_energybar.skin.xml b/extern/mygui_3.0.1/openmw_resources/openmw_hud_energybar.skin.xml index 6b0bef484..03d2835d6 100644 --- a/extern/mygui_3.0.1/openmw_resources/openmw_hud_energybar.skin.xml +++ b/extern/mygui_3.0.1/openmw_resources/openmw_hud_energybar.skin.xml @@ -2,17 +2,17 @@ - + - + - + diff --git a/extern/mygui_3.0.1/openmw_resources/openmw_mainmenu_skin.xml b/extern/mygui_3.0.1/openmw_resources/openmw_mainmenu_skin.xml index 4679430cc..4100a2eb7 100644 --- a/extern/mygui_3.0.1/openmw_resources/openmw_mainmenu_skin.xml +++ b/extern/mygui_3.0.1/openmw_resources/openmw_mainmenu_skin.xml @@ -1,32 +1,32 @@ - + - + - + - + - + - + diff --git a/extern/mygui_3.0.1/openmw_resources/openmw_windows.skin.xml b/extern/mygui_3.0.1/openmw_resources/openmw_windows.skin.xml index 41962cf85..50925715f 100644 --- a/extern/mygui_3.0.1/openmw_resources/openmw_windows.skin.xml +++ b/extern/mygui_3.0.1/openmw_resources/openmw_windows.skin.xml @@ -9,28 +9,28 @@ - + - + - + - + @@ -38,25 +38,25 @@ - + - + - + - + @@ -64,52 +64,52 @@ - + - + - + - + - + - + - + - + - + diff --git a/old_d_version/gui/bindings.d b/old_d_version/gui/bindings.d deleted file mode 100644 index a7f53b531..000000000 --- a/old_d_version/gui/bindings.d +++ /dev/null @@ -1,62 +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 (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 cpp_mygui.cpp - -typedef void* WidgetPtr; -void gui_setupGUI(int debugOut); -void gui_toggleGui(); -void gui_setCellName(char *str); -void gui_showHUD(); - -// Console stuff -void gui_toggleConsole(); -void gui_setConsoleFont(char*); -void gui_clearConsole(); - -// Get the widget type, as a string -char *gui_widgetType(WidgetPtr); - -// Get the guiMode flag -int *gui_getGuiModePtr(); - -// 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); diff --git a/old_d_version/gui/cpp_mygui.cpp b/old_d_version/gui/cpp_mygui.cpp index 14dc54a41..42a9c8c30 100644 --- a/old_d_version/gui/cpp_mygui.cpp +++ b/old_d_version/gui/cpp_mygui.cpp @@ -1,396 +1,3 @@ -/* - OpenMW - The completely unofficial reimplementation of Morrowind - Copyright (C) 2008 Nicolay Korslund - Email: < korslund@gmail.com > - WWW: http://openmw.snaptoad.com/ - - This file (cpp_mygui.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/ . - - */ - -// TODO: KILLME -std::string cellName; - -extern "C" void gui_setCellName(char *str) -{ - cellName = str; -} - -// Get the widget type, as a string -extern "C" const char *gui_widgetType(MyGUI::WidgetPtr p) -{ return p->getTypeName().c_str(); } - -extern "C" int32_t gui_getHeight(MyGUI::WidgetPtr p) -{ - if(p == NULL) mWindow->getHeight(); - return p->getHeight(); -} - -extern "C" int32_t gui_getWidth(MyGUI::WidgetPtr p) -{ - if(p == NULL) return mWindow->getWidth(); - return p->getWidth(); -} - -// Set various properties of a given widget -extern "C" void gui_setCaption(MyGUI::WidgetPtr p, char* s) -{ - p->setCaption(s); -} - -extern "C" void gui_setNeedMouseFocus(MyGUI::WidgetPtr p, int32_t b) -{ p->setNeedMouseFocus(b); } - -extern "C" void gui_setTextColor(MyGUI::WidgetPtr p, float r,float g,float b) -{ - MyGUI::StaticText *st = dynamic_cast(p); - if(st != NULL) - st->setTextColour(Ogre::ColourValue(b,g,r)); -} - -extern "C" void gui_setCoord(MyGUI::WidgetPtr p, - int32_t x,int32_t y,int32_t w,int32_t h) -{ p->setCoord(x,y,w,h); } - -// Various ways to get or create widgets -extern "C" MyGUI::WidgetPtr gui_loadLayout(char *file, char *prefix, - MyGUI::WidgetPtr parent) -{ - // Get the list of Widgets in this layout - MyGUI::VectorWidgetPtr wlist; - wlist = MyGUI::LayoutManager::getInstance(). - loadLayout(file, prefix, parent); - - MyGUI::VectorWidgetPtr::iterator iter; - iter = wlist.begin(); - - // Return null if the list is empty - if(wlist.end() == iter) - return NULL; - - MyGUI::WidgetPtr res = *iter; - - ++iter; - - if(iter != wlist.end()) - std::cout << "WARNING: Layout '" << file - << "' has more than one root widget. Ignored.\n"; - - return res; -} - -extern "C" MyGUI::WidgetPtr gui_getChild(MyGUI::WidgetPtr p, char* name) -{ - return p->findWidget(name); -} - -extern "C" MyGUI::WidgetPtr gui_createText(const char *skin, - int32_t x, int32_t y, - int32_t w, int32_t h, - const char *layer) -{ - return mGUI->createWidget - (skin, - x,y,w,h, - MyGUI::ALIGN_LEFT | MyGUI::ALIGN_TOP, - layer); -} - -// Copied from MyGUI demo code, with a few modifications -class Layout -{ -public: - Layout(const std::string & _layout, MyGUI::WidgetPtr _parent = nullptr) - : mMainWidget(nullptr) - { - initialise(_layout, _parent); - } - - template - void getWidget(T * & _widget, const std::string & _name, bool _throw = true) - { - _widget = nullptr; - for (MyGUI::VectorWidgetPtr::iterator iter=mListWindowRoot.begin(); - iter!=mListWindowRoot.end(); ++iter) - { - MyGUI::WidgetPtr find = (*iter)->findWidget(mPrefix + _name); - if (nullptr != find) - { - T * cast = find->castType(false); - if (nullptr != cast) - _widget = cast; - else if (_throw) - { - MYGUI_EXCEPT("Error cast : dest type = '" << T::getClassTypeName() - << "' source name = '" << find->getName() - << "' source type = '" << find->getTypeName() << "' in layout '" << mLayoutName << "'"); - } - return; - } - } - MYGUI_ASSERT( ! _throw, "widget name '" << _name << "' in layout '" << mLayoutName << "' not found."); - } - - void initialise(const std::string & _layout, - MyGUI::WidgetPtr _parent = nullptr) - { - const std::string MAIN_WINDOW = "_Main"; - mLayoutName = _layout; - - if (mLayoutName.empty()) - mMainWidget = _parent; - else - { - mPrefix = MyGUI::utility::toString(this, "_"); - mListWindowRoot = MyGUI::LayoutManager::getInstance().loadLayout(mLayoutName, mPrefix, _parent); - - const std::string main_name = mPrefix + MAIN_WINDOW; - for (MyGUI::VectorWidgetPtr::iterator iter=mListWindowRoot.begin(); iter!=mListWindowRoot.end(); ++iter) - { - if ((*iter)->getName() == main_name) - { - mMainWidget = (*iter); - break; - } - } - MYGUI_ASSERT(mMainWidget, "root widget name '" << MAIN_WINDOW << "' in layout '" << mLayoutName << "' not found."); - } - } - - void shutdown() - { - for (VectorBasePtr::iterator iter=mListBase.begin(); iter!=mListBase.end(); ++iter) { - delete (*iter); - } - mListBase.clear(); - - MyGUI::LayoutManager::getInstance().unloadLayout(mListWindowRoot); - mListWindowRoot.clear(); - } - - void setCoord(int x, int y, int w, int h) - { - mMainWidget->setCoord(x,y,w,h); - } - - void setVisible(bool b) - { - mMainWidget->setVisible(b); - } - - virtual ~Layout() - { - shutdown(); - } - - void setText(const char* name, const char* caption) - { - MyGUI::WidgetPtr pt; - getWidget(pt, name); - pt->setCaption(caption); - } - - void setColor(const char* name, float r, float g, float b) - { - MyGUI::WidgetPtr pt; - getWidget(pt, name); - gui_setTextColor(pt,r,g,b); - } - - void setImage(const char* name, const char* imgName) - { - MyGUI::StaticImagePtr pt; - getWidget(pt, name); - pt->setImageTexture(imgName); - } - -protected: - - MyGUI::WidgetPtr mMainWidget; - - std::string mPrefix; - std::string mLayoutName; - MyGUI::VectorWidgetPtr mListWindowRoot; - typedef std::vector VectorBasePtr; - VectorBasePtr mListBase; -}; - -class HUD : public Layout -{ -public: - HUD() - : Layout("openmw_hud_layout.xml") - { - setCoord(0,0, - mWindow->getWidth(), - mWindow->getHeight()); - - // Energy bars - getWidget(health, "Health"); - getWidget(magicka, "Magicka"); - getWidget(stamina, "Stamina"); - - // Item and spell images and status bars - getWidget(weapImage, "WeapImage"); - getWidget(weapStatus, "WeapStatus"); - getWidget(spellImage, "SpellImage"); - getWidget(spellStatus, "SpellStatus"); - - getWidget(effectBox, "EffectBox"); - getWidget(effect1, "Effect1"); - - getWidget(minimap, "MiniMap"); - getWidget(compass, "Compass"); - - getWidget(crosshair, "Crosshair"); - - compass->setImageTexture("compass.dds"); - crosshair->setImageTexture("target.dds"); - } - - void setStats(int h, int hmax, int m, int mmax, int s, int smax) - { - health->setProgressRange(hmax); - health->setProgressPosition(h); - magicka->setProgressRange(mmax); - magicka->setProgressPosition(m); - stamina->setProgressRange(smax); - stamina->setProgressPosition(s); - } - - void setWeapIcon(const char *str) - { weapImage->setImageTexture(str); } - void setSpellIcon(const char *str) - { spellImage->setImageTexture(str); } - - void setWeapStatus(int s, int smax) - { - weapStatus->setProgressRange(smax); - weapStatus->setProgressPosition(s); - } - void setSpellStatus(int s, int smax) - { - spellStatus->setProgressRange(smax); - spellStatus->setProgressPosition(s); - } - - void setEffect(const char *img) - { effect1->setImageTexture(img); } - - MyGUI::ProgressPtr health, magicka, stamina; - - MyGUI::StaticImagePtr weapImage, spellImage; - MyGUI::ProgressPtr weapStatus, spellStatus; - - MyGUI::WidgetPtr effectBox; - MyGUI::StaticImagePtr effect1; - - MyGUI::StaticImagePtr minimap; - MyGUI::StaticImagePtr compass; - - MyGUI::StaticImagePtr crosshair; -}; - -class MapWindow : public Layout -{ -public: - MapWindow() - : Layout("openmw_map_window_layout.xml") - { - setCoord(500,0,320,300); - mMainWidget->setCaption(cellName); - setText("WorldButton", "World"); - setImage("Compass", "compass.dds"); - } -}; - -class MainMenu : public Layout -{ -public: - MainMenu() - : Layout("openmw_mainmenu_layout.xml") - { - setCoord(0,0, - mWindow->getWidth(), - mWindow->getHeight()); - } -}; - -class StatsWindow : public Layout -{ -public: - void setBar(const char* name, const char* tname, int val, int max) - { - MyGUI::ProgressPtr pt; - getWidget(pt, name); - pt->setProgressRange(max); - pt->setProgressPosition(val); - - std::stringstream out; - out << val << "/" << max; - setText(tname, out.str().c_str()); - } - - StatsWindow() - : Layout("openmw_stats_window_layout.xml") - { - setCoord(0,0,498, 342); - mMainWidget->setCaption("Playername"); - - setText("Health_str", "Health"); - setText("Magicka_str", "Magicka"); - setText("Fatigue_str", "Fatigue"); - - setText("Level_str", "Level"); - setText("Race_str", "Race"); - setText("Class_str", "Class"); - - setText("LevelText", "5"); - setText("RaceText", "Wood Elf"); - setText("ClassText", "Pilgrim"); - - setBar("HBar", "HBarT", 60, 100); - setBar("MBar", "MBarT", 30, 100); - setBar("FBar", "FBarT", 80, 100); - - setText("Attrib1", "Strength"); - setText("Attrib2", "Intelligence"); - setText("Attrib3", "Willpower"); - setText("Attrib4", "Agility"); - setText("Attrib5", "Speed"); - setText("Attrib6", "Endurance"); - setText("Attrib7", "Personality"); - setText("Attrib8", "Luck"); - - setText("AttribVal1", "30"); - setText("AttribVal2", "40"); - setText("AttribVal3", "30"); - setText("AttribVal4", "75"); - setText("AttribVal5", "50"); - setText("AttribVal6", "40"); - setText("AttribVal7", "50"); - setText("AttribVal8", "40"); - } -}; - -HUD *hud; -StatsWindow *stats; -MapWindow *map; -MyGUI::WidgetPtr FPSText; -OIS::MouseState state; bool consoleMode = false; bool inventoryMode = false; @@ -429,8 +36,6 @@ void leaveGui() } } -#include "cpp_console.cpp" - extern "C" void gui_toggleGui() { if(inventoryMode) @@ -453,49 +58,8 @@ extern "C" void gui_toggleGui() inventoryMode = !inventoryMode; } -extern "C" int32_t* gui_getGuiModePtr() { return &guiMode; } - -extern "C" void gui_showHUD() -{ - if(hud) - hud->setVisible(true); -} - extern "C" void gui_setupGUI(int32_t debugOut) { - int mWidth = mWindow->getWidth(); - int mHeight = mWindow->getHeight(); - - stats = new StatsWindow(); - map = new MapWindow(); - cons = new Console(); - - // Hide all the windows at startup - stats->setVisible(false); - map->setVisible(false); - cons->setVisible(false); guiMode = 1; leaveGui(); - - // Start the mouse in the middle of the screen - state.X.abs = mWidth / 2; - state.Y.abs = mHeight / 2; - - // Set up the HUD - hud = new HUD(); - - hud->setStats(60, 100, - 30, 100, - 80, 100); - - hud->setWeapIcon("icons\\w\\tx_knife_iron.dds"); - hud->setWeapStatus(90, 100); - hud->setSpellIcon("icons\\s\\b_tx_s_rstor_health.dds"); - hud->setSpellStatus(65, 100); - - hud->setEffect("icons\\s\\tx_s_chameleon.dds"); - - hud->setVisible(false); - - //new MainMenu(); } diff --git a/old_d_version/gui/gui.d b/old_d_version/gui/gui.d deleted file mode 100644 index dbb8a1ac2..000000000 --- a/old_d_version/gui/gui.d +++ /dev/null @@ -1,321 +0,0 @@ -/* - OpenMW - The completely unofficial reimplementation of Morrowind - Copyright (C) 2008-2009 Nicolay Korslund - Email: < korslund@gmail.com > - WWW: http://openmw.snaptoad.com/ - - This file (gui.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.gui; - -import monster.monster; -import monster.vm.mclass; -import monster.modules.console; -import gui.bindings; -import bullet.bindings; -import std.string; -import std.stdio; - -// Widget class and gui module -MonsterClass - gmc, // GUI module - wid_mc, // Widget - but_mc, // Button - tex_mc, // StaticText - img_mc, // StaticImage - pro_mc, // Progress - win_mc; // Window - -MWidget[WidgetPtr] gui_store; - -class MWidget -{ - WidgetPtr widget; - MonsterObject *mo; - - // Used for layouts - bool isLayout; - char[] prefix; - - // For layouts - this(char[] layout, WidgetPtr parent = null) - { - assert(layout.length); - - isLayout = true; - prefix = format("%s", cast(void*)this); - - widget = gui_loadLayout(layout.toStringz(), prefix.toStringz(), parent); - if(widget is null) - fail("Layout " ~ layout ~ " is empty"); - - this(); - } - - // For normal widgets - this(WidgetPtr w) - { - isLayout = false; - widget = w; - assert(widget !is null); - this(); - } - - private this() - { - assert(widget !is null); - - // Create the object from the right class - mo = toClass(widget).createObject(); - // But store the pointer in the Widget's pointer slot - mo.getExtra(wid_mc).obj = this; - // Also store a lookup for later - gui_store[widget] = this; - } - - MWidget getChild(char[] name) - { - if(prefix.length) - name = prefix ~ name; - - // Get the child widget - auto pt = gui_getChild(widget, name.toStringz()); - - if(pt is null) - fail("Widget has no child named " ~ name); - - // Return the MWidget - return get(pt); - } - - // Return the MonsterClass corresponding to a given widget. - private static MonsterClass toClass(WidgetPtr p) - { - switch(widgetType(p)) - { - /* - case "Button": return but_mc; - case "StaticText": return tex_mc; - case "StaticImage": return img_mc; - case "Progress": return pro_mc; - case "Window": return win_mc; - */ - default: - // Use "Widget" for all unimplemented types - case "Widget": return wid_mc; - } - } - - // Get the MWidget (and associatied MonsterObject) corresponding to - // a given Widget. - static MWidget get(WidgetPtr wid) - { - // First, check if the instance exists - auto p = wid in gui_store; - if(p) return *p; - - // No MWidget exists. We have to create one. - return new MWidget(wid); - } -}; - -char[] widgetType(WidgetPtr p) -{ - return toString(gui_widgetType(p)); -} - -MWidget getMWOwner(MonsterObject *mo) -{ - return (cast(MWidget)mo.getExtra(wid_mc).obj); -} -MWidget getMWOwner() -{ - return getMWOwner(params.obj()); -} -WidgetPtr getOwner(MonsterObject *mo) -{ - return getMWOwner(mo).widget; -} -WidgetPtr getOwner() -{ - return getMWOwner().widget; -} - -// Widget functions -void setCaption() -{ - AIndex[] args = stack.popAArray(); - - char[] res; - - foreach(AIndex ind; args) - res ~= format("%s", arrays.getRef(ind).carr); - - gui_setCaption(getOwner(), toStringz(res)); -} -void setNeedMouseFocus() -{ gui_setNeedMouseFocus(getOwner(), stack.popBool); } -void setTextColor() -{ - float b = stack.popFloat(); - float g = stack.popFloat(); - float r = stack.popFloat(); - gui_setTextColor(getOwner(), r,g,b); -} -void setCoord() -{ - int h = stack.popInt(); - int w = stack.popInt(); - int y = stack.popInt(); - int x = stack.popInt(); - gui_setCoord(getOwner(), x,y,w,h); -} - -void get() -{ - // Get the owner MWidget - auto mw = getMWOwner(); - // Get the child - mw = mw.getChild(stack.popString8()); - // Push the object - stack.pushObject(mw.mo); -} - -// TODO: These are all written to be used with the 'gui' module. Later -// they should be part of Widget, and create child widgets. When used -// with 'gui' they create root widgets. - -void loadLayout() -{ - MWidget mw = new MWidget(stack.popString8()); - stack.pushObject(mw.mo); -} - -void text() -{ - char[] layer = stack.popString8(); - int h = stack.popInt(); - int w = stack.popInt(); - int y = stack.popInt(); - int x = stack.popInt(); - char[] skin = stack.popString8(); - WidgetPtr ptr = gui_createText(skin.toStringz(), - x,y,w,h, - layer.toStringz()); - assert(widgetType(ptr) == "StaticText"); - MWidget mw = new MWidget(ptr); - stack.pushObject(mw.mo); -} - -void getWidth() -{ - stack.pushInt(gui_getWidth(null)); -} - -void getHeight() -{ - stack.pushInt(gui_getHeight(null)); -} - -void initGUI(bool debugOut) -{ - // Load the GUI system - gui_setupGUI(debugOut); -} - -void startGUI() -{ - gui_showHUD(); - - // Run GUI scripts - // Create the HUD and windows - vm.run("makegui.mn"); - - // Run the fps ticker - vm.run("fpsticker.mn"); -} - -void setupGUIScripts() -{ - vm.addPath("mscripts/guiscripts/"); - vm.addPath("mscripts/guiscripts/module/"); - gmc = vm.load("gui", "gui.mn"); - wid_mc = vm.load("Widget", "widget.mn"); - /* - but_mc = new MonsterClass("Button", "button.mn"); - tex_mc = new MonsterClass("Text", "text.mn"); - img_mc = new MonsterClass("Image", "image.mn"); - pro_mc = new MonsterClass("Progress", "progress.mn"); - win_mc = new MonsterClass("Window", "window.mn"); - */ - - wid_mc.bind("setCaption", &setCaption); - wid_mc.bind("setNeedMouseFocus", &setNeedMouseFocus); - wid_mc.bind("setTextColor", &setTextColor); - wid_mc.bind("setCoord", &setCoord); - wid_mc.bind("get", &get); - - gmc.bind("text", &text); - gmc.bind("loadLayout", &loadLayout); - gmc.bind("getWidth", &getWidth); - gmc.bind("getHeight", &getHeight); - - // Set up the console - auto cmc = vm.load("Console"); - auto cmo = cmc.createObject; - cons = new Console(cmo); - - // Bind native functions - cmc.bind("walk", { bullet_walk(); cons.putln("Walk mode enabled");}); - cmc.bind("fly", { bullet_fly(); cons.putln("Fly mode enabled");}); - cmc.bind("ghost", { bullet_ghost(); cons.putln("Ghost mode enabled");}); - cmc.bind("setfont", - { - char[] fnt = stack.popString8(); - gui_setConsoleFont(toStringz(fnt)); - cons.putln("Setting font " ~ fnt); - }); - cmc.bind("clear", { gui_clearConsole(); }); - cmc.bind("exit", { exitProgram(); }); - cmc.bind("wireframe", { cons.putln("Wireframe mode not implemented yet"); }); -} - -Console cons; - -// Checked from input/events.d. Shouldn't really be here, but it's a -// workaround for a DMD import issue. -bool doExit = false; -void exitProgram() -{ - doExit = true; -} - -// Some glue code that will go away later when we use the C++ -// interface to Monster directly. -extern(C): -int console_input(char* str) -{ - char[] dstr = toString(str); - return cons.input(dstr); -} - -char* console_output() -{ - char[] dstr = cons.output(); - return toStringz(dstr); -}