/*(LGPL) --------------------------------------------------------------------------- window.h - Generic Rendering Window --------------------------------------------------------------------------- * Copyright (C) 2001-2003, 2007 David Olofson * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or (at * your option) any later version. * * 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * Programmer's Documentation: * The window_t class represents a simple window of the * screen surface. It provides some high level rendering * functions that operate inside the window's bounding * rectangle. All operations are clipped. However, * window occlusion is *not* handled, so you can't use * this class for "real" windows. * * virtual void init(gfxengine_t *e); * Call this to connect a window_t instance to * the gfxengine_t instance that manages your * screen. You *must* call this for pretty much * any other calls to work. * * void place(int left, int top, int sizex, int sizey); * Position the window on the screen. * * int offscreen(); * Make this an off-screen window, with a * surface of it's own for rendering. An off- * screen window will never be directly visible, * but can be used as a source window for blit(). * May return -1 if there is an error. * * void select(); * Makes this window active, and sets up SDL's * clipping appropriately. You should not use * this call normally, but it's provided to * allow this engine to interface with other * SDL code. * * void invalidate(SDL_Rect *r = NULL); * Invalidate the specified area, or the whole * window if r is NULL. This will ensure that * any changes in the invalidated area are made * visible on the screen. Note that this call * may also indirectly cause one or more calls * to refresh(). * * virtual void refresh(SDL_Rect *r); * Virtual refresh call to be implemented by * windows that aren't repainted every frame. * After a call to invalidate(), refresh() will * be called by the engine as necessary to * produce a correct display. Note that in some * cases, this means that refresh() will be * called once for each screen flip, until all * buffers (usually two) are up to date. Also * note that you should do all rendering to the * window either directly *or* in the refresh() * function. * * Uint32 map_rgb(Uint8 r, Uint8 g, Uint8 b); * Uint32 map_rgb(Uint32 rgb); * Two different ways of translating a color in * standard RGB format (separate components or * HTML style hex code, respectively) into a * pixel value compatible with the screen. * * void foreground(Uint32 color); * void background(Uint32 color); * Change the foreground and background colors * used by subsequent rendering operations. * Note that the arguments have to be in screen * pixel format - the easiest way is to use the * map_rgb() calls to generate the values. * * void bgimage(int bank, int frame); * Select a background image, to use instead of * a background color. Setting bank and frame to * -1 (default) disables the image, so that the * background color is used instead. * * void colorkey(Uint32 color); * void colorkey(); * Set the colorkey for this window to 'color' * and enable colorkeying. This affects blit() * when this window is used as the source. The * version without arguments disables * colorkeying for this window. * NOTE: Colorkeying is only supported by * offscreen windows. * * void alpha(float a); * Set the full surface alpha of this window. * 0.0 is fully transparent and 1.0 is opaque. * NOTE: Alpha is only supported by offscreen * windows. * * void clear(SDL_Rect *r = NULL); * Fill the specified rectangle with the current * background color or background image. If r is * NULL (default), clear the whole window. * * void font(int fnt); * Select the font to be used for subsequent * text rendering operations. The argument is a * gfxengine_t bank index, and must refer to a * bank that has been loaded with * gfxengine_t::loadfont(). * * void string(int _x, int _y, const char *txt); * Put text string 'txt' starting at (_x, _y). * * void center(int _y, const char *txt); * Put text string 'txt' centered horizontally * inside the window, using '_y' as the y coord. * * void center_token(int _x, int _y, const char *txt, char token = 0); * Print string 'txt', positioning it so that * the first occurrence of character 'token' * is located at (_x, _y). Omitting the 'token' * argument, or passing 0 aligns the end of the * string with _x. Setting 'token' to -1 results * in the graphical center of the string being * located at (_x, _y) - basically an advanced * version of center(). * * void string_fxp(int _x, int _y, const char *txt); * void center_fxp(int _y, const char *txt); * void center_token_fxp(int _x, int _y, const char *txt, char token = 0); * gfxengine_t fixed point format versions of * the corresponding non-fxp calls. (For sub- * pixel accurate rendering and/or to make use * of the higher resolutions in scaled modes.) * * int textwidth(const char *txt, int min = 0, int max = 255); * Calculates the graphical width of 'txt' if it * was to be printed with the current font. * Calculation starts at position 'min' in the * string, and ends at 'max', which makes it * possible to use this call for various * advanced alignment calculations. * * int fontheight(); * Returns the height of the currently selected * font. * * void point(int _x, int _y); * Plot a pixel with the current foreground * color at (_x, _y). Note that the pixel will * become a quadratic block if the screen is * scaled to a higher resolution. * * void rectangle(int _x, int _y, int w, int h); * Draw a hollow rectangle of w x h pixels at * (_x, _y). The line thickness is scaled along * with screen resolution, as with point(). * * void fillrect(int _x, int _y, int w, int h); * Draw a solid rectangle of w x h pixels at * (_x, _y). * * void fillrect_fxp(int _x, int _y, int w, int h); * As fillrect(), but with pixel or sub-pixel * accuracy, depending on scaling and video * driver. * * void sprite(int _x, int _y, int bank, int frame, int inval = 1); * Render sprite 'bank':'frame' at (_x, _y). If * inval is passed and set to 0, the affected * area will *not* be invalidated automatically. * * void sprite_fxp(int _x, int _y, int bank, int frame, int inval = 1); * As sprite(), but with pixel or sub-pixel * accuracy, depending on scaling and video * driver. * * void blit(int dx, int dy, window_t *src); * Blit from window 'src' into this window, placing * the top left corner of 'src' at (dx, dy). * * void blit(int dx, int dy, int sx, int sy, int sw, int sh, window_t *src); * Blit rectangle (sx, sy, sw, sh) from window 'src' * into this window, placing the top left corner of * 'src' at (dx, dy). * * int x() { return rect.x / xsc; } * int y() { return rect.y / ysc; } * int width() { return rect.w / xsc; } * int height() { return rect.h / ysc; } * Get the current screen position of the * window's top-left corner, and it's size. * * int x2() { return (rect.x + rect.w) / xsc; } * int y2() { return (rect.y + rect.h) / ysc; } * Get the screen position of the bottom-right * corner of the window. */ #ifndef _WINDOW_H_ #define _WINDOW_H_ #include "glSDL.h" class gfxengine_t; class window_t { friend class gfxengine_t; public: window_t(); window_t(gfxengine_t *e); virtual ~window_t(); virtual void init(gfxengine_t *e); void place(int left, int top, int sizex, int sizey); int offscreen(); void visible(int vis); int visible() { return _visible; } void select(); void invalidate(SDL_Rect *r = NULL); virtual void refresh(SDL_Rect *r) { ; } /* Color tools */ Uint32 mulrgb(Uint32 c1, Uint32 c2) { int r = ((c1 >> 16) & 0xff) * ((c2 >> 16) & 0xff) * 258 >> 16; int g = ((c1 >> 8) & 0xff) * ((c2 >> 8) & 0xff) * 258 >> 16; int b = (c1 & 0xff) * (c2 & 0xff) * 258 >> 16; return r << 16 | g << 8 | b; } Uint32 fadergb(Uint32 rgb, Uint8 fade) { int r = ((rgb >> 16) & 0xff) * fade * 258 >> 16; int g = ((rgb >> 8) & 0xff) * fade * 258 >> 16; int b = (rgb & 0xff) * fade * 258 >> 16; return r << 16 | g << 8 | b; } /* Rendering */ Uint32 map_rgb(Uint8 r, Uint8 g, Uint8 b); Uint32 map_rgb(Uint32 rgb); void foreground(Uint32 color) { fgcolor = color; } void background(Uint32 color) { bgcolor = color; }; void bgimage(int bank = -1, int frame = -1); void colorkey(Uint32 color); void colorkey(); void alpha(float a); void clear(SDL_Rect *r = NULL); void font(int fnt); void string(int _x, int _y, const char *txt); void center(int _y, const char *txt); void center_token(int _x, int _y, const char *txt, char token = 0); void string_fxp(int _x, int _y, const char *txt); void center_fxp(int _y, const char *txt); void center_token_fxp(int _x, int _y, const char *txt, char token = 0); int textwidth(const char *txt, int min = 0, int max = 255); int textwidth_fxp(const char *txt, int min = 0, int max = 255); int fontheight(); void point(int _x, int _y); void rectangle(int _x, int _y, int w, int h); void fillrect(int _x, int _y, int w, int h); void fillrect_fxp(int _x, int _y, int w, int h); void sprite(int _x, int _y, int bank, int frame, int inval = 1); void sprite_fxp(int _x, int _y, int bank, int frame, int inval = 1); void blit(int dx, int dy, int sx, int sy, int sw, int sh, window_t *src); void blit(int dx, int dy, window_t *src); int x() { return (phys_rect.x * 256 + 128) / xs; } int y() { return (phys_rect.y * 256 + 128) / ys; } int x2() { return ((phys_rect.x + phys_rect.w) * 256 + 128) / xs; } int y2() { return ((phys_rect.y + phys_rect.h) * 256 + 128) / ys; } int width() { return x2() - x(); } int height() { return y2() - y(); } SDL_Rect phys_rect; protected: window_t *next, *prev; /* * Kludge: This is for window selection to work. * the problem is that this will break (along * with some other things) if more than one * gfxengine_t instance is used. */ static window_t *selected; //Currently selected window gfxengine_t *engine; SDL_Surface *surface; int xs, ys; //fixp 24:8 Uint32 fgcolor, bgcolor; int bg_bank, bg_frame; int _font; int _visible; int _offscreen; void _select(); //Internal version void link(gfxengine_t *e); void unlink(void); void phys_refresh(SDL_Rect *r) { if(!r) refresh(NULL); else { SDL_Rect dr; dr.x = r->x - phys_rect.x; dr.y = r->y - phys_rect.y; int x2 = (int)(dr.x + r->w) * 256 / xs; int y2 = (int)(dr.y + r->h) * 256 / ys; dr.x = (int)dr.x * 256 / xs; dr.y = (int)dr.y * 256 / ys; dr.w = x2 - dr.x; dr.h = y2 - dr.y; refresh(&dr); } } }; #endif