summaryrefslogtreecommitdiff
path: root/library
diff options
context:
space:
mode:
authorAlexander Gavrilov2012-08-19 09:31:09 +0400
committerAlexander Gavrilov2012-08-19 09:31:09 +0400
commitb8ee52131bccd174f06c9124980bbcb8df7c80e4 (patch)
treea6a665c6d454f9a9d2610bba9f05b8571dc513d9 /library
parentfd0bf2ef929d3bc98570012b21e6e603c570a8f6 (diff)
downloaddfhack-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')
-rw-r--r--library/CMakeLists.txt2
-rw-r--r--library/include/modules/Screen.h116
-rw-r--r--library/modules/Gui.cpp6
-rw-r--r--library/modules/Screen.cpp215
4 files changed, 339 insertions, 0 deletions
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index cd3d52c8..109a97e7 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -119,6 +119,7 @@ include/modules/Maps.h
include/modules/MapCache.h
include/modules/Materials.h
include/modules/Notes.h
+include/modules/Screen.h
include/modules/Translation.h
include/modules/Vegetation.h
include/modules/Vermin.h
@@ -139,6 +140,7 @@ modules/kitchen.cpp
modules/Maps.cpp
modules/Materials.cpp
modules/Notes.cpp
+modules/Screen.cpp
modules/Translation.cpp
modules/Vegetation.cpp
modules/Vermin.cpp
diff --git a/library/include/modules/Screen.h b/library/include/modules/Screen.h
new file mode 100644
index 00000000..7c5c8ba5
--- /dev/null
+++ b/library/include/modules/Screen.h
@@ -0,0 +1,116 @@
+/*
+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 "Export.h"
+#include "Module.h"
+#include "BitArray.h"
+#include "ColorText.h"
+#include <string>
+
+#include "DataDefs.h"
+#include "df/graphic.h"
+#include "df/viewscreen.h"
+
+/**
+ * \defgroup grp_screen utilities for painting to the screen
+ * @ingroup grp_screen
+ */
+
+namespace DFHack
+{
+ class Core;
+
+ /**
+ * The Screen module
+ * \ingroup grp_modules
+ * \ingroup grp_screen
+ */
+ namespace Screen
+ {
+ /// Data structure describing all properties a screen tile can have
+ struct Pen {
+ // Ordinary text symbol
+ char ch;
+ int8_t fg, bg;
+ bool bold;
+
+ // Graphics tile
+ int tile;
+ enum TileMode {
+ AsIs, // Tile colors used without modification
+ CharColor, // The fg/bg pair is used
+ TileColor // The fields below are used
+ } tile_mode;
+ int8_t tile_fg, tile_bg;
+
+ Pen(char ch = 0, int8_t fg = 7, int8_t bg = 0, int tile = 0, bool color_tile = false)
+ : ch(ch), fg(fg&7), bg(bg), bold(!!(fg&8)),
+ tile(tile), tile_mode(color_tile ? CharColor : AsIs), tile_fg(0), tile_bg(0)
+ {}
+ Pen(char ch, int8_t fg, int8_t bg, bool bold, int tile = 0, bool color_tile = false)
+ : ch(ch), fg(fg), bg(bg), bold(bold),
+ tile(tile), tile_mode(color_tile ? CharColor : AsIs), tile_fg(0), tile_bg(0)
+ {}
+ Pen(char ch, int8_t fg, int8_t bg, int tile, int8_t tile_fg, int8_t tile_bg)
+ : ch(ch), fg(fg&7), bg(bg), bold(!!(fg&8)),
+ tile(tile), tile_mode(TileColor), tile_fg(tile_fg), tile_bg(tile_bg)
+ {}
+ Pen(char ch, int8_t fg, int8_t bg, bool bold, int tile, int8_t tile_fg, int8_t tile_bg)
+ : ch(ch), fg(fg), bg(bg), bold(bold),
+ tile(tile), tile_mode(TileColor), tile_fg(tile_fg), tile_bg(tile_bg)
+ {}
+ };
+
+ DFHACK_EXPORT df::coord2d getMousePos();
+ DFHACK_EXPORT df::coord2d getWindowSize();
+
+ /// Paint one screen tile with the given pen
+ DFHACK_EXPORT bool paintTile(const Pen &pen, int x, int y);
+
+ /// Paint a string onto the screen. Ignores ch and tile of pen.
+ DFHACK_EXPORT bool paintString(const Pen &pen, int x, int y, const std::string &text);
+
+ /// Fills a rectangle with one pen. Possibly more efficient than a loop over paintTile.
+ DFHACK_EXPORT bool fillRect(const Pen &pen, int x1, int y1, int x2, int y2);
+
+ /// Find a loaded graphics tile from graphics raws.
+ DFHACK_EXPORT bool findGraphicsTile(const std::string &page, int x, int y, int *ptile, int *pgs = NULL);
+
+ // Push and remove viewscreens
+ DFHACK_EXPORT bool show(df::viewscreen *screen, df::viewscreen *before = NULL);
+ DFHACK_EXPORT void dismiss(df::viewscreen *screen);
+ DFHACK_EXPORT bool isDismissed(df::viewscreen *screen);
+ }
+
+ class DFHACK_EXPORT dfhack_viewscreen : public df::viewscreen {
+ public:
+ dfhack_viewscreen();
+ virtual ~dfhack_viewscreen();
+
+ static bool is_instance(df::viewscreen *screen);
+
+ virtual std::string getFocusString() = 0;
+ };
+}
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;
+}