From a45fc827430f8a707a0e6d97f92cd99a9bb2dccf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Mon, 5 Mar 2012 01:34:04 +0100 Subject: [PATCH] First pass at windowing, track df2mc, stonesense --- library/CMakeLists.txt | 1 + library/Core.cpp | 31 +--- library/include/Core.h | 9 +- library/include/TileTypes.h | 4 - library/include/modules/Windows.h | 275 ++++++++++++++++++++++++++++++ library/modules/Windows.cpp | 114 +++++++++++++ plugins/df2mc | 2 +- plugins/stonesense | 2 +- 8 files changed, 407 insertions(+), 31 deletions(-) create mode 100644 library/include/modules/Windows.h create mode 100644 library/modules/Windows.cpp diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 3f672eba9..94704beba 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -101,6 +101,7 @@ modules/Vegetation.cpp modules/Vermin.cpp modules/World.cpp modules/Graphic.cpp +modules/Windows.cpp ) SET(PROJECT_HDRS_WINDOWS diff --git a/library/Core.cpp b/library/Core.cpp index 4f75eed90..3dbd6fc36 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -47,7 +47,7 @@ using namespace std; #include "modules/Gui.h" #include "modules/World.h" #include "modules/Graphic.h" -//#include "modules/Windows.h" +#include "modules/Windows.h" using namespace DFHack; #include "SDL_events.h" @@ -572,6 +572,7 @@ Core::Core() misc_data_mutex=0; last_world_data_ptr = NULL; top_viewscreen = NULL; + screen_window = NULL; }; void Core::fatal (std::string output, bool deactivate) @@ -677,6 +678,8 @@ bool Core::Init() HotkeyMutex = new mutex(); HotkeyCond = new condition_variable(); thread * HK = new thread(fHKthread, (void *) temp); + screen_window = new Windows::top_level_window(); + screen_window->addChild(new Windows::dfhack_dummy(0,0)); started = true; cerr << "DFHack is running.\n"; return true; @@ -755,29 +758,11 @@ void Core::Resume() AccessMutex->unlock(); } -struct screen_tile -{ - unsigned char symbol; - unsigned char front; - unsigned char back; - unsigned char bright; -}; - -void screen_paint (int x, int y, uint8_t symbol) -{ - int tile = x * df::global::gps->dimy + y; - screen_tile *s = (screen_tile *) (df::global::gps->screen + tile*4); - s->symbol = symbol; -} - int Core::TileUpdate() { - screen_paint(0,0,'D'); - screen_paint(1,0,'F'); - screen_paint(2,0,'H'); - screen_paint(3,0,'a'); - screen_paint(4,0,'c'); - screen_paint(5,0,'k'); + if(!started) + return false; + screen_window->paint(); return true; } @@ -1005,7 +990,7 @@ static bool parseKeySpec(std::string keyspec, int *psym, int *pmod) *psym = SDL::K_F1 + (keyspec[1]-'1'); return true; } else - return false; + return false; } bool Core::ClearKeyBindings(std::string keyspec) diff --git a/library/include/Core.h b/library/include/Core.h index a2fa27a5f..b9297ca0b 100644 --- a/library/include/Core.h +++ b/library/include/Core.h @@ -59,6 +59,10 @@ namespace DFHack class VersionInfoFactory; class PluginManager; class Core; + namespace Windows + { + class df_window; + } // anon type, pretty much struct DFLibrary; @@ -125,6 +129,7 @@ namespace DFHack DFHack::Process * p; DFHack::VersionInfo * vinfo; DFHack::Console con; + DFHack::Windows::df_window * screen_window; private: Core(); bool Init(); @@ -179,8 +184,8 @@ namespace DFHack // Very important! bool started; - tthread::mutex * misc_data_mutex; - std::map misc_data_map; + tthread::mutex * misc_data_mutex; + std::map misc_data_map; }; class CoreSuspender { diff --git a/library/include/TileTypes.h b/library/include/TileTypes.h index 318aa2b8e..835be2398 100644 --- a/library/include/TileTypes.h +++ b/library/include/TileTypes.h @@ -24,9 +24,6 @@ distribution. #pragma once -#ifndef TILETYPES_H_INCLUDED -#define TILETYPES_H_INCLUDED - #include "Pragma.h" #include "Export.h" #include "DataDefs.h" @@ -276,4 +273,3 @@ namespace DFHack DFHACK_EXPORT df::tiletype findRandomVariant(const df::tiletype tile); } -#endif // TILETYPES_H_INCLUDED diff --git a/library/include/modules/Windows.h b/library/include/modules/Windows.h new file mode 100644 index 000000000..e8309562a --- /dev/null +++ b/library/include/modules/Windows.h @@ -0,0 +1,275 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#pragma once +#include + +namespace DFHack +{ +namespace Windows +{ + /* + * DF window stuffs + */ + enum df_color + { + black, + blue, + green, + cyan, + red, + magenta, + brown, + lgray, + dgray, + lblue, + lgreen, + lcyan, + lred, + lmagenta, + yellow, + white + // maybe add transparency? + }; + + // The tile format DF uses internally + struct df_screentile + { + uint8_t symbol; + uint8_t foreground; ///< df_color + uint8_t background; ///< df_color + uint8_t bright; + }; + + + // our silly painter things and window things follow. + class df_window; + struct df_tilebuf + { + df_tilebuf(unsigned int width, unsigned int height):width(width),height(height) + { + data = new df_screentile[width*height]; + } + ~df_tilebuf() + { + delete data; + } + df_screentile * data; + unsigned int width; + unsigned int height; + }; + + DFHACK_EXPORT df_screentile *getScreenBuffer(); + + class DFHACK_EXPORT painter + { + friend class df_window; + public: + df_screentile* get(unsigned int x, unsigned int y) + { + if(x >= width || y >= height) + return 0; + return &buffer[x*height + y]; + }; + bool set(unsigned int x, unsigned int y, df_screentile tile ) + { + if(x >= width || y >= height) + return false; + buffer[x*height + y] = tile; + return true; + } + df_color foreground (df_color change = (df_color) -1) + { + if(change != -1) + current_foreground = change; + return current_foreground; + } + df_color background (df_color change = (df_color) -1) + { + if(change != -1) + current_background = change; + return current_background; + } + void bright (bool change) + { + current_bright = change; + } + bool bright () + { + return current_bright; + } + void printStr(std::string & str, bool wrap = false) + { + for ( auto iter = str.begin(); iter != str.end(); iter++) + { + auto elem = *iter; + if(cursor_y >= height) + break; + if(wrap) + { + if(cursor_x >= width) + cursor_x = wrap_column; + } + df_screentile & tile = buffer[cursor_x * height + cursor_y]; + tile.symbol = elem; + tile.foreground = current_foreground; + tile.background = current_background; + tile.bright = current_bright; + cursor_x++; + } + } + void set_wrap (int new_column) + { + wrap_column = new_column; + } + void gotoxy(unsigned int x, unsigned int y) + { + cursor_x = x; + cursor_y = y; + } + void reset() + { + cursor_x = 0; + cursor_y = 0; + current_background = black; + current_foreground = white; + current_bright = false; + wrap_column = 0; + } + private: + painter (df_window * orig, df_screentile * buf, unsigned int width, unsigned int height) + { + origin = orig; + this->width = width; + this->height = height; + this->buffer = buf; + reset(); + } + df_window* origin; + unsigned int width; + unsigned int height; + df_screentile* buffer; + // current paint cursor position + int cursor_x; + int cursor_y; + int wrap_column; + // current foreground color + df_color current_foreground; + // current background color + df_color current_background; + // make bright? + bool current_bright; + }; + + class DFHACK_EXPORT df_window + { + friend class painter; + public: + df_window(int x, int y, unsigned int width, unsigned int height); + virtual ~df_window(); + virtual bool move (int left_, int top_, unsigned int width_, unsigned int height_) = 0; + virtual void paint () = 0; + virtual painter * lock(); + bool unlock (painter * painter); + virtual bool addChild(df_window *); + virtual df_screentile * getBuffer() = 0; + public: + df_screentile* buffer; + unsigned int width; + unsigned int height; + protected: + df_window * parent; + std::vector children; + int left; + int top; + // FIXME: FAKE + bool locked; + painter * current_painter; + }; + + class DFHACK_EXPORT top_level_window : public df_window + { + public: + top_level_window(); + virtual bool move (int left_, int top_, unsigned int width_, unsigned int height_); + virtual void paint (); + virtual painter * lock(); + virtual df_screentile * getBuffer(); + }; + class DFHACK_EXPORT buffered_window : public df_window + { + public: + buffered_window(int x, int y, unsigned int width, unsigned int height):df_window(x,y,width, height) + { + buffer = new df_screentile[width*height]; + }; + virtual ~buffered_window() + { + delete buffer; + } + virtual void blit_to_parent () + { + df_screentile * parbuf = parent->getBuffer(); + int parent_width = parent->width; + int parent_height = parent->height; + for(int xi = 0; xi < width; xi++) + { + for(int yi = 0; yi < height; yi++) + { + int parx = left + xi; + int pary = top + yi; + if(pary >= parent_height) continue; + if(parx >= parent_width) continue; + parbuf[parx * parent_height + pary] = buffer[xi * height + yi]; + } + } + } + virtual df_screentile* getBuffer() + { + return buffer; + }; + }; + class DFHACK_EXPORT dfhack_dummy : public buffered_window + { + public: + dfhack_dummy(int x, int y):buffered_window(x,y,6,1){}; + virtual bool move (int left_, int top_, unsigned int width_, unsigned int height_) + { + top = top_; + left = left_; + return true; + } + virtual void paint () + { + painter * p = lock(); + p->bright(true); + p->background(black); + p->foreground(white); + std::string dfhack = "DFHack"; + p->printStr(dfhack); + blit_to_parent(); + } + }; +} +} \ No newline at end of file diff --git a/library/modules/Windows.cpp b/library/modules/Windows.cpp new file mode 100644 index 000000000..18149e61e --- /dev/null +++ b/library/modules/Windows.cpp @@ -0,0 +1,114 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#include "Export.h" +#include "Module.h" +#include "Virtual.h" +#include "BitArray.h" +#include + +#include "DataDefs.h" +#include "df/init.h" +#include "df/ui.h" +#include +#include +#include "modules/Windows.h" + +using namespace DFHack; + +Windows::df_screentile *Windows::getScreenBuffer() +{ + return (df_screentile *) df::global::gps->screen; +} + +Windows::df_window::df_window(int x, int y, unsigned int width, unsigned int height) +:buffer(0), parent(0), left(x), top(y), width(width), height(height), current_painter(NULL) +{ + buffer = 0; +}; +Windows::df_window::~df_window() +{ + for(auto iter = children.begin();iter != children.end();iter++) + { + delete *iter; + } + children.clear(); +}; +Windows::painter * Windows::df_window::lock() +{ + locked = true; + current_painter = new Windows::painter(this,buffer,width, height); + return current_painter; +}; + +bool Windows::df_window::addChild( df_window * child) +{ + children.push_back(child); + child->parent = this; + return true; +} + +bool Windows::df_window::unlock (painter * painter) +{ + if(current_painter == painter) + { + delete current_painter; + current_painter = 0; + locked = false; + return true; + } + return false; +} + +Windows::top_level_window::top_level_window(): df_window(0,0,df::global::gps->dimx,df::global::gps->dimy) +{ + buffer = 0; +} + +bool Windows::top_level_window::move (int left_, int top_, unsigned int width_, unsigned int height_) +{ + width = width_; + height = height_; + // what if we are painting already? Is that possible? + return true; +}; + +Windows::painter * Windows::top_level_window::lock() +{ + buffer = getScreenBuffer(); + return df_window::lock(); +} + +void Windows::top_level_window::paint () +{ + for(auto iter = children.begin();iter != children.end();iter++) + { + (*iter)->paint(); + } +}; + +Windows::df_screentile * Windows::top_level_window::getBuffer() +{ + return getScreenBuffer(); +} \ No newline at end of file diff --git a/plugins/df2mc b/plugins/df2mc index f149da6ef..617a845f5 160000 --- a/plugins/df2mc +++ b/plugins/df2mc @@ -1 +1 @@ -Subproject commit f149da6efead3c46845d7478d1ff3d11119c589d +Subproject commit 617a845f5d5c0d32fdbc59817b59de4c53a528e3 diff --git a/plugins/stonesense b/plugins/stonesense index 34183f96b..50bbecc54 160000 --- a/plugins/stonesense +++ b/plugins/stonesense @@ -1 +1 @@ -Subproject commit 34183f96b86394895975fb59ae3c4673cd78f502 +Subproject commit 50bbecc544aa227fb7bfc4a5c90c6b27369d8bcd