diff options
| author | Alexander Gavrilov | 2012-08-19 09:31:09 +0400 |
|---|---|---|
| committer | Alexander Gavrilov | 2012-08-19 09:31:09 +0400 |
| commit | b8ee52131bccd174f06c9124980bbcb8df7c80e4 (patch) | |
| tree | a6a665c6d454f9a9d2610bba9f05b8571dc513d9 /library/modules | |
| parent | fd0bf2ef929d3bc98570012b21e6e603c570a8f6 (diff) | |
| download | dfhack-b8ee52131bccd174f06c9124980bbcb8df7c80e4.tar.gz dfhack-b8ee52131bccd174f06c9124980bbcb8df7c80e4.tar.bz2 dfhack-b8ee52131bccd174f06c9124980bbcb8df7c80e4.tar.xz | |
Add a module for painting tiles into the gps global.
Diffstat (limited to 'library/modules')
| -rw-r--r-- | library/modules/Gui.cpp | 6 | ||||
| -rw-r--r-- | library/modules/Screen.cpp | 215 |
2 files changed, 221 insertions, 0 deletions
diff --git a/library/modules/Gui.cpp b/library/modules/Gui.cpp index cd44401f..9d3ee96e 100644 --- a/library/modules/Gui.cpp +++ b/library/modules/Gui.cpp @@ -42,6 +42,7 @@ using namespace std; using namespace DFHack; #include "modules/Job.h" +#include "modules/Screen.h" #include "DataDefs.h" #include "df/world.h" @@ -466,6 +467,11 @@ std::string Gui::getFocusString(df::viewscreen *top) return name; } + else if (dfhack_viewscreen::is_instance(top)) + { + auto name = static_cast<dfhack_viewscreen*>(top)->getFocusString(); + return name.empty() ? "dfhack" : "dfhack/"+name; + } else { Core &core = Core::getInstance(); diff --git a/library/modules/Screen.cpp b/library/modules/Screen.cpp new file mode 100644 index 00000000..f6155bd6 --- /dev/null +++ b/library/modules/Screen.cpp @@ -0,0 +1,215 @@ +/* +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 "Internal.h" + +#include <string> +#include <vector> +#include <map> +using namespace std; + +#include "modules/Screen.h" +#include "MemAccess.h" +#include "VersionInfo.h" +#include "Types.h" +#include "Error.h" +#include "ModuleFactory.h" +#include "Core.h" +#include "PluginManager.h" +#include "MiscUtils.h" +using namespace DFHack; + +#include "DataDefs.h" +#include "df/init.h" +#include "df/texture_handler.h" +#include "df/tile_page.h" +#include "df/interfacest.h" + +using namespace df::enums; +using df::global::init; +using df::global::gps; +using df::global::texture; +using df::global::gview; + +using Screen::Pen; + +df::coord2d Screen::getMousePos() +{ + if (!gps) return df::coord2d(); + + return df::coord2d(gps->mouse_x, gps->mouse_y); +} + +df::coord2d Screen::getWindowSize() +{ + if (!gps) return df::coord2d(); + + return df::coord2d(gps->dimx, gps->dimy); +} + +static void doSetTile(const Pen &pen, int index) +{ + auto screen = gps->screen + index*4; + screen[0] = uint8_t(pen.ch); + screen[1] = uint8_t(pen.fg) & 15; + screen[2] = uint8_t(pen.bg) & 15; + screen[3] = uint8_t(pen.bold) & 1; + gps->screentexpos[index] = pen.tile; + gps->screentexpos_addcolor[index] = (pen.tile_mode == Screen::Pen::CharColor); + gps->screentexpos_grayscale[index] = (pen.tile_mode == Screen::Pen::TileColor); + gps->screentexpos_cf[index] = pen.tile_fg; + gps->screentexpos_cbr[index] = pen.tile_bg; +} + +bool Screen::paintTile(const Pen &pen, int x, int y) +{ + if (!gps) return false; + + int dimx = gps->dimx, dimy = gps->dimy; + if (x < 0 || x >= dimx || y < 0 || y >= dimy) return false; + + doSetTile(pen, x*dimy + y); + return true; +} + +bool Screen::paintString(const Pen &pen, int x, int y, const std::string &text) +{ + if (!gps || y < 0 || y >= gps->dimy) return false; + + Pen tmp(pen); + bool ok = false; + + for (size_t i = -std::min(0,x); i < text.size(); i++) + { + if (x + i >= size_t(gps->dimx)) + break; + + tmp.ch = text[i]; + tmp.tile = (pen.tile ? pen.tile + uint8_t(text[i]) : 0); + paintTile(tmp, x+i, y); + ok = true; + } + + return ok; +} + +bool Screen::fillRect(const Pen &pen, int x1, int y1, int x2, int y2) +{ + if (!gps) return false; + + if (x1 < 0) x1 = 0; + if (y1 < 0) y1 = 0; + if (x2 >= gps->dimx) x2 = gps->dimx-1; + if (y2 >= gps->dimy) y2 = gps->dimy-1; + if (x1 > x2 || y1 > y2) return false; + + for (int x = x1; x <= x2; x++) + { + int index = x*gps->dimy; + + for (int y = y1; y <= y2; y++) + doSetTile(pen, index+y); + } + + return true; +} + +bool Screen::findGraphicsTile(const std::string &pagename, int x, int y, int *ptile, int *pgs) +{ + if (!gps || !texture || x < 0 || y < 0) return false; + + for (size_t i = 0; i < texture->page.size(); i++) + { + auto page = texture->page[i]; + if (!page->loaded || page->token != pagename) continue; + + if (x >= page->page_dim_x || y >= page->page_dim_y) + break; + int idx = y*page->page_dim_x + x; + if (size_t(idx) >= page->texpos.size()) + break; + + if (ptile) *ptile = page->texpos[idx]; + if (pgs) *pgs = page->texpos_gs[idx]; + return true; + } + + return false; +} + +bool Screen::show(df::viewscreen *screen, df::viewscreen *before) +{ + CHECK_NULL_POINTER(screen); + CHECK_INVALID_ARGUMENT(!screen->parent && !screen->child); + + if (!gps || !gview) return false; + + df::viewscreen *parent = &gview->view; + while (parent && parent->child != before) + parent = parent->child; + + if (!parent) return false; + + gps->force_full_display_count += 2; + + screen->child = parent->child; + screen->parent = parent; + parent->child = screen; + if (screen->child) + screen->child->parent = screen; + + return true; +} + +void Screen::dismiss(df::viewscreen *screen) +{ + CHECK_NULL_POINTER(screen); + + screen->breakdown_level = interface_breakdown_types::STOPSCREEN; +} + +bool Screen::isDismissed(df::viewscreen *screen) +{ + CHECK_NULL_POINTER(screen); + + return screen->breakdown_level != interface_breakdown_types::NONE; +} + +static std::set<df::viewscreen*> dfhack_screens; + +dfhack_viewscreen::dfhack_viewscreen() +{ + dfhack_screens.insert(this); +} + +dfhack_viewscreen::~dfhack_viewscreen() +{ + dfhack_screens.erase(this); +} + +bool dfhack_viewscreen::is_instance(df::viewscreen *screen) +{ + return dfhack_screens.count(screen) != 0; +} |
