mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-24 05:01:43 +00:00
parent
5d88c39549
commit
4fae197c67
@ -20,6 +20,7 @@
|
||||
|
||||
#include "common/stdafx.h"
|
||||
#include "graphics/font.h"
|
||||
#include "gui/newgui.h"
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
@ -36,8 +37,11 @@ int NewFont::getCharWidth(byte chr) const {
|
||||
return desc.width[chr - desc.firstchar];
|
||||
}
|
||||
|
||||
void NewFont::drawChar(const Surface *dst, byte chr, int tx, int ty, uint32 color) const {
|
||||
void NewFont::drawChar(const Surface *dst, byte chr, int tx, int ty, uint32 color, bool scale) const {
|
||||
assert(dst != 0);
|
||||
const int scaleFactor = scale ? g_gui.getScaleFactor() : 1;
|
||||
tx *= scaleFactor; ty *= scaleFactor;
|
||||
|
||||
byte *ptr = (byte *)dst->getBasePtr(tx, ty);
|
||||
|
||||
assert(desc.bits != 0 && desc.maxwidth <= 16);
|
||||
@ -54,16 +58,30 @@ void NewFont::drawChar(const Surface *dst, byte chr, int tx, int ty, uint32 colo
|
||||
chr -= desc.firstchar;
|
||||
const bitmap_t *tmp = desc.bits + (desc.offset ? desc.offset[chr] : (chr * desc.height));
|
||||
|
||||
for (int y = 0; y < desc.height; y++, ptr += dst->pitch) {
|
||||
const bitmap_t buffer = *tmp++;
|
||||
for (int y = 0; y < desc.height * scaleFactor; y++, ptr += dst->pitch) {
|
||||
const bitmap_t *buffer = 0;
|
||||
if(scaleFactor != 1) {
|
||||
if(!(y % 2))
|
||||
buffer = tmp++;
|
||||
else
|
||||
buffer = tmp;
|
||||
} else
|
||||
buffer = tmp++;
|
||||
bitmap_t mask = 0x8000;
|
||||
if (ty + y < 0 || ty + y >= dst->h)
|
||||
continue;
|
||||
|
||||
for (int x = 0; x < w; x++, mask >>= 1) {
|
||||
|
||||
for (int x = 0; x < w * scaleFactor; x++) {
|
||||
if(scaleFactor != 1) {
|
||||
if(!(x % 2) && x != 0)
|
||||
mask >>= 1;
|
||||
} else if(x != 0) {
|
||||
mask >>= 1;
|
||||
}
|
||||
|
||||
if (tx + x < 0 || tx + x >= dst->w)
|
||||
continue;
|
||||
if ((buffer & mask) != 0) {
|
||||
if ((*buffer & mask) != 0) {
|
||||
if (dst->bytesPerPixel == 1)
|
||||
ptr[x] = color;
|
||||
else if (dst->bytesPerPixel == 2)
|
||||
@ -85,13 +103,13 @@ int Font::getStringWidth(const Common::String &str) const {
|
||||
return space;
|
||||
}
|
||||
|
||||
void Font::drawString(const Surface *dst, const Common::String &s, int x, int y, int w, uint32 color, TextAlignment align, int deltax, bool useEllipsis) const {
|
||||
void Font::drawString(const Surface *dst, const Common::String &s, int x, int y, int w, uint32 color, TextAlignment align, int deltax, bool useEllipsis, bool scale) const {
|
||||
assert(dst != 0);
|
||||
const int leftX = x, rightX = x + w;
|
||||
uint i;
|
||||
int width = getStringWidth(s);
|
||||
Common::String str;
|
||||
|
||||
|
||||
if (useEllipsis && width > w) {
|
||||
// String is too wide. So we shorten it "intellegently", by replacing
|
||||
// parts of it by an ellipsis ("..."). There are three possibilities
|
||||
@ -100,12 +118,12 @@ void Font::drawString(const Surface *dst, const Common::String &s, int x, int y,
|
||||
// make this configurable, replacing the middle probably is a good
|
||||
// compromise.
|
||||
const int ellipsisWidth = getStringWidth("...");
|
||||
|
||||
|
||||
// SLOW algorithm to remove enough of the middle. But it is good enough
|
||||
// for now.
|
||||
const int halfWidth = (w - ellipsisWidth) / 2;
|
||||
int w2 = 0;
|
||||
|
||||
|
||||
for (i = 0; i < s.size(); ++i) {
|
||||
int charWidth = getCharWidth(s[i]);
|
||||
if (w2 + charWidth > halfWidth)
|
||||
@ -116,7 +134,7 @@ void Font::drawString(const Surface *dst, const Common::String &s, int x, int y,
|
||||
// At this point we know that the first 'i' chars are together 'w2'
|
||||
// pixels wide. We took the first i-1, and add "..." to them.
|
||||
str += "...";
|
||||
|
||||
|
||||
// The original string is width wide. Of those we already skipped past
|
||||
// w2 pixels, which means (width - w2) remain.
|
||||
// The new str is (w2+ellipsisWidth) wide, so we can accomodate about
|
||||
@ -150,7 +168,7 @@ void Font::drawString(const Surface *dst, const Common::String &s, int x, int y,
|
||||
if (x+w > rightX)
|
||||
break;
|
||||
if (x >= leftX)
|
||||
drawChar(dst, str[i], x, y, color);
|
||||
drawChar(dst, str[i], x, y, color, scale);
|
||||
x += w;
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ enum TextAlignment {
|
||||
|
||||
/**
|
||||
* Instances of this class represent a distinct font, with a built-in renderer.
|
||||
* @todo Maybe move the high-level methods (drawString etc.) to a separate
|
||||
* @todo Maybe move the high-level methods (drawString etc.) to a separate
|
||||
* FontRenderer class? That way, we could have different variants... ?
|
||||
* @todo Add more parameters to drawString, or additional similar methods,
|
||||
* featuring abilities like
|
||||
@ -52,9 +52,9 @@ public:
|
||||
virtual int getMaxCharWidth() const = 0;
|
||||
|
||||
virtual int getCharWidth(byte chr) const = 0;
|
||||
virtual void drawChar(const Surface *dst, byte chr, int x, int y, uint32 color) const = 0;
|
||||
virtual void drawChar(const Surface *dst, byte chr, int x, int y, uint32 color, bool scale = false) const = 0;
|
||||
|
||||
void drawString(const Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, TextAlignment align = kTextAlignLeft, int deltax = 0, bool useEllipsis = true) const;
|
||||
void drawString(const Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, TextAlignment align = kTextAlignLeft, int deltax = 0, bool useEllipsis = true, bool scale = false) const;
|
||||
int getStringWidth(const Common::String &str) const;
|
||||
};
|
||||
|
||||
@ -65,7 +65,7 @@ public:
|
||||
virtual int getMaxCharWidth() const { return 8; };
|
||||
|
||||
virtual int getCharWidth(byte chr) const;
|
||||
virtual void drawChar(const Surface *dst, byte chr, int x, int y, uint32 color) const;
|
||||
virtual void drawChar(const Surface *dst, byte chr, int x, int y, uint32 color, bool scale) const;
|
||||
};
|
||||
|
||||
extern const ScummFont g_scummfont;
|
||||
@ -96,12 +96,12 @@ protected:
|
||||
|
||||
public:
|
||||
NewFont(const FontDesc &d) : desc(d) {}
|
||||
|
||||
|
||||
virtual int getFontHeight() const { return desc.height; }
|
||||
virtual int getMaxCharWidth() const { return desc.maxwidth; };
|
||||
|
||||
virtual int getCharWidth(byte chr) const;
|
||||
virtual void drawChar(const Surface *dst, byte chr, int x, int y, uint32 color) const;
|
||||
virtual void drawChar(const Surface *dst, byte chr, int x, int y, uint32 color, bool scale) const;
|
||||
};
|
||||
|
||||
extern const NewFont g_sysfont;
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "graphics/font.h"
|
||||
#include "gui/newgui.h"
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
@ -62,24 +63,36 @@ int ScummFont::getCharWidth(byte chr) const {
|
||||
}
|
||||
|
||||
//void ScummFont::drawChar(byte chr, int xx, int yy, OverlayColor color) {
|
||||
void ScummFont::drawChar(const Surface *dst, byte chr, int tx, int ty, uint32 color) const {
|
||||
void ScummFont::drawChar(const Surface *dst, byte chr, int tx, int ty, uint32 color, bool scale) const {
|
||||
assert(dst != 0);
|
||||
const int scaleFactor = scale ? g_gui.getScaleFactor() : 1;
|
||||
tx *= scaleFactor; ty *= scaleFactor;
|
||||
|
||||
byte *ptr = (byte *)dst->getBasePtr(tx, ty);
|
||||
|
||||
const byte *tmp = guifont + 6 + guifont[4] + chr * 8;
|
||||
uint buffer = 0;
|
||||
uint mask = 0;
|
||||
|
||||
for (int y = 0; y < 8; y++) {
|
||||
for (int y = 0; y < 8 * scaleFactor; y++) {
|
||||
if (ty + y < 0 || ty + y >= dst->h)
|
||||
continue;
|
||||
for (int x = 0; x < 8; x++) {
|
||||
for (int x = 0; x < 8 * scaleFactor; x++) {
|
||||
if(scaleFactor != 1 && !(x % 2))
|
||||
mask >>= 1;
|
||||
else if(scaleFactor == 1)
|
||||
mask >>= 1;
|
||||
|
||||
if (tx + x < 0 || tx + x >= dst->w)
|
||||
continue;
|
||||
unsigned char c;
|
||||
mask >>= 1;
|
||||
|
||||
if (mask == 0) {
|
||||
buffer = *tmp++;
|
||||
if(scaleFactor != 1 && !(y % 2))
|
||||
buffer = *tmp++;
|
||||
else if(scaleFactor == 1)
|
||||
buffer = *tmp++;
|
||||
|
||||
mask = 0x80;
|
||||
}
|
||||
c = ((buffer & mask) != 0);
|
||||
|
@ -49,9 +49,9 @@ enum {
|
||||
* - a *lot* of others things, this code is in no way complete and heavily under progress
|
||||
*/
|
||||
ConsoleDialog::ConsoleDialog(float widthPercent, float heightPercent)
|
||||
: Dialog(0, 0, 1, 1),
|
||||
: Dialog(0, 0, 1, 1),
|
||||
_widthPercent(widthPercent), _heightPercent(heightPercent) {
|
||||
|
||||
|
||||
// Setup basic layout/dialog size
|
||||
reflowLayout();
|
||||
|
||||
@ -111,10 +111,13 @@ void ConsoleDialog::slideUpAndClose() {
|
||||
}
|
||||
|
||||
void ConsoleDialog::open() {
|
||||
// disable scaling because the console is using non fixed positions
|
||||
g_gui.enableScaling(false);
|
||||
|
||||
// Initiate sliding the console down. We do a very simple trick to achieve
|
||||
// this effect: we simply move the console dialog just above (outside) the
|
||||
// visible screen area, then shift it down in handleTickle() over a
|
||||
// certain period of time.
|
||||
// certain period of time.
|
||||
_y = -_h;
|
||||
_slideTime = g_system->getMillis();
|
||||
_slideMode = kDownSlideMode;
|
||||
@ -165,7 +168,7 @@ void ConsoleDialog::handleTickle() {
|
||||
_caretTime = time + kCaretBlinkTime;
|
||||
drawCaret(_caretVisible);
|
||||
}
|
||||
|
||||
|
||||
// Perform the "slide animation".
|
||||
if (_slideMode != kNoSlideMode) {
|
||||
const float tmp = (float)(g_system->getMillis() - _slideTime) / kConsoleSlideDownDuration;
|
||||
@ -174,7 +177,7 @@ void ConsoleDialog::handleTickle() {
|
||||
} else {
|
||||
_y = (int)(_h * (tmp - 1.0));
|
||||
}
|
||||
|
||||
|
||||
if (_slideMode == kDownSlideMode && _y > 0) {
|
||||
// End the slide
|
||||
_slideMode = kNoSlideMode;
|
||||
@ -195,7 +198,7 @@ void ConsoleDialog::handleMouseWheel(int x, int y, int direction) {
|
||||
|
||||
void ConsoleDialog::handleKeyDown(uint16 ascii, int keycode, int modifiers) {
|
||||
int i;
|
||||
|
||||
|
||||
if (_slideMode != kNoSlideMode)
|
||||
return;
|
||||
|
||||
@ -204,7 +207,7 @@ void ConsoleDialog::handleKeyDown(uint16 ascii, int keycode, int modifiers) {
|
||||
case '\r': {
|
||||
if (_caretVisible)
|
||||
drawCaret(true);
|
||||
|
||||
|
||||
nextLine();
|
||||
|
||||
assert(_promptEndPos >= _promptStartPos);
|
||||
@ -217,7 +220,7 @@ void ConsoleDialog::handleKeyDown(uint16 ascii, int keycode, int modifiers) {
|
||||
// We have to allocate the string buffer with new, since VC++ sadly does not
|
||||
// comply to the C++ standard, so we can't use a dynamic sized stack array.
|
||||
char *str = new char[len + 1];
|
||||
|
||||
|
||||
// Copy the user input to str
|
||||
for (i = 0; i < len; i++)
|
||||
str[i] = buffer(_promptStartPos + i);
|
||||
|
@ -29,7 +29,7 @@ namespace GUI {
|
||||
|
||||
/*
|
||||
* TODO list
|
||||
* - add some sense of the window being "active" (i.e. in front) or not. If it
|
||||
* - add some sense of the window being "active" (i.e. in front) or not. If it
|
||||
* was inactive and just became active, reset certain vars (like who is focused).
|
||||
* Maybe we should just add lostFocus and receivedFocus methods to Dialog, just
|
||||
* like we have for class Widget?
|
||||
@ -98,7 +98,7 @@ void Dialog::draw() {
|
||||
}
|
||||
|
||||
void Dialog::drawDialog() {
|
||||
|
||||
|
||||
if (!isVisible())
|
||||
return;
|
||||
|
||||
@ -117,9 +117,12 @@ void Dialog::drawDialog() {
|
||||
}
|
||||
|
||||
void Dialog::handleMouseDown(int x, int y, int button, int clickCount) {
|
||||
x /= g_gui.getScaleFactor(); y /= g_gui.getScaleFactor();
|
||||
|
||||
Widget *w;
|
||||
|
||||
w = findWidget(x, y);
|
||||
|
||||
|
||||
_dragWidget = w;
|
||||
|
||||
// If the click occured inside a widget which is not the currently
|
||||
@ -141,11 +144,13 @@ void Dialog::handleMouseDown(int x, int y, int button, int clickCount) {
|
||||
}
|
||||
|
||||
void Dialog::handleMouseUp(int x, int y, int button, int clickCount) {
|
||||
x /= g_gui.getScaleFactor(); y /= g_gui.getScaleFactor();
|
||||
|
||||
Widget *w;
|
||||
|
||||
if (_focusedWidget) {
|
||||
//w = _focusedWidget;
|
||||
|
||||
|
||||
// Lose focus on mouseup unless the widget requested to retain the focus
|
||||
if (! (_focusedWidget->getFlags() & WIDGET_RETAIN_FOCUS )) {
|
||||
releaseFocus();
|
||||
@ -161,6 +166,8 @@ void Dialog::handleMouseUp(int x, int y, int button, int clickCount) {
|
||||
}
|
||||
|
||||
void Dialog::handleMouseWheel(int x, int y, int direction) {
|
||||
x /= g_gui.getScaleFactor(); y /= g_gui.getScaleFactor();
|
||||
|
||||
Widget *w;
|
||||
|
||||
// This may look a bit backwards, but I think it makes more sense for
|
||||
@ -212,16 +219,18 @@ void Dialog::handleKeyUp(uint16 ascii, int keycode, int modifiers) {
|
||||
}
|
||||
|
||||
void Dialog::handleMouseMoved(int x, int y, int button) {
|
||||
x /= g_gui.getScaleFactor(); y /= g_gui.getScaleFactor();
|
||||
|
||||
Widget *w;
|
||||
|
||||
|
||||
//if (!button)
|
||||
// _dragWidget = 0;
|
||||
|
||||
|
||||
if (_focusedWidget && !_dragWidget) {
|
||||
w = _focusedWidget;
|
||||
int wx = w->getAbsX() - _x;
|
||||
int wy = w->getAbsY() - _y;
|
||||
|
||||
|
||||
// We still send mouseEntered/Left messages to the focused item
|
||||
// (but to no other items).
|
||||
bool mouseInFocusedWidget = (x >= wx && x < wx + w->_w && y >= wy && y < wy + w->_h);
|
||||
@ -237,7 +246,7 @@ void Dialog::handleMouseMoved(int x, int y, int button) {
|
||||
|
||||
w->handleMouseMoved(x - wx, y - wy, button);
|
||||
}
|
||||
|
||||
|
||||
// While a "drag" is in process (i.e. mouse is moved while a button is pressed),
|
||||
// only deal with the widget in which the click originated.
|
||||
if (_dragWidget)
|
||||
@ -251,7 +260,7 @@ void Dialog::handleMouseMoved(int x, int y, int button) {
|
||||
if (w)
|
||||
w->handleMouseEntered(button);
|
||||
_mouseWidget = w;
|
||||
}
|
||||
}
|
||||
|
||||
if (w && (w->getFlags() & WIDGET_TRACK_MOUSE)) {
|
||||
w->handleMouseMoved(x - (w->getAbsX() - _x), y - (w->getAbsY() - _y), button);
|
||||
|
@ -41,7 +41,7 @@ namespace GUI {
|
||||
* - allow multi line (l/c/r aligned) text via StaticTextWidget ?
|
||||
* - add "close" widget to all dialogs (with a flag to turn it off) ?
|
||||
* - make dialogs "moveable" ?
|
||||
* - come up with a new look & feel / theme for the GUI
|
||||
* - come up with a new look & feel / theme for the GUI
|
||||
* - ...
|
||||
*/
|
||||
|
||||
@ -54,9 +54,9 @@ enum {
|
||||
|
||||
|
||||
// Constructor
|
||||
NewGui::NewGui() : _needRedraw(false),
|
||||
NewGui::NewGui() : _scaleEnable(true), _needRedraw(false),
|
||||
_stateIsSaved(false), _cursorAnimateCounter(0), _cursorAnimateTimer(0) {
|
||||
|
||||
|
||||
_system = &OSystem::instance();
|
||||
|
||||
// Clear the cursor
|
||||
@ -64,6 +64,9 @@ NewGui::NewGui() : _needRedraw(false),
|
||||
|
||||
// Reset key repeat
|
||||
_currentKeyDown.keycode = 0;
|
||||
|
||||
// updates the scaling factor
|
||||
updateScaleFactor();
|
||||
}
|
||||
|
||||
void NewGui::updateColors() {
|
||||
@ -75,17 +78,32 @@ void NewGui::updateColors() {
|
||||
_textcolorhi = _system->RGBToColor(0, 255, 0);
|
||||
}
|
||||
|
||||
void NewGui::updateScaleFactor() {
|
||||
if(!_scaleEnable) {
|
||||
_scaleFactor = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
enum {
|
||||
kDefaultGUIWidth = 320,
|
||||
kDefaultGUIHeight = 200
|
||||
};
|
||||
|
||||
_scaleFactor = MIN(_system->getWidth() / kDefaultGUIWidth, _system->getHeight() / kDefaultGUIHeight);
|
||||
}
|
||||
|
||||
void NewGui::runLoop() {
|
||||
Dialog *activeDialog = _dialogStack.top();
|
||||
bool didSaveState = false;
|
||||
|
||||
if (activeDialog == 0)
|
||||
return;
|
||||
|
||||
|
||||
// Setup some default GUI colors. Normally this will be done whenever an
|
||||
// EVENT_SCREEN_CHANGED is received. However, not yet all backends support
|
||||
// that event, so we also do it "manually" whenever a run loop is entered.
|
||||
updateColors();
|
||||
updateScaleFactor();
|
||||
|
||||
if (!_stateIsSaved) {
|
||||
saveState();
|
||||
@ -106,7 +124,7 @@ void NewGui::runLoop() {
|
||||
}
|
||||
|
||||
animateCursor();
|
||||
_system->updateScreen();
|
||||
_system->updateScreen();
|
||||
|
||||
OSystem::Event event;
|
||||
uint32 time = _system->getMillis();
|
||||
@ -131,7 +149,7 @@ void NewGui::runLoop() {
|
||||
_currentKeyDown.keycode = 0;
|
||||
break;
|
||||
case OSystem::EVENT_MOUSEMOVE:
|
||||
activeDialog->handleMouseMoved(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y, 0);
|
||||
activeDialog->handleMouseMoved(event.mouse.x - (activeDialog->_x * _scaleFactor), event.mouse.y - (activeDialog->_y * _scaleFactor), 0);
|
||||
break;
|
||||
// We don't distinguish between mousebuttons (for now at least)
|
||||
case OSystem::EVENT_LBUTTONDOWN:
|
||||
@ -146,23 +164,24 @@ void NewGui::runLoop() {
|
||||
_lastClick.count = 1;
|
||||
}
|
||||
_lastClick.time = time;
|
||||
activeDialog->handleMouseDown(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y, 1, _lastClick.count);
|
||||
activeDialog->handleMouseDown(event.mouse.x - (activeDialog->_x * _scaleFactor), event.mouse.y - (activeDialog->_y * _scaleFactor), 1, _lastClick.count);
|
||||
break;
|
||||
case OSystem::EVENT_LBUTTONUP:
|
||||
case OSystem::EVENT_RBUTTONUP:
|
||||
activeDialog->handleMouseUp(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y, 1, _lastClick.count);
|
||||
activeDialog->handleMouseUp(event.mouse.x - (activeDialog->_x * _scaleFactor), event.mouse.y - (activeDialog->_y * _scaleFactor), 1, _lastClick.count);
|
||||
break;
|
||||
case OSystem::EVENT_WHEELUP:
|
||||
activeDialog->handleMouseWheel(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y, -1);
|
||||
activeDialog->handleMouseWheel(event.mouse.x - (activeDialog->_x * _scaleFactor), event.mouse.y - (activeDialog->_y * _scaleFactor), -1);
|
||||
break;
|
||||
case OSystem::EVENT_WHEELDOWN:
|
||||
activeDialog->handleMouseWheel(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y, 1);
|
||||
activeDialog->handleMouseWheel(event.mouse.x - (activeDialog->_x * _scaleFactor), event.mouse.y - (activeDialog->_y * _scaleFactor), 1);
|
||||
break;
|
||||
case OSystem::EVENT_QUIT:
|
||||
_system->quit();
|
||||
return;
|
||||
case OSystem::EVENT_SCREEN_CHANGED:
|
||||
updateColors();
|
||||
updateScaleFactor();
|
||||
activeDialog->handleScreenChanged();
|
||||
break;
|
||||
}
|
||||
@ -180,7 +199,7 @@ void NewGui::runLoop() {
|
||||
// Delay for a moment
|
||||
_system->delayMillis(10);
|
||||
}
|
||||
|
||||
|
||||
if (didSaveState)
|
||||
restoreState();
|
||||
}
|
||||
@ -212,6 +231,7 @@ void NewGui::saveState() {
|
||||
_lastClick.count = 0;
|
||||
|
||||
_stateIsSaved = true;
|
||||
_scaleEnable = true;
|
||||
}
|
||||
|
||||
void NewGui::restoreState() {
|
||||
@ -224,7 +244,7 @@ void NewGui::restoreState() {
|
||||
}
|
||||
|
||||
_system->updateScreen();
|
||||
|
||||
|
||||
_stateIsSaved = false;
|
||||
}
|
||||
|
||||
@ -270,20 +290,20 @@ void NewGui::box(int x, int y, int width, int height, OverlayColor colorA, Overl
|
||||
}
|
||||
|
||||
void NewGui::hLine(int x, int y, int x2, OverlayColor color) {
|
||||
_screen.hLine(x, y, x2, color);
|
||||
_screen.hLine(x * _scaleFactor, y * _scaleFactor, x2 * _scaleFactor, color);
|
||||
}
|
||||
|
||||
void NewGui::vLine(int x, int y, int y2, OverlayColor color) {
|
||||
_screen.vLine(x, y, y2, color);
|
||||
_screen.vLine(x * _scaleFactor, y * _scaleFactor, y2 * _scaleFactor, color);
|
||||
}
|
||||
|
||||
void NewGui::blendRect(int x, int y, int w, int h, OverlayColor color, int level) {
|
||||
#ifdef NEWGUI_256
|
||||
fillRect(x, y, w, h, color);
|
||||
#else
|
||||
Common::Rect rect(x, y, x + w, y + h);
|
||||
Common::Rect rect(x * _scaleFactor, y * _scaleFactor, (x + w) * _scaleFactor, (y + h) * _scaleFactor);
|
||||
rect.clip(_screen.w, _screen.h);
|
||||
|
||||
|
||||
if (!rect.isValidRect())
|
||||
return;
|
||||
|
||||
@ -311,17 +331,17 @@ void NewGui::blendRect(int x, int y, int w, int h, OverlayColor color, int level
|
||||
}
|
||||
|
||||
void NewGui::fillRect(int x, int y, int w, int h, OverlayColor color) {
|
||||
_screen.fillRect(Common::Rect(x, y, x+w, y+h), color);
|
||||
_screen.fillRect(Common::Rect(x * _scaleFactor, y * _scaleFactor, (x+w) * _scaleFactor, (y+h) * _scaleFactor), color);
|
||||
}
|
||||
|
||||
void NewGui::frameRect(int x, int y, int w, int h, OverlayColor color) {
|
||||
_screen.frameRect(Common::Rect(x, y, x+w, y+h), color);
|
||||
_screen.frameRect(Common::Rect(x * _scaleFactor, y * _scaleFactor, (x+w) * _scaleFactor, (y+h) * _scaleFactor), color);
|
||||
}
|
||||
|
||||
void NewGui::addDirtyRect(int x, int y, int w, int h) {
|
||||
Common::Rect rect(x, y, x + w, y + h);
|
||||
Common::Rect rect(x * _scaleFactor, y * _scaleFactor, (x + w) * _scaleFactor, (y + h) * _scaleFactor);
|
||||
rect.clip(_screen.w, _screen.h);
|
||||
|
||||
|
||||
if (!rect.isValidRect())
|
||||
return;
|
||||
|
||||
@ -335,7 +355,7 @@ void NewGui::addDirtyRect(int x, int y, int w, int h) {
|
||||
void NewGui::drawChar(byte chr, int xx, int yy, OverlayColor color, const Graphics::Font *font) {
|
||||
if (font == 0)
|
||||
font = &getFont();
|
||||
font->drawChar(&_screen, chr, xx, yy, color);
|
||||
font->drawChar(&_screen, chr, xx, yy, color, _scaleEnable);
|
||||
}
|
||||
|
||||
int NewGui::getStringWidth(const String &str) {
|
||||
@ -347,24 +367,31 @@ int NewGui::getCharWidth(byte c) {
|
||||
}
|
||||
|
||||
void NewGui::drawString(const String &s, int x, int y, int w, OverlayColor color, TextAlignment align, int deltax, bool useEllipsis) {
|
||||
getFont().drawString(&_screen, s, x, y, w, color, align, deltax, useEllipsis);
|
||||
getFont().drawString(&_screen, s, x, y, w, color, align, deltax, useEllipsis, _scaleEnable);
|
||||
}
|
||||
|
||||
//
|
||||
// Draw an 8x8 bitmap at location (x,y)
|
||||
//
|
||||
void NewGui::drawBitmap(uint32 *bitmap, int tx, int ty, OverlayColor color, int h) {
|
||||
tx *= _scaleFactor; ty *= _scaleFactor;
|
||||
h *= _scaleFactor;
|
||||
OverlayColor *ptr = getBasePtr(tx, ty);
|
||||
|
||||
for (int y = 0; y < h; y++, ptr += _screenPitch) {
|
||||
uint32 mask = 0xF0000000;
|
||||
if (ty + y < 0 || ty + y >= _screen.h)
|
||||
continue;
|
||||
for (int x = 0; x < 8; x++, mask >>= 4) {
|
||||
for (int x = 0; x < 8 * _scaleFactor; x++) {
|
||||
if(!(x % 2) && _scaleFactor != 1 && x != 0)
|
||||
mask >>= 4;
|
||||
else if(_scaleFactor == 1)
|
||||
mask >>= 4;
|
||||
|
||||
if (tx + x < 0 || tx + x >= _screen.w)
|
||||
continue;
|
||||
if (bitmap[y] & mask)
|
||||
ptr[x] = color;
|
||||
if (bitmap[y / _scaleFactor] & mask)
|
||||
ptr[x] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -374,19 +401,19 @@ void NewGui::drawBitmap(uint32 *bitmap, int tx, int ty, OverlayColor color, int
|
||||
// We could plug in a different cursor here if we like to.
|
||||
//
|
||||
void NewGui::animateCursor() {
|
||||
int time = _system->getMillis();
|
||||
int time = _system->getMillis();
|
||||
if (time > _cursorAnimateTimer + kCursorAnimateDelay) {
|
||||
const byte colors[4] = { 15, 15, 7, 8 };
|
||||
const byte color = colors[_cursorAnimateCounter];
|
||||
int i;
|
||||
|
||||
|
||||
for (i = 0; i < 15; i++) {
|
||||
if ((i < 6) || (i > 8)) {
|
||||
_cursor[16 * 7 + i] = color;
|
||||
_cursor[16 * i + 7] = color;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_system->setMouseCursor(_cursor, 16, 16, 7, 7);
|
||||
|
||||
_cursorAnimateTimer = time;
|
||||
|
33
gui/newgui.h
33
gui/newgui.h
@ -52,7 +52,7 @@ typedef Common::FixedStack<Dialog *> DialogStack;
|
||||
|
||||
/**
|
||||
* GUI manager singleton.
|
||||
*/
|
||||
*/
|
||||
class NewGui : public Common::Singleton<NewGui> {
|
||||
typedef Common::String String;
|
||||
friend class Dialog;
|
||||
@ -66,16 +66,22 @@ public:
|
||||
|
||||
bool isActive() { return ! _dialogStack.empty(); }
|
||||
|
||||
int getScaleFactor() { return _scaleFactor; }
|
||||
void enableScaling(bool enable) { _scaleEnable = enable; updateScaleFactor(); }
|
||||
|
||||
protected:
|
||||
OSystem *_system;
|
||||
Graphics::Surface _screen;
|
||||
OSystem *_system;
|
||||
Graphics::Surface _screen;
|
||||
int _screenPitch;
|
||||
|
||||
|
||||
int _scaleFactor;
|
||||
bool _scaleEnable;
|
||||
|
||||
bool _needRedraw;
|
||||
DialogStack _dialogStack;
|
||||
|
||||
|
||||
bool _stateIsSaved;
|
||||
|
||||
|
||||
// for continuous events (keyDown)
|
||||
struct {
|
||||
uint16 ascii;
|
||||
@ -83,30 +89,31 @@ protected:
|
||||
int keycode;
|
||||
} _currentKeyDown;
|
||||
uint32 _keyRepeatTime;
|
||||
|
||||
|
||||
// position and time of last mouse click (used to detect double clicks)
|
||||
struct {
|
||||
int16 x, y; // Position of mouse when the click occured
|
||||
uint32 time; // Time
|
||||
int count; // How often was it already pressed?
|
||||
} _lastClick;
|
||||
|
||||
|
||||
// mouse cursor state
|
||||
bool _oldCursorMode;
|
||||
int _cursorAnimateCounter;
|
||||
int _cursorAnimateTimer;
|
||||
int _cursorAnimateCounter;
|
||||
int _cursorAnimateTimer;
|
||||
byte _cursor[2048];
|
||||
|
||||
void saveState();
|
||||
void restoreState();
|
||||
|
||||
|
||||
void openDialog(Dialog *dialog);
|
||||
void closeTopDialog();
|
||||
|
||||
|
||||
void loop();
|
||||
|
||||
void animateCursor();
|
||||
void updateColors();
|
||||
void updateScaleFactor();
|
||||
|
||||
OverlayColor *getBasePtr(int x, int y);
|
||||
|
||||
@ -116,7 +123,7 @@ public:
|
||||
OverlayColor _bgcolor;
|
||||
OverlayColor _textcolor;
|
||||
OverlayColor _textcolorhi;
|
||||
|
||||
|
||||
// Font
|
||||
const Graphics::Font &getFont() const;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user