summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorpixel <pixel>2004-11-27 21:48:01 +0000
committerpixel <pixel>2004-11-27 21:48:01 +0000
commitf9969775e6d2f798a3bfea5c58fc5478dad07eae (patch)
treec82d4ed9c87d7e09c71be3554ac5d0486c774eda /lib
parent1ae229afb9bff4a3636c08632032b509e1e80ec4 (diff)
Large dos2unix commit...
Diffstat (limited to 'lib')
-rw-r--r--lib/base.cc356
-rw-r--r--lib/engine.cc818
-rw-r--r--lib/font.cc1410
-rw-r--r--lib/glbase.cc534
-rw-r--r--lib/glfont.cc144
-rw-r--r--lib/glshape.cc506
-rw-r--r--lib/glsprite.cc210
-rw-r--r--lib/glwidgets.cc58
-rw-r--r--lib/mcolor.cc132
-rw-r--r--lib/shape.cc1856
-rw-r--r--lib/sprite.cc380
-rw-r--r--lib/texture.cc722
-rw-r--r--lib/widgets.cc2364
13 files changed, 4745 insertions, 4745 deletions
diff --git a/lib/base.cc b/lib/base.cc
index 61426eb..13d6052 100644
--- a/lib/base.cc
+++ b/lib/base.cc
@@ -1,178 +1,178 @@
-/*
- * mogltk
- * Copyright (C) 1999-2004 Nicolas "Pixel" Noble
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* $Id: base.cc,v 1.13 2004-11-27 21:44:52 pixel Exp $ */
-
-#include <stdio.h>
-#include <SDL.h>
-#include "base.h"
-#include "engine.h"
-#include "generic.h"
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "gettext.h"
-
-mogltk::base::base(int w, int h, int flags) throw(GeneralException) : surface(0) {
- width = w;
- height = h;
-
- mogltk::engine::setup();
- if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
- throw GeneralException(String("Couldn't initialise Video SubSystem: ") + SDL_GetError());
- }
-
- if (!(surface = SDL_SetVideoMode(width, height, 0, flags | SDL_HWSURFACE))) {
- throw GeneralException(String("Couldn't set SDL mode: ") + SDL_GetError());
- }
-
- mogltk::engine::base_o = this;
-
- float ratio = surface->w;
- ratio /= surface->h;
-
- printm(M_INFO, "Video resolution: %dx%dx%d (ratio = %3.2f)\n", surface->w, surface->h, surface->format->BitsPerPixel, ratio);
-
- SDL_ShowCursor(SDL_DISABLE);
- SDL_FillRect(surface, NULL, 0);
- SDL_Flip(surface);
- SDL_FillRect(surface, NULL, 0);
- mogltk::engine::postsetup();
-}
-
-mogltk::base::~base() {
-}
-
-int mogltk::base::GetWidth(void) {
- return width;
-}
-
-int mogltk::base::GetHeight(void) {
- return height;
-}
-
-void mogltk::base::Flip(bool clear) {
- mogltk::engine::pollevents();
- SDL_Flip(surface);
- if (clear)
- SDL_FillRect(surface, NULL, 0);
-}
-
-mogltk::base::base(int w, int h, int flags, int) : surface(0) {
- width = w;
- height = h;
-
- SDL_ShowCursor(SDL_DISABLE);
-}
-
-void mogltk::base::setsurface(SDL_Surface * _surface) throw (GeneralException) {
- if (surface)
- throw GeneralException("Can't set video surface twice");
- surface = _surface;
-}
-
-SDL_Surface * mogltk::base::getsurface() {
- return surface;
-}
-
-void mogltk::base::Enter2DMode() {
-}
-
-void mogltk::base::Leave2DMode() {
-}
-
-bool mogltk::base::is2D() {
- return true;
-}
-
-void mogltk::base::changeviewport(int x, int y, unsigned int w, unsigned int h) {
- SDL_Rect r;
-
- if ((w == 0) && (h == 0)) {
- w = GetWidth() - x;
- h = GetHeight() - y;
- }
-
- r.x = x;
- r.y = y;
- r.w = w;
- r.h = h;
-
- SDL_SetClipRect(surface, &r);
-}
-
-void mogltk::base::ToggleFullscreen() {
- int newflags = surface->flags;
-
- if (surface->flags & SDL_FULLSCREEN)
- newflags &= ~SDL_FULLSCREEN;
- else
- newflags |= SDL_FULLSCREEN;
-
- texture::Taintall();
-
- surface = SDL_SetVideoMode(surface->w, surface->h, surface->format->BitsPerPixel,
- SDL_HWSURFACE | newflags);
-}
-
-inline static unsigned int nextpower(unsigned int n) {
- unsigned int i;
-
- if (!n)
- return n;
-
- if (ISPOT(n))
- return n;
-
- for (i = 31; i >= 0; i--) {
- if ((n >> i) & 1) {
- return 1 << (i + 1);
- }
- }
-}
-
-mogltk::texture * mogltk::base::GrabTexture() {
- int w = nextpower(GetWidth());
- int h = nextpower(GetHeight());
- texture * r = new texture(w, h);
-
- SDL_BlitSurface(getsurface(), NULL, r->GetSurface(), NULL);
-
- return r;
-}
-
-SDL_Surface * mogltk::base::GrabSurface() {
- SDL_Surface * r = SDL_CreateRGBSurface(SDL_SWSURFACE, GetWidth(), GetHeight(), 24,
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- 0xff000000,
- 0x00ff0000,
- 0x0000ff00,
- 0x00000000
-#else
- 0x000000ff,
- 0x0000ff00,
- 0x00ff0000,
- 0x00000000
-#endif
- );
-
- SDL_BlitSurface(getsurface(), NULL, r, NULL);
-
- return r;
-}
+/*
+ * mogltk
+ * Copyright (C) 1999-2004 Nicolas "Pixel" Noble
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: base.cc,v 1.14 2004-11-27 21:48:03 pixel Exp $ */
+
+#include <stdio.h>
+#include <SDL.h>
+#include "base.h"
+#include "engine.h"
+#include "generic.h"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "gettext.h"
+
+mogltk::base::base(int w, int h, int flags) throw(GeneralException) : surface(0) {
+ width = w;
+ height = h;
+
+ mogltk::engine::setup();
+ if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
+ throw GeneralException(String("Couldn't initialise Video SubSystem: ") + SDL_GetError());
+ }
+
+ if (!(surface = SDL_SetVideoMode(width, height, 0, flags | SDL_HWSURFACE))) {
+ throw GeneralException(String("Couldn't set SDL mode: ") + SDL_GetError());
+ }
+
+ mogltk::engine::base_o = this;
+
+ float ratio = surface->w;
+ ratio /= surface->h;
+
+ printm(M_INFO, "Video resolution: %dx%dx%d (ratio = %3.2f)\n", surface->w, surface->h, surface->format->BitsPerPixel, ratio);
+
+ SDL_ShowCursor(SDL_DISABLE);
+ SDL_FillRect(surface, NULL, 0);
+ SDL_Flip(surface);
+ SDL_FillRect(surface, NULL, 0);
+ mogltk::engine::postsetup();
+}
+
+mogltk::base::~base() {
+}
+
+int mogltk::base::GetWidth(void) {
+ return width;
+}
+
+int mogltk::base::GetHeight(void) {
+ return height;
+}
+
+void mogltk::base::Flip(bool clear) {
+ mogltk::engine::pollevents();
+ SDL_Flip(surface);
+ if (clear)
+ SDL_FillRect(surface, NULL, 0);
+}
+
+mogltk::base::base(int w, int h, int flags, int) : surface(0) {
+ width = w;
+ height = h;
+
+ SDL_ShowCursor(SDL_DISABLE);
+}
+
+void mogltk::base::setsurface(SDL_Surface * _surface) throw (GeneralException) {
+ if (surface)
+ throw GeneralException("Can't set video surface twice");
+ surface = _surface;
+}
+
+SDL_Surface * mogltk::base::getsurface() {
+ return surface;
+}
+
+void mogltk::base::Enter2DMode() {
+}
+
+void mogltk::base::Leave2DMode() {
+}
+
+bool mogltk::base::is2D() {
+ return true;
+}
+
+void mogltk::base::changeviewport(int x, int y, unsigned int w, unsigned int h) {
+ SDL_Rect r;
+
+ if ((w == 0) && (h == 0)) {
+ w = GetWidth() - x;
+ h = GetHeight() - y;
+ }
+
+ r.x = x;
+ r.y = y;
+ r.w = w;
+ r.h = h;
+
+ SDL_SetClipRect(surface, &r);
+}
+
+void mogltk::base::ToggleFullscreen() {
+ int newflags = surface->flags;
+
+ if (surface->flags & SDL_FULLSCREEN)
+ newflags &= ~SDL_FULLSCREEN;
+ else
+ newflags |= SDL_FULLSCREEN;
+
+ texture::Taintall();
+
+ surface = SDL_SetVideoMode(surface->w, surface->h, surface->format->BitsPerPixel,
+ SDL_HWSURFACE | newflags);
+}
+
+inline static unsigned int nextpower(unsigned int n) {
+ unsigned int i;
+
+ if (!n)
+ return n;
+
+ if (ISPOT(n))
+ return n;
+
+ for (i = 31; i >= 0; i--) {
+ if ((n >> i) & 1) {
+ return 1 << (i + 1);
+ }
+ }
+}
+
+mogltk::texture * mogltk::base::GrabTexture() {
+ int w = nextpower(GetWidth());
+ int h = nextpower(GetHeight());
+ texture * r = new texture(w, h);
+
+ SDL_BlitSurface(getsurface(), NULL, r->GetSurface(), NULL);
+
+ return r;
+}
+
+SDL_Surface * mogltk::base::GrabSurface() {
+ SDL_Surface * r = SDL_CreateRGBSurface(SDL_SWSURFACE, GetWidth(), GetHeight(), 24,
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ 0xff000000,
+ 0x00ff0000,
+ 0x0000ff00,
+ 0x00000000
+#else
+ 0x000000ff,
+ 0x0000ff00,
+ 0x00ff0000,
+ 0x00000000
+#endif
+ );
+
+ SDL_BlitSurface(getsurface(), NULL, r, NULL);
+
+ return r;
+}
diff --git a/lib/engine.cc b/lib/engine.cc
index e0e1efd..d9e479f 100644
--- a/lib/engine.cc
+++ b/lib/engine.cc
@@ -1,409 +1,409 @@
-/*
- * mogltk
- * Copyright (C) 1999-2004 Nicolas "Pixel" Noble
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* $Id: engine.cc,v 1.27 2004-11-27 21:44:52 pixel Exp $ */
-
-#include <SDL.h>
-#include <Input.h>
-#include "engine.h"
-#include "glfont.h"
-#include "glsprite.h"
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "gettext.h"
-
-bool mogltk::engine::inited = false, mogltk::engine::postsetuped = false;
-bool mogltk::engine::appactive = false, mogltk::engine::cursorvisible = false, mogltk::engine::quitrequest = false;
-int mogltk::engine::mx, mogltk::engine::my, mogltk::engine::mz = 0, mogltk::engine::mbuttons;
-int mogltk::engine::frames, mogltk::engine::locked = 0;
-double mogltk::engine::curfps = -1;
-Uint32 mogltk::engine::curticks;
-mogltk::widget * mogltk::engine::root = 0;
-
-mogltk::glbase * mogltk::engine::glbase_o = 0;
-mogltk::base * mogltk::engine::base_o = 0;
-
-mogltk::engine::keyevent * mogltk::engine::keyevent_h = 0;
-mogltk::engine::mouseevent * mogltk::engine::mouseevent_h = 0;
-
-#define UPDATERATE 1000
-
-mogltk::engine::keyevent::keyevent() {
- new_handler = 0;
- if ((old_handler = getkeyevent()))
- old_handler->new_handler = this;
- setkeyevent(this);
-}
-
-mogltk::engine::keyevent::~keyevent() {
- if (new_handler)
- new_handler->old_handler = old_handler;
- if (old_handler)
- old_handler->new_handler = new_handler;
-
- if (getkeyevent() == this)
- setkeyevent(old_handler);
-}
-
-void mogltk::engine::keyevent::up(SDL_keysym) {
- printm(M_INFO, "Generic keyevent::up called\n");
-}
-
-void mogltk::engine::keyevent::down(SDL_keysym) {
- printm(M_INFO, "Generic keyevent::down called\n");
-}
-
-class keyhandler_t : public mogltk::engine::keyevent {
- virtual void down(SDL_keysym keysym) {
- if (keysym.sym == SDLK_ESCAPE)
- mogltk::engine::quit();
- else if ((keysym.sym == SDLK_RETURN) && (keysym.mod & KMOD_ALT))
- mogltk::engine::base_o->ToggleFullscreen();
- else if (old_handler)
- old_handler->down(keysym);
- }
- virtual void up(SDL_keysym keysym) {
- if (old_handler)
- old_handler->up(keysym);
- }
-} basic_keyhandler;
-
-mogltk::engine::mouseevent::mouseevent() {
- new_handler = 0;
- if ((old_handler = getmouseevent()))
- old_handler->new_handler = this;
- setmouseevent(this);
-}
-
-mogltk::engine::mouseevent::~mouseevent() {
- if (new_handler)
- new_handler->old_handler = old_handler;
- if (old_handler)
- old_handler->new_handler = new_handler;
-
- if (getmouseevent() == this)
- setmouseevent(old_handler);
-}
-
-void mogltk::engine::mouseevent::move(SDL_MouseMotionEvent) {
- printm(M_INFO, "Generic mouseevent::move called\n");
-}
-
-void mogltk::engine::mouseevent::action(SDL_MouseButtonEvent) {
- printm(M_INFO, "Generic mouseevent::action called\n");
-}
-
-int mogltk::engine::setup() throw(GeneralException) {
- if (inited) {
- printm(M_WARNING, FUNCNAME + _(" called twice, ignoring second call.\n"));
- return -1;
- }
- if (SDL_Init(0) < 0) {
- throw GeneralException(FUNCNAME + _(": Unable to start SDL base system"));
- }
- atexit(SDL_Quit);
-
- inited = true;
-
- return 0;
-}
-
-int mogltk::engine::postsetup() throw(GeneralException) {
- if (postsetuped) {
- printm(M_WARNING, FUNCNAME + _(" called twice, ignoring second call.\n"));
- return -1;
- }
-
- SDL_EnableUNICODE(1);
- curticks = SDL_GetTicks();
-
- postsetuped = true;
-
- if (glbase_o) {
- mogltk::SystemFont = new mogltk::glfont(&Input("font.bin"));
- mogltk::FixedFont = new mogltk::glfont(&Input("fixed-font.bin"));
- Sprite::Cursor = new mogltk::glSprite(&Input("cursor.rgba"), 25, 25);
- } else {
- mogltk::SystemFont = new mogltk::font(&Input("font.bin"));
- mogltk::FixedFont = new mogltk::font(&Input("fixed-font.bin"));
- Sprite::Cursor = new mogltk::Sprite(&Input("cursor.rgba"), 25, 25);
- }
-
- return 0;
-}
-
-int mogltk::engine::GetInited() {
- return inited;
-}
-
-class embedRWops : public Base {
- public:
- embedRWops(Handle *);
- int seek(int, int);
- int read(void *, int, int);
- int write(const void *, int, int);
- private:
- Handle * h;
-};
-
-embedRWops::embedRWops(Handle * ah) : h(ah) {}
-
-int embedRWops::seek(int offset, int whence) {
- return h->seek(offset, whence);
-}
-
-int embedRWops::read(void * ptr, int size, int num) {
- return h->read(ptr, size * num);
-}
-
-int embedRWops::write(const void * ptr, int size, int num) {
- return h->write(ptr, size * num);
-}
-
-static int embedRWseek(SDL_RWops * context, int offset, int whence) {
- if (context->hidden.unknown.data1)
- return ((embedRWops *)(context->hidden.unknown.data1))->seek(offset, whence);
- return -1;
-}
-
-static int embedRWread(SDL_RWops * context, void * ptr, int size, int num) {
- if (context->hidden.unknown.data1)
- return ((embedRWops *)(context->hidden.unknown.data1))->read(ptr, size, num);
- return -1;
-}
-
-static int embedRWwrite(SDL_RWops * context, const void * ptr, int size, int num) {
- if (context->hidden.unknown.data1)
- return ((embedRWops *)(context->hidden.unknown.data1))->write(ptr, size, num);
- return -1;
-}
-
-static int embedRWclose(SDL_RWops * context) {
- if (context->hidden.unknown.data1) {
- delete ((embedRWops *)(context->hidden.unknown.data1));
- context->hidden.unknown.data1 = 0;
- return 0;
- }
- return -1;
-}
-
-SDL_RWops * mogltk::engine::RWFromHandle(Handle * h) throw (GeneralException) {
- SDL_RWops * r = 0;
- if (h) {
- if (!(r = SDL_AllocRW()))
- throw GeneralException(_("Couldn't allocate memory for SDL_RWops"));
- r->hidden.unknown.data1 = (void *) new embedRWops(h);
- r->seek = embedRWseek;
- r->read = embedRWread;
- r->write = embedRWwrite;
- r->close = embedRWclose;
- }
- return r;
-}
-
-void mogltk::engine::pollevents() throw (GeneralException) {
- SDL_Event event;
- bool hastoreturn = appactive;
-
- if (!postsetuped)
- postsetup();
-
- if (appactive) {
- Uint32 ticks = SDL_GetTicks();
- frames++;
- if (ticks - curticks > UPDATERATE) {
- curfps = (double) frames * 1000 / (ticks - curticks);
- frames = 0;
- curticks = ticks;
- }
- } else {
- curfps = -1;
- }
-
- while(true) {
- if (hastoreturn || quitrequest)
- if (!SDL_PollEvent(NULL)) {
- updatemouse();
- return;
- }
- if (!SDL_WaitEvent(&event)) {
- throw GeneralException("Error polling for SDL Event");
- }
- switch(event.type) {
- case SDL_ACTIVEEVENT:
- switch (event.active.state) {
- case SDL_APPMOUSEFOCUS:
- printm(M_INFO, String("Application ") + (event.active.gain ? "gained" : "loosed") + " mouse focus\n");
- if (cursorvisible)
- hastoreturn = true;
- break;
- case SDL_APPINPUTFOCUS:
- printm(M_INFO, String("Application ") + (event.active.gain ? "gained" : "loosed") + " input focus\n");
- if (cursorvisible)
- hastoreturn = true;
- break;
- case SDL_APPACTIVE:
- printm(M_INFO, String("Application was ") + (event.active.gain ? "restored" : "iconified"));
- if (cursorvisible)
- hastoreturn = true;
- break;
- }
- break;
- case SDL_KEYDOWN:
- case SDL_KEYUP:
- printm(M_INFO, String("Key ") + event.key.keysym.scancode + " on keyboard " + event.key.which + (event.key.state == SDL_PRESSED ? " pressed" : " released") + "\n");
- printm(M_INFO, "SDL keysym: %i - Unicode: %04x = `%c`- modifiers: %04x\n", event.key.keysym.sym, event.key.keysym.unicode, event.key.keysym.unicode, event.key.keysym.mod);
- if (keyevent_h) {
- if (event.key.state == SDL_PRESSED) {
- keyevent_h->down(event.key.keysym);
- } else {
- keyevent_h->up(event.key.keysym);
- }
- }
- break;
- case SDL_MOUSEMOTION:
- printm(M_INFO, "Mouse slept over the screen - (%i, %i)\n", event.motion.x, event.motion.y);
- if (locked) {
- if (!((event.motion.x == mx) && (event.motion.y == my))) {
- SDL_WarpMouse(mx, my);
- }
- }
- if (cursorvisible)
- hastoreturn = true;
- if (mouseevent_h) {
- mouseevent_h->move(event.motion);
- }
- break;
- case SDL_MOUSEBUTTONDOWN:
- case SDL_MOUSEBUTTONUP:
- printm(M_INFO, String().set("Mouse button %02x ", event.button.button) + String((event.button.state == SDL_PRESSED ? "pressed" : "released")) + " at (" + event.button.x + ", " + event.button.y + ")\n");
- if (event.button.state == SDL_PRESSED) {
- if (event.button.button == SDL_BUTTON_WHEELUP) {
- mz--;
- }
- if (event.button.button == SDL_BUTTON_WHEELDOWN) {
- mz++;
- }
- }
- if (mouseevent_h) {
- mouseevent_h->action(event.button);
- }
- break;
- case SDL_QUIT:
- printm(M_INFO, "Quit requested\n");
- hastoreturn = quitrequest = true;
- break;
- case SDL_VIDEOEXPOSE:
- printm(M_INFO, "Needs to redraw\n");
- hastoreturn = true;
- break;
- default:
- printm(M_INFO, "Unknow event: %i\n", event.type);
- break;
- }
- }
-}
-
-void mogltk::engine::setappactive(bool p) {
- appactive = p;
-}
-
-bool mogltk::engine::getappactive() {
- return appactive;
-}
-
-void mogltk::engine::setcursorvisible(bool p) {
- cursorvisible = p;
-}
-
-bool mogltk::engine::getcursorvisible() {
- return cursorvisible;
-}
-
-void mogltk::engine::quit() {
- quitrequest = true;
-}
-
-bool mogltk::engine::quitrequested() {
- return quitrequest;
-}
-
-void mogltk::engine::updatemouse() {
- mbuttons = SDL_GetMouseState(&mx, &my);
-}
-
-int mogltk::engine::mouseX() {
- return mx;
-}
-
-int mogltk::engine::mouseY() {
- return my;
-}
-
-int mogltk::engine::mouseZ() {
- return mz;
-}
-
-void mogltk::engine::setmouseX(int _mx) {
- mx = _mx;
- SDL_WarpMouse(mx, my);
-}
-
-void mogltk::engine::setmouseY(int _my) {
- my = _my;
- SDL_WarpMouse(mx, my);
-}
-
-void mogltk::engine::setmouseZ(int _mz) {
- mz = _mz;
-}
-
-int mogltk::engine::mousebuttons() {
- return mbuttons;
-}
-
-double mogltk::engine::FPS() {
- return curfps;
-}
-
-void mogltk::engine::lockmouse() {
- locked = 1;
-}
-
-void mogltk::engine::unlockmouse() {
- locked = 0;
-}
-
-void mogltk::engine::setkeyevent(keyevent * k) {
- keyevent_h = k;
-}
-
-void mogltk::engine::setmouseevent(mouseevent * m) {
- mouseevent_h = m;
-}
-
-mogltk::engine::keyevent * mogltk::engine::getkeyevent() {
- return keyevent_h;
-}
-
-mogltk::engine::mouseevent * mogltk::engine::getmouseevent() {
- return mouseevent_h;
-}
+/*
+ * mogltk
+ * Copyright (C) 1999-2004 Nicolas "Pixel" Noble
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: engine.cc,v 1.28 2004-11-27 21:48:03 pixel Exp $ */
+
+#include <SDL.h>
+#include <Input.h>
+#include "engine.h"
+#include "glfont.h"
+#include "glsprite.h"
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "gettext.h"
+
+bool mogltk::engine::inited = false, mogltk::engine::postsetuped = false;
+bool mogltk::engine::appactive = false, mogltk::engine::cursorvisible = false, mogltk::engine::quitrequest = false;
+int mogltk::engine::mx, mogltk::engine::my, mogltk::engine::mz = 0, mogltk::engine::mbuttons;
+int mogltk::engine::frames, mogltk::engine::locked = 0;
+double mogltk::engine::curfps = -1;
+Uint32 mogltk::engine::curticks;
+mogltk::widget * mogltk::engine::root = 0;
+
+mogltk::glbase * mogltk::engine::glbase_o = 0;
+mogltk::base * mogltk::engine::base_o = 0;
+
+mogltk::engine::keyevent * mogltk::engine::keyevent_h = 0;
+mogltk::engine::mouseevent * mogltk::engine::mouseevent_h = 0;
+
+#define UPDATERATE 1000
+
+mogltk::engine::keyevent::keyevent() {
+ new_handler = 0;
+ if ((old_handler = getkeyevent()))
+ old_handler->new_handler = this;
+ setkeyevent(this);
+}
+
+mogltk::engine::keyevent::~keyevent() {
+ if (new_handler)
+ new_handler->old_handler = old_handler;
+ if (old_handler)
+ old_handler->new_handler = new_handler;
+
+ if (getkeyevent() == this)
+ setkeyevent(old_handler);
+}
+
+void mogltk::engine::keyevent::up(SDL_keysym) {
+ printm(M_INFO, "Generic keyevent::up called\n");
+}
+
+void mogltk::engine::keyevent::down(SDL_keysym) {
+ printm(M_INFO, "Generic keyevent::down called\n");
+}
+
+class keyhandler_t : public mogltk::engine::keyevent {
+ virtual void down(SDL_keysym keysym) {
+ if (keysym.sym == SDLK_ESCAPE)
+ mogltk::engine::quit();
+ else if ((keysym.sym == SDLK_RETURN) && (keysym.mod & KMOD_ALT))
+ mogltk::engine::base_o->ToggleFullscreen();
+ else if (old_handler)
+ old_handler->down(keysym);
+ }
+ virtual void up(SDL_keysym keysym) {
+ if (old_handler)
+ old_handler->up(keysym);
+ }
+} basic_keyhandler;
+
+mogltk::engine::mouseevent::mouseevent() {
+ new_handler = 0;
+ if ((old_handler = getmouseevent()))
+ old_handler->new_handler = this;
+ setmouseevent(this);
+}
+
+mogltk::engine::mouseevent::~mouseevent() {
+ if (new_handler)
+ new_handler->old_handler = old_handler;
+ if (old_handler)
+ old_handler->new_handler = new_handler;
+
+ if (getmouseevent() == this)
+ setmouseevent(old_handler);
+}
+
+void mogltk::engine::mouseevent::move(SDL_MouseMotionEvent) {
+ printm(M_INFO, "Generic mouseevent::move called\n");
+}
+
+void mogltk::engine::mouseevent::action(SDL_MouseButtonEvent) {
+ printm(M_INFO, "Generic mouseevent::action called\n");
+}
+
+int mogltk::engine::setup() throw(GeneralException) {
+ if (inited) {
+ printm(M_WARNING, FUNCNAME + _(" called twice, ignoring second call.\n"));
+ return -1;
+ }
+ if (SDL_Init(0) < 0) {
+ throw GeneralException(FUNCNAME + _(": Unable to start SDL base system"));
+ }
+ atexit(SDL_Quit);
+
+ inited = true;
+
+ return 0;
+}
+
+int mogltk::engine::postsetup() throw(GeneralException) {
+ if (postsetuped) {
+ printm(M_WARNING, FUNCNAME + _(" called twice, ignoring second call.\n"));
+ return -1;
+ }
+
+ SDL_EnableUNICODE(1);
+ curticks = SDL_GetTicks();
+
+ postsetuped = true;
+
+ if (glbase_o) {
+ mogltk::SystemFont = new mogltk::glfont(&Input("font.bin"));
+ mogltk::FixedFont = new mogltk::glfont(&Input("fixed-font.bin"));
+ Sprite::Cursor = new mogltk::glSprite(&Input("cursor.rgba"), 25, 25);
+ } else {
+ mogltk::SystemFont = new mogltk::font(&Input("font.bin"));
+ mogltk::FixedFont = new mogltk::font(&Input("fixed-font.bin"));
+ Sprite::Cursor = new mogltk::Sprite(&Input("cursor.rgba"), 25, 25);
+ }
+
+ return 0;
+}
+
+int mogltk::engine::GetInited() {
+ return inited;
+}
+
+class embedRWops : public Base {
+ public:
+ embedRWops(Handle *);
+ int seek(int, int);
+ int read(void *, int, int);
+ int write(const void *, int, int);
+ private:
+ Handle * h;
+};
+
+embedRWops::embedRWops(Handle * ah) : h(ah) {}
+
+int embedRWops::seek(int offset, int whence) {
+ return h->seek(offset, whence);
+}
+
+int embedRWops::read(void * ptr, int size, int num) {
+ return h->read(ptr, size * num);
+}
+
+int embedRWops::write(const void * ptr, int size, int num) {
+ return h->write(ptr, size * num);
+}
+
+static int embedRWseek(SDL_RWops * context, int offset, int whence) {
+ if (context->hidden.unknown.data1)
+ return ((embedRWops *)(context->hidden.unknown.data1))->seek(offset, whence);
+ return -1;
+}
+
+static int embedRWread(SDL_RWops * context, void * ptr, int size, int num) {
+ if (context->hidden.unknown.data1)
+ return ((embedRWops *)(context->hidden.unknown.data1))->read(ptr, size, num);
+ return -1;
+}
+
+static int embedRWwrite(SDL_RWops * context, const void * ptr, int size, int num) {
+ if (context->hidden.unknown.data1)
+ return ((embedRWops *)(context->hidden.unknown.data1))->write(ptr, size, num);
+ return -1;
+}
+
+static int embedRWclose(SDL_RWops * context) {
+ if (context->hidden.unknown.data1) {
+ delete ((embedRWops *)(context->hidden.unknown.data1));
+ context->hidden.unknown.data1 = 0;
+ return 0;
+ }
+ return -1;
+}
+
+SDL_RWops * mogltk::engine::RWFromHandle(Handle * h) throw (GeneralException) {
+ SDL_RWops * r = 0;
+ if (h) {
+ if (!(r = SDL_AllocRW()))
+ throw GeneralException(_("Couldn't allocate memory for SDL_RWops"));
+ r->hidden.unknown.data1 = (void *) new embedRWops(h);
+ r->seek = embedRWseek;
+ r->read = embedRWread;
+ r->write = embedRWwrite;
+ r->close = embedRWclose;
+ }
+ return r;
+}
+
+void mogltk::engine::pollevents() throw (GeneralException) {
+ SDL_Event event;
+ bool hastoreturn = appactive;
+
+ if (!postsetuped)
+ postsetup();
+
+ if (appactive) {
+ Uint32 ticks = SDL_GetTicks();
+ frames++;
+ if (ticks - curticks > UPDATERATE) {
+ curfps = (double) frames * 1000 / (ticks - curticks);
+ frames = 0;
+ curticks = ticks;
+ }
+ } else {
+ curfps = -1;
+ }
+
+ while(true) {
+ if (hastoreturn || quitrequest)
+ if (!SDL_PollEvent(NULL)) {
+ updatemouse();
+ return;
+ }
+ if (!SDL_WaitEvent(&event)) {
+ throw GeneralException("Error polling for SDL Event");
+ }
+ switch(event.type) {
+ case SDL_ACTIVEEVENT:
+ switch (event.active.state) {
+ case SDL_APPMOUSEFOCUS:
+ printm(M_INFO, String("Application ") + (event.active.gain ? "gained" : "loosed") + " mouse focus\n");
+ if (cursorvisible)
+ hastoreturn = true;
+ break;
+ case SDL_APPINPUTFOCUS:
+ printm(M_INFO, String("Application ") + (event.active.gain ? "gained" : "loosed") + " input focus\n");
+ if (cursorvisible)
+ hastoreturn = true;
+ break;
+ case SDL_APPACTIVE:
+ printm(M_INFO, String("Application was ") + (event.active.gain ? "restored" : "iconified"));
+ if (cursorvisible)
+ hastoreturn = true;
+ break;
+ }
+ break;
+ case SDL_KEYDOWN:
+ case SDL_KEYUP:
+ printm(M_INFO, String("Key ") + event.key.keysym.scancode + " on keyboard " + event.key.which + (event.key.state == SDL_PRESSED ? " pressed" : " released") + "\n");
+ printm(M_INFO, "SDL keysym: %i - Unicode: %04x = `%c`- modifiers: %04x\n", event.key.keysym.sym, event.key.keysym.unicode, event.key.keysym.unicode, event.key.keysym.mod);
+ if (keyevent_h) {
+ if (event.key.state == SDL_PRESSED) {
+ keyevent_h->down(event.key.keysym);
+ } else {
+ keyevent_h->up(event.key.keysym);
+ }
+ }
+ break;
+ case SDL_MOUSEMOTION:
+ printm(M_INFO, "Mouse slept over the screen - (%i, %i)\n", event.motion.x, event.motion.y);
+ if (locked) {
+ if (!((event.motion.x == mx) && (event.motion.y == my))) {
+ SDL_WarpMouse(mx, my);
+ }
+ }
+ if (cursorvisible)
+ hastoreturn = true;
+ if (mouseevent_h) {
+ mouseevent_h->move(event.motion);
+ }
+ break;
+ case SDL_MOUSEBUTTONDOWN:
+ case SDL_MOUSEBUTTONUP:
+ printm(M_INFO, String().set("Mouse button %02x ", event.button.button) + String((event.button.state == SDL_PRESSED ? "pressed" : "released")) + " at (" + event.button.x + ", " + event.button.y + ")\n");
+ if (event.button.state == SDL_PRESSED) {
+ if (event.button.button == SDL_BUTTON_WHEELUP) {
+ mz--;
+ }
+ if (event.button.button == SDL_BUTTON_WHEELDOWN) {
+ mz++;
+ }
+ }
+ if (mouseevent_h) {
+ mouseevent_h->action(event.button);
+ }
+ break;
+ case SDL_QUIT:
+ printm(M_INFO, "Quit requested\n");
+ hastoreturn = quitrequest = true;
+ break;
+ case SDL_VIDEOEXPOSE:
+ printm(M_INFO, "Needs to redraw\n");
+ hastoreturn = true;
+ break;
+ default:
+ printm(M_INFO, "Unknow event: %i\n", event.type);
+ break;
+ }
+ }
+}
+
+void mogltk::engine::setappactive(bool p) {
+ appactive = p;
+}
+
+bool mogltk::engine::getappactive() {
+ return appactive;
+}
+
+void mogltk::engine::setcursorvisible(bool p) {
+ cursorvisible = p;
+}
+
+bool mogltk::engine::getcursorvisible() {
+ return cursorvisible;
+}
+
+void mogltk::engine::quit() {
+ quitrequest = true;
+}
+
+bool mogltk::engine::quitrequested() {
+ return quitrequest;
+}
+
+void mogltk::engine::updatemouse() {
+ mbuttons = SDL_GetMouseState(&mx, &my);
+}
+
+int mogltk::engine::mouseX() {
+ return mx;
+}
+
+int mogltk::engine::mouseY() {
+ return my;
+}
+
+int mogltk::engine::mouseZ() {
+ return mz;
+}
+
+void mogltk::engine::setmouseX(int _mx) {
+ mx = _mx;
+ SDL_WarpMouse(mx, my);
+}
+
+void mogltk::engine::setmouseY(int _my) {
+ my = _my;
+ SDL_WarpMouse(mx, my);
+}
+
+void mogltk::engine::setmouseZ(int _mz) {
+ mz = _mz;
+}
+
+int mogltk::engine::mousebuttons() {
+ return mbuttons;
+}
+
+double mogltk::engine::FPS() {
+ return curfps;
+}
+
+void mogltk::engine::lockmouse() {
+ locked = 1;
+}
+
+void mogltk::engine::unlockmouse() {
+ locked = 0;
+}
+
+void mogltk::engine::setkeyevent(keyevent * k) {
+ keyevent_h = k;
+}
+
+void mogltk::engine::setmouseevent(mouseevent * m) {
+ mouseevent_h = m;
+}
+
+mogltk::engine::keyevent * mogltk::engine::getkeyevent() {
+ return keyevent_h;
+}
+
+mogltk::engine::mouseevent * mogltk::engine::getmouseevent() {
+ return mouseevent_h;
+}
diff --git a/lib/font.cc b/lib/font.cc
index 2a17d20..07ade78 100644
--- a/lib/font.cc
+++ b/lib/font.cc
@@ -1,705 +1,705 @@
-/*
- * mogltk
- * Copyright (C) 1999-2004 Nicolas "Pixel" Noble
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* $Id: font.cc,v 1.15 2004-11-27 21:44:53 pixel Exp $ */
-
-#include <stdarg.h>
-#include <SDL.h>
-#include <Input.h>
-#include "base.h"
-#include "font.h"
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "engine.h"
-
-Uint8 prescale2[4] = { 0, 85, 170, 255 }, prescale3[8] = { 0, 36, 72, 109, 145, 182, 218, 255 };
-
-#define STRBUFSIZ 512
-
-/*
-
-font file format
-================
-
-off|siz|description
----+---+-------------------------------
- 0 | 2 | Number of entries = nbentries
- 2 | 1 | Flags
- 3 | 1 | maxX (maximum width)
- 4 | 1 | maxY (maximum height)
- 5 | 1 | base (bottom line from top)
- 6 | 1 | inter (size of the interline)
- 7 | X | char entries
-7+X| Y | char map
-
-X = (maxX * maxY + 1) * nbentries
-Y = nbentries * 4
-
-
-Flags:
-=====
-
-0000000R
-
-R = RGBA (=1) or Alpha (=0)
-
-RGBA in 1232 format:
-ABBGGGRR
-
-
-Each entries:
-============
-
-off|siz|description
----+---+-------------------------------
- 0 | 1 | True size of the entry
- 1 | Z | Datas
-
-Z = maxX * maxY
-Datas are stored in order X first, then Y.
-
-Char map:
-========
-
-nbentries entries, each entry = 4 bytes = 2 uint16
-
-off|siz|description
----+---+-------------------------------
- 0 | 2 | Unicode (?)
- 2 | 2 | Corresponding char entry
-
-I'm not sure about my word 'Unicode'. I write this only to say it's an attempt
-to make the fonts "internationals". If the "unicode" is < 255, then it should
-match only one byte in the string. Otherwise, it should match two bytes.
-
-
-Variables comments
-==================
-
-nbcU = number of chars on X by texture
-nbcV = number of chars on Y by texture
-nbcT = number of char by texture
-nbT = number of textures
-
-*/
-
-mogltk::ColorP colorcached[16] = {
- DOS_BLACK,
- DOS_BLUE,
- DOS_GREEN,
- DOS_CYAN,
- DOS_RED,
- DOS_MAGENTA,
- DOS_BRAWN,
- DOS_WHITE,
- DOS_GRAY,
- DOS_HIGH_BLUE,
- DOS_HIGH_GREEN,
- DOS_HIGH_CYAN,
- DOS_HIGH_RED,
- DOS_HIGH_MAGENTA,
- DOS_YELLOW,
- DOS_HIGH_WHITE
-};
-
-mogltk::font::font(Handle * ffont) : textcolor(255, 255, 255, 255), shadow(0), wspace(0) {
- int i, j;
-
- nbentries = ffont->readU16();
- flags = ffont->readU8();
- maxX = ffont->readU8();
- maxY = ffont->readU8();
- base = ffont->readU8();
- inter = ffont->readU8();
-
- nbcU = 256 / maxX;
- nbcV = 256 / maxY;
-
- nbcT = nbcU * nbcV;
-
- nbT = nbentries / nbcT;
-
- if (nbentries % nbcT) {
- nbT++;
- }
-
- printm(M_INFO, "Creating font texture: %i entries, flags = 0x%02x, maxX = %i, maxY = %i\n", nbentries, flags, maxX, maxY);
- printm(M_INFO, "Which makes %i texture(s), with %i char by texture, %i on X, and %i on Y\n", nbT, nbcT, nbcU, nbcV);
-
- fonttex = (texture **) malloc(nbT * sizeof(texture *));
- for (i = 0; i < 16; i++) {
- fontcache[i] = (texture **) malloc(nbT * sizeof(texture *));
- }
-
- for (i = 0; i < nbT; i++) {
- fonttex[i] = alloctexture();
- for (j = 0; j < 15; j++) {
- fontcache[j][i] = 0;
- }
- fontcache[15][i] = fonttex[i];
- }
-
- sizes = (Uint8 *) malloc(nbentries * sizeof(Uint8));
-
- Uint8 * curtex = (Uint8 *) fonttex[0]->GetSurface()->pixels;
- Uint32 curU = 0, curV = 0, curT = 0;
- for (i = 0; i < nbentries; i++) {
- sizes[i] = ffont->readU8();
- for (int v = 0; v < maxY; v++) {
- for (int u = 0; u < maxX; u++) {
- Uint8 f;
- f = ffont->readU8();
- if (flags & 1) {
- Uint8 r, g, b, a;
- r = f & 3;
- g = (f >> 2) & 7;
- b = (f >> 5) & 3;
- a = (f >> 7) & 1;
- curtex[(curU + u + (curV + v) * 256) * 4 + 0] = prescale2[r];
- curtex[(curU + u + (curV + v) * 256) * 4 + 1] = prescale3[g];
- curtex[(curU + u + (curV + v) * 256) * 4 + 2] = prescale2[b];
- curtex[(curU + u + (curV + v) * 256) * 4 + 3] = a ? 255 : 0;
- } else {
- curtex[(curU + u + (curV + v) * 256) * 4 + 0] = 255;
- curtex[(curU + u + (curV + v) * 256) * 4 + 1] = 255;
- curtex[(curU + u + (curV + v) * 256) * 4 + 2] = 255;
- curtex[(curU + u + (curV + v) * 256) * 4 + 3] = f;
- }
- }
- }
- if (((curU += maxX) + maxX) > 256) {
- curU = 0;
- if (((curV += maxY) + maxY) > 256) {
- curV = 0;
- if ((curT + 1) != nbT)
- curtex = (Uint8 *) fonttex[++curT]->GetSurface()->pixels;
- }
- }
- }
-
- corresp = (Uint16 *) malloc(nbentries * 2 * sizeof(Uint16));
-
- for (i = 0; i < 2 * nbentries; i++) {
- corresp[i] = ffont->readU16();
- }
-}
-
-mogltk::font::~font() {
- int i, j;
- for (i = 0; i < nbT; i++)
- for (j = 0; j < 16; j++)
- if (fontcache[j][i])
- delete fontcache[j][i];
-
- for (i = 0; i < 16; i++)
- free((void *&) fontcache[i]);
-
- free((void *&) fonttex);
- free(sizes);
-}
-
-void mogltk::font::drawentry(Uint16 entry, int x, int y, ColorP c) {
- bool locked = false;
- int trueentry, cx, cy, px, py;
- SDL_Rect src, dst;
-
- if (SDL_MUSTLOCK(mogltk::engine::base_o->getsurface())) {
- locked = true;
- SDL_LockSurface(mogltk::engine::base_o->getsurface());
- }
-
- if (shadow) {
- int os = shadow;
- shadow = 0;
-
- drawentry(entry, x + os, y + os, BLACK);
-
- shadow = os;
- }
-
- checknbind(entry / nbcT, c);
-
- y -= base;
-
- trueentry = entry % nbcT;
- cx = trueentry % nbcU;
- cy = trueentry / nbcU;
- px = cx * maxX;
- py = cy * maxY;
-
- src.x = px; src.y = py; src.w = maxX; src.h = maxY;
- dst.x = x; dst.y = y; dst.w = maxX; dst.h = maxY;
-
- SDL_BlitSurface(fonttex[entry / nbcT]->GetSurface(), &src, mogltk::engine::base_o->getsurface(), &dst);
-
- if (locked)
- SDL_UnlockSurface(mogltk::engine::base_o->getsurface());
-}
-
-void mogltk::font::drawtotex(texture * t, Uint16 entry, int x, int y, ColorP c) {
- bool locked = false;
- int trueentry, cx, cy, px, py;
- SDL_Rect src, dst;
-
- if (SDL_MUSTLOCK(t->GetSurface())) {
- locked = true;
- SDL_LockSurface(t->GetSurface());
- }
-
- if (shadow) {
- int os = shadow;
- shadow = 0;
-
- drawtotex(t, entry, x + os, y + os, BLACK);
-
- shadow = os;
- }
-
- checknbind(entry / nbcT, c);
-
- y -= base;
-
- trueentry = entry % nbcT;
- cx = trueentry % nbcU;
- cy = trueentry / nbcU;
- px = cx * maxX;
- py = cy * maxY;
-
- src.x = px; src.y = py; src.w = maxX; src.h = maxY;
- dst.x = x; dst.y = y; dst.w = maxX; dst.h = maxY;
-
- SDL_BlitSurface(fonttex[entry / nbcT]->GetSurface(), &src, t->GetSurface(), &dst);
-
- if (locked)
- SDL_UnlockSurface(t->GetSurface());
-}
-
-void mogltk::font::putcursor(int x, int y) {
- cx = ox = x;
- cy = y;
-}
-
-void mogltk::font::putentry(Uint16 entry, ColorP c) {
- drawentry(entry, cx, cy, c);
- cx += sizes[entry] + wspace;
-}
-
-void mogltk::font::putentryontex(texture * t, Uint16 entry, ColorP c) {
- drawtotex(t, entry, cx, cy, c);
- cx += sizes[entry] + wspace;
-}
-
-void mogltk::font::drawchar(char ch, ColorP c) {
- Uint16 * p;
- int i;
-
- for (i = 0, p = corresp; i < nbentries; i++, p++) {
- if (*(p++) == ch) {
- putentry(*p, c);
- return;
- }
- }
-}
-
-void mogltk::font::drawcharontex(texture * t, char ch, ColorP c) {
- Uint16 * p;
- int i;
-
- for (i = 0, p = corresp; i < nbentries; i++, p++) {
- if (*(p++) == ch) {
- putentryontex(t, *p, c);
- return;
- }
- }
-}
-
-int mogltk::font::findchar(char ch) const {
- Uint16 * p;
- int i;
-
- for (i = 0, p = corresp; i < nbentries; i++, p++) {
- if (*(p++) == ch) {
- return *p;
- }
- }
-
- return -1;
-}
-
-void mogltk::font::newline(void) {
- cx = ox;
- cy += inter;
-}
-
-int mogltk::font::printf(const ugly_string & m, va_list ap) {
- char * p;
- static char buffer[STRBUFSIZ + 1];
- int r;
-
-#ifdef HAVE_VSNPRINTF
- r = vsnprintf(buffer, STRBUFSIZ, m.p, ap);
-#else
- r = vsprintf(buffer, m.p, ap);
-#endif
-
- for (p = buffer; *p; p++) {
- if (*p == '\n') {
- newline();
- } else {
- drawchar(*p, textcolor);
- }
- }
-
- return r;
-}
-
-int mogltk::font::printf(const ugly_string & m, ...) {
- va_list ap;
- int r;
-
- va_start(ap, m);
- r = printf(m, ap);
- va_end(ap);
-
- return r;
-}
-
-int mogltk::font::printf(const char * p, ...) {
- ugly_string m;
- va_list ap;
- int r;
-
- m.p = p;
-
- va_start(ap, p);
- r = printf(m, ap);
- va_end(ap);
-
- return r;
-}
-
-mogltk::rect mogltk::font::size(const ugly_string & m, va_list ap) {
- char * p;
- static char buffer[STRBUFSIZ + 1];
- rect r;
- int mw, w;
-
- r.x = cx;
- r.y = cy;
- r.h = inter;
- r.w = 0;
- mw = 0;
- w = 0;
-
-#ifdef HAVE_VSNPRINTF
- vsnprintf(buffer, STRBUFSIZ, m.p, ap);
-#else
- vsprintf(buffer, m.p, ap);
-#endif
-
- for (p = buffer; *p; p++) {
- if (*p == '\n') {
- if (*(p+1)) {
- r.h += inter;
- if (w > mw) {
- mw = w;
- }
- w = 0;
- }
- } else {
- w += sizes[findchar(*p)] + wspace;
- }
- }
-
- if (w > mw) {
- mw = w;
- }
-
- r.w = mw;
-
- return r;
-}
-
-mogltk::rect mogltk::font::size(const ugly_string & m, ...) {
- va_list ap;
- rect r;
-
- va_start(ap, m);
- r = size(m, ap);
- va_end(ap);
-
- return r;
-}
-
-mogltk::rect mogltk::font::size(const char * p, ...) {
- ugly_string m;
- va_list ap;
- rect r;
-
- m.p = p;
-
- va_start(ap, p);
- r = size(m, ap);
- va_end(ap);
-
- return r;
-}
-
-mogltk::rect mogltk::font::printtotex(texture * t, const ugly_string & m, va_list ap) {
- char * p;
- static char buffer[STRBUFSIZ + 1];
- rect r;
- int mw, w;
-
- r.x = cx;
- r.y = cy;
- r.h = inter;
- r.w = 0;
- mw = 0;
- w = 0;
-
-#ifdef HAVE_VSNPRINTF
- vsnprintf(buffer, STRBUFSIZ, m.p, ap);
-#else
- vsprintf(buffer, m.p, ap);
-#endif
-
- for (p = buffer; *p; p++) {
- if (*p == '\n') {
- if (*(p+1)) {
- r.h += inter;
- if (w > mw) {
- mw = w;
- }
- w = 0;
- }
- } else {
- w += sizes[findchar(*p)] + wspace;
- }
- }
-
- if (w > mw) {
- mw = w;
- }
-
- r.w = mw;
-
- for (p = buffer; *p; p++) {
- if (*p == '\n') {
- newline();
- } else {
- drawcharontex(t, *p, textcolor);
- }
- }
-
- return r;
-}
-
-mogltk::rect mogltk::font::printtotex(texture * t, const ugly_string & m, ...) {
- va_list ap;
- rect r;
-
- va_start(ap, m);
- r = printtotex(t, m, ap);
- va_end(ap);
-
- return r;
-}
-
-mogltk::rect mogltk::font::printtotex(texture * t, const char * p, ...) {
- ugly_string m;
- va_list ap;
- rect r;
-
- m.p = p;
-
- va_start(ap, p);
- r = printtotex(t, m, ap);
- va_end(ap);
-
- return r;
-}
-
-inline static unsigned int nextpower(unsigned int n) {
- unsigned int i;
-
- if (!n)
- return n;
-
- if (ISPOT(n))
- return n;
-
- for (i = 31; i >= 0; i--) {
- if ((n >> i) & 1) {
- return 1 << (i + 1);
- }
- }
-}
-
-mogltk::texture * mogltk::font::printtex(rect * _r, const ugly_string & m, va_list ap) {
- rect r;
- char * p;
- static char buffer[STRBUFSIZ + 1];
- int mw, w, pw, ph;
- texture * t;
- int ocx, ocy, oox;
-
- ocx = cx;
- ocy = cy;
- oox = ox;
-
- cx = ox = 0;
- cy = base;
-
- r.x = cx;
- r.y = cy;
- r.h = inter;
- r.w = 0;
- mw = 0;
- w = 0;
-
-#ifdef HAVE_VSNPRINTF
- vsnprintf(buffer, STRBUFSIZ, m.p, ap);
-#else
- vsprintf(buffer, m.p, ap);
-#endif
-
- for (p = buffer; *p; p++) {
- if (*p == '\n') {
- if (*(p+1)) {
- r.h += inter;
- if (w > mw) {
- mw = w;
- }
- w = 0;
- }
- } else {
- w += sizes[findchar(*p)] + wspace;
- }
- }
-
- if (w > mw) {
- mw = w;
- }
-
- r.w = mw;
-
- pw = nextpower(r.w);
- ph = nextpower(r.h);
-
- t = new texture(pw, ph);
-
- for (p = buffer; *p; p++) {
- if (*p == '\n') {
- newline();
- } else {
- drawcharontex(t, *p, textcolor);
- }
- }
-
- if (_r)
- *_r = r;
-
- return t;
-}
-
-mogltk::texture * mogltk::font::printtex(rect * r, const ugly_string & m, ...) {
- va_list ap;
- texture * t;
-
- va_start(ap, m);
- t = printtex(r, m, ap);
- va_end(ap);
-
- return t;
-}
-
-mogltk::texture * mogltk::font::printtex(rect * r, const char * p, ...) {
- ugly_string m;
- va_list ap;
- texture * t;
-
- m.p = p;
-
- va_start(ap, p);
- t = printtex(r, m, ap);
- va_end(ap);
-
- return t;
-}
-
-void mogltk::font::setcolor(ColorP c) {
- textcolor = c;
-}
-
-void mogltk::font::setshadow(int s) {
- shadow = s;
-}
-
-void mogltk::font::setwspace(int w) {
- wspace = w;
-}
-
-int mogltk::font::singletextsize(const String & s) const {
- unsigned int i;
- int r = 0;
-
- for (i = 0; i < s.strlen(); i++) {
- r += sizes[findchar(s[i])] + wspace;
- }
-
- return r;
-}
-
-mogltk::font * mogltk::SystemFont;
-mogltk::font * mogltk::FixedFont;
-
-mogltk::texture * mogltk::font::alloctexture() {
- return new mogltk::texture(256, 256);
-}
-
-void mogltk::font::Bind(int f) {
- fonttex[f]->Bind();
-}
-
-void mogltk::font::checknbind(int index, ColorP c) {
- int i, x, y;
- ColorP oldmax = ColorP::Max, t;
- ColorP::Max = c.c;
- SDL_PixelFormat * f = fonttex[0]->GetSurface()->format;
-
- for (i = 0; i < 15; i++)
- if (c == colorcached[i])
- break;
-
- if (!fontcache[i][index]) {
- fontcache[i][index] = alloctexture();
- for (y = 0; y < 256; y++) {
- for (x = 0; x < 256; x++) {
- t.fromSDL(fontcache[15][index]->GetPixels()[(y << 8) + x], f);
- fontcache[i][index]->GetPixels()[(y << 8) + x] = t.toSDL(f);
- }
- }
- }
-
- fonttex[index] = fontcache[i][index];
-
- ColorP::Max = oldmax.c;
-}
+/*
+ * mogltk
+ * Copyright (C) 1999-2004 Nicolas "Pixel" Noble
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: font.cc,v 1.16 2004-11-27 21:48:03 pixel Exp $ */
+
+#include <stdarg.h>
+#include <SDL.h>
+#include <Input.h>
+#include "base.h"
+#include "font.h"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "engine.h"
+
+Uint8 prescale2[4] = { 0, 85, 170, 255 }, prescale3[8] = { 0, 36, 72, 109, 145, 182, 218, 255 };
+
+#define STRBUFSIZ 512
+
+/*
+
+font file format
+================
+
+off|siz|description
+---+---+-------------------------------
+ 0 | 2 | Number of entries = nbentries
+ 2 | 1 | Flags
+ 3 | 1 | maxX (maximum width)
+ 4 | 1 | maxY (maximum height)
+ 5 | 1 | base (bottom line from top)
+ 6 | 1 | inter (size of the interline)
+ 7 | X | char entries
+7+X| Y | char map
+
+X = (maxX * maxY + 1) * nbentries
+Y = nbentries * 4
+
+
+Flags:
+=====
+
+0000000R
+
+R = RGBA (=1) or Alpha (=0)
+
+RGBA in 1232 format:
+ABBGGGRR
+
+
+Each entries:
+============
+
+off|siz|description
+---+---+-------------------------------
+ 0 | 1 | True size of the entry
+ 1 | Z | Datas
+
+Z = maxX * maxY
+Datas are stored in order X first, then Y.
+
+Char map:
+========
+
+nbentries entries, each entry = 4 bytes = 2 uint16
+
+off|siz|description
+---+---+-------------------------------
+ 0 | 2 | Unicode (?)
+ 2 | 2 | Corresponding char entry
+
+I'm not sure about my word 'Unicode'. I write this only to say it's an attempt
+to make the fonts "internationals". If the "unicode" is < 255, then it should
+match only one byte in the string. Otherwise, it should match two bytes.
+
+
+Variables comments
+==================
+
+nbcU = number of chars on X by texture
+nbcV = number of chars on Y by texture
+nbcT = number of char by texture
+nbT = number of textures
+
+*/
+
+mogltk::ColorP colorcached[16] = {
+ DOS_BLACK,
+ DOS_BLUE,
+ DOS_GREEN,
+ DOS_CYAN,
+ DOS_RED,
+ DOS_MAGENTA,
+ DOS_BRAWN,
+ DOS_WHITE,
+ DOS_GRAY,
+ DOS_HIGH_BLUE,
+ DOS_HIGH_GREEN,
+ DOS_HIGH_CYAN,
+ DOS_HIGH_RED,
+ DOS_HIGH_MAGENTA,
+ DOS_YELLOW,
+ DOS_HIGH_WHITE
+};
+
+mogltk::font::font(Handle * ffont) : textcolor(255, 255, 255, 255), shadow(0), wspace(0) {
+ int i, j;
+
+ nbentries = ffont->readU16();
+ flags = ffont->readU8();
+ maxX = ffont->readU8();
+ maxY = ffont->readU8();
+ base = ffont->readU8();
+ inter = ffont->readU8();
+
+ nbcU = 256 / maxX;
+ nbcV = 256 / maxY;
+
+ nbcT = nbcU * nbcV;
+
+ nbT = nbentries / nbcT;
+
+ if (nbentries % nbcT) {
+ nbT++;
+ }
+
+ printm(M_INFO, "Creating font texture: %i entries, flags = 0x%02x, maxX = %i, maxY = %i\n", nbentries, flags, maxX, maxY);
+ printm(M_INFO, "Which makes %i texture(s), with %i char by texture, %i on X, and %i on Y\n", nbT, nbcT, nbcU, nbcV);
+
+ fonttex = (texture **) malloc(nbT * sizeof(texture *));
+ for (i = 0; i < 16; i++) {
+ fontcache[i] = (texture **) malloc(nbT * sizeof(texture *));
+ }
+
+ for (i = 0; i < nbT; i++) {
+ fonttex[i] = alloctexture();
+ for (j = 0; j < 15; j++) {
+ fontcache[j][i] = 0;
+ }
+ fontcache[15][i] = fonttex[i];
+ }
+
+ sizes = (Uint8 *) malloc(nbentries * sizeof(Uint8));
+
+ Uint8 * curtex = (Uint8 *) fonttex[0]->GetSurface()->pixels;
+ Uint32 curU = 0, curV = 0, curT = 0;
+ for (i = 0; i < nbentries; i++) {
+ sizes[i] = ffont->readU8();
+ for (int v = 0; v < maxY; v++) {
+ for (int u = 0; u < maxX; u++) {
+ Uint8 f;
+ f = ffont->readU8();
+ if (flags & 1) {
+ Uint8 r, g, b, a;
+ r = f & 3;
+ g = (f >> 2) & 7;
+ b = (f >> 5) & 3;
+ a = (f >> 7) & 1;
+ curtex[(curU + u + (curV + v) * 256) * 4 + 0] = prescale2[r];
+ curtex[(curU + u + (curV + v) * 256) * 4 + 1] = prescale3[g];
+ curtex[(curU + u + (curV + v) * 256) * 4 + 2] = prescale2[b];
+ curtex[(curU + u + (curV + v) * 256) * 4 + 3] = a ? 255 : 0;
+ } else {
+ curtex[(curU + u + (curV + v) * 256) * 4 + 0] = 255;
+ curtex[(curU + u + (curV + v) * 256) * 4 + 1] = 255;
+ curtex[(curU + u + (curV + v) * 256) * 4 + 2] = 255;
+ curtex[(curU + u + (curV + v) * 256) * 4 + 3] = f;
+ }
+ }
+ }
+ if (((curU += maxX) + maxX) > 256) {
+ curU = 0;
+ if (((curV += maxY) + maxY) > 256) {
+ curV = 0;
+ if ((curT + 1) != nbT)
+ curtex = (Uint8 *) fonttex[++curT]->GetSurface()->pixels;
+ }
+ }
+ }
+
+ corresp = (Uint16 *) malloc(nbentries * 2 * sizeof(Uint16));
+
+ for (i = 0; i < 2 * nbentries; i++) {
+ corresp[i] = ffont->readU16();
+ }
+}
+
+mogltk::font::~font() {
+ int i, j;
+ for (i = 0; i < nbT; i++)
+ for (j = 0; j < 16; j++)
+ if (fontcache[j][i])
+ delete fontcache[j][i];
+
+ for (i = 0; i < 16; i++)
+ free((void *&) fontcache[i]);
+
+ free((void *&) fonttex);
+ free(sizes);
+}
+
+void mogltk::font::drawentry(Uint16 entry, int x, int y, ColorP c) {
+ bool locked = false;
+ int trueentry, cx, cy, px, py;
+ SDL_Rect src, dst;
+
+ if (SDL_MUSTLOCK(mogltk::engine::base_o->getsurface())) {
+ locked = true;
+ SDL_LockSurface(mogltk::engine::base_o->getsurface());
+ }
+
+ if (shadow) {
+ int os = shadow;
+ shadow = 0;
+
+ drawentry(entry, x + os, y + os, BLACK);
+
+ shadow = os;
+ }
+
+ checknbind(entry / nbcT, c);
+
+ y -= base;
+
+ trueentry = entry % nbcT;
+ cx = trueentry % nbcU;
+ cy = trueentry / nbcU;
+ px = cx * maxX;
+ py = cy * maxY;
+
+ src.x = px; src.y = py; src.w = maxX; src.h = maxY;
+ dst.x = x; dst.y = y; dst.w = maxX; dst.h = maxY;
+
+ SDL_BlitSurface(fonttex[entry / nbcT]->GetSurface(), &src, mogltk::engine::base_o->getsurface(), &dst);
+
+ if (locked)
+ SDL_UnlockSurface(mogltk::engine::base_o->getsurface());
+}
+
+void mogltk::font::drawtotex(texture * t, Uint16 entry, int x, int y, ColorP c) {
+ bool locked = false;
+ int trueentry, cx, cy, px, py;
+ SDL_Rect src, dst;
+
+ if (SDL_MUSTLOCK(t->GetSurface())) {
+ locked = true;
+ SDL_LockSurface(t->GetSurface());
+ }
+
+ if (shadow) {
+ int os = shadow;
+ shadow = 0;
+
+ drawtotex(t, entry, x + os, y + os, BLACK);
+
+ shadow = os;
+ }
+
+ checknbind(entry / nbcT, c);
+
+ y -= base;
+
+ trueentry = entry % nbcT;
+ cx = trueentry % nbcU;
+ cy = trueentry / nbcU;
+ px = cx * maxX;
+ py = cy * maxY;
+
+ src.x = px; src.y = py; src.w = maxX; src.h = maxY;
+ dst.x = x; dst.y = y; dst.w = maxX; dst.h = maxY;
+
+ SDL_BlitSurface(fonttex[entry / nbcT]->GetSurface(), &src, t->GetSurface(), &dst);
+
+ if (locked)
+ SDL_UnlockSurface(t->GetSurface());
+}
+
+void mogltk::font::putcursor(int x, int y) {
+ cx = ox = x;
+ cy = y;
+}
+
+void mogltk::font::putentry(Uint16 entry, ColorP c) {
+ drawentry(entry, cx, cy, c);
+ cx += sizes[entry] + wspace;
+}
+
+void mogltk::font::putentryontex(texture * t, Uint16 entry, ColorP c) {
+ drawtotex(t, entry, cx, cy, c);
+ cx += sizes[entry] + wspace;
+}
+
+void mogltk::font::drawchar(char ch, ColorP c) {
+ Uint16 * p;
+ int i;
+
+ for (i = 0, p = corresp; i < nbentries; i++, p++) {
+ if (*(p++) == ch) {
+ putentry(*p, c);
+ return;
+ }
+ }
+}
+
+void mogltk::font::drawcharontex(texture * t, char ch, ColorP c) {
+ Uint16 * p;
+ int i;
+
+ for (i = 0, p = corresp; i < nbentries; i++, p++) {
+ if (*(p++) == ch) {
+ putentryontex(t, *p, c);
+ return;
+ }
+ }
+}
+
+int mogltk::font::findchar(char ch) const {
+ Uint16 * p;
+ int i;
+
+ for (i = 0, p = corresp; i < nbentries; i++, p++) {
+ if (*(p++) == ch) {
+ return *p;
+ }
+ }
+
+ return -1;
+}
+
+void mogltk::font::newline(void) {
+ cx = ox;
+ cy += inter;
+}
+
+int mogltk::font::printf(const ugly_string & m, va_list ap) {
+ char * p;
+ static char buffer[STRBUFSIZ + 1];
+ int r;
+
+#ifdef HAVE_VSNPRINTF
+ r = vsnprintf(buffer, STRBUFSIZ, m.p, ap);
+#else
+ r = vsprintf(buffer, m.p, ap);
+#endif
+
+ for (p = buffer; *p; p++) {
+ if (*p == '\n') {
+ newline();
+ } else {
+ drawchar(*p, textcolor);
+ }
+ }
+
+ return r;
+}
+
+int mogltk::font::printf(const ugly_string & m, ...) {
+ va_list ap;
+ int r;
+
+ va_start(ap, m);
+ r = printf(m, ap);
+ va_end(ap);
+
+ return r;
+}
+
+int mogltk::font::printf(const char * p, ...) {
+ ugly_string m;
+ va_list ap;
+ int r;
+
+ m.p = p;
+
+ va_start(ap, p);
+ r = printf(m, ap);
+ va_end(ap);
+
+ return r;
+}
+
+mogltk::rect mogltk::font::size(const ugly_string & m, va_list ap) {
+ char * p;
+ static char buffer[STRBUFSIZ + 1];
+ rect r;
+ int mw, w;
+
+ r.x = cx;
+ r.y = cy;
+ r.h = inter;
+ r.w = 0;
+ mw = 0;
+ w = 0;
+
+#ifdef HAVE_VSNPRINTF
+ vsnprintf(buffer, STRBUFSIZ, m.p, ap);
+#else
+ vsprintf(buffer, m.p, ap);
+#endif
+
+ for (p = buffer; *p; p++) {
+ if (*p == '\n') {
+ if (*(p+1)) {
+ r.h += inter;
+ if (w > mw) {
+ mw = w;
+ }
+ w = 0;
+ }
+ } else {
+ w += sizes[findchar(*p)] + wspace;
+ }
+ }
+
+ if (w > mw) {
+ mw = w;
+ }
+
+ r.w = mw;
+
+ return r;
+}
+
+mogltk::rect mogltk::font::size(const ugly_string & m, ...) {
+ va_list ap;
+ rect r;
+
+ va_start(ap, m);
+ r = size(m, ap);
+ va_end(ap);
+
+ return r;
+}
+
+mogltk::rect mogltk::font::size(const char * p, ...) {
+ ugly_string m;
+ va_list ap;
+ rect r;
+
+ m.p = p;
+
+ va_start(ap, p);
+ r = size(m, ap);
+ va_end(ap);
+
+ return r;
+}
+
+mogltk::rect mogltk::font::printtotex(texture * t, const ugly_string & m, va_list ap) {
+ char * p;
+ static char buffer[STRBUFSIZ + 1];
+ rect r;
+ int mw, w;
+
+ r.x = cx;
+ r.y = cy;
+ r.h = inter;
+ r.w = 0;
+ mw = 0;
+ w = 0;
+
+#ifdef HAVE_VSNPRINTF
+ vsnprintf(buffer, STRBUFSIZ, m.p, ap);
+#else
+ vsprintf(buffer, m.p, ap);
+#endif
+
+ for (p = buffer; *p; p++) {
+ if (*p == '\n') {
+ if (*(p+1)) {
+ r.h += inter;
+ if (w > mw) {
+ mw = w;
+ }
+ w = 0;
+ }
+ } else {
+ w += sizes[findchar(*p)] + wspace;
+ }
+ }
+
+ if (w > mw) {
+ mw = w;
+ }
+
+ r.w = mw;
+
+ for (p = buffer; *p; p++) {
+ if (*p == '\n') {
+ newline();
+ } else {
+ drawcharontex(t, *p, textcolor);
+ }
+ }
+
+ return r;
+}
+
+mogltk::rect mogltk::font::printtotex(texture * t, const ugly_string & m, ...) {
+ va_list ap;
+ rect r;
+
+ va_start(ap, m);
+ r = printtotex(t, m, ap);
+ va_end(ap);
+
+ return r;
+}
+
+mogltk::rect mogltk::font::printtotex(texture * t, const char * p, ...) {
+ ugly_string m;
+ va_list ap;
+ rect r;
+
+ m.p = p;
+
+ va_start(ap, p);
+ r = printtotex(t, m, ap);
+ va_end(ap);
+
+ return r;
+}
+
+inline static unsigned int nextpower(unsigned int n) {
+ unsigned int i;
+
+ if (!n)
+ return n;
+
+ if (ISPOT(n))
+ return n;
+
+ for (i = 31; i >= 0; i--) {
+ if ((n >> i) & 1) {
+ return 1 << (i + 1);
+ }
+ }
+}
+
+mogltk::texture * mogltk::font::printtex(rect * _r, const ugly_string & m, va_list ap) {
+ rect r;
+ char * p;
+ static char buffer[STRBUFSIZ + 1];
+ int mw, w, pw, ph;
+ texture * t;
+ int ocx, ocy, oox;
+
+ ocx = cx;
+ ocy = cy;
+ oox = ox;
+
+ cx = ox = 0;
+ cy = base;
+
+ r.x = cx;
+ r.y = cy;
+ r.h = inter;
+ r.w = 0;
+ mw = 0;
+ w = 0;
+
+#ifdef HAVE_VSNPRINTF
+ vsnprintf(buffer, STRBUFSIZ, m.p, ap);
+#else
+ vsprintf(buffer, m.p, ap);
+#endif
+
+ for (p = buffer; *p; p++) {
+ if (*p == '\n') {
+ if (*(p+1)) {
+ r.h += inter;
+ if (w > mw) {
+ mw = w;
+ }
+ w = 0;
+ }
+ } else {
+ w += sizes[findchar(*p)] + wspace;
+ }
+ }
+
+ if (w > mw) {
+ mw = w;
+ }
+
+ r.w = mw;
+
+ pw = nextpower(r.w);
+ ph = nextpower(r.h);
+
+ t = new texture(pw, ph);
+
+ for (p = buffer; *p; p++) {
+ if (*p == '\n') {
+ newline();
+ } else {
+ drawcharontex(t, *p, textcolor);
+ }
+ }
+
+ if (_r)
+ *_r = r;
+
+ return t;
+}
+
+mogltk::texture * mogltk::font::printtex(rect * r, const ugly_string & m, ...) {
+ va_list ap;
+ texture * t;
+
+ va_start(ap, m);
+ t = printtex(r, m, ap);
+ va_end(ap);
+
+ return t;
+}
+
+mogltk::texture * mogltk::font::printtex(rect * r, const char * p, ...) {
+ ugly_string m;
+ va_list ap;
+ texture * t;
+
+ m.p = p;
+
+ va_start(ap, p);
+ t = printtex(r, m, ap);
+ va_end(ap);
+
+ return t;
+}
+
+void mogltk::font::setcolor(ColorP c) {
+ textcolor = c;
+}
+
+void mogltk::font::setshadow(int s) {
+ shadow = s;
+}
+
+void mogltk::font::setwspace(int w) {
+ wspace = w;
+}
+
+int mogltk::font::singletextsize(const String & s) const {
+ unsigned int i;
+ int r = 0;
+
+ for (i = 0; i < s.strlen(); i++) {
+ r += sizes[findchar(s[i])] + wspace;
+ }
+
+ return r;
+}
+
+mogltk::font * mogltk::SystemFont;
+mogltk::font * mogltk::FixedFont;
+
+mogltk::texture * mogltk::font::alloctexture() {
+ return new mogltk::texture(256, 256);
+}
+
+void mogltk::font::Bind(int f) {
+ fonttex[f]->Bind();
+}
+
+void mogltk::font::checknbind(int index, ColorP c) {
+ int i, x, y;
+ ColorP oldmax = ColorP::Max, t;
+ ColorP::Max = c.c;
+ SDL_PixelFormat * f = fonttex[0]->GetSurface()->format;
+
+ for (i = 0; i < 15; i++)
+ if (c == colorcached[i])
+ break;
+
+ if (!fontcache[i][index]) {
+ fontcache[i][index] = alloctexture();
+ for (y = 0; y < 256; y++) {
+ for (x = 0; x < 256; x++) {
+ t.fromSDL(fontcache[15][index]->GetPixels()[(y << 8) + x], f);
+ fontcache[i][index]->GetPixels()[(y << 8) + x] = t.toSDL(f);
+ }
+ }
+ }
+
+ fonttex[index] = fontcache[i][index];
+
+ ColorP::Max = oldmax.c;
+}
diff --git a/lib/glbase.cc b/lib/glbase.cc
index abd3f1e..2edeec5 100644
--- a/lib/glbase.cc
+++ b/lib/glbase.cc
@@ -1,267 +1,267 @@
-/*
- * mogltk
- * Copyright (C) 1999-2004 Nicolas "Pixel" Noble
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* $Id: glbase.cc,v 1.21 2004-10-19 01:27:30 pixel Exp $ */
-
-#include <stdio.h>
-#include <SDL.h>
-#include <SDL_opengl.h>
-#include <Output.h>
-#include <Handle.h>
-#include "glbase.h"
-#include "engine.h"
-#include "generic.h"
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-mogltk::glbase::glbase(int w, int h, int flags) throw (GeneralException) : mogltk::base(w, h, flags, 0), twoD(0), fovy(60.0) {
- SDL_Surface * surface;
- GLint bits;
-
- mogltk::engine::setup();
- if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
- throw GeneralException(String("Couldn't initialise Video SubSystem: ") + SDL_GetError());
- }
-
-#if 1
- SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
-// SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 32);
- SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
- SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, 8);
-#endif
- if (!(surface = SDL_SetVideoMode(w, h, 0, flags | SDL_OPENGL | SDL_HWSURFACE))) {
- throw GeneralException(String("Couldn't set GL mode: ") + SDL_GetError());
- }
-
- mogltk::engine::glbase_o = this;
- mogltk::engine::base_o = this;
-
- ratio = (GLdouble) surface->w / surface->h;
-
- glGetIntegerv(GL_STENCIL_BITS, &bits);
-
- printm(M_INFO, "Video resolution: %dx%dx%d (ratio = %3.2f)\n", surface->w, surface->h, surface->format->BitsPerPixel, ratio);
- printm(M_INFO, "\n");
- printm(M_INFO, "OpenGL infos\n");
- printm(M_INFO, "------------\n");
- printm(M_INFO, String("Vendor : ") + (char *) glGetString(GL_VENDOR) + "\n");
- printm(M_INFO, String("Renderer : ") + (char *) glGetString(GL_RENDERER) + "\n");
- printm(M_INFO, String("Version : ") + (char *) glGetString(GL_VERSION) + "\n");
- printm(M_INFO, String("Extensions: ") + (char *) glGetString(GL_EXTENSIONS) + "\n");
-
- glViewport(0, 0, surface->w, surface->h);
-
- glCullFace(GL_BACK);
- glFrontFace(GL_CCW);
- glEnable(GL_CULL_FACE);
-
- glClearColor(0, 0, 0, 0);
- glShadeModel(GL_SMOOTH);
-
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_LEQUAL);
- glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective(fovy, ratio, 1.0, 1024.0);
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- SDL_GL_SwapBuffers();
- SDL_ShowCursor(SDL_DISABLE);
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- setsurface(surface);
- mogltk::engine::postsetup();
-}
-
-mogltk::glbase::~glbase() {
-}
-
-void mogltk::glbase::Enter2DMode(void) {
- if (twoD)
- return;
-
- glPushAttrib(GL_ENABLE_BIT);
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_CULL_FACE);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- glOrtho(0.0, GetWidth(), GetHeight(), 0.0, 0.0, 1.0);
-
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
-
- twoD = 1;
-}
-
-void mogltk::glbase::Leave2DMode(void) {
- if (!twoD)
- return;
-
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
-
- glPopAttrib();
-
- twoD = 0;
-}
-
-void mogltk::glbase::Flip(bool clear) {
- mogltk::engine::pollevents();
- SDL_GL_SwapBuffers();
- if (clear)
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-}
-
-bool mogltk::glbase::is2D() {
- return twoD;
-}
-
-void mogltk::glbase::glVertex(GLshort x, GLshort y, GLshort z, GLshort w) {
-#ifdef DEBUG
- printm(M_INFO, "Calling glVertex(%i, %i, %i, %i) (shorts)\n", x, y, z, w);
-#endif
- glVertex4i(x, y, z, w);
-}
-
-void mogltk::glbase::glVertex(GLint x, GLint y, GLint z, GLint w) {
-#ifdef DEBUG
- printm(M_INFO, "Calling glVertex(%i, %i, %i, %i) (ints)\n", x, y, z, w);
-#endif
- glVertex4i(x, y, z, w);
-}
-
-void mogltk::glbase::glVertex(GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
-#ifdef DEBUG
- printm(M_INFO, "Calling glVertex(%f, %f, %f, %f) (floats)\n", x, y, z, w);
-#endif
- glVertex4f(x, y, z, w);
-}
-
-void mogltk::glbase::glVertex(GLdouble x, GLdouble y, GLdouble z, GLdouble w) {
-#ifdef DEBUG
- printm(M_INFO, "Calling glVertex(%f, %f, %f, %f) (doubles)\n", x, y, z, w);
-#endif
- glVertex4d(x, y, z, w);
-}
-
-void mogltk::glbase::changeviewport(int x, int y, unsigned int w, unsigned int h) {
-#if 0
- if ((w == 0) && (h == 0)) {
- w = GetWidth() - x;
- h = GetHeight() - y;
- }
-
- ratio = (GLdouble) w / h;
- glViewport(x, y, w, h);
- if (!engine::base_o->is2D())
- gluPerspective(fovy, ratio, 1.0, 1024.0);
-#endif
- glScissor(x, GetHeight() - y - h - 1, w + 1, h + 1);
- glEnable(GL_SCISSOR_TEST);
-}
-
-void mogltk::glbase::changefovy(GLdouble nfoyv) {
- fovy = nfoyv;
- if (!engine::base_o->is2D())
- gluPerspective(fovy, ratio, 1.0, 1024.0);
-}
-
-inline static unsigned int nextpower(unsigned int n) {
- unsigned int i;
-
- if (!n)
- return n;
-
- if (ISPOT(n))
- return n;
-
- for (i = 31; i >= 0; i--) {
- if ((n >> i) & 1) {
- return 1 << (i + 1);
- }
- }
-}
-
-mogltk::texture * mogltk::glbase::GrabTexture() {
- int w = nextpower(GetWidth());
- int h = nextpower(GetHeight());
- texture * r = new texture(w, h);
- SDL_Surface * t;
-
- t = GrabSurface();
- SDL_BlitSurface(t, NULL, r->GetSurface(), NULL);
- SDL_FreeSurface(t);
-
- return r;
-}
-
-SDL_Surface * mogltk::glbase::GrabSurface() {
- int i;
- SDL_Surface * r;
- Uint8 * pixels = (Uint8 *) malloc(GetWidth() * GetHeight() * 3);
- Uint8 * s, * d;
-
- glReadPixels(0, 0, GetWidth(), GetHeight(), GL_RGB, GL_UNSIGNED_BYTE, pixels);
-
- r = SDL_CreateRGBSurface(SDL_SWSURFACE, GetWidth(), GetHeight(), 24,
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- 0xff000000,
- 0x00ff0000,
- 0x0000ff00,
- 0x00000000
-#else
- 0x000000ff,
- 0x0000ff00,
- 0x00ff0000,
- 0x00000000
-#endif
- );
-
- for (i = 0; i < GetHeight(); i++) {
- s = pixels + i * GetWidth() * 3;
- d = ((Uint8 *) r->pixels) + (GetHeight() - i - 1) * GetWidth() * 3;
- memcpy(d, s, GetWidth() * 3);
- }
-
- free(pixels);
-
- return r;
-}
+/*
+ * mogltk
+ * Copyright (C) 1999-2004 Nicolas "Pixel" Noble
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: glbase.cc,v 1.22 2004-11-27 21:48:03 pixel Exp $ */
+
+#include <stdio.h>
+#include <SDL.h>
+#include <SDL_opengl.h>
+#include <Output.h>
+#include <Handle.h>
+#include "glbase.h"
+#include "engine.h"
+#include "generic.h"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+mogltk::glbase::glbase(int w, int h, int flags) throw (GeneralException) : mogltk::base(w, h, flags, 0), twoD(0), fovy(60.0) {
+ SDL_Surface * surface;
+ GLint bits;
+
+ mogltk::engine::setup();
+ if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
+ throw GeneralException(String("Couldn't initialise Video SubSystem: ") + SDL_GetError());
+ }
+
+#if 1
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
+// SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 32);
+ SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, 8);
+#endif
+ if (!(surface = SDL_SetVideoMode(w, h, 0, flags | SDL_OPENGL | SDL_HWSURFACE))) {
+ throw GeneralException(String("Couldn't set GL mode: ") + SDL_GetError());
+ }
+
+ mogltk::engine::glbase_o = this;
+ mogltk::engine::base_o = this;
+
+ ratio = (GLdouble) surface->w / surface->h;
+
+ glGetIntegerv(GL_STENCIL_BITS, &bits);
+
+ printm(M_INFO, "Video resolution: %dx%dx%d (ratio = %3.2f)\n", surface->w, surface->h, surface->format->BitsPerPixel, ratio);
+ printm(M_INFO, "\n");
+ printm(M_INFO, "OpenGL infos\n");
+ printm(M_INFO, "------------\n");
+ printm(M_INFO, String("Vendor : ") + (char *) glGetString(GL_VENDOR) + "\n");
+ printm(M_INFO, String("Renderer : ") + (char *) glGetString(GL_RENDERER) + "\n");
+ printm(M_INFO, String("Version : ") + (char *) glGetString(GL_VERSION) + "\n");
+ printm(M_INFO, String("Extensions: ") + (char *) glGetString(GL_EXTENSIONS) + "\n");
+
+ glViewport(0, 0, surface->w, surface->h);
+
+ glCullFace(GL_BACK);
+ glFrontFace(GL_CCW);
+ glEnable(GL_CULL_FACE);
+
+ glClearColor(0, 0, 0, 0);
+ glShadeModel(GL_SMOOTH);
+
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LEQUAL);
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluPerspective(fovy, ratio, 1.0, 1024.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ SDL_GL_SwapBuffers();
+ SDL_ShowCursor(SDL_DISABLE);
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ setsurface(surface);
+ mogltk::engine::postsetup();
+}
+
+mogltk::glbase::~glbase() {
+}
+
+void mogltk::glbase::Enter2DMode(void) {
+ if (twoD)
+ return;
+
+ glPushAttrib(GL_ENABLE_BIT);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_CULL_FACE);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glOrtho(0.0, GetWidth(), GetHeight(), 0.0, 0.0, 1.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+
+ twoD = 1;
+}
+
+void mogltk::glbase::Leave2DMode(void) {
+ if (!twoD)
+ return;
+
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+
+ glPopAttrib();
+
+ twoD = 0;
+}
+
+void mogltk::glbase::Flip(bool clear) {
+ mogltk::engine::pollevents();
+ SDL_GL_SwapBuffers();
+ if (clear)
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+}
+
+bool mogltk::glbase::is2D() {
+ return twoD;
+}
+
+void mogltk::glbase::glVertex(GLshort x, GLshort y, GLshort z, GLshort w) {
+#ifdef DEBUG
+ printm(M_INFO, "Calling glVertex(%i, %i, %i, %i) (shorts)\n", x, y, z, w);
+#endif
+ glVertex4i(x, y, z, w);
+}
+
+void mogltk::glbase::glVertex(GLint x, GLint y, GLint z, GLint w) {
+#ifdef DEBUG
+ printm(M_INFO, "Calling glVertex(%i, %i, %i, %i) (ints)\n", x, y, z, w);
+#endif
+ glVertex4i(x, y, z, w);
+}
+
+void mogltk::glbase::glVertex(GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
+#ifdef DEBUG
+ printm(M_INFO, "Calling glVertex(%f, %f, %f, %f) (floats)\n", x, y, z, w);
+#endif
+ glVertex4f(x, y, z, w);
+}
+
+void mogltk::glbase::glVertex(GLdouble x, GLdouble y, GLdouble z, GLdouble w) {
+#ifdef DEBUG
+ printm(M_INFO, "Calling glVertex(%f, %f, %f, %f) (doubles)\n", x, y, z, w);
+#endif
+ glVertex4d(x, y, z, w);
+}
+
+void mogltk::glbase::changeviewport(int x, int y, unsigned int w, unsigned int h) {
+#if 0
+ if ((w == 0) && (h == 0)) {
+ w = GetWidth() - x;
+ h = GetHeight() - y;
+ }
+
+ ratio = (GLdouble) w / h;
+ glViewport(x, y, w, h);
+ if (!engine::base_o->is2D())
+ gluPerspective(fovy, ratio, 1.0, 1024.0);
+#endif
+ glScissor(x, GetHeight() - y - h - 1, w + 1, h + 1);
+ glEnable(GL_SCISSOR_TEST);
+}
+
+void mogltk::glbase::changefovy(GLdouble nfoyv) {
+ fovy = nfoyv;
+ if (!engine::base_o->is2D())
+ gluPerspective(fovy, ratio, 1.0, 1024.0);
+}
+
+inline static unsigned int nextpower(unsigned int n) {
+ unsigned int i;
+
+ if (!n)
+ return n;
+
+ if (ISPOT(n))
+ return n;
+
+ for (i = 31; i >= 0; i--) {
+ if ((n >> i) & 1) {
+ return 1 << (i + 1);
+ }
+ }
+}
+
+mogltk::texture * mogltk::glbase::GrabTexture() {
+ int w = nextpower(GetWidth());
+ int h = nextpower(GetHeight());
+ texture * r = new texture(w, h);
+ SDL_Surface * t;
+
+ t = GrabSurface();
+ SDL_BlitSurface(t, NULL, r->GetSurface(), NULL);
+ SDL_FreeSurface(t);
+
+ return r;
+}
+
+SDL_Surface * mogltk::glbase::GrabSurface() {
+ int i;
+ SDL_Surface * r;
+ Uint8 * pixels = (Uint8 *) malloc(GetWidth() * GetHeight() * 3);
+ Uint8 * s, * d;
+
+ glReadPixels(0, 0, GetWidth(), GetHeight(), GL_RGB, GL_UNSIGNED_BYTE, pixels);
+
+ r = SDL_CreateRGBSurface(SDL_SWSURFACE, GetWidth(), GetHeight(), 24,
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ 0xff000000,
+ 0x00ff0000,
+ 0x0000ff00,
+ 0x00000000
+#else
+ 0x000000ff,
+ 0x0000ff00,
+ 0x00ff0000,
+ 0x00000000
+#endif
+ );
+
+ for (i = 0; i < GetHeight(); i++) {
+ s = pixels + i * GetWidth() * 3;
+ d = ((Uint8 *) r->pixels) + (GetHeight() - i - 1) * GetWidth() * 3;
+ memcpy(d, s, GetWidth() * 3);
+ }
+
+ free(pixels);
+
+ return r;
+}
diff --git a/lib/glfont.cc b/lib/glfont.cc
index 350f721..5b28591 100644
--- a/lib/glfont.cc
+++ b/lib/glfont.cc
@@ -1,72 +1,72 @@
-/*
- * mogltk
- * Copyright (C) 1999-2004 Nicolas "Pixel" Noble
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* $Id: glfont.cc,v 1.24 2004-11-27 21:44:53 pixel Exp $ */
-
-#include "engine.h"
-#include "glbase.h"
-#include "glfont.h"
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-mogltk::glfont::glfont(Handle * ffont) : font(ffont) {
-}
-
-mogltk::glfont::~glfont() {
-}
-
-void mogltk::glfont::drawentry(Uint16 entry, int x, int y, ColorP c) {
- bool was2D;
- int trueentry, cx, cy, px, py;
-
- was2D = mogltk::engine::glbase_o->is2D();
-
- if (!was2D)
- mogltk::engine::glbase_o->Enter2DMode();
-
- if (shadow) {
- int os = shadow;
- shadow = 0;
-
- drawentry(entry, x + os, y + os, BLACK);
-
- shadow = os;
- }
-
- y -= base;
-
- Bind(entry / nbcT);
- c.Bind();
- trueentry = entry % nbcT;
- cx = trueentry % nbcU;
- cy = trueentry / nbcU;
- px = cx * maxX;
- py = cy * maxY;
-
- glBegin(GL_TRIANGLE_STRIP);
- glTexCoord2i(px , py ); glVertex2i(x , y );
- glTexCoord2i(px + maxX , py ); glVertex2i(x + maxX , y );
- glTexCoord2i(px , py + maxY ); glVertex2i(x , y + maxY );
- glTexCoord2i(px + maxX , py + maxY ); glVertex2i(x + maxX , y + maxY );
- glEnd();
-
- if (!was2D)
- mogltk::engine::glbase_o->Leave2DMode();
-}
+/*
+ * mogltk
+ * Copyright (C) 1999-2004 Nicolas "Pixel" Noble
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: glfont.cc,v 1.25 2004-11-27 21:48:03 pixel Exp $ */
+
+#include "engine.h"
+#include "glbase.h"
+#include "glfont.h"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+mogltk::glfont::glfont(Handle * ffont) : font(ffont) {
+}
+
+mogltk::glfont::~glfont() {
+}
+
+void mogltk::glfont::drawentry(Uint16 entry, int x, int y, ColorP c) {
+ bool was2D;
+ int trueentry, cx, cy, px, py;
+
+ was2D = mogltk::engine::glbase_o->is2D();
+
+ if (!was2D)
+ mogltk::engine::glbase_o->Enter2DMode();
+
+ if (shadow) {
+ int os = shadow;
+ shadow = 0;
+
+ drawentry(entry, x + os, y + os, BLACK);
+
+ shadow = os;
+ }
+
+ y -= base;
+
+ Bind(entry / nbcT);
+ c.Bind();
+ trueentry = entry % nbcT;
+ cx = trueentry % nbcU;
+ cy = trueentry / nbcU;
+ px = cx * maxX;
+ py = cy * maxY;
+
+ glBegin(GL_TRIANGLE_STRIP);
+ glTexCoord2i(px , py ); glVertex2i(x , y );
+ glTexCoord2i(px + maxX , py ); glVertex2i(x + maxX , y );
+ glTexCoord2i(px , py + maxY ); glVertex2i(x , y + maxY );
+ glTexCoord2i(px + maxX , py + maxY ); glVertex2i(x + maxX , y + maxY );
+ glEnd();
+
+ if (!was2D)
+ mogltk::engine::glbase_o->Leave2DMode();
+}
diff --git a/lib/glshape.cc b/lib/glshape.cc
index 937173d..8fa718e 100644
--- a/lib/glshape.cc
+++ b/lib/glshape.cc
@@ -1,253 +1,253 @@
-/*
- * mogltk
- * Copyright (C) 1999-2004 Nicolas "Pixel" Noble
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* $Id: glshape.cc,v 1.15 2004-11-27 21:44:53 pixel Exp $ */
-
-#include <SDL_opengl.h>
-#include "glbase.h"
-#include "glshape.h"
-#include "texture.h"
-#include "glfont.h"
-#include "engine.h"
-
-#define ENTER bool was2d = Enter(true)
-#define ENTERT bool was2d = Enter(false)
-#define LEAVE Leave(was2d)
-
-void mogltk::glshape::box(int x1, int y1, int x2, int y2, ColorP c) {
- ENTER;
-
- c.Bind();
- glBegin(GL_TRIANGLE_STRIP);
- glVertex2i(x1, y1);
- glVertex2i(x2 + 1, y1);
- glVertex2i(x1, y2 + 1);
- glVertex2i(x2 + 1, y2 + 1);
- glEnd();
-
- LEAVE;
-}
-
-void mogltk::glshape::box(int x1, int y1, int x2, int y2, ColorP c1, ColorP c2, ColorP c3, ColorP c4) {
- ENTER;
-
- glBegin(GL_TRIANGLE_STRIP);
- c1.Bind(); glVertex2i(x1, y1);
- c2.Bind(); glVertex2i(x2 + 1, y1);
- c3.Bind(); glVertex2i(x1, y2 + 1);
- c4.Bind(); glVertex2i(x2 + 1, y2 + 1);
- glEnd();
-
- LEAVE;
-}
-
-void mogltk::glshape::hline(int x1, int x2, int y, ColorP c1, ColorP c2) {
- box(x1, y, x2, y, c1, c2, c1, c2);
-}
-
-void mogltk::glshape::hline(int x1, int x2, int y, ColorP c) {
- box(x1, y, x2, y, c, c, c, c);
-}
-
-void mogltk::glshape::vline(int x, int y1, int y2, ColorP c1, ColorP c2) {
- box(x, y1, x, y2, c1, c1, c2, c2);
-}
-
-void mogltk::glshape::vline(int x, int y1, int y2, ColorP c) {
- box(x, y1, x, y2, c, c, c, c);
-}
-
-void mogltk::glshape::pixel(int x, int y, ColorP c) {
- box(x, y, x, y, c);
-}
-
-void mogltk::glshape::obox(int x1, int y1, int x2, int y2, ColorP c) {
- ENTER;
- shape::obox(x1, y1, x2, y2, c);
- LEAVE;
-}
-
-void mogltk::glshape::obox(int x1, int y1, int x2, int y2, ColorP c1, ColorP c2, ColorP c3, ColorP c4) {
- ENTER;
-
- hline(x1, x2, y1, c1, c2);
- hline(x1, x2, y2, c3, c4);
- vline(x1, y1 + 1, y2 - 1, c1, c3);
- vline(x2, y1 + 1, y2 - 1, c2, c4);
-
- LEAVE;
-}
-
-void mogltk::glshape::tbox(mogltk::texture * t, int x1, int y1, int x2, int y2, int tx, int ty, double f, ColorP c) {
- tbox(t, x1, y1, x2, y2, tx, ty, tx + (int) ((x2 - x1) * f), ty + (int) ((y2 - y1) * f), c);
-}
-void mogltk::glshape::tbox(mogltk::texture * t, int x1, int y1, int x2, int y2, int tx1, int ty1, int tx2, int ty2, ColorP c) {
- ENTERT;
-
- c.Bind();
- t->Bind();
- glBegin(GL_TRIANGLE_STRIP);
- glTexCoord2i(tx1, ty1); glVertex2i(x1, y1);
- glTexCoord2i(tx2 + 1, ty1); glVertex2i(x2 + 1, y1);
- glTexCoord2i(tx1, ty2 + 1); glVertex2i(x1, y2 + 1);
- glTexCoord2i(tx2 + 1, ty2 + 1); glVertex2i(x2 + 1, y2 + 1);
- glEnd();
-
- LEAVE;
-}
-
-void mogltk::glshape::tbox(mogltk::texture * t, int x1, int y1, int x2, int y2, ColorP c1, ColorP c2, ColorP c3, ColorP c4, int tx, int ty, double f) {
- tbox(t, x1, y1, x2, y2, c1, c2, c3, c4, tx, ty, tx + (int) ((x2 - x1) * f), ty + (int) ((y2 - y1) * f));
-}
-
-void mogltk::glshape::tbox(mogltk::texture * t, int x1, int y1, int x2, int y2, ColorP c1, ColorP c2, ColorP c3, ColorP c4, int tx1, int ty1, int tx2, int ty2) {
- ENTERT;
-
- t->Bind();
- glBegin(GL_TRIANGLE_STRIP);
- c1.Bind(); glTexCoord2i(tx1, ty1); glVertex2i(x1, y1);
- c2.Bind(); glTexCoord2i(tx2 + 1, ty1); glVertex2i(x2 + 1, y1);
- c3.Bind(); glTexCoord2i(tx1, ty2 + 1); glVertex2i(x1, y2 + 1);
- c4.Bind(); glTexCoord2i(tx2 + 1, ty2 + 1); glVertex2i(x2 + 1, y2 + 1);
- glEnd();
-
- LEAVE;
-}
-
-void mogltk::glshape::box3d(int x1, int y1, int x2, int y2, ColorP face, ColorP shade1, ColorP shade2, int depth, bool bevel) {
- ENTER;
-
- if (!bevel) {
- shade1.Bind();
- } else {
- shade2.Bind();
- }
- glBegin(GL_TRIANGLE_FAN);
- glVertex2i(x1, y1);
- glVertex2i(x2 + 1, y1);
- glVertex2i(x2 + 1 - depth, y1 + depth);
- glVertex2i(x1 + depth, y2 + 1 - depth);
- glVertex2i(x1, y2 + 1);
- glEnd();
-
- if (!bevel) {
- shade2.Bind();
- } else {
- shade1.Bind();
- }
- glBegin(GL_TRIANGLE_FAN);
- glVertex2i(x2 + 1, y2 + 1);
- glVertex2i(x1, y2 + 1);
- glVertex2i(x1 + depth, y2 + 1 - depth);
- glVertex2i(x2 + 1 - depth, y1 + depth);
- glVertex2i(x2 + 1, y1);
- glEnd();
-
- face.Bind();
- glBegin(GL_TRIANGLE_STRIP);
- glVertex2i(x1 + depth, y1 + depth);
- glVertex2i(x2 + 1 - depth, y1 + depth);
- glVertex2i(x1 + depth, y2 + 1 - depth);
- glVertex2i(x2 + 1 - depth, y2 + 1 - depth);
- glEnd();
-
- LEAVE;
-}
-
-bool mogltk::glshape::Enter(bool unbind) {
- bool was2D = mogltk::engine::glbase_o->is2D();
-
- if (!was2D)
- mogltk::engine::glbase_o->Enter2DMode();
-
- if (unbind) mogltk::texture::Unbind();
-
- return was2D;
-}
-
-bool mogltk::glshape::Enter() {
- return Enter(true);
-}
-
-void mogltk::glshape::Leave(bool was2D) {
- if (!was2D)
- mogltk::engine::glbase_o->Leave2DMode();
-}
-
-void mogltk::glshape::fdraw(fill * f, ColorP c, int sx, int sy) {
- ENTERT;
-
- if (!f)
- return;
-
- texture * t = f->GetTexture();
-
- if (!t) {
- filldrawer * w = new filldrawer(f, t = f->Talloc(), WHITE);
- f->walk(w);
- delete w;
- }
-
- c.Bind();
- t->Bind();
- int w = t->GetWidth();
- int h = t->GetHeight();
- int x = f->GetMinX() + sx;
- int y = f->GetMinY() + sy;
-
- glBegin(GL_TRIANGLE_STRIP);
- glTexCoord2i(0, 0); glVertex2i(x , y );
- glTexCoord2i(w, 0); glVertex2i(x + w, y );
- glTexCoord2i(0, h); glVertex2i(x , y + h);
- glTexCoord2i(w, h); glVertex2i(x + w, y + h);
- glEnd();
-
- LEAVE;
-}
-
-void mogltk::glshape::sdraw(fill * f, ColorP c, int sx, int sy) {
- ENTERT;
-
- if (!f)
- return;
-
- texture * t = f->GetSTexture();
-
- if (!t) {
- segdrawer * w = new segdrawer(f, t = f->STalloc(), WHITE);
- f->swalk(w);
- delete w;
- }
-
- c.Bind();
- t->Bind();
- int w = t->GetWidth();
- int h = t->GetHeight();
- int x = f->GetMinX() + sx;
- int y = f->GetMinY() + sy;
-
- glBegin(GL_TRIANGLE_STRIP);
- glTexCoord2i(0, 0); glVertex2i(x , y );
- glTexCoord2i(w, 0); glVertex2i(x + w, y );
- glTexCoord2i(0, h); glVertex2i(x , y + h);
- glTexCoord2i(w, h); glVertex2i(x + w, y + h);
- glEnd();
-
- LEAVE;
-}
+/*
+ * mogltk
+ * Copyright (C) 1999-2004 Nicolas "Pixel" Noble
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: glshape.cc,v 1.16 2004-11-27 21:48:03 pixel Exp $ */
+
+#include <SDL_opengl.h>
+#include "glbase.h"
+#include "glshape.h"
+#include "texture.h"
+#include "glfont.h"
+#include "engine.h"
+
+#define ENTER bool was2d = Enter(true)
+#define ENTERT bool was2d = Enter(false)
+#define LEAVE Leave(was2d)
+
+void mogltk::glshape::box(int x1, int y1, int x2, int y2, ColorP c) {
+ ENTER;
+
+ c.Bind();
+ glBegin(GL_TRIANGLE_STRIP);
+ glVertex2i(x1, y1);
+ glVertex2i(x2 + 1, y1);
+ glVertex2i(x1, y2 + 1);
+ glVertex2i(x2 + 1, y2 + 1);
+ glEnd();
+
+ LEAVE;
+}
+
+void mogltk::glshape::box(int x1, int y1, int x2, int y2, ColorP c1, ColorP c2, ColorP c3, ColorP c4) {
+ ENTER;
+
+ glBegin(GL_TRIANGLE_STRIP);
+ c1.Bind(); glVertex2i(x1, y1);
+ c2.Bind(); glVertex2i(x2 + 1, y1);
+ c3.Bind(); glVertex2i(x1, y2 + 1);
+ c4.Bind(); glVertex2i(x2 + 1, y2 + 1);
+ glEnd();
+
+ LEAVE;
+}
+
+void mogltk::glshape::hline(int x1, int x2, int y, ColorP c1, ColorP c2) {
+ box(x1, y, x2, y, c1, c2, c1, c2);
+}
+
+void mogltk::glshape::hline(int x1, int x2, int y, ColorP c) {
+ box(x1, y, x2, y, c, c, c, c);
+}
+
+void mogltk::glshape::vline(int x, int y1, int y2, ColorP c1, ColorP c2) {
+ box(x, y1, x, y2, c1, c1, c2, c2);
+}
+
+void mogltk::glshape::vline(int x, int y1, int y2, ColorP c) {
+ box(x, y1, x, y2, c, c, c, c);
+}
+
+void mogltk::glshape::pixel(int x, int y, ColorP c) {
+ box(x, y, x, y, c);
+}
+
+void mogltk::glshape::obox(int x1, int y1, int x2, int y2, ColorP c) {
+ ENTER;
+ shape::obox(x1, y1, x2, y2, c);
+ LEAVE;
+}
+
+void mogltk::glshape::obox(int x1, int y1, int x2, int y2, ColorP c1, ColorP c2, ColorP c3, ColorP c4) {
+ ENTER;
+
+ hline(x1, x2, y1, c1, c2);
+ hline(x1, x2, y2, c3, c4);
+ vline(x1, y1 + 1, y2 - 1, c1, c3);
+ vline(x2, y1 + 1, y2 - 1, c2, c4);
+
+ LEAVE;
+}
+
+void mogltk::glshape::tbox(mogltk::texture * t, int x1, int y1, int x2, int y2, int tx, int ty, double f, ColorP c) {
+ tbox(t, x1, y1, x2, y2, tx, ty, tx + (int) ((x2 - x1) * f), ty + (int) ((y2 - y1) * f), c);
+}
+void mogltk::glshape::tbox(mogltk::texture * t, int x1, int y1, int x2, int y2, int tx1, int ty1, int tx2, int ty2, ColorP c) {
+ ENTERT;
+
+ c.Bind();
+ t->Bind();
+ glBegin(GL_TRIANGLE_STRIP);
+ glTexCoord2i(tx1, ty1); glVertex2i(x1, y1);
+ glTexCoord2i(tx2 + 1, ty1); glVertex2i(x2 + 1, y1);
+ glTexCoord2i(tx1, ty2 + 1); glVertex2i(x1, y2 + 1);
+ glTexCoord2i(tx2 + 1, ty2 + 1); glVertex2i(x2 + 1, y2 + 1);
+ glEnd();
+
+ LEAVE;
+}
+
+void mogltk::glshape::tbox(mogltk::texture * t, int x1, int y1, int x2, int y2, ColorP c1, ColorP c2, ColorP c3, ColorP c4, int tx, int ty, double f) {
+ tbox(t, x1, y1, x2, y2, c1, c2, c3, c4, tx, ty, tx + (int) ((x2 - x1) * f), ty + (int) ((y2 - y1) * f));
+}
+
+void mogltk::glshape::tbox(mogltk::texture * t, int x1, int y1, int x2, int y2, ColorP c1, ColorP c2, ColorP c3, ColorP c4, int tx1, int ty1, int tx2, int ty2) {
+ ENTERT;
+
+ t->Bind();
+ glBegin(GL_TRIANGLE_STRIP);
+ c1.Bind(); glTexCoord2i(tx1, ty1); glVertex2i(x1, y1);
+ c2.Bind(); glTexCoord2i(tx2 + 1, ty1); glVertex2i(x2 + 1, y1);
+ c3.Bind(); glTexCoord2i(tx1, ty2 + 1); glVertex2i(x1, y2 + 1);
+ c4.Bind(); glTexCoord2i(tx2 + 1, ty2 + 1); glVertex2i(x2 + 1, y2 + 1);
+ glEnd();
+
+ LEAVE;
+}
+
+void mogltk::glshape::box3d(int x1, int y1, int x2, int y2, ColorP face, ColorP shade1, ColorP shade2, int depth, bool bevel) {
+ ENTER;
+
+ if (!bevel) {
+ shade1.Bind();
+ } else {
+ shade2.Bind();
+ }
+ glBegin(GL_TRIANGLE_FAN);
+ glVertex2i(x1, y1);
+ glVertex2i(x2 + 1, y1);
+ glVertex2i(x2 + 1 - depth, y1 + depth);
+ glVertex2i(x1 + depth, y2 + 1 - depth);
+ glVertex2i(x1, y2 + 1);
+ glEnd();
+
+ if (!bevel) {
+ shade2.Bind();
+ } else {
+ shade1.Bind();
+ }
+ glBegin(GL_TRIANGLE_FAN);
+ glVertex2i(x2 + 1, y2 + 1);
+ glVertex2i(x1, y2 + 1);
+ glVertex2i(x1 + depth, y2 + 1 - depth);
+ glVertex2i(x2 + 1 - depth, y1 + depth);
+ glVertex2i(x2 + 1, y1);
+ glEnd();
+
+ face.Bind();
+ glBegin(GL_TRIANGLE_STRIP);
+ glVertex2i(x1 + depth, y1 + depth);
+ glVertex2i(x2 + 1 - depth, y1 + depth);
+ glVertex2i(x1 + depth, y2 + 1 - depth);
+ glVertex2i(x2 + 1 - depth, y2 + 1 - depth);
+ glEnd();
+
+ LEAVE;
+}
+
+bool mogltk::glshape::Enter(bool unbind) {
+ bool was2D = mogltk::engine::glbase_o->is2D();
+
+ if (!was2D)
+ mogltk::engine::glbase_o->Enter2DMode();
+
+ if (unbind) mogltk::texture::Unbind();
+
+ return was2D;
+}
+
+bool mogltk::glshape::Enter() {
+ return Enter(true);
+}
+
+void mogltk::glshape::Leave(bool was2D) {
+ if (!was2D)
+ mogltk::engine::glbase_o->Leave2DMode();
+}
+
+void mogltk::glshape::fdraw(fill * f, ColorP c, int sx, int sy) {
+ ENTERT;
+
+ if (!f)
+ return;
+
+ texture * t = f->GetTexture();
+
+ if (!t) {
+ filldrawer * w = new filldrawer(f, t = f->Talloc(), WHITE);
+ f->walk(w);
+ delete w;
+ }
+
+ c.Bind();
+ t->Bind();
+ int w = t->GetWidth();
+ int h = t->GetHeight();
+ int x = f->GetMinX() + sx;
+ int y = f->GetMinY() + sy;
+
+ glBegin(GL_TRIANGLE_STRIP);
+ glTexCoord2i(0, 0); glVertex2i(x , y );
+ glTexCoord2i(w, 0); glVertex2i(x + w, y );
+ glTexCoord2i(0, h); glVertex2i(x , y + h);
+ glTexCoord2i(w, h); glVertex2i(x + w, y + h);
+ glEnd();
+
+ LEAVE;
+}
+
+void mogltk::glshape::sdraw(fill * f, ColorP c, int sx, int sy) {
+ ENTERT;
+
+ if (!f)
+ return;
+
+ texture * t = f->GetSTexture();
+
+ if (!t) {
+ segdrawer * w = new segdrawer(f, t = f->STalloc(), WHITE);
+ f->swalk(w);
+ delete w;
+ }
+
+ c.Bind();
+ t->Bind();
+ int w = t->GetWidth();
+ int h = t->GetHeight();
+ int x = f->GetMinX() + sx;
+ int y = f->GetMinY() + sy;
+
+ glBegin(GL_TRIANGLE_STRIP);
+ glTexCoord2i(0, 0); glVertex2i(x , y );
+ glTexCoord2i(w, 0); glVertex2i(x + w, y );
+ glTexCoord2i(0, h); glVertex2i(x , y + h);
+ glTexCoord2i(w, h); glVertex2i(x + w, y + h);
+ glEnd();
+
+ LEAVE;
+}
diff --git a/lib/glsprite.cc b/lib/glsprite.cc
index 7091ca3..49db695 100644
--- a/lib/glsprite.cc
+++ b/lib/glsprite.cc
@@ -1,105 +1,105 @@
-/*
- * mogltk
- * Copyright (C) 1999-2004 Nicolas "Pixel" Noble
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* $Id: glsprite.cc,v 1.10 2004-11-27 21:44:53 pixel Exp $ */
-
-#include <SDL.h>
-#include "glbase.h"
-#include "glsprite.h"
-#include "engine.h"
-
-#define TEXSIZE 256
-
-mogltk::glSprite::glSprite(Handle * h, int asx, int asy) : Sprite(h, asx, asy) {
-}
-
-mogltk::glSprite::glSprite(Uint8 * p, int asx, int asy) : Sprite(p, asx, asy) {
-}
-
-mogltk::glSprite::~glSprite() {
-}
-
-void mogltk::glSprite::draw(int dx, int dy, ColorP c, float sx, float sy) {
- bool was2D;
-
- if (!(was2D = mogltk::engine::glbase_o->is2D()))
- mogltk::engine::glbase_o->Enter2DMode();
-
- c.Bind();
-
- Bind();
- glBegin(GL_TRIANGLE_STRIP);
- glTexCoord2i(GetPX() , GetPY() ); glVertex2i(dx , dy );
- glTexCoord2i(GetPX() + GetSX(), GetPY() ); glVertex2i(dx + GetSX() * sx, dy );
- glTexCoord2i(GetPX() , GetPY() + GetSY()); glVertex2i(dx , dy + GetSY() * sy);
- glTexCoord2i(GetPX() + GetSX(), GetPY() + GetSY()); glVertex2i(dx + GetSX() * sx, dy + GetSY() * sy);
- glEnd();
-
- if (!was2D)
- mogltk::engine::glbase_o->Leave2DMode();
-}
-
-void mogltk::glSprite::bindcorner(float fx, float fy) {
- if (fx > 1)
- fx = 1;
- if (fy > 1)
- fy = 1;
- if (fx < 0)
- fx = 0;
- if (fy < 0)
- fy = 0;
- glTexCoord2i(GetPX() + fx * GetSX(), GetPY() + fy * GetSY());
-}
-
-void mogltk::glSprite::drawrotate(int cx, int cy, double a, ColorP c) {
- bool was2D;
-
- int sx, sy;
-
- sx = GetSX() / 2;
- sy = GetSY() / 2;
-
- was2D = mogltk::engine::glbase_o->is2D();
-
- if (!was2D)
- mogltk::engine::glbase_o->Enter2DMode();
-
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glTranslated(cx, cy, 0);
- glRotated(a, 0, 0, 1);
-
-// glMatrixMode(GL_TEXTURE);
-// glRotated(a, 0, 0, 1);
-
- c.Bind();
-
- Bind();
- glBegin(GL_TRIANGLE_STRIP);
- glTexCoord2i(GetPX() , GetPY() ); glVertex2i( - sx, - sy);
- glTexCoord2i(GetPX() + GetSX(), GetPY() ); glVertex2i(GetSX() - sx, - sy);
- glTexCoord2i(GetPX() , GetPY() + GetSY()); glVertex2i( - sx, GetSY() - sy);
- glTexCoord2i(GetPX() + GetSX(), GetPY() + GetSY()); glVertex2i(GetSX() - sx, GetSY() - sy);
- glEnd();
-
- glPopMatrix();
-
- if (!was2D)
- mogltk::engine::glbase_o->Leave2DMode();
-}
+/*
+ * mogltk
+ * Copyright (C) 1999-2004 Nicolas "Pixel" Noble
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: glsprite.cc,v 1.11 2004-11-27 21:48:03 pixel Exp $ */
+
+#include <SDL.h>
+#include "glbase.h"
+#include "glsprite.h"
+#include "engine.h"
+
+#define TEXSIZE 256
+
+mogltk::glSprite::glSprite(Handle * h, int asx, int asy) : Sprite(h, asx, asy) {
+}
+
+mogltk::glSprite::glSprite(Uint8 * p, int asx, int asy) : Sprite(p, asx, asy) {
+}
+
+mogltk::glSprite::~glSprite() {
+}
+
+void mogltk::glSprite::draw(int dx, int dy, ColorP c, float sx, float sy) {
+ bool was2D;
+
+ if (!(was2D = mogltk::engine::glbase_o->is2D()))
+ mogltk::engine::glbase_o->Enter2DMode();
+
+ c.Bind();
+
+ Bind();
+ glBegin(GL_TRIANGLE_STRIP);
+ glTexCoord2i(GetPX() , GetPY() ); glVertex2i(dx , dy );
+ glTexCoord2i(GetPX() + GetSX(), GetPY() ); glVertex2i(dx + GetSX() * sx, dy );
+ glTexCoord2i(GetPX() , GetPY() + GetSY()); glVertex2i(dx , dy + GetSY() * sy);
+ glTexCoord2i(GetPX() + GetSX(), GetPY() + GetSY()); glVertex2i(dx + GetSX() * sx, dy + GetSY() * sy);
+ glEnd();
+
+ if (!was2D)
+ mogltk::engine::glbase_o->Leave2DMode();
+}
+
+void mogltk::glSprite::bindcorner(float fx, float fy) {
+ if (fx > 1)
+ fx = 1;
+ if (fy > 1)
+ fy = 1;
+ if (fx < 0)
+ fx = 0;
+ if (fy < 0)
+ fy = 0;
+ glTexCoord2i(GetPX() + fx * GetSX(), GetPY() + fy * GetSY());
+}
+
+void mogltk::glSprite::drawrotate(int cx, int cy, double a, ColorP c) {
+ bool was2D;
+
+ int sx, sy;
+
+ sx = GetSX() / 2;
+ sy = GetSY() / 2;
+
+ was2D = mogltk::engine::glbase_o->is2D();
+
+ if (!was2D)
+ mogltk::engine::glbase_o->Enter2DMode();
+
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glTranslated(cx, cy, 0);
+ glRotated(a, 0, 0, 1);
+
+// glMatrixMode(GL_TEXTURE);
+// glRotated(a, 0, 0, 1);
+
+ c.Bind();
+
+ Bind();
+ glBegin(GL_TRIANGLE_STRIP);
+ glTexCoord2i(GetPX() , GetPY() ); glVertex2i( - sx, - sy);
+ glTexCoord2i(GetPX() + GetSX(), GetPY() ); glVertex2i(GetSX() - sx, - sy);
+ glTexCoord2i(GetPX() , GetPY() + GetSY()); glVertex2i( - sx, GetSY() - sy);
+ glTexCoord2i(GetPX() + GetSX(), GetPY() + GetSY()); glVertex2i(GetSX() - sx, GetSY() - sy);
+ glEnd();
+
+ glPopMatrix();
+
+ if (!was2D)
+ mogltk::engine::glbase_o->Leave2DMode();
+}
diff --git a/lib/glwidgets.cc b/lib/glwidgets.cc
index be3617f..5ff8c23 100644
--- a/lib/glwidgets.cc
+++ b/lib/glwidgets.cc
@@ -1,29 +1,29 @@
-/*
- * mogltk
- * Copyright (C) 1999-2004 Nicolas "Pixel" Noble
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* $Id: glwidgets.cc,v 1.8 2004-11-27 21:44:53 pixel Exp $ */
-
-#include <SDL.h>
-#include <SDL_opengl.h>
-#include "mcolor.h"
-#include "glwidgets.h"
-
-void mogltk::widgets::glRoot::draw() {
- Shaper()->box(GetAX(), GetAY(), GetAX2(), GetAY2());
-}
+/*
+ * mogltk
+ * Copyright (C) 1999-2004 Nicolas "Pixel" Noble
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: glwidgets.cc,v 1.9 2004-11-27 21:48:03 pixel Exp $ */
+
+#include <SDL.h>
+#include <SDL_opengl.h>
+#include "mcolor.h"
+#include "glwidgets.h"
+
+void mogltk::widgets::glRoot::draw() {
+ Shaper()->box(GetAX(), GetAY(), GetAX2(), GetAY2());
+}
diff --git a/lib/mcolor.cc b/lib/mcolor.cc
index df75007..e2a921d 100644
--- a/lib/mcolor.cc
+++ b/lib/mcolor.cc
@@ -1,66 +1,66 @@
-/*
- * mogltk
- * Copyright (C) 1999-2004 Nicolas "Pixel" Noble
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* $Id: mcolor.cc,v 1.7 2004-11-27 21:44:53 pixel Exp $ */
-
-#include <SDL.h>
-#include <SDL_opengl.h>
-#include "engine.h"
-#include "mcolor.h"
-
-Color mogltk::ColorP::Min(0, 0, 0, 0), mogltk::ColorP::Max = WHITE;
-
-mogltk::ColorP::ColorP(const Color & ac) : c(ac) {
-}
-
-mogltk::ColorP::ColorP(Uint8 ar, Uint8 ag, Uint8 ab, Uint8 aa) : c(ar, ag, ab, aa) {
-}
-
-void mogltk::ColorP::Bind() {
- glColor4d((double) MIN(MAX(c.R, Min.R), Max.R) / 255, (double) MIN(MAX(c.G, Min.G), Max.G) / 255, (double) MIN(MAX(c.B, Min.B), Max.B) / 255, (double) MIN(MAX(c.A, Min.A), Max.A) / 255);
-}
-
-Uint32 mogltk::ColorP::toSDL(SDL_PixelFormat * f) {
- if (!f)
- f = mogltk::engine::base_o->getsurface()->format;
-
- return SDL_MapRGBA(f, MIN(MAX(c.R, Min.R), Max.R), MIN(MAX(c.G, Min.G), Max.G), MIN(MAX(c.B, Min.B), Max.B), MIN(MAX(c.A, Min.A), Max.A));
-}
-
-void mogltk::ColorP::fromSDL(Uint32 p, SDL_PixelFormat * f) {
- if (!f)
- f = mogltk::engine::base_o->getsurface()->format;
-
- SDL_GetRGBA(p, f, &c.R, &c.G, &c.B, &c.A);
-}
-
-void mogltk::ColorP::Norm() {
- c.R = MIN(MAX(c.R, Min.R), Max.R);
- c.G = MIN(MAX(c.R, Min.G), Max.G);
- c.B = MIN(MAX(c.R, Min.B), Max.B);
- c.A = MIN(MAX(c.R, Min.A), Max.A);
-}
-
-bool mogltk::ColorP::operator==(const ColorP & nc) {
- return c == nc.c;
-}
-
-Color * mogltk::ColorP::operator->() {
- return &c;
-}
+/*
+ * mogltk
+ * Copyright (C) 1999-2004 Nicolas "Pixel" Noble
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: mcolor.cc,v 1.8 2004-11-27 21:48:03 pixel Exp $ */
+
+#include <SDL.h>
+#include <SDL_opengl.h>
+#include "engine.h"
+#include "mcolor.h"
+
+Color mogltk::ColorP::Min(0, 0, 0, 0), mogltk::ColorP::Max = WHITE;
+
+mogltk::ColorP::ColorP(const Color & ac) : c(ac) {
+}
+
+mogltk::ColorP::ColorP(Uint8 ar, Uint8 ag, Uint8 ab, Uint8 aa) : c(ar, ag, ab, aa) {
+}
+
+void mogltk::ColorP::Bind() {
+ glColor4d((double) MIN(MAX(c.R, Min.R), Max.R) / 255, (double) MIN(MAX(c.G, Min.G), Max.G) / 255, (double) MIN(MAX(c.B, Min.B), Max.B) / 255, (double) MIN(MAX(c.A, Min.A), Max.A) / 255);
+}
+
+Uint32 mogltk::ColorP::toSDL(SDL_PixelFormat * f) {
+ if (!f)
+ f = mogltk::engine::base_o->getsurface()->format;
+
+ return SDL_MapRGBA(f, MIN(MAX(c.R, Min.R), Max.R), MIN(MAX(c.G, Min.G), Max.G), MIN(MAX(c.B, Min.B), Max.B), MIN(MAX(c.A, Min.A), Max.A));
+}
+
+void mogltk::ColorP::fromSDL(Uint32 p, SDL_PixelFormat * f) {
+ if (!f)
+ f = mogltk::engine::base_o->getsurface()->format;
+
+ SDL_GetRGBA(p, f, &c.R, &c.G, &c.B, &c.A);
+}
+
+void mogltk::ColorP::Norm() {
+ c.R = MIN(MAX(c.R, Min.R), Max.R);
+ c.G = MIN(MAX(c.R, Min.G), Max.G);
+ c.B = MIN(MAX(c.R, Min.B), Max.B);
+ c.A = MIN(MAX(c.R, Min.A), Max.A);
+}
+
+bool mogltk::ColorP::operator==(const ColorP & nc) {
+ return c == nc.c;
+}
+
+Color * mogltk::ColorP::operator->() {
+ return &c;
+}
diff --git a/lib/shape.cc b/lib/shape.cc
index 2a493cb..a7ed137 100644
--- a/lib/shape.cc
+++ b/lib/shape.cc
@@ -1,928 +1,928 @@
-/*
- * mogltk
- * Copyright (C) 1999-2004 Nicolas "Pixel" Noble
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* $Id: shape.cc,v 1.18 2004-11-27 21:44:53 pixel Exp $ */
-
-#include <math.h>
-#include <limits.h>
-#include <SDL.h>
-#include <sys/types.h>
-#include <generic.h>
-#include "engine.h"
-#include "base.h"
-#include "shape.h"
-#include "texture.h"
-#include "font.h"
-
-#define ENTER bool flag = Enter()
-#define LEAVE Leave(flag)
-
-mogltk::fillwalker::fillwalker() {
-}
-
-mogltk::fillwalker::~fillwalker() {
-}
-
-void mogltk::fillwalker::step(int x, int y) {
-}
-
-mogltk::segwalker::segwalker() {
-}
-
-mogltk::segwalker::~segwalker() {
-}
-
-void mogltk::segwalker::step(int x1, int y1, int x2, int y2) {
-}
-
-mogltk::fill::fill() : minX(INT_MAX), minY(INT_MAX), maxX(INT_MIN), maxY(INT_MIN), cached(0), scached(0), header(0) {
-}
-
-mogltk::fill::~fill() {
- if (header)
- delete header;
-
- if (cached)
- delete cached;
-
- if (scached)
- delete scached;
-}
-
-void mogltk::fill::walk(fillwalker * w) {
- if (header)
- header->walk(w);
-}
-
-void mogltk::fill::swalk(segwalker * s) {
- std::vector<struct segment>::iterator i;
-
- for (i = segments.begin(); i != segments.end(); i++) {
- s->step(i->x1, i->y1, i->x2, i->y2);
- }
-}
-
-void mogltk::fill::insert(int x, int y) {
- if (cached) {
- delete cached;
- cached = 0;
- }
-
- if (scached) {
- delete scached;
- scached = 0;
- }
-
- if (!header) {
- new sline(y, this);
- }
- header->insert(x, y);
-
- if (x > maxX)
- maxX = x;
-
- if (x < minX)
- minX = x;
-
- if (y > maxY)
- maxY = y;
-
- if (y < minY)
- minY = y;
-}
-
-void mogltk::fill::insert(int x1, int y1, int x2, int y2) {
- int dx, dy, y;
- double x, i, i2;
-
- struct segment s;
- s.x1 = x1;
- s.y1 = y1;
- s.x2 = x2;
- s.y2 = y2;
- segments.push_back(s);
-
- if (y1 == y2)
- return;
-
- if (y2 < y1) {
- SWAP(x1, x2);
- SWAP(y1, y2);
- }
-
- dx = x1 - x2;
- dy = y1 - y2;
-
- x = x1;
- i = ((double) dx) / ((double) dy);
- i2 = i / 2;
- for (y = y1; y < y2; y++, x += i)
- insert(x + i2, y);
-}
-
-void mogltk::fill::insertfix(int x, int y) {
- if (!header)
- return;
-
- header->insertfix(x, y);
-}
-
-int mogltk::fill::GetMaxX() const {
- return maxX;
-}
-
-int mogltk::fill::GetMaxY() const {
- return maxY;
-}
-
-int mogltk::fill::GetMinX() const {
- return minX;
-}
-
-int mogltk::fill::GetMinY() const {
- return minY;
-}
-
-mogltk::texture * mogltk::fill::GetTexture() {
- return cached;
-}
-
-mogltk::texture * mogltk::fill::GetSTexture() {
- return scached;
-}
-
-mogltk::texture * mogltk::fill::Talloc() {
- if (cached)
- return cached;
-
- int x; int y;
-
- for (x = 1; x <= (maxX - minX); x <<= 1);
- for (y = 1; y <= (maxY - minY); y <<= 1);
-
- cached = new texture(x, y, true);
- return cached;
-}
-
-mogltk::texture * mogltk::fill::STalloc() {
- if (scached)
- return scached;
-
- int x; int y;
-
- for (x = 1; x <= (maxX - minX); x <<= 1);
- for (y = 1; y <= (maxY - minY); y <<= 1);
-
- scached = new texture(x, y, true);
- return scached;
-}
-
-mogltk::fill::sline::sline(int _y, fill * _header) : y(_y), header(_header), pheader(0) {
- if (!header->header) {
- header->header = this;
- } else {
- if (header->header->y > y) {
- next = header->header;
- header->header = this;
- } else {
- sline * p;
- for (p = header->header; p->next; p = p->next) {
- if (p->next->y > y) {
- next = p->next;
- p->next = this;
- return;
- }
- }
- p->next = this;
- next = 0;
- }
- }
-}
-
-mogltk::fill::sline::~sline() {
- if (pheader)
- delete pheader;
- if (next)
- delete next;
-}
-
-int mogltk::fill::sline::GetY() const {
- return y;
-}
-
-void mogltk::fill::sline::insert(int ax, int ay) {
- sline * f;
-
- if (ay == y) {
- if (!pheader)
- new point(ax, this);
- else if (!pheader->look(ax))
- new point(ax, this);
- } else {
- f = header->header->look(ay);
-
- if (!f) {
- f = new sline(ay, header);
- }
-
- f->insert(ax, ay);
- }
-}
-
-void mogltk::fill::sline::insertfix(int ax, int ay) {
- sline * f;
-
- if (ay == y) {
- if (count() & 1) {
- insert(ax, ay);
- }
- } else {
- f = header->header->look(ay);
- if (!f)
- return;
-
- f->insertfix(ax, ay);
- }
-}
-
-int mogltk::fill::sline::count() const {
- int r = 0;
-
- if (next)
- r = next->count();
-
- return r + 1;
-}
-
-void mogltk::fill::sline::walk(fillwalker * w) {
- if (pheader)
- pheader->walk(w);
- if (next)
- next->walk(w);
-}
-
-mogltk::fill::sline::point::point(int _x, sline * _header) : x(_x), header(_header) {
- if (!header->pheader) {
- header->pheader = this;
- } else {
- if (header->pheader->x > x) {
- next = header->pheader;
- header->pheader = this;
- } else {
- point * p;
- for (p = header->pheader; p->next; p = p->next) {
- if (p->next->x > x) {
- next = p->next;
- p->next = this;
- return;
- }
- }
- p->next = this;
- next = 0;
- }
- }
-}
-
-mogltk::fill::sline::point::~point() {
- if (next)
- delete next;
-}
-
-int mogltk::fill::sline::point::GetX() const {
- return x;
-}
-
-int mogltk::fill::sline::point::GetY() const {
- return header->GetY();
-}
-
-void mogltk::fill::sline::point::walk(fillwalker * w) {
- w->step(GetX(), GetY());
- if (next)
- next->walk(w);
-}
-
-mogltk::fill::sline::point * mogltk::fill::sline::point::look(int _x) {
- if (x > _x)
- return 0;
-
- if (x == _x)
- return this;
-
- if (!next)
- return 0;
-
- return next->look(_x);
-}
-
-mogltk::fill::sline * mogltk::fill::sline::look(int _y) {
- if (y > _y)
- return 0;
-
- if (y == _y)
- return this;
-
- if (!next)
- return 0;
-
- return next->look(_y);
-}
-
-mogltk::shape::shape(SDL_Surface * _surf) : surf(_surf) {
- if (!surf)
- surf = mogltk::engine::base_o->getsurface();
-}
-
-SDL_Surface * mogltk::shape::GetSurf() {
- return surf;
-}
-
-void mogltk::shape::box(int x1, int y1, int x2, int y2, ColorP c) {
- ENTER;
-
- SDL_Rect rect;
-
- rect.x = x1; rect.y = y1; rect.w = x2 - x1 + 1; rect.h = y2 - y1 + 1;
- SDL_FillRect(surf, &rect, c.toSDL(surf->format));
-
- LEAVE;
-}
-
-void mogltk::shape::hline(int x1, int x2, int y, ColorP c) {
- for (; x1 <= x2; x1++) {
- pixel(x1, y, c);
- }
-}
-
-void mogltk::shape::hline3d(int x1, int x2, int y, ColorP shade1, ColorP shade2, bool bevel) {
- ENTER;
-
- if (!bevel) {
- hline(x1, x2, y, shade2);
- hline(x1, x2, y + 1, shade1);
- } else {
- hline(x1, x2, y, shade1);
- hline(x1, x2, y + 1, shade2);
- }
-
- LEAVE;
-}
-
-void mogltk::shape::vline(int x, int y1, int y2, ColorP c) {
- for (; y1 <= y2; y1++) {
- pixel(x, y1, c);
- }
-}
-
-void mogltk::shape::vline3d(int x, int y1, int y2, ColorP shade1, ColorP shade2, bool bevel) {
- ENTER;
-
- if (!bevel) {
- vline(x, y1, y2, shade2);
- vline(x + 1, y1, y2, shade1);
- } else {
- vline(x, y1, y2, shade1);
- vline(x + 1, y1, y2, shade2);
- }
-
- LEAVE;
-}
-
-void mogltk::shape::bsubline_1(int x1, int y1, int x2, int y2, ColorP c) {
- int x, y, ddx, ddy, e;
- ddx = abs(x2 - x1);
- ddy = abs(y2 - y1) << 1;
- e = ddx - ddy;
- ddx <<= 1;
-
- if (x1 > x2) {
- SWAP(x1, x2);
- SWAP(y1, y2);
- }
-
- ENTER;
-
- for (x = x1, y = y1; x <= x2; x++) {
- pixel(x, y, c);
- if (e < 0) {
- y++;
- e += ddx - ddy;
- } else {
- e -= ddy;
- }
- }
-
- LEAVE;
-}
-
-void mogltk::shape::bsubline_2(int x1, int y1, int x2, int y2, ColorP c) {
- int x, y, ddx, ddy, e;
- ddx = abs(x2 - x1) << 1;
- ddy = abs(y2 - y1);
- e = ddy - ddx;
- ddy <<= 1;
-
- if (y1 > y2) {
- SWAP(x1, x2);
- SWAP(y1, y2);
- }
-
- ENTER;
-
- for (y = y1, x = x1; y <= y2; y++) {
- pixel(x, y, c);
- if (e < 0) {
- x++;
- e += ddy - ddx;
- } else {
- e -= ddx;
- }
- }
-
- LEAVE;
-}
-
-void mogltk::shape::bsubline_3(int x1, int y1, int x2, int y2, ColorP c) {
- int x, y, ddx, ddy, e;
- ddx = abs(x1 - x2) << 1;
- ddy = abs(y2 - y1);
- e = ddy - ddx;
- ddy <<= 1;
-
- if (y1 > y2) {
- SWAP(x1, x2);
- SWAP(y1, y2);
- }
-
- ENTER;
-
- for (y = y1, x = x1; y <= y2; y++) {
- pixel(x, y, c);
- if (e < 0) {
- x--;
- e += ddy - ddx;
- } else {
- e -= ddx;
- }
- }
-
- LEAVE;
-}
-
-void mogltk::shape::bsubline_4(int x1, int y1, int x2, int y2, ColorP c) {
- int x, y, ddx, ddy, e;
- ddy = abs(y2 - y1) << 1;
- ddx = abs(x1 - x2);
- e = ddx - ddy;
- ddx <<= 1;
-
- if (x1 > x2) {
- SWAP(x1, x2);
- SWAP(y1, y2);
- }
-
- for (x = x1, y = y1; x <= x2; x++) {
- pixel(x, y, c);
- if (e < 0) {
- y--;
- e += ddx - ddy;
- } else {
- e -= ddy;
- }
- }
-}
-
-void mogltk::shape::line(int x1, int y1, int x2, int y2, ColorP c) {
- if ((x1 == x2) && (y1 == y2)) {
- printm(M_INFO, "Line is a pixel...\n");
- pixel(x1, y1, c);
- return;
- }
-
- if (x1 == x2) {
- vline(x1, MIN(y1, y2), MAX(y1, y2), c);
- return;
- }
-
- if (y1 == y2) {
- hline(MIN(x1, x2), MAX(x1, x2), y1, c);
- return;
- }
-
- float k = float(y2 - y1) / float(x2 - x1);
-
- if ((k >= 0) && (k <= 1)) {
- bsubline_1(x1, y1, x2, y2, c);
- } else if (k > 1) {
- bsubline_2(x1, y1, x2, y2, c);
- } else if ((k < 0) && (k >= -1)) {
- bsubline_4(x1, y1, x2, y2, c);
- } else {
- bsubline_3(x1, y1, x2, y2, c);
- }
-}
-
-void mogltk::shape::pixel(int x, int y, ColorP c) {
- ENTER;
-
- int bpp = surf->format->BytesPerPixel;
- Uint8 *p = (Uint8 *)surf->pixels + y * surf->pitch + x * bpp;
- Uint32 pixel = c.toSDL(surf->format);
-
- if ((x < 0) || (y < 0) || (x >= surf->w) || (y >= surf->h)) {
- printm(M_INFO, "Pixel culling, out of bounds.\n");
- return;
- }
-
- switch(bpp) {
- case 1:
- *p = pixel;
- break;
-
- case 2:
- *(Uint16 *)p = pixel;
- break;
-
- case 3:
- if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
- p[0] = (pixel >> 16) & 0xff;
- p[1] = (pixel >> 8) & 0xff;
- p[2] = pixel & 0xff;
- } else {
- p[0] = pixel & 0xff;
- p[1] = (pixel >> 8) & 0xff;
- p[2] = (pixel >> 16) & 0xff;
- }
- break;
-
- case 4:
- *(Uint32 *)p = pixel;
- break;
- }
-
- LEAVE;
-}
-
-void mogltk::shape::circle(int x0, int y0, int r, ColorP c) {
- ENTER;
-
- int x = 0;
- int y = r - 1;
- int d = 3 - 2 * r;
- int dI = 10 - 4 * r;
- int rI = 6;
-
- while (x <= y) {
- pixel(x0 + x, y0 + y, c);
- pixel(x0 - x, y0 + y, c);
- pixel(x0 + x, y0 - y, c);
- pixel(x0 - x, y0 - y, c);
- pixel(x0 + y, y0 + x, c);
- pixel(x0 - y, y0 + x, c);
- pixel(x0 + y, y0 - x, c);
- pixel(x0 - y, y0 - x, c);
- if (d >= 0) {
- d += dI;
- dI += 8;
- y -= 1;
- } else {
- d += rI;
- dI += 4;
- }
- rI += 4;
- x += 1;
- }
-
- LEAVE;
-}
-
-mogltk::fill * mogltk::shape::fcircle(int x0, int y0, int r) {
- int x = 0;
- int y = r - 1;
- int d = 3 - 2 * r;
- int dI = 10 - 4 * r;
- int rI = 6;
- mogltk::fill * f = new fill();
- bool t = false;
- int ox = 0, oy = 0;
-
- while (x <= y) {
-/*
- if (t) {
- f->insert(x0 - x, y0 - y);
- f->insert(x0 + x, y0 - y);
- f->insert(x0 - x, y0 + y);
- f->insert(x0 + x, y0 + y);
- }
- f->insert(x0 - y, y0 - x);
- f->insert(x0 + y, y0 - x);
- f->insert(x0 - y, y0 + x);
- f->insert(x0 + y, y0 + x);
-*/
- if (t) {
- f->insert(x0 - ox, y0 - oy, x0 - x, y0 - y);
- f->insert(x0 + ox, y0 - oy, x0 + x, y0 - y);
- f->insert(x0 - ox, y0 + oy, x0 - x, y0 + y);
- f->insert(x0 + ox, y0 + oy, x0 + x, y0 + y);
- f->insert(x0 - oy, y0 - ox, x0 - y, y0 - x);
- f->insert(x0 + oy, y0 - ox, x0 + y, y0 - x);
- f->insert(x0 - oy, y0 + ox, x0 - y, y0 + x);
- f->insert(x0 + oy, y0 + ox, x0 + y, y0 + x);
- }
- ox = x;
- oy = y;
- t = true;
- if (d >= 0) {
- d += dI;
- dI += 8;
- y -= 1;
- } else {
- d += rI;
- dI += 4;
- }
- rI += 4;
- x += 1;
- }
- return f;
-}
-
-void mogltk::shape::pcircle(int x, int y, int r, ColorP c) {
- fill * f = fcircle(x, y, r);
- fdraw(f, c);
- delete f;
-}
-
-mogltk::filldrawer::filldrawer(fill * _f, texture * _t, ColorP _c) : f(_f), t(_t), c(_c), oldx(-1), oldy(-1) {
-}
-
-mogltk::filldrawer::~filldrawer() {
-}
-
-void mogltk::filldrawer::step(int x, int y) {
- if (oldy != y) {
- oldx = -1;
- }
- if (oldx == -1) {
- oldx = x;
- } else {
-/* s->hline(oldx, x, y, c); */
- Uint32 * p = t->GetPixels();
- int i,
- first = t->GetWidth() * (y - f->GetMinY()) + oldx - f->GetMinX(),
- last = first - oldx + x;
- SDL_PixelFormat * format = t->GetFormat();
-
- for (i = first; i <= last; i++) {
- if (i > (t->GetWidth() * t->GetHeight())) {
- printm(M_ERROR, "Big problem here. i = %i and W, H = %i, %i\n", i, t->GetWidth(), t->GetHeight());
- printm(M_ERROR, "Initially, wanted to draw hline(%i, %i, %i)\n", oldx, x, y);
- printm(M_ERROR, "With MinX = %i and MinY = %i --> hline(%i, %i, %i)\n", f->GetMinX(), f->GetMinY(), oldx - f->GetMinX(), x - f->GetMinX(), y - f->GetMinY());
- printm(M_ERROR, "For info, MaxX = %i and MaxY = %i\n", f->GetMaxX(), f->GetMaxY());
- exit(-1);
- }
- p[i] = c.toSDL(format);
- }
-
- oldx = -1;
- }
- oldy = y;
-}
-
-void mogltk::shape::fdraw(fill * f, ColorP c, int sx, int sy) {
- ENTER;
- if (!f)
- return;
- if (!f->GetTexture()) {
- filldrawer * w = new filldrawer(f, f->Talloc(), c);
- f->walk(w);
- delete w;
- f->last = c.c;
- }
- SDL_PixelFormat * format = f->GetTexture()->GetFormat();
-
- if (f->last == c.c) {
- Uint32 * p = f->GetTexture()->GetPixels();
- int i, n = f->GetTexture()->GetWidth() * f->GetTexture()->GetHeight();
- for (i = 0; i < n; i++)
- if (p[i] & 0xff000000)
- p[i] = c.toSDL(format);
- }
- SDL_Rect r;
- r.x = f->GetMinX() + sx;
- r.y = f->GetMinY() + sy;
- SDL_BlitSurface(f->GetTexture()->GetSurface(), 0, surf, &r);
-
- f->last = c.c;
- LEAVE;
-}
-
-mogltk::segdrawer::segdrawer(fill * _f, texture * _t, ColorP _c) : f(_f), t(_t), c(_c), sh(new shape(_t->GetSurface())) {
-}
-
-mogltk::segdrawer::~segdrawer() {
- delete sh;
-}
-
-void mogltk::segdrawer::step(int x1, int y1, int x2, int y2) {
- sh->line(x1 - f->GetMinX(), y1 - f->GetMinY(), x2 - f->GetMinX(), y2 - f->GetMinY(), c);
-}
-
-void mogltk::shape::sdraw(fill * f, ColorP c, int sx, int sy) {
- ENTER;
-
- if (!f)
- return;
-
- if (!f->GetSTexture()) {
- segdrawer * w = new segdrawer(f, f->STalloc(), c);
- f->swalk(w);
- delete w;
- f->last = c.c;
- }
- SDL_PixelFormat * format = f->GetSTexture()->GetFormat();
-
- if (f->last == c.c) {
- Uint32 * p = f->GetSTexture()->GetPixels();
- int i, n = f->GetSTexture()->GetWidth() * f->GetSTexture()->GetHeight();
- for (i = 0; i < n; i++)
- if (p[i] & 0xff000000)
- p[i] = c.toSDL(format);
- }
- SDL_Rect r;
- r.x = f->GetMinX() + sx;
- r.y = f->GetMinY() + sy;
- SDL_BlitSurface(f->GetSTexture()->GetSurface(), 0, surf, &r);
-
- f->last = c.c;
- LEAVE;
-}
-
-void mogltk::shape::obox(int x1, int y1, int x2, int y2, ColorP c) {
- ENTER;
-
- hline(x1, x2, y1, c);
- hline(x1, x2, y2, c);
- vline(x1, y1 + 1, y2 - 1, c);
- vline(x2, y1 + 1, y2 - 1, c);
-
- LEAVE;
-}
-
-void mogltk::shape::box3d(int x1, int y1, int x2, int y2, ColorP face, ColorP shade1, ColorP shade2, int depth, bool bevel) {
- ENTER;
-
- int i;
-
- for (i = 0; i < depth; i++) {
- hline(x1 + i, x2 - i, y1 + i, bevel ? shade2 : shade1);
- vline(x1 + i, y1 + i, y2 - i, bevel ? shade2 : shade1);
- }
-
- for (i = 0; i < depth; i++) {
- hline(x1 + i, x2 - i, y2 - i, bevel ? shade1 : shade2);
- vline(x2 - i, y1 + i, y2 - i, bevel ? shade1 : shade2);
- }
-
- box(x1 + depth, y1 + depth, x2 - depth, y2 - depth, face);
-
- LEAVE;
-}
-
-void mogltk::shape::obox3d(int x1, int y1, int x2, int y2, ColorP shade1, ColorP shade2, bool bevel) {
- ENTER;
-
- if (!bevel) {
- obox(x1 + 1, y1 + 1, x2, y2, shade1);
- obox(x1, y1, x2 - 1, y2 - 1, shade2);
- } else {
- obox(x1, y1, x2 - 1, y2 - 1, shade1);
- obox(x1 + 1, y1 + 1, x2, y2, shade2);
- }
-
- LEAVE;
-}
-
-void mogltk::shape::window(int x1, int y1, int x2, int y2, const String & title,
- ColorP titlecolor, ColorP titlebackcolor,
- ColorP front, ColorP shade1, ColorP shade2) {
- ENTER;
-
- box3d(x1, y1, x2, y2, front, shade1, shade2);
- hline3d(x1 + 2, x2 - 2, y1 + 19, shade1, shade2, 1);
- box(x1 + 2, y1 + 2, x2 - 2, y1 + 18, titlebackcolor);
- text((x1 + x2) / 2, y1 + 2, title, titlecolor, CENTER);
-
- LEAVE;
-}
-
-void mogltk::shape::text(int x, int y, const String & text, ColorP textcolor, align_t align) {
- int tsize = SystemFont->singletextsize(text);
- switch (align) {
- case LEFT:
- SystemFont->putcursor(x, y);
- break;
- case CENTER:
- SystemFont->putcursor(x - (tsize / 2), y);
- break;
- case RIGHT:
- SystemFont->putcursor(x - tsize, y);
- break;
- }
- SystemFont->setcolor(textcolor);
- SystemFont->setshadow(0);
- SystemFont->printf(text);
-}
-
-void mogltk::shape::text3d(int x, int y, const String & atext, ColorP textcolor,
- ColorP shade1, ColorP shade2,
- align_t align, bool bevel) {
- ENTER;
-
- SystemFont->setwspace(1);
- if (!bevel) {
- text(x - 1, y - 1, atext, shade2, align);
- text(x + 1, y + 1, atext, shade1, align);
- } else {
- text(x - 1, y - 1, atext, shade1, align);
- text(x + 1, y + 1, atext, shade2, align);
- }
- text(x, y, atext, textcolor, align);
- SystemFont->setwspace(0);
-
- LEAVE;
-}
-
-void mogltk::shape::button(int x1, int y1, int x2, int y2,
- const String & atext, bool bevel,
- ColorP front, ColorP shade1, ColorP shade2,
- ColorP round, ColorP textcolor,
- ColorP tshade1, ColorP tshade2) {
- ENTER;
-
- box3d(x1, y1, x2, y2, front, shade1, shade2, 2, bevel);
- hline(x1, x2, y1 - 1, round);
- hline(x1, x2, y2 + 1, round);
- vline(x1 - 1, y1, y2, round);
- vline(x2 + 1, y1, y2, round);
- pixel(x1, y1, round);
- pixel(x1, y2, round);
- pixel(x2, y1, round);
- pixel(x2, y2, round);
- text3d((x1 + x2) / 2, (y1 + y2) / 2 - 8, atext, textcolor, tshade1, tshade2, CENTER, bevel);
-
- LEAVE;
-}
-
-bool mogltk::shape::Enter() {
- if (SDL_MUSTLOCK(surf)) {
- SDL_LockSurface(surf);
- return true;
- } else {
- return false;
- }
-}
-
-void mogltk::shape::Leave(bool locked) {
- if (locked)
- SDL_UnlockSurface(surf);
-}
-
-void mogltk::shape::tbox(texture *, int x1, int y1, int x2, int y2, int tx, int ty, double f, ColorP c) {
-}
-
-void mogltk::shape::tbox(texture *, int x1, int y1, int x2, int y2, int tx1, int ty1, int tx2, int ty2, ColorP c) {
-}
-
-void mogltk::shape::tbox(texture *, int x1, int y1, int x2, int y2, ColorP, ColorP, ColorP, ColorP, int tx, int ty, double f) {
-}
-
-void mogltk::shape::tbox(texture *, int x1, int y1, int x2, int y2, ColorP, ColorP, ColorP, ColorP, int tx1, int ty1, int tx2, int ty2) {
-}
-
-void mogltk::shape::vline(int x, int y1, int y2, ColorP c1, ColorP c2) {
-}
-
-void mogltk::shape::hline(int x1, int x2, int y, ColorP c1, ColorP c2) {
-}
-
-void mogltk::shape::box(int x1, int y1, int x2, int y2, ColorP c1, ColorP c2, ColorP c3, ColorP c4) {
-}
-
-void mogltk::shape::obox(int x1, int y1, int x2, int y2, ColorP c1, ColorP c2, ColorP c3, ColorP c4) {
-}
+/*
+ * mogltk
+ * Copyright (C) 1999-2004 Nicolas "Pixel" Noble
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: shape.cc,v 1.19 2004-11-27 21:48:03 pixel Exp $ */
+
+#include <math.h>
+#include <limits.h>
+#include <SDL.h>
+#include <sys/types.h>
+#include <generic.h>
+#include "engine.h"
+#include "base.h"
+#include "shape.h"
+#include "texture.h"
+#include "font.h"
+
+#define ENTER bool flag = Enter()
+#define LEAVE Leave(flag)
+
+mogltk::fillwalker::fillwalker() {
+}
+
+mogltk::fillwalker::~fillwalker() {
+}
+
+void mogltk::fillwalker::step(int x, int y) {
+}
+
+mogltk::segwalker::segwalker() {
+}
+
+mogltk::segwalker::~segwalker() {
+}
+
+void mogltk::segwalker::step(int x1, int y1, int x2, int y2) {
+}
+
+mogltk::fill::fill() : minX(INT_MAX), minY(INT_MAX), maxX(INT_MIN), maxY(INT_MIN), cached(0), scached(0), header(0) {
+}
+
+mogltk::fill::~fill() {
+ if (header)
+ delete header;
+
+ if (cached)
+ delete cached;
+
+ if (scached)
+ delete scached;
+}
+
+void mogltk::fill::walk(fillwalker * w) {
+ if (header)
+ header->walk(w);
+}
+
+void mogltk::fill::swalk(segwalker * s) {
+ std::vector<struct segment>::iterator i;
+
+ for (i = segments.begin(); i != segments.end(); i++) {
+ s->step(i->x1, i->y1, i->x2, i->y2);
+ }
+}
+
+void mogltk::fill::insert(int x, int y) {
+ if (cached) {
+ delete cached;
+ cached = 0;
+ }
+
+ if (scached) {
+ delete scached;
+ scached = 0;
+ }
+
+ if (!header) {
+ new sline(y, this);
+ }
+ header->insert(x, y);
+
+ if (x > maxX)
+ maxX = x;
+
+ if (x < minX)
+ minX = x;
+
+ if (y > maxY)
+ maxY = y;
+
+ if (y < minY)
+ minY = y;
+}
+
+void mogltk::fill::insert(int x1, int y1, int x2, int y2) {
+ int dx, dy, y;
+ double x, i, i2;
+
+ struct segment s;
+ s.x1 = x1;
+ s.y1 = y1;
+ s.x2 = x2;
+ s.y2 = y2;
+ segments.push_back(s);
+
+ if (y1 == y2)
+ return;
+
+ if (y2 < y1) {
+ SWAP(x1, x2);
+ SWAP(y1, y2);
+ }
+
+ dx = x1 - x2;
+ dy = y1 - y2;
+
+ x = x1;
+ i = ((double) dx) / ((double) dy);
+ i2 = i / 2;
+ for (y = y1; y < y2; y++, x += i)
+ insert(x + i2, y);
+}
+
+void mogltk::fill::insertfix(int x, int y) {
+ if (!header)
+ return;
+
+ header->insertfix(x, y);
+}
+
+int mogltk::fill::GetMaxX() const {
+ return maxX;
+}
+
+int mogltk::fill::GetMaxY() const {
+ return maxY;
+}
+
+int mogltk::fill::GetMinX() const {
+ return minX;
+}
+
+int mogltk::fill::GetMinY() const {
+ return minY;
+}
+
+mogltk::texture * mogltk::fill::GetTexture() {
+ return cached;
+}
+
+mogltk::texture * mogltk::fill::GetSTexture() {
+ return scached;
+}
+
+mogltk::texture * mogltk::fill::Talloc() {
+ if (cached)
+ return cached;
+
+ int x; int y;
+
+ for (x = 1; x <= (maxX - minX); x <<= 1);
+ for (y = 1; y <= (maxY - minY); y <<= 1);
+
+ cached = new texture(x, y, true);
+ return cached;
+}
+
+mogltk::texture * mogltk::fill::STalloc() {
+ if (scached)
+ return scached;
+
+ int x; int y;
+
+ for (x = 1; x <= (maxX - minX); x <<= 1);
+ for (y = 1; y <= (maxY - minY); y <<= 1);
+
+ scached = new texture(x, y, true);
+ return scached;
+}
+
+mogltk::fill::sline::sline(int _y, fill * _header) : y(_y), header(_header), pheader(0) {
+ if (!header->header) {
+ header->header = this;
+ } else {
+ if (header->header->y > y) {
+ next = header->header;
+ header->header = this;
+ } else {
+ sline * p;
+ for (p = header->header; p->next; p = p->next) {
+ if (p->next->y > y) {
+ next = p->next;
+ p->next = this;
+ return;
+ }
+ }
+ p->next = this;
+ next = 0;
+ }
+ }
+}
+
+mogltk::fill::sline::~sline() {
+ if (pheader)
+ delete pheader;
+ if (next)
+ delete next;
+}
+
+int mogltk::fill::sline::GetY() const {
+ return y;
+}
+
+void mogltk::fill::sline::insert(int ax, int ay) {
+ sline * f;
+
+ if (ay == y) {
+ if (!pheader)
+ new point(ax, this);
+ else if (!pheader->look(ax))
+ new point(ax, this);
+ } else {
+ f = header->header->look(ay);
+
+ if (!f) {
+ f = new sline(ay, header);
+ }
+
+ f->insert(ax, ay);
+ }
+}
+
+void mogltk::fill::sline::insertfix(int ax, int ay) {
+ sline * f;
+
+ if (ay == y) {
+ if (count() & 1) {
+ insert(ax, ay);
+ }
+ } else {
+ f = header->header->look(ay);
+ if (!f)
+ return;
+
+ f->insertfix(ax, ay);
+ }
+}
+
+int mogltk::fill::sline::count() const {
+ int r = 0;
+
+ if (next)
+ r = next->count();
+
+ return r + 1;
+}
+
+void mogltk::fill::sline::walk(fillwalker * w) {
+ if (pheader)
+ pheader->walk(w);
+ if (next)
+ next->walk(w);
+}
+
+mogltk::fill::sline::point::point(int _x, sline * _header) : x(_x), header(_header) {
+ if (!header->pheader) {
+ header->pheader = this;
+ } else {
+ if (header->pheader->x > x) {
+ next = header->pheader;
+ header->pheader = this;
+ } else {
+ point * p;
+ for (p = header->pheader; p->next; p = p->next) {
+ if (p->next->x > x) {
+ next = p->next;
+ p->next = this;
+ return;
+ }
+ }
+ p->next = this;
+ next = 0;
+ }
+ }
+}
+
+mogltk::fill::sline::point::~point() {
+ if (next)
+ delete next;
+}
+
+int mogltk::fill::sline::point::GetX() const {
+ return x;
+}
+
+int mogltk::fill::sline::point::GetY() const {
+ return header->GetY();
+}
+
+void mogltk::fill::sline::point::walk(fillwalker * w) {
+ w->step(GetX(), GetY());
+ if (next)
+ next->walk(w);
+}
+
+mogltk::fill::sline::point * mogltk::fill::sline::point::look(int _x) {
+ if (x > _x)
+ return 0;
+
+ if (x == _x)
+ return this;
+
+ if (!next)
+ return 0;
+
+ return next->look(_x);
+}
+
+mogltk::fill::sline * mogltk::fill::sline::look(int _y) {
+ if (y > _y)
+ return 0;
+
+ if (y == _y)
+ return this;
+
+ if (!next)
+ return 0;
+
+ return next->look(_y);
+}
+
+mogltk::shape::shape(SDL_Surface * _surf) : surf(_surf) {
+ if (!surf)
+ surf = mogltk::engine::base_o->getsurface();
+}
+
+SDL_Surface * mogltk::shape::GetSurf() {
+ return surf;
+}
+
+void mogltk::shape::box(int x1, int y1, int x2, int y2, ColorP c) {
+ ENTER;
+
+ SDL_Rect rect;
+
+ rect.x = x1; rect.y = y1; rect.w = x2 - x1 + 1; rect.h = y2 - y1 + 1;
+ SDL_FillRect(surf, &rect, c.toSDL(surf->format));
+
+ LEAVE;
+}
+
+void mogltk::shape::hline(int x1, int x2, int y, ColorP c) {
+ for (; x1 <= x2; x1++) {
+ pixel(x1, y, c);
+ }
+}
+
+void mogltk::shape::hline3d(int x1, int x2, int y, ColorP shade1, ColorP shade2, bool bevel) {
+ ENTER;
+
+ if (!bevel) {
+ hline(x1, x2, y, shade2);
+ hline(x1, x2, y + 1, shade1);
+ } else {
+ hline(x1, x2, y, shade1);
+ hline(x1, x2, y + 1, shade2);
+ }
+
+ LEAVE;
+}
+
+void mogltk::shape::vline(int x, int y1, int y2, ColorP c) {
+ for (; y1 <= y2; y1++) {
+ pixel(x, y1, c);
+ }
+}
+
+void mogltk::shape::vline3d(int x, int y1, int y2, ColorP shade1, ColorP shade2, bool bevel) {
+ ENTER;
+
+ if (!bevel) {
+ vline(x, y1, y2, shade2);
+ vline(x + 1, y1, y2, shade1);
+ } else {
+ vline(x, y1, y2, shade1);
+ vline(x + 1, y1, y2, shade2);
+ }
+
+ LEAVE;
+}
+
+void mogltk::shape::bsubline_1(int x1, int y1, int x2, int y2, ColorP c) {
+ int x, y, ddx, ddy, e;
+ ddx = abs(x2 - x1);
+ ddy = abs(y2 - y1) << 1;
+ e = ddx - ddy;
+ ddx <<= 1;
+
+ if (x1 > x2) {
+ SWAP(x1, x2);
+ SWAP(y1, y2);
+ }
+
+ ENTER;
+
+ for (x = x1, y = y1; x <= x2; x++) {
+ pixel(x, y, c);
+ if (e < 0) {
+ y++;
+ e += ddx - ddy;
+ } else {
+ e -= ddy;
+ }
+ }
+
+ LEAVE;
+}
+
+void mogltk::shape::bsubline_2(int x1, int y1, int x2, int y2, ColorP c) {
+ int x, y, ddx, ddy, e;
+ ddx = abs(x2 - x1) << 1;
+ ddy = abs(y2 - y1);
+ e = ddy - ddx;
+ ddy <<= 1;
+
+ if (y1 > y2) {
+ SWAP(x1, x2);
+ SWAP(y1, y2);
+ }
+
+ ENTER;
+
+ for (y = y1, x = x1; y <= y2; y++) {
+ pixel(x, y, c);
+ if (e < 0) {
+ x++;
+ e += ddy - ddx;
+ } else {
+ e -= ddx;
+ }
+ }
+
+ LEAVE;
+}
+
+void mogltk::shape::bsubline_3(int x1, int y1, int x2, int y2, ColorP c) {
+ int x, y, ddx, ddy, e;
+ ddx = abs(x1 - x2) << 1;
+ ddy = abs(y2 - y1);
+ e = ddy - ddx;
+ ddy <<= 1;
+
+ if (y1 > y2) {
+ SWAP(x1, x2);
+ SWAP(y1, y2);
+ }
+
+ ENTER;
+
+ for (y = y1, x = x1; y <= y2; y++) {
+ pixel(x, y, c);
+ if (e < 0) {
+ x--;
+ e += ddy - ddx;
+ } else {
+ e -= ddx;
+ }
+ }
+
+ LEAVE;
+}
+
+void mogltk::shape::bsubline_4(int x1, int y1, int x2, int y2, ColorP c) {
+ int x, y, ddx, ddy, e;
+ ddy = abs(y2 - y1) << 1;
+ ddx = abs(x1 - x2);
+ e = ddx - ddy;
+ ddx <<= 1;
+
+ if (x1 > x2) {
+ SWAP(x1, x2);
+ SWAP(y1, y2);
+ }
+
+ for (x = x1, y = y1; x <= x2; x++) {
+ pixel(x, y, c);
+ if (e < 0) {
+ y--;
+ e += ddx - ddy;
+ } else {
+ e -= ddy;
+ }
+ }
+}
+
+void mogltk::shape::line(int x1, int y1, int x2, int y2, ColorP c) {
+ if ((x1 == x2) && (y1 == y2)) {
+ printm(M_INFO, "Line is a pixel...\n");
+ pixel(x1, y1, c);
+ return;
+ }
+
+ if (x1 == x2) {
+ vline(x1, MIN(y1, y2), MAX(y1, y2), c);
+ return;
+ }
+
+ if (y1 == y2) {
+ hline(MIN(x1, x2), MAX(x1, x2), y1, c);
+ return;
+ }
+
+ float k = float(y2 - y1) / float(x2 - x1);
+
+ if ((k >= 0) && (k <= 1)) {
+ bsubline_1(x1, y1, x2, y2, c);
+ } else if (k > 1) {
+ bsubline_2(x1, y1, x2, y2, c);
+ } else if ((k < 0) && (k >= -1)) {
+ bsubline_4(x1, y1, x2, y2, c);
+ } else {
+ bsubline_3(x1, y1, x2, y2, c);
+ }
+}
+
+void mogltk::shape::pixel(int x, int y, ColorP c) {
+ ENTER;
+
+ int bpp = surf->format->BytesPerPixel;
+ Uint8 *p = (Uint8 *)surf->pixels + y * surf->pitch + x * bpp;
+ Uint32 pixel = c.toSDL(surf->format);
+
+ if ((x < 0) || (y < 0) || (x >= surf->w) || (y >= surf->h)) {
+ printm(M_INFO, "Pixel culling, out of bounds.\n");
+ return;
+ }
+
+ switch(bpp) {
+ case 1:
+ *p = pixel;
+ break;
+
+ case 2:
+ *(Uint16 *)p = pixel;
+ break;
+
+ case 3:
+ if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
+ p[0] = (pixel >> 16) & 0xff;
+ p[1] = (pixel >> 8) & 0xff;
+ p[2] = pixel & 0xff;
+ } else {
+ p[0] = pixel & 0xff;
+ p[1] = (pixel >> 8) & 0xff;
+ p[2] = (pixel >> 16) & 0xff;
+ }
+ break;
+
+ case 4:
+ *(Uint32 *)p = pixel;
+ break;
+ }
+
+ LEAVE;
+}
+
+void mogltk::shape::circle(int x0, int y0, int r, ColorP c) {
+ ENTER;
+
+ int x = 0;
+ int y = r - 1;
+ int d = 3 - 2 * r;
+ int dI = 10 - 4 * r;
+ int rI = 6;
+
+ while (x <= y) {
+ pixel(x0 + x, y0 + y, c);
+ pixel(x0 - x, y0 + y, c);
+ pixel(x0 + x, y0 - y, c);
+ pixel(x0 - x, y0 - y, c);
+ pixel(x0 + y, y0 + x, c);
+ pixel(x0 - y, y0 + x, c);
+ pixel(x0 + y, y0 - x, c);
+ pixel(x0 - y, y0 - x, c);
+ if (d >= 0) {
+ d += dI;
+ dI += 8;
+ y -= 1;
+ } else {
+ d += rI;
+ dI += 4;
+ }
+ rI += 4;
+ x += 1;
+ }
+
+ LEAVE;
+}
+
+mogltk::fill * mogltk::shape::fcircle(int x0, int y0, int r) {
+ int x = 0;
+ int y = r - 1;
+ int d = 3 - 2 * r;
+ int dI = 10 - 4 * r;
+ int rI = 6;
+ mogltk::fill * f = new fill();
+ bool t = false;
+ int ox = 0, oy = 0;
+
+ while (x <= y) {
+/*
+ if (t) {
+ f->insert(x0 - x, y0 - y);
+ f->insert(x0 + x, y0 - y);
+ f->insert(x0 - x, y0 + y);
+ f->insert(x0 + x, y0 + y);
+ }
+ f->insert(x0 - y, y0 - x);
+ f->insert(x0 + y, y0 - x);
+ f->insert(x0 - y, y0 + x);
+ f->insert(x0 + y, y0 + x);
+*/
+ if (t) {
+ f->insert(x0 - ox, y0 - oy, x0 - x, y0 - y);
+ f->insert(x0 + ox, y0 - oy, x0 + x, y0 - y);
+ f->insert(x0 - ox, y0 + oy, x0 - x, y0 + y);
+ f->insert(x0 + ox, y0 + oy, x0 + x, y0 + y);
+ f->insert(x0 - oy, y0 - ox, x0 - y, y0 - x);
+ f->insert(x0 + oy, y0 - ox, x0 + y, y0 - x);
+ f->insert(x0 - oy, y0 + ox, x0 - y, y0 + x);
+ f->insert(x0 + oy, y0 + ox, x0 + y, y0 + x);
+ }
+ ox = x;
+ oy = y;
+ t = true;
+ if (d >= 0) {
+ d += dI;
+ dI += 8;
+ y -= 1;
+ } else {
+ d += rI;
+ dI += 4;
+ }
+ rI += 4;
+ x += 1;
+ }
+ return f;
+}
+
+void mogltk::shape::pcircle(int x, int y, int r, ColorP c) {
+ fill * f = fcircle(x, y, r);
+ fdraw(f, c);
+ delete f;
+}
+
+mogltk::filldrawer::filldrawer(fill * _f, texture * _t, ColorP _c) : f(_f), t(_t), c(_c), oldx(-1), oldy(-1) {
+}
+
+mogltk::filldrawer::~filldrawer() {
+}
+
+void mogltk::filldrawer::step(int x, int y) {
+ if (oldy != y) {
+ oldx = -1;
+ }
+ if (oldx == -1) {
+ oldx = x;
+ } else {
+/* s->hline(oldx, x, y, c); */
+ Uint32 * p = t->GetPixels();
+ int i,
+ first = t->GetWidth() * (y - f->GetMinY()) + oldx - f->GetMinX(),
+ last = first - oldx + x;
+ SDL_PixelFormat * format = t->GetFormat();
+
+ for (i = first; i <= last; i++) {
+ if (i > (t->GetWidth() * t->GetHeight())) {
+ printm(M_ERROR, "Big problem here. i = %i and W, H = %i, %i\n", i, t->GetWidth(), t->GetHeight());
+ printm(M_ERROR, "Initially, wanted to draw hline(%i, %i, %i)\n", oldx, x, y);
+ printm(M_ERROR, "With MinX = %i and MinY = %i --> hline(%i, %i, %i)\n", f->GetMinX(), f->GetMinY(), oldx - f->GetMinX(), x - f->GetMinX(), y - f->GetMinY());
+ printm(M_ERROR, "For info, MaxX = %i and MaxY = %i\n", f->GetMaxX(), f->GetMaxY());
+ exit(-1);
+ }
+ p[i] = c.toSDL(format);
+ }
+
+ oldx = -1;
+ }
+ oldy = y;
+}
+
+void mogltk::shape::fdraw(fill * f, ColorP c, int sx, int sy) {
+ ENTER;
+ if (!f)
+ return;
+ if (!f->GetTexture()) {
+ filldrawer * w = new filldrawer(f, f->Talloc(), c);
+ f->walk(w);
+ delete w;
+ f->last = c.c;
+ }
+ SDL_PixelFormat * format = f->GetTexture()->GetFormat();
+
+ if (f->last == c.c) {
+ Uint32 * p = f->GetTexture()->GetPixels();
+ int i, n = f->GetTexture()->GetWidth() * f->GetTexture()->GetHeight();
+ for (i = 0; i < n; i++)
+ if (p[i] & 0xff000000)
+ p[i] = c.toSDL(format);
+ }
+ SDL_Rect r;
+ r.x = f->GetMinX() + sx;
+ r.y = f->GetMinY() + sy;
+ SDL_BlitSurface(f->GetTexture()->GetSurface(), 0, surf, &r);
+
+ f->last = c.c;
+ LEAVE;
+}
+
+mogltk::segdrawer::segdrawer(fill * _f, texture * _t, ColorP _c) : f(_f), t(_t), c(_c), sh(new shape(_t->GetSurface())) {
+}
+
+mogltk::segdrawer::~segdrawer() {
+ delete sh;
+}
+
+void mogltk::segdrawer::step(int x1, int y1, int x2, int y2) {
+ sh->line(x1 - f->GetMinX(), y1 - f->GetMinY(), x2 - f->GetMinX(), y2 - f->GetMinY(), c);
+}
+
+void mogltk::shape::sdraw(fill * f, ColorP c, int sx, int sy) {
+ ENTER;
+
+ if (!f)
+ return;
+
+ if (!f->GetSTexture()) {
+ segdrawer * w = new segdrawer(f, f->STalloc(), c);
+ f->swalk(w);
+ delete w;
+ f->last = c.c;
+ }
+ SDL_PixelFormat * format = f->GetSTexture()->GetFormat();
+
+ if (f->last == c.c) {
+ Uint32 * p = f->GetSTexture()->GetPixels();
+ int i, n = f->GetSTexture()->GetWidth() * f->GetSTexture()->GetHeight();
+ for (i = 0; i < n; i++)
+ if (p[i] & 0xff000000)
+ p[i] = c.toSDL(format);
+ }
+ SDL_Rect r;
+ r.x = f->GetMinX() + sx;
+ r.y = f->GetMinY() + sy;
+ SDL_BlitSurface(f->GetSTexture()->GetSurface(), 0, surf, &r);
+
+ f->last = c.c;
+ LEAVE;
+}
+
+void mogltk::shape::obox(int x1, int y1, int x2, int y2, ColorP c) {
+ ENTER;
+
+ hline(x1, x2, y1, c);
+ hline(x1, x2, y2, c);
+ vline(x1, y1 + 1, y2 - 1, c);
+ vline(x2, y1 + 1, y2 - 1, c);
+
+ LEAVE;
+}
+
+void mogltk::shape::box3d(int x1, int y1, int x2, int y2, ColorP face, ColorP shade1, ColorP shade2, int depth, bool bevel) {
+ ENTER;
+
+ int i;
+
+ for (i = 0; i < depth; i++) {
+ hline(x1 + i, x2 - i, y1 + i, bevel ? shade2 : shade1);
+ vline(x1 + i, y1 + i, y2 - i, bevel ? shade2 : shade1);
+ }
+
+ for (i = 0; i < depth; i++) {
+ hline(x1 + i, x2 - i, y2 - i, bevel ? shade1 : shade2);
+ vline(x2 - i, y1 + i, y2 - i, bevel ? shade1 : shade2);
+ }
+
+ box(x1 + depth, y1 + depth, x2 - depth, y2 - depth, face);
+
+ LEAVE;
+}
+
+void mogltk::shape::obox3d(int x1, int y1, int x2, int y2, ColorP shade1, ColorP shade2, bool bevel) {
+ ENTER;
+
+ if (!bevel) {
+ obox(x1 + 1, y1 + 1, x2, y2, shade1);
+ obox(x1, y1, x2 - 1, y2 - 1, shade2);
+ } else {
+ obox(x1, y1, x2 - 1, y2 - 1, shade1);
+ obox(x1 + 1, y1 + 1, x2, y2, shade2);
+ }
+
+ LEAVE;
+}
+
+void mogltk::shape::window(int x1, int y1, int x2, int y2, const String & title,
+ ColorP titlecolor, ColorP titlebackcolor,
+ ColorP front, ColorP shade1, ColorP shade2) {
+ ENTER;
+
+ box3d(x1, y1, x2, y2, front, shade1, shade2);
+ hline3d(x1 + 2, x2 - 2, y1 + 19, shade1, shade2, 1);
+ box(x1 + 2, y1 + 2, x2 - 2, y1 + 18, titlebackcolor);
+ text((x1 + x2) / 2, y1 + 2, title, titlecolor, CENTER);
+
+ LEAVE;
+}
+
+void mogltk::shape::text(int x, int y, const String & text, ColorP textcolor, align_t align) {
+ int tsize = SystemFont->singletextsize(text);
+ switch (align) {
+ case LEFT:
+ SystemFont->putcursor(x, y);
+ break;
+ case CENTER:
+ SystemFont->putcursor(x - (tsize / 2), y);
+ break;
+ case RIGHT:
+ SystemFont->putcursor(x - tsize, y);
+ break;
+ }
+ SystemFont->setcolor(textcolor);
+ SystemFont->setshadow(0);
+ SystemFont->printf(text);
+}
+
+void mogltk::shape::text3d(int x, int y, const String & atext, ColorP textcolor,
+ ColorP shade1, ColorP shade2,
+ align_t align, bool bevel) {
+ ENTER;
+
+ SystemFont->setwspace(1);
+ if (!bevel) {
+ text(x - 1, y - 1, atext, shade2, align);
+ text(x + 1, y + 1, atext, shade1, align);
+ } else {
+ text(x - 1, y - 1, atext, shade1, align);
+ text(x + 1, y + 1, atext, shade2, align);
+ }
+ text(x, y, atext, textcolor, align);
+ SystemFont->setwspace(0);
+
+ LEAVE;
+}
+
+void mogltk::shape::button(int x1, int y1, int x2, int y2,
+ const String & atext, bool bevel,
+ ColorP front, ColorP shade1, ColorP shade2,
+ ColorP round, ColorP textcolor,
+ ColorP tshade1, ColorP tshade2) {
+ ENTER;
+
+ box3d(x1, y1, x2, y2, front, shade1, shade2, 2, bevel);
+ hline(x1, x2, y1 - 1, round);
+ hline(x1, x2, y2 + 1, round);
+ vline(x1 - 1, y1, y2, round);
+ vline(x2 + 1, y1, y2, round);
+ pixel(x1, y1, round);
+ pixel(x1, y2, round);
+ pixel(x2, y1, round);
+ pixel(x2, y2, round);
+ text3d((x1 + x2) / 2, (y1 + y2) / 2 - 8, atext, textcolor, tshade1, tshade2, CENTER, bevel);
+
+ LEAVE;
+}
+
+bool mogltk::shape::Enter() {
+ if (SDL_MUSTLOCK(surf)) {
+ SDL_LockSurface(surf);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void mogltk::shape::Leave(bool locked) {
+ if (locked)
+ SDL_UnlockSurface(surf);
+}
+
+void mogltk::shape::tbox(texture *, int x1, int y1, int x2, int y2, int tx, int ty, double f, ColorP c) {
+}
+
+void mogltk::shape::tbox(texture *, int x1, int y1, int x2, int y2, int tx1, int ty1, int tx2, int ty2, ColorP c) {
+}
+
+void mogltk::shape::tbox(texture *, int x1, int y1, int x2, int y2, ColorP, ColorP, ColorP, ColorP, int tx, int ty, double f) {
+}
+
+void mogltk::shape::tbox(texture *, int x1, int y1, int x2, int y2, ColorP, ColorP, ColorP, ColorP, int tx1, int ty1, int tx2, int ty2) {
+}
+
+void mogltk::shape::vline(int x, int y1, int y2, ColorP c1, ColorP c2) {
+}
+
+void mogltk::shape::hline(int x1, int x2, int y, ColorP c1, ColorP c2) {
+}
+
+void mogltk::shape::box(int x1, int y1, int x2, int y2, ColorP c1, ColorP c2, ColorP c3, ColorP c4) {
+}
+
+void mogltk::shape::obox(int x1, int y1, int x2, int y2, ColorP c1, ColorP c2, ColorP c3, ColorP c4) {
+}
diff --git a/lib/sprite.cc b/lib/sprite.cc
index ef5d7a8..bd0df94 100644
--- a/lib/sprite.cc
+++ b/lib/sprite.cc
@@ -1,190 +1,190 @@
-/*
- * mogltk
- * Copyright (C) 1999-2004 Nicolas "Pixel" Noble
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* $Id: sprite.cc,v 1.14 2004-11-27 21:44:53 pixel Exp $ */
-
-#include <SDL.h>
-#include "engine.h"
-#include "base.h"
-#include "sprite.h"
-
-#define TEXSIZE 1024
-
-mogltk::Sprite * mogltk::Sprite::Cursor;
-
-mogltk::Sprite::TexList * mogltk::Sprite::TexList::header = 0;
-
-mogltk::Sprite::Sprite(Handle * h, int asx, int asy) throw (GeneralException) : sx(asx), sy(asy) {
- alloc();
- for (int y = 0; y < sy; y++) {
- h->read(tlist->GetTex()->GetPixels() + TEXSIZE * y + posx, sx * 4);
- }
-}
-
-mogltk::Sprite::Sprite(Uint8 * p, int asx, int asy) : sx(asx), sy(asy) {
- alloc();
- for (int y = 0; y < sy; y++) {
- bcopy(p, tlist->GetTex()->GetPixels() + TEXSIZE * y + posx, sx * 4);
- p += sx * 4;
- }
-}
-
-mogltk::Sprite::~Sprite() {
- if (prev)
- prev->next = next;
- else
- tlist->sprheader = next;
-
- if (next)
- next->prev = prev;
-
- if (!tlist->sprheader) {
- delete tlist;
- }
-}
-
-void mogltk::Sprite::alloc() {
- /* FIXMEEEEEEEEEEEEE */
- bool found = false;
- TexList * p;
-
- for (p = tlist; p && !found; p = p->GetNext()) {
- for (posy = 0; (posy < (TEXSIZE - sy)) && !found; posy++) {
- for (posx = 0; (posx < (TEXSIZE - sx)) && !found; posx++) {
- if (p->sprheader->canfit(posx, posy, posx + sx, posy + sy)) {
- found = true;
- }
- }
- }
- }
-
- if (!found) {
- printm(M_INFO, "Allocating a new texture for sprites\n");
- posx = posy = 0;
- p = new TexList(TEXSIZE);
- }
-
- tlist = p;
-}
-
-mogltk::Sprite::TexList::TexList(int size) {
- tex = new texture(size, size, true);
-
- if (header)
- header->prev = this;
- prev = 0;
- next = header;
- header = this;
-}
-
-mogltk::Sprite::TexList::~TexList() {
- delete tex;
-
- if (prev)
- prev->next = next;
- else
- header = next;
-
- if (next)
- next->prev = prev;
-}
-
-const mogltk::texture * mogltk::Sprite::TexList::GetTex() const {
- return tex;
-}
-
-mogltk::texture * mogltk::Sprite::TexList::GetTex() {
- return tex;
-}
-
-const mogltk::Sprite::TexList * mogltk::Sprite::TexList::GetHead() {
- return header;
-}
-
-const mogltk::Sprite::TexList * mogltk::Sprite::TexList::GetNext() const {
- return next;
-}
-
-mogltk::Sprite::TexList * mogltk::Sprite::TexList::GetNext() {
- return next;
-}
-
-void mogltk::Sprite::TexList::Bind() const {
- tex->Bind();
-}
-
-SDL_Surface * mogltk::Sprite::TexList::GetSurface() {
- return tex->GetSurface();
-}
-
-
-bool mogltk::Sprite::intersect(int x1, int y1, int x2, int y2) const {
- int sx1 = posx, sy1 = posy, sx2 = posx + sx, sy2 = posy + sy;
-
- return !((sx1 >= x2) || (sx2 <= x1) || (sy1 >= y1) || (sy2 <= y2));
-}
-
-bool mogltk::Sprite::canfit(int x1, int y1, int x2, int y2) const {
- if (!intersect(x1, y1, x2, y2))
- return true;
- else
- if (next)
- return next->canfit(x1, y1, x2, y2);
- else
- return false;
-}
-
-void mogltk::Sprite::draw(int dx, int dy, ColorP c, float sx, float sy) {
- bool locked = false;
-
- if (SDL_MUSTLOCK(mogltk::engine::base_o->getsurface())) {
- locked = true;
- SDL_LockSurface(mogltk::engine::base_o->getsurface());
- }
-
- SDL_Rect src, dst;
-
- src.x = posx; src.y = posy; src.w = sx; src.h = sy;
- dst.x = dx; dst.y = dy; dst.w = sx; dst.h = sy;
-
- SDL_BlitSurface(tlist->GetSurface(), &src, mogltk::engine::base_o->getsurface(), &dst);
-
- if (locked)
- SDL_UnlockSurface(mogltk::engine::base_o->getsurface());
-}
-
-void mogltk::Sprite::Bind() {
- tlist->Bind();
-}
-
-int mogltk::Sprite::GetPX() {
- return posx;
-}
-
-int mogltk::Sprite::GetPY() {
- return posy;
-}
-
-int mogltk::Sprite::GetSX() {
- return sx;
-}
-
-int mogltk::Sprite::GetSY() {
- return sy;
-}
+/*
+ * mogltk
+ * Copyright (C) 1999-2004 Nicolas "Pixel" Noble
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: sprite.cc,v 1.15 2004-11-27 21:48:03 pixel Exp $ */
+
+#include <SDL.h>
+#include "engine.h"
+#include "base.h"
+#include "sprite.h"
+
+#define TEXSIZE 1024
+
+mogltk::Sprite * mogltk::Sprite::Cursor;
+
+mogltk::Sprite::TexList * mogltk::Sprite::TexList::header = 0;
+
+mogltk::Sprite::Sprite(Handle * h, int asx, int asy) throw (GeneralException) : sx(asx), sy(asy) {
+ alloc();
+ for (int y = 0; y < sy; y++) {
+ h->read(tlist->GetTex()->GetPixels() + TEXSIZE * y + posx, sx * 4);
+ }
+}
+
+mogltk::Sprite::Sprite(Uint8 * p, int asx, int asy) : sx(asx), sy(asy) {
+ alloc();
+ for (int y = 0; y < sy; y++) {
+ bcopy(p, tlist->GetTex()->GetPixels() + TEXSIZE * y + posx, sx * 4);
+ p += sx * 4;
+ }
+}
+
+mogltk::Sprite::~Sprite() {
+ if (prev)
+ prev->next = next;
+ else
+ tlist->sprheader = next;
+
+ if (next)
+ next->prev = prev;
+
+ if (!tlist->sprheader) {
+ delete tlist;
+ }
+}
+
+void mogltk::Sprite::alloc() {
+ /* FIXMEEEEEEEEEEEEE */
+ bool found = false;
+ TexList * p;
+
+ for (p = tlist; p && !found; p = p->GetNext()) {
+ for (posy = 0; (posy < (TEXSIZE - sy)) && !found; posy++) {
+ for (posx = 0; (posx < (TEXSIZE - sx)) && !found; posx++) {
+ if (p->sprheader->canfit(posx, posy, posx + sx, posy + sy)) {
+ found = true;
+ }
+ }
+ }
+ }
+
+ if (!found) {
+ printm(M_INFO, "Allocating a new texture for sprites\n");
+ posx = posy = 0;
+ p = new TexList(TEXSIZE);
+ }
+
+ tlist = p;
+}
+
+mogltk::Sprite::TexList::TexList(int size) {
+ tex = new texture(size, size, true);
+
+ if (header)
+ header->prev = this;
+ prev = 0;
+ next = header;
+ header = this;
+}
+
+mogltk::Sprite::TexList::~TexList() {
+ delete tex;
+
+ if (prev)
+ prev->next = next;
+ else
+ header = next;
+
+ if (next)
+ next->prev = prev;
+}
+
+const mogltk::texture * mogltk::Sprite::TexList::GetTex() const {
+ return tex;
+}
+
+mogltk::texture * mogltk::Sprite::TexList::GetTex() {
+ return tex;
+}
+
+const mogltk::Sprite::TexList * mogltk::Sprite::TexList::GetHead() {
+ return header;
+}
+
+const mogltk::Sprite::TexList * mogltk::Sprite::TexList::GetNext() const {
+ return next;
+}
+
+mogltk::Sprite::TexList * mogltk::Sprite::TexList::GetNext() {
+ return next;
+}
+
+void mogltk::Sprite::TexList::Bind() const {
+ tex->Bind();
+}
+
+SDL_Surface * mogltk::Sprite::TexList::GetSurface() {
+ return tex->GetSurface();
+}
+
+
+bool mogltk::Sprite::intersect(int x1, int y1, int x2, int y2) const {
+ int sx1 = posx, sy1 = posy, sx2 = posx + sx, sy2 = posy + sy;
+
+ return !((sx1 >= x2) || (sx2 <= x1) || (sy1 >= y1) || (sy2 <= y2));
+}
+
+bool mogltk::Sprite::canfit(int x1, int y1, int x2, int y2) const {
+ if (!intersect(x1, y1, x2, y2))
+ return true;
+ else
+ if (next)
+ return next->canfit(x1, y1, x2, y2);
+ else
+ return false;
+}
+
+void mogltk::Sprite::draw(int dx, int dy, ColorP c, float sx, float sy) {
+ bool locked = false;
+
+ if (SDL_MUSTLOCK(mogltk::engine::base_o->getsurface())) {
+ locked = true;
+ SDL_LockSurface(mogltk::engine::base_o->getsurface());
+ }
+
+ SDL_Rect src, dst;
+
+ src.x = posx; src.y = posy; src.w = sx; src.h = sy;
+ dst.x = dx; dst.y = dy; dst.w = sx; dst.h = sy;
+
+ SDL_BlitSurface(tlist->GetSurface(), &src, mogltk::engine::base_o->getsurface(), &dst);
+
+ if (locked)
+ SDL_UnlockSurface(mogltk::engine::base_o->getsurface());
+}
+
+void mogltk::Sprite::Bind() {
+ tlist->Bind();
+}
+
+int mogltk::Sprite::GetPX() {
+ return posx;
+}
+
+int mogltk::Sprite::GetPY() {
+ return posy;
+}
+
+int mogltk::Sprite::GetSX() {
+ return sx;
+}
+
+int mogltk::Sprite::GetSY() {
+ return sy;
+}
diff --git a/lib/texture.cc b/lib/texture.cc
index ea504ab..a06c345 100644
--- a/lib/texture.cc
+++ b/lib/texture.cc
@@ -1,361 +1,361 @@
-/*
- * mogltk
- * Copyright (C) 1999-2004 Nicolas "Pixel" Noble
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* $Id: texture.cc,v 1.10 2004-11-27 21:44:53 pixel Exp $ */
-
-#include <sys/types.h>
-#include <SDL.h>
-#include <SDL_opengl.h>
-#include <generic.h>
-#include "texture.h"
-#include "engine.h"
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "gettext.h"
-
-#define DEBUG 1
-
-mogltk::texture * mogltk::texture::header = 0;
-mogltk::texture * mogltk::texture::footer = 0;
-
-mogltk::texture * mogltk::texture::active = 0;
-
-mogltk::texture::texture(int w, int h, bool plane) throw (GeneralException) : width(w), height(h),
- texture_allocated(false), planar(plane), tainted(true), taintable(true) {
- if ((!ISPOT(w)) || (!ISPOT(h)))
- throw GeneralException(_("Size of the texture not a power of 2!"));
-
- if (!(surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32,
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- 0xff000000,
- 0x00ff0000,
- 0x0000ff00,
- 0x000000ff
-#else
- 0x000000ff,
- 0x0000ff00,
- 0x00ff0000,
- 0xff000000
-#endif
- ))) {
- throw GeneralException(_("Can't create RGB Surface"));
- }
-
- SDL_FillRect(surface, 0, 0);
-
- next = 0;
- prev = footer;
- footer = this;
- if (!header) {
- header = this;
- }
- if (prev) {
- prev->next = this;
- }
-}
-
-mogltk::texture::texture(Handle * h, bool plane) throw (GeneralException) :
- texture_allocated(false), planar(plane), tainted(true), taintable(true) {
-
- SDL_Surface * temp;
-
- temp = LoadNTEX(h);
- width = temp->w;
- height = temp->h;
-
-#ifdef DEBUG
- printm(M_INFO, "Creating texture from file: size %ix%i\n", height, width);
-#endif
-
- if ((!ISPOT(width)) || (!ISPOT(height))) {
- SDL_FreeSurface(temp);
- throw GeneralException(_("Size of the texture not a power of 2!"));
- }
-
- SDL_PixelFormat f;
-
- f.palette = 0;
- f.BitsPerPixel = 32;
- f.BytesPerPixel = 4;
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- f.Amask = 0x000000ff;
- f.Bmask = 0x0000ff00;
- f.Gmask = 0x00ff0000;
- f.Rmask = 0xff000000;
- f.Ashift = 0;
- f.Bshift = 8;
- f.Gshift = 16;
- f.Rshift = 24;
-#else
- f.Rmask = 0x000000ff;
- f.Gmask = 0x0000ff00;
- f.Bmask = 0x00ff0000;
- f.Amask = 0xff000000;
- f.Rshift = 0;
- f.Gshift = 8;
- f.Bshift = 16;
- f.Ashift = 24;
-#endif
- f.Rloss = 0;
- f.Gloss = 0;
- f.Bloss = 0;
- f.Aloss = 0;
-
- if (!(surface = SDL_ConvertSurface(temp, &f, 0))) {
- throw GeneralException("Could not convert texture to OpenGL format");
- }
-
- SDL_FreeSurface(temp);
-
- next = 0;
- prev = footer;
- footer = this;
- if (!header) {
- header = this;
- }
- if (prev) {
- prev->next = this;
- }
-}
-
-inline static unsigned int nextpower(unsigned int n) {
- unsigned int i;
-
- if (!n)
- return n;
-
- if (ISPOT(n))
- return n;
-
- for (i = 31; i >= 0; i--) {
- if ((n >> i) & 1) {
- return 1 << (i + 1);
- }
- }
-}
-
-mogltk::texture::texture(int x, int y, int w, int h) : width(nextpower(w)), height(nextpower(h)),
- texture_allocated(true), planar(false), tainted(false), taintable(false) {
- glGenTextures(1, &tex);
- glBindTexture(GL_TEXTURE_2D, tex);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, x, y, w, h);
-}
-
-mogltk::texture::~texture() {
- if (surface) {
- SDL_FreeSurface(surface);
- }
-
- if (texture_allocated) {
- glDeleteTextures(1, &tex);
- }
-
- if (prev) {
- prev->next = next;
- }
-
- if (next) {
- next->prev = prev;
- }
-
- if (this == footer) {
- footer = prev;
- }
-
- if (this == header) {
- header = next;
- }
-}
-
-Uint32 * mogltk::texture::GetPixels() {
- if (surface)
- return (Uint32 *) surface->pixels;
- else
- return 0;
-}
-
-SDL_Surface * mogltk::texture::GetSurface() {
- return surface;
-}
-
-SDL_PixelFormat * mogltk::texture::GetFormat() {
- if (surface)
- return surface->format;
- else
- return 0;
-}
-
-void mogltk::texture::Generate() {
- if (texture_allocated) {
- glDeleteTextures(1, &tex);
- }
-
- glGenTextures(1, &tex);
-#ifdef DEBUG
- printm(M_INFO, _("Generated texture index: %i\n"), tex);
-#endif
-
- glBindTexture(GL_TEXTURE_2D, tex);
-
-#if 0
- if (planar) {
-#ifdef DEBUG
- printm(M_INFO, _("Generating planar texture: %i\n"), tex);
-#endif
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels);
- } else {
-#endif
-#ifdef DEBUG
- printm(M_INFO, _("Generating 3D texture: %i\n"), tex);
-#endif
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, width, height, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels);
-// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels);
-#if 0
- }
-#endif
-
- texture_allocated = true;
- tainted = false;
-}
-
-void mogltk::texture::Bind(bool expand) {
- if ((!texture_allocated) || tainted)
- Generate();
- glEnable(GL_TEXTURE_2D);
- if (active == this)
- return;
- glBindTexture(GL_TEXTURE_2D, tex);
- if (expand) {
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
- glScaled(1 / (double) width, 1 / (double) height, 1);
- glMatrixMode(GL_MODELVIEW);
- }
-
- active = this;
-
- if (header == this)
- return;
-
- if (prev) {
- prev->next = next;
- }
-
- if (next) {
- next->prev = prev;
- }
-
- if (footer = this) {
- footer = prev;
- }
-
- next = header;
- prev = 0;
- header->prev = this;
- header = this;
-}
-
-GLuint mogltk::texture::GetWidth() {
- return width;
-}
-
-GLuint mogltk::texture::GetHeight() {
- return height;
-}
-
-void mogltk::texture::Unbind(void) {
- if (active) {
- glBindTexture(GL_TEXTURE_2D, 0);
- glDisable(GL_TEXTURE_2D);
- active = 0;
- }
-}
-
-void mogltk::texture::Taint(void) {
- if (taintable)
- tainted = true;
-}
-
-void mogltk::texture::Taintall(void) {
- if (header)
- header->recTaint();
-}
-
-void mogltk::texture::recTaint(void) {
- Taint();
- if (next)
- next->recTaint();
-}
-
-#ifdef WORDS_BIGENDIAN
-#define NTEX_SIGNATURE 0x4e544558
-#else
-#define NTEX_SIGNATURE 0x5845544e
-#endif
-
-SDL_Surface * mogltk::texture::LoadNTEX(Handle * h) throw (GeneralException) {
- SDL_Surface * r;
- char buffer[5];
- Uint16 height, width;
-
- h->read(buffer, 4);
- buffer[4] = 0;
- if (*((Uint32 *) buffer) != NTEX_SIGNATURE)
- throw GeneralException("Texture file " + h->GetName() + " corrupted");
-
- height = h->readU16();
- width = h->readU16();
-
- if (!(r = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32,
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- 0xff000000,
- 0x00ff0000,
- 0x0000ff00,
- 0x000000ff
-#else
- 0x000000ff,
- 0x0000ff00,
- 0x00ff0000,
- 0xff000000
-#endif
- ))) {
- throw GeneralException(_("Can't create RGB Surface for LoadNTEX"));
- }
-
- h->read(r->pixels, height * width * 4);
-
- return r;
-}
-
-void mogltk::texture::DumpBMP(const String & n) {
- if (surface)
- SDL_SaveBMP(surface, n.to_charp());
-}
+/*
+ * mogltk
+ * Copyright (C) 1999-2004 Nicolas "Pixel" Noble
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: texture.cc,v 1.11 2004-11-27 21:48:03 pixel Exp $ */
+
+#include <sys/types.h>
+#include <SDL.h>
+#include <SDL_opengl.h>
+#include <generic.h>
+#include "texture.h"
+#include "engine.h"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "gettext.h"
+
+#define DEBUG 1
+
+mogltk::texture * mogltk::texture::header = 0;
+mogltk::texture * mogltk::texture::footer = 0;
+
+mogltk::texture * mogltk::texture::active = 0;
+
+mogltk::texture::texture(int w, int h, bool plane) throw (GeneralException) : width(w), height(h),
+ texture_allocated(false), planar(plane), tainted(true), taintable(true) {
+ if ((!ISPOT(w)) || (!ISPOT(h)))
+ throw GeneralException(_("Size of the texture not a power of 2!"));
+
+ if (!(surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32,
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ 0xff000000,
+ 0x00ff0000,
+ 0x0000ff00,
+ 0x000000ff
+#else
+ 0x000000ff,
+ 0x0000ff00,
+ 0x00ff0000,
+ 0xff000000
+#endif
+ ))) {
+ throw GeneralException(_("Can't create RGB Surface"));
+ }
+
+ SDL_FillRect(surface, 0, 0);
+
+ next = 0;
+ prev = footer;
+ footer = this;
+ if (!header) {
+ header = this;
+ }
+ if (prev) {
+ prev->next = this;
+ }
+}
+
+mogltk::texture::texture(Handle * h, bool plane) throw (GeneralException) :
+ texture_allocated(false), planar(plane), tainted(true), taintable(true) {
+
+ SDL_Surface * temp;
+
+ temp = LoadNTEX(h);
+ width = temp->w;
+ height = temp->h;
+
+#ifdef DEBUG
+ printm(M_INFO, "Creating texture from file: size %ix%i\n", height, width);
+#endif
+
+ if ((!ISPOT(width)) || (!ISPOT(height))) {
+ SDL_FreeSurface(temp);
+ throw GeneralException(_("Size of the texture not a power of 2!"));
+ }
+
+ SDL_PixelFormat f;
+
+ f.palette = 0;
+ f.BitsPerPixel = 32;
+ f.BytesPerPixel = 4;
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ f.Amask = 0x000000ff;
+ f.Bmask = 0x0000ff00;
+ f.Gmask = 0x00ff0000;
+ f.Rmask = 0xff000000;
+ f.Ashift = 0;
+ f.Bshift = 8;
+ f.Gshift = 16;
+ f.Rshift = 24;
+#else
+ f.Rmask = 0x000000ff;
+ f.Gmask = 0x0000ff00;
+ f.Bmask = 0x00ff0000;
+ f.Amask = 0xff000000;
+ f.Rshift = 0;
+ f.Gshift = 8;
+ f.Bshift = 16;
+ f.Ashift = 24;
+#endif
+ f.Rloss = 0;
+ f.Gloss = 0;
+ f.Bloss = 0;
+ f.Aloss = 0;
+
+ if (!(surface = SDL_ConvertSurface(temp, &f, 0))) {
+ throw GeneralException("Could not convert texture to OpenGL format");
+ }
+
+ SDL_FreeSurface(temp);
+
+ next = 0;
+ prev = footer;
+ footer = this;
+ if (!header) {
+ header = this;
+ }
+ if (prev) {
+ prev->next = this;
+ }
+}
+
+inline static unsigned int nextpower(unsigned int n) {
+ unsigned int i;
+
+ if (!n)
+ return n;
+
+ if (ISPOT(n))
+ return n;
+
+ for (i = 31; i >= 0; i--) {
+ if ((n >> i) & 1) {
+ return 1 << (i + 1);
+ }
+ }
+}
+
+mogltk::texture::texture(int x, int y, int w, int h) : width(nextpower(w)), height(nextpower(h)),
+ texture_allocated(true), planar(false), tainted(false), taintable(false) {
+ glGenTextures(1, &tex);
+ glBindTexture(GL_TEXTURE_2D, tex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, x, y, w, h);
+}
+
+mogltk::texture::~texture() {
+ if (surface) {
+ SDL_FreeSurface(surface);
+ }
+
+ if (texture_allocated) {
+ glDeleteTextures(1, &tex);
+ }
+
+ if (prev) {
+ prev->next = next;
+ }
+
+ if (next) {
+ next->prev = prev;
+ }
+
+ if (this == footer) {
+ footer = prev;
+ }
+
+ if (this == header) {
+ header = next;
+ }
+}
+
+Uint32 * mogltk::texture::GetPixels() {
+ if (surface)
+ return (Uint32 *) surface->pixels;
+ else
+ return 0;
+}
+
+SDL_Surface * mogltk::texture::GetSurface() {
+ return surface;
+}
+
+SDL_PixelFormat * mogltk::texture::GetFormat() {
+ if (surface)
+ return surface->format;
+ else
+ return 0;
+}
+
+void mogltk::texture::Generate() {
+ if (texture_allocated) {
+ glDeleteTextures(1, &tex);
+ }
+
+ glGenTextures(1, &tex);
+#ifdef DEBUG
+ printm(M_INFO, _("Generated texture index: %i\n"), tex);
+#endif
+
+ glBindTexture(GL_TEXTURE_2D, tex);
+
+#if 0
+ if (planar) {
+#ifdef DEBUG
+ printm(M_INFO, _("Generating planar texture: %i\n"), tex);
+#endif
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels);
+ } else {
+#endif
+#ifdef DEBUG
+ printm(M_INFO, _("Generating 3D texture: %i\n"), tex);
+#endif
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, width, height, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels);
+// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels);
+#if 0
+ }
+#endif
+
+ texture_allocated = true;
+ tainted = false;
+}
+
+void mogltk::texture::Bind(bool expand) {
+ if ((!texture_allocated) || tainted)
+ Generate();
+ glEnable(GL_TEXTURE_2D);
+ if (active == this)
+ return;
+ glBindTexture(GL_TEXTURE_2D, tex);
+ if (expand) {
+ glMatrixMode(GL_TEXTURE);
+ glLoadIdentity();
+ glScaled(1 / (double) width, 1 / (double) height, 1);
+ glMatrixMode(GL_MODELVIEW);
+ }
+
+ active = this;
+
+ if (header == this)
+ return;
+
+ if (prev) {
+ prev->next = next;
+ }
+
+ if (next) {
+ next->prev = prev;
+ }
+
+ if (footer = this) {
+ footer = prev;
+ }
+
+ next = header;
+ prev = 0;
+ header->prev = this;
+ header = this;
+}
+
+GLuint mogltk::texture::GetWidth() {
+ return width;
+}
+
+GLuint mogltk::texture::GetHeight() {
+ return height;
+}
+
+void mogltk::texture::Unbind(void) {
+ if (active) {
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glDisable(GL_TEXTURE_2D);
+ active = 0;
+ }
+}
+
+void mogltk::texture::Taint(void) {
+ if (taintable)
+ tainted = true;
+}
+
+void mogltk::texture::Taintall(void) {
+ if (header)
+ header->recTaint();
+}
+
+void mogltk::texture::recTaint(void) {
+ Taint();
+ if (next)
+ next->recTaint();
+}
+
+#ifdef WORDS_BIGENDIAN
+#define NTEX_SIGNATURE 0x4e544558
+#else
+#define NTEX_SIGNATURE 0x5845544e
+#endif
+
+SDL_Surface * mogltk::texture::LoadNTEX(Handle * h) throw (GeneralException) {
+ SDL_Surface * r;
+ char buffer[5];
+ Uint16 height, width;
+
+ h->read(buffer, 4);
+ buffer[4] = 0;
+ if (*((Uint32 *) buffer) != NTEX_SIGNATURE)
+ throw GeneralException("Texture file " + h->GetName() + " corrupted");
+
+ height = h->readU16();
+ width = h->readU16();
+
+ if (!(r = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32,
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ 0xff000000,
+ 0x00ff0000,
+ 0x0000ff00,
+ 0x000000ff
+#else
+ 0x000000ff,
+ 0x0000ff00,
+ 0x00ff0000,
+ 0xff000000
+#endif
+ ))) {
+ throw GeneralException(_("Can't create RGB Surface for LoadNTEX"));
+ }
+
+ h->read(r->pixels, height * width * 4);
+
+ return r;
+}
+
+void mogltk::texture::DumpBMP(const String & n) {
+ if (surface)
+ SDL_SaveBMP(surface, n.to_charp());
+}
diff --git a/lib/widgets.cc b/lib/widgets.cc
index c70ad95..55c709c 100644
--- a/lib/widgets.cc
+++ b/lib/widgets.cc
@@ -1,1182 +1,1182 @@
-/*
- * mogltk
- * Copyright (C) 1999-2004 Nicolas "Pixel" Noble
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* $Id: widgets.cc,v 1.9 2004-10-19 01:27:30 pixel Exp $ */
-
-#include <SDL.h>
-#include <vector>
-#include <Input.h>
-#include "font.h"
-#include "engine.h"
-#include "widgets.h"
-#include "sprite.h"
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "gettext.h"
-
-mogltk::widget * dragged_widget = 0;
-
-std::vector<mogltk::widget *> out_move, out_click;
-std::vector<mogltk::widget::timed_event> mogltk::widget::timed_events;
-
-
-class widget_mouse_event : public mogltk::engine::mouseevent {
- public:
- widget_mouse_event(mogltk::widget *);
- virtual void move(SDL_MouseMotionEvent);
- virtual void action(SDL_MouseButtonEvent);
- private:
- mogltk::widget * root;
- int mouse_x_down, mouse_y_down;
- bool mouse_down, mouse_drag;
- Uint32 old_click;
-};
-
-widget_mouse_event::widget_mouse_event(mogltk::widget * _root) : root(_root), mouse_down(false), mouse_drag(false) {
-}
-
-void widget_mouse_event::move(SDL_MouseMotionEvent m) {
- int mx, my;
- bool out_threshold;
- std::vector<mogltk::widget *>::iterator i;
- std::vector<mogltk::widget *> out_move_stack;
-
- mx = mogltk::engine::mouseX();
- my = mogltk::engine::mouseY();
-
- if (mouse_down) {
- int dx, dy;
-
- dx = ABS(mouse_x_down - mx);
- dy = ABS(mouse_y_down - my);
-
- out_threshold = (dx <= 1) && (dy <= 1);
- }
-
- if (mouse_down && (out_threshold || mouse_drag)) {
- if (!mouse_drag) {
- printm(M_INFO, "mouse_start_drag\n");
- // generate a mouse_start_drag event
- root->m_event(mouse_x_down, mouse_y_down, mogltk::E_MOUSE_START_DRAG);
- }
- if (dragged_widget) {
- printm(M_INFO, "mouse_drag_over");
- // generate a mouse_drag_over event
- dragged_widget->m_event(mx, my, mogltk::E_MOUSE_DRAG_OVER);
- }
-
- printm(M_INFO, "mouse_drag\n");
- // generate a mouse_drag event
- root->m_event(mx, my, mogltk::E_MOUSE_DRAG);
- mouse_drag = true;
- } else {
- printm(M_INFO, "mouse_move\n");
- root->m_event(mx, my, mogltk::E_MOUSE_MOVE);
- // generate a mouse_move event
- }
-
- for (i = out_move.begin(); i != out_move.end(); i++) {
- out_move_stack.push_back(*i);
- }
-
- for (i = out_move_stack.begin(); i != out_move_stack.end(); i++) {
- if (!(*i)->inside(mx, my)) {
- (*i)->m_event(mx, my, mogltk::E_MOUSE_OUT);
- // generate a mouse_out event
- }
- }
-
- out_move_stack.empty();
-}
-
-void widget_mouse_event::action(SDL_MouseButtonEvent b) {
- int mx, my;
- std::vector<mogltk::widget *>::iterator i;
- std::vector<mogltk::widget *> out_click_stack;
-
- mx = mogltk::engine::mouseX();
- my = mogltk::engine::mouseY();
-
- if (b.button == 1) {
- if (b.state) {
- mouse_x_down = mx;
- mouse_y_down = my;
- mouse_down = true;
- printm(M_INFO, "mouse_down\n");
- root->m_event(mx, my, mogltk::E_MOUSE_DOWN);
- // generate a mouse_down event;
- for (i = out_click.begin(); i != out_click.end(); i++) {
- out_click_stack.push_back(*i);
- }
-
- for (i = out_click_stack.begin(); i != out_click_stack.end(); i++) {
- if (!(*i)->inside(mx, my)) {
- (*i)->m_event(mx, my, mogltk::E_MOUSE_OUT_CLICK);
- // generate a mouse_out_click event
- }
- }
-
- out_click_stack.empty();
-
- } else {
- mouse_down = false;
- if (mouse_drag) {
- mouse_drag = false;
- printm(M_INFO, "mouse_end_drag\n");
- root->m_event(mx, my, mogltk::E_MOUSE_END_DRAG);
- // generate a mouse_end_drag event
- if (dragged_widget) {
- printm(M_INFO, "mouse_end_drag_over");
- dragged_widget->m_event(mx, my, mogltk::E_MOUSE_END_DRAG_OVER);
- // generate a mouse_end_drag_over event
- dragged_widget = 0;
- }
- } else {
- printm(M_INFO, "mouse_click\n");
- root->m_event(mx, my, mogltk::E_MOUSE_CLICK);
- // generate a mouse_click event
-
- for (i = out_click.begin(); i != out_click.end(); i++) {
- out_click_stack.push_back(*i);
- }
-
- for (i = out_click_stack.begin(); i != out_click_stack.end(); i++) {
- if (!(*i)->inside(mx, my)) {
- (*i)->m_event(mx, my, mogltk::E_MOUSE_OUT_CLICK);
- // generate a mouse_out_click event
- }
- }
-
- out_click_stack.empty();
-
- if ((SDL_GetTicks() - old_click) < 500) {
- printm(M_INFO, "mouse_dbl_click\n");
- root->m_event(mx, my, mogltk::E_MOUSE_DBL_CLICK);
- // generate a mouse_dbl_click event
- }
-
- old_click = SDL_GetTicks();
- }
- printm(M_INFO, "mouse_up\n");
- root->m_event(mx, my, mogltk::E_MOUSE_UP);
- // generate a mouse_up event.
- }
- }
-}
-
-mogltk::widget * mogltk::widget::focused = 0;
-
-mogltk::widget::widget(widget * _father, int _x, int _y, int _sx, int _sy, int _type, String _name, mogltk::shape * _sh) :
- x(_x), y(_y), sx(_sx), sy(_sy), father(_father), prev(0), child(0), last(0), panel(0), type(_type), name(_name), sh(_sh), exclusive(0), visible(true), enabled(true) {
- if (!father) {
- root = this;
- father = this;
- next = 0;
- x = 0;
- y = 0;
- sx = engine::base_o->GetWidth();
- sy = engine::base_o->GetHeight();
- } else {
- next = father->child;
- if (next)
- next->prev = this;
- if (!father->last)
- father->last = this;
- father->child = this;
- root = father->root;
- }
-
- computeabs();
-}
-
-mogltk::widget::~widget() {
- while(child)
- delete child;
-
- if (prev)
- prev->next = next;
- else
- father->child = next;
-
- if (next)
- next->prev = prev;
- else
- father->last = prev;
-}
-
-void mogltk::widget::computeabs() {
- if (father != this) {
- ax = father->ax + x;
- ay = father->ay + y;
- } else {
- ax = x;
- ay = y;
- }
- ax2 = ax + sx;
- ay2 = ay + sy;
-}
-
-void mogltk::widget::move(int nx, int ny) {
- x = nx;
- y = ny;
-
- computeabs();
-
- if (child)
- child->icomputeabs();
-}
-
-void mogltk::widget::resize(int nsx, int nsy) {
- sx = nsx;
- sy = nsy;
-
- ax2 = ax + sx;
- ay2 = ay + sy;
-
- if (child)
- child->iresize_notify();
-}
-
-int mogltk::widget::GetX() {
- return x;
-}
-
-int mogltk::widget::GetY() {
- return y;
-}
-
-int mogltk::widget::GetH() {
- return sy;
-}
-
-int mogltk::widget::GetW() {
- return sx;
-}
-
-int mogltk::widget::GetAX() {
- return ax;
-}
-
-int mogltk::widget::GetAY() {
- return ay;
-}
-
-int mogltk::widget::GetAX2() {
- return ax2;
-}
-
-int mogltk::widget::GetAY2() {
- return ay2;
-}
-
-mogltk::rect mogltk::widget::GetDrawRect() {
- rect r;
- r.x = 0;
- r.y = 0;
- r.w = GetW();
- r.h = GetH();
-
- return r;
-}
-
-mogltk::widget * mogltk::widget::Father() {
- return father;
-}
-
-mogltk::widget * mogltk::widget::Child() {
- return child;
-}
-
-mogltk::widget * mogltk::widget::Next() {
- return next;
-}
-
-mogltk::widget * mogltk::widget::Prev() {
- return prev;
-}
-
-mogltk::widget * mogltk::widget::InnerPanel() {
- if (!panel)
- panel = create_panel();
- return panel;
-}
-
-mogltk::widget * mogltk::widget::find_widget(int _x, int _y) {
- widget * r = 0;
-
- if (visible && enabled && (_x >= ax) && (_y >= ay) && (_x <= ax2) && (_y <= ay2)) {
- if (child)
- r = child->find_widget(_x, _y);
- if (!r)
- r = this;
- }
-
- if (!r && next) {
- r = next->find_widget(_x, _y);
- }
-
- return r;
-}
-
-mogltk::shape * mogltk::widget::Shaper() {
- return sh;
-}
-
-void mogltk::widget::fulldraw() {
- bool was2D = true;
-
- if (mogltk::engine::glbase_o)
- if (!(was2D = mogltk::engine::glbase_o->is2D()))
- mogltk::engine::glbase_o->Enter2DMode();
-
- texture::Unbind();
- mogltk::ColorP::Max = WHITE;
- mogltk::ColorP::Min = BLACK;
- mogltk::ColorP::Min.A = 0;
-
- root->idraw();
-
- if (!was2D)
- mogltk::engine::glbase_o->Leave2DMode();
-}
-
-void mogltk::widget::idraw() {
- int x1, y1, x2, y2;
-
- if (next)
- next->idraw();
-
- if (!visible)
- return;
-
- x1 = MAX(GetAX(), father->GetAX());
- y1 = MAX(GetAY(), father->GetAY());
-
- x2 = MIN(GetAX2(), father->GetAX2());
- y2 = MIN(GetAY2(), father->GetAY2());
-
- engine::base_o->changeviewport(x1, y1, x2 - x1, y2 - y1);
-
- draw();
-
- if (child)
- child->idraw();
-}
-
-bool mogltk::widget::inside(int xe, int ye) {
- if (!visible)
- return false;
- return !((xe < ax) || (xe > ax2) || (ye < ay) || (ye > ay2));
-}
-
-void mogltk::widget::m_event(int x, int y, mogltk::event_t event) {
- switch (event) {
- case E_MOUSE_DRAG_OVER:
- case E_MOUSE_END_DRAG_OVER:
- case E_MOUSE_OUT:
- case E_MOUSE_OUT_CLICK:
- process_event(x, y, event);
- break;
- default:
- ievent(x, y, event);
- }
-}
-
-bool mogltk::widget::ievent(int xe, int ye, mogltk::event_t event) {
- if (prev)
- if (prev->ievent(xe, ye, event))
- return true;
-
- if (!inside(xe, ye))
- return false;
-
- if (exclusive)
- return exclusive->ievent(xe, ye, event);
-
- if (last)
- if (last->ievent(xe, ye, event))
- return true;
-
- if (!enabled || !visible)
- return false;
-
- return process_event(xe, ye, event);
-}
-
-void mogltk::widget::draw() {
-}
-
-bool mogltk::widget::process_event(int, int, mogltk::event_t) {
- return false;
-}
-
-void mogltk::widget::resize_notify() {
-}
-
-mogltk::widget * mogltk::widget::create_panel() {
- mogltk::rect r = GetDrawRect();
- return new widgets::Panel(Shaper(), this, r.x, r.y, r.w, r.h);
-}
-
-void mogltk::widget::icomputeabs() {
- computeabs();
-
- if (next)
- next->computeabs();
-
- if (child)
- child->computeabs();
-}
-
-void mogltk::widget::iresize_notify() {
- if (next)
- next->iresize_notify();
- if (child)
- child->iresize_notify();
- resize_notify();
-}
-
-void mogltk::widget::set_exclusive(mogltk::widget * w) {
- w->exclusive = this;
-}
-
-void mogltk::widget::unset_exclusive(mogltk::widget * w) {
- w->exclusive = 0;
-}
-
-bool mogltk::widget::GetVisible() {
- return visible;
-}
-
-void mogltk::widget::SetVisible(bool _visible) {
- visible = _visible;
-}
-
-bool mogltk::widget::GetEnabled() {
- return enabled;
-}
-
-void mogltk::widget::SetEnabled(bool _enabled) {
- enabled = _enabled;
-}
-
-void mogltk::widget::MoveOnTop() {
- if (!prev)
- return;
-
- if (!next) {
- father->last = prev;
- } else {
- next->prev = prev;
- }
- prev->next = next;
- prev = 0;
- next = father->child;
-
- next->prev = this;
- father->child = this;
-}
-
-void mogltk::widget::check_timed_events() {
- std::vector<timed_event>::iterator i;
- Uint32 t = SDL_GetTicks();
- widget * w;
-
- for (i = timed_events.begin(); i != timed_events.end(); i++) {
- if (i->t <= t) {
- w = i->w;
- timed_events.erase(i);
- w->process_event(engine::mouseX(), engine::mouseY(), E_TIMER);
- i = timed_events.begin();
- if (i == timed_events.end())
- return ;
- }
- }
-}
-
-void mogltk::widget::add_out_move() {
- std::vector<widget *>::iterator i;
-
- for (i = out_move.begin(); i != out_move.end(); i++) {
- if (*i == this)
- return;
- }
-
- out_move.push_back(this);
-}
-
-void mogltk::widget::remove_out_move() {
- std::vector<widget *>::iterator i;
-
- for (i = out_move.begin(); i != out_move.end(); i++) {
- if (*i == this) {
- out_move.erase(i);
- return;
- }
- }
-}
-
-void mogltk::widget::add_out_click() {
- std::vector<widget *>::iterator i;
-
- for (i = out_click.begin(); i != out_click.end(); i++) {
- if (*i == this)
- return;
- }
-
- out_click.push_back(this);
-}
-
-void mogltk::widget::remove_out_click() {
- std::vector<widget *>::iterator i;
-
- for (i = out_click.begin(); i != out_click.end(); i++) {
- if (*i == this) {
- out_click.erase(i);
- return;
- }
- }
-}
-
-void mogltk::widget::set_timed_event(Uint32 t) {
- timed_events.push_back(timed_event(this, SDL_GetTicks() + t));
-}
-
-void mogltk::widget::set_absolute_timed_event(Uint32 t) {
- timed_events.push_back(timed_event(this, t));
-}
-
-
-/*
- * Predefined widgets.
- */
-
-/***************
-* Here is Root *
-***************/
-
-mogltk::widgets::Root::Root(mogltk::shape * sh, mogltk::widgets::drawer * _dr) : widget(0, 0, 0, 0, 0, 0, "Root", sh), dr(_dr) {
- if (engine::root)
- delete engine::root;
- engine::root = this;
-}
-
-void mogltk::widgets::Root::draw() {
- if (dr)
- dr->draw(this);
- else
- Shaper()->box(GetAX(), GetAY(), GetAX2(), GetAY2());
-}
-
-void mogltk::widgets::Root::setdrawer(drawer * _dr) {
- dr = _dr;
-}
-
-
-/**************************
-* A simple clipping Panel *
-**************************/
-
-mogltk::widgets::Panel::Panel(shape * sh, widget * father, int x, int y, int w, int h) : widget(father, x, y, w, h, 0, "Panel", sh) {
-}
-
-
-/***********************
-* The classical Button *
-***********************/
-
-mogltk::widgets::Button::Button(action * _a, shape * sh, widget * father, int x, int y, int w, int h, const String & _caption) : widget(father, x, y, w, h, 0, "Button", sh), bevel(false), dragging(false), a(_a) {
- caption = _caption;
-}
-
-void mogltk::widgets::Button::draw() {
- Shaper()->button(GetAX() + 1, GetAY() + 1, GetAX2() - 1, GetAY2() - 1, caption, bevel);
-}
-
-bool mogltk::widgets::Button::process_event(int xe, int ye, mogltk::event_t event) {
- switch (event) {
- case E_MOUSE_DOWN:
- bevel = true;
- return true;
- case E_MOUSE_CLICK:
- bevel = false;
- // action here.
- if (a)
- a->do_action(this);
- return true;
- case E_MOUSE_START_DRAG:
- dragged_widget = this;
- dragging = true;
- return true;
- case E_MOUSE_DRAG_OVER:
- bevel = inside(xe, ye);
- return true;
- case E_MOUSE_END_DRAG_OVER:
- dragging = false;
- if (bevel)
- // action here.
- if (a)
- a->do_action(this);
- bevel = false;
- return true;
- }
- return false;
-}
-
-
-/**********************
-* The SmartBox window *
-**********************/
-
-mogltk::widgets::SmartBox::SmartBox(shape * sh, mogltk::widget * father, int x, int y, int w, int h, const String & _caption) : widget(father, x, y, w, h, 0, "SmartBox", sh) {
- caption = _caption;
-}
-
-void mogltk::widgets::SmartBox::draw() {
- Shaper()->window(GetAX(), GetAY(), GetAX2(), GetAY2(), caption);
-}
-
-bool mogltk::widgets::SmartBox::process_event(int x, int y, mogltk::event_t event) {
- switch (event) {
- case E_MOUSE_START_DRAG:
- if ((GetAY() + 20) > y) {
- dragged_widget = this;
- ox = x;
- oy = y;
- oax = GetX();
- oay = GetY();
- return true;
- }
- break;
- case E_MOUSE_DRAG_OVER:
- move(x - ox + oax, y - oy + oay);
- MoveOnTop();
- return true;
- }
- return false;
-}
-
-mogltk::rect mogltk::widgets::SmartBox::GetDrawRect() {
- rect r;
-
- r.x = 2;
- r.y = 21;
- r.w = GetW() - 4;
- r.h = GetH() - 23;
-
- return r;
-}
-
-
-/***********************
-* The MessageBox child *
-***********************/
-
-class MessageBoxAction : public mogltk::widgets::action {
- public:
- MessageBoxAction(mogltk::widget * _parent) : parent(_parent) { }
- virtual void do_action(mogltk::widget *) {
- delete parent;
- delete this;
- }
- private:
- mogltk::widget * parent;
-};
-
-mogltk::widgets::MsgBox::MsgBox(shape * sh, mogltk::widget * father, const String & caption, const String & text) : SmartBox(sh, father, 0, 0, 0, 0, caption) {
- rect size = SystemFont->size(text);
- rect lsize = size;
-
- size.w += 12;
- size.h += 60;
-
- size.x = (father->GetW() - size.w) / 2;
- size.y = (father->GetH() - size.h) / 2;
- resize(size.w, size.h);
- move(size.x, size.y);
-
- new Button(new MessageBoxAction(this), sh, this, size.w / 2 - 25, size.h - 30, 50, 24, "Ok");
- new Label(sh, this, 6, 24, lsize.w, lsize.h, text, BLACK);
-
- set_exclusive(father);
-}
-
-mogltk::widgets::MsgBox::~MsgBox() {
- unset_exclusive(Father());
-}
-
-
-/*****************
-* A simple Label *
-*****************/
-
-mogltk::widgets::Label::Label(shape * sh, mogltk::widget * father, int x, int y, int w, int h, const String & _caption, const ColorP & _color) : widget(father, x, y, w, h, 0, "Label", sh), color(_color) {
- caption = _caption;
-}
-
-void mogltk::widgets::Label::draw() {
- Shaper()->text(GetAX(), GetAY(), caption, color);
-}
-
-
-/*************************
-* The classical 3D Frame *
-*************************/
-
-mogltk::widgets::Frame::Frame(shape * sh, widget * father, int x, int y, int w, int h) : widget(father, x, y, w, h, 0, "Frame", sh) {
-}
-
-void mogltk::widgets::Frame::draw() {
- Shaper()->obox3d(GetAX(), GetAY(), GetAX2(), GetAY2());
-}
-
-mogltk::rect mogltk::widgets::Frame::GetDrawRect() {
- rect r;
-
- r.x = 4;
- r.y = 4;
- r.w = GetW() - 8;
- r.h = GetH() - 8;
-
- return r;
-}
-
-
-/***********************************
-* The huge and bloated ContextMenu *
-***********************************/
-
-mogltk::widgets::ContextMenu::node::node(const String & _caption, int _x, int _y, int _w, int _h, mogltk::widgets::action * _a, mogltk::widgets::ContextMenu * _sub, mogltk::widgets::ContextMenu * _father, bool _line) : caption(_caption), x(_x), y(_y), w(_w), h(_h), a(_a), sub(_sub), father(_father), line(_line), enabled(true) {
-}
-
-String mogltk::widgets::ContextMenu::node::GetCaption() {
- return caption;
-}
-
-mogltk::widgets::action * mogltk::widgets::ContextMenu::node::GetAction() {
- return a;
-}
-
-mogltk::widgets::ContextMenu * mogltk::widgets::ContextMenu::node::GetFather() {
- return father;
-}
-
-mogltk::widgets::ContextMenu * mogltk::widgets::ContextMenu::node::GetSub() {
- return sub;
-}
-
-bool mogltk::widgets::ContextMenu::node::GetLine() {
- return line;
-}
-
-bool mogltk::widgets::ContextMenu::node::GetEnabled() {
- return enabled;
-}
-
-void mogltk::widgets::ContextMenu::node::SetEnabled(bool _enabled) {
- enabled = _enabled;
-}
-
-int mogltk::widgets::ContextMenu::node::GetX() {
- return x;
-}
-
-int mogltk::widgets::ContextMenu::node::GetY() {
- return y;
-}
-
-int mogltk::widgets::ContextMenu::node::GetW() {
- return w;
-}
-
-int mogltk::widgets::ContextMenu::node::GetH() {
- return h;
-}
-
-mogltk::widgets::ContextMenu::ContextMenu(shape * sh, mogltk::widget * father, int x, int y) : widget(father, x, y, 8, 4, 1, "ContextMenu", sh), selected(-1), subselected(0), in_click(false), sticky(false) {
-}
-
-mogltk::widgets::ContextMenu::~ContextMenu() {
- std::vector<node>::iterator i;
- ContextMenu * sub;
-
- for (i = nodes.begin(); i != nodes.end(); i++) {
- if ((sub = i->GetSub()))
- delete sub;
- }
-}
-
-void mogltk::widgets::ContextMenu::addnode(const String & caption, mogltk::widgets::action * a) {
- rect size;
-
- size = SystemFont->size(caption);
- nodes.push_back(node(caption, 4, GetH() - 2, size.w, size.h, a, 0, this, false));
- size.w += 8;
- if (GetW() > size.w)
- size.w = GetW();
- resize(size.w, GetH() + size.h);
-}
-
-void mogltk::widgets::ContextMenu::addsub(const String & caption, mogltk::widgets::ContextMenu * sub) {
- rect size;
-
- size = SystemFont->size(caption + " >");
- nodes.push_back(node(caption + " >", 4, GetH() - 2, size.w, size.h, 0, sub, this, false));
- size.w += 8;
- if (GetW() > size.w)
- size.w = GetW();
- resize(size.w, GetH() + size.h);
-}
-
-void mogltk::widgets::ContextMenu::addline() {
- nodes.push_back(node("", 2, GetH() - 1, 0, 0, 0, 0, this, true));
- resize(GetW(), GetH() + 4);
-}
-
-mogltk::widgets::ContextMenu * mogltk::widgets::ContextMenu::createsub(const String & caption) {
- ContextMenu * r;
-
- r = new ContextMenu(Shaper(), Father(), GetX() + GetW(), GetY() + GetH());
- r->SetVisible(false);
-
- addsub(caption, r);
-
- return r;
-}
-
-void mogltk::widgets::ContextMenu::move(int x, int y) {
- int dx, dy;
- std::vector<node>::iterator i;
- ContextMenu * sub;
-
- dx = x - GetX();
- dy = y - GetY();
- widget::move(x, y);
-
- for (i = nodes.begin(); i != nodes.end(); i++) {
- if ((sub = i->GetSub()))
- sub->move(sub->GetX() + dx, sub->GetY() + dy);
- }
-}
-
-void mogltk::widgets::ContextMenu::resize(int w, int h) {
- int dw;
- std::vector<node>::iterator i;
- ContextMenu * sub;
-
- dw = w - GetW();
- widget::resize(w, h);
-
- for (i = nodes.begin(); i != nodes.end(); i++) {
- if ((sub = i->GetSub()))
- sub->move(sub->GetX() + dw, sub->GetY());
- }
-}
-
-void mogltk::widgets::ContextMenu::SetVisible(bool visible) {
- if (!visible && sticky)
- return;
- widget::SetVisible(visible);
- if (!visible && subselected) {
- subselected->SetVisible(false);
- }
-
- if (visible) {
- add_out_click();
- MoveOnTop();
- }
-}
-
-void mogltk::widgets::ContextMenu::SetEnabled(int i, bool e) {
- nodes[i].SetEnabled(e);
-}
-
-void mogltk::widgets::ContextMenu::StickyDisplay() {
- sticky = true;
- SetVisible(true);
-}
-
-void mogltk::widgets::ContextMenu::draw() {
- std::vector<node>::iterator i;
- int n;
- rect size;
-
- Shaper()->box3d(GetAX(), GetAY(), GetAX2(), GetAY2());
-
- for (i = nodes.begin(), n = 0; i != nodes.end(); i++, n++) {
- size = SystemFont->size(i->GetCaption());
- if (i->GetLine()) {
- Shaper()->hline3d(GetAX() + i->GetX(), GetAX() + i->GetX() + GetW() - 4, GetAY() + i->GetY());
- } else {
- if (n == selected) {
- Shaper()->box(GetAX() + 2, GetAY() + i->GetY(), GetAX() + GetW() - 2, GetAY() + i->GetY() + i->GetH(), DOS_MAGENTA);
- }
- Shaper()->text(GetAX() + i->GetX(), GetAY() + i->GetY(), i->GetCaption(), i->GetEnabled() ? BLACK : DOS_GRAY);
- }
- }
-}
-
-bool mogltk::widgets::ContextMenu::process_event(int xe, int ye, mogltk::event_t event) {
- std::vector<node>::iterator i;
- action * a;
- int n;
-
- switch (event) {
- case E_MOUSE_MOVE:
- sticky = false;
- selected = -1;
- for (i = nodes.begin(), n = 0; i != nodes.end(); i++, n++) {
- if (!i->GetLine()) {
- int ax, ax2, ay, ay2;
-
- ax = GetAX() + 2;
- ay = GetAY() + i->GetY();
- ax2 = GetAX() + GetW() - 2;
- ay2 = GetAY() + i->GetY() + i->GetH();
-
- if (!((xe < ax) || (xe > ax2) || (ye < ay) || (ye > ay2))) {
- selected = n;
- if (subselected) {
- subselected->SetVisible(false);
- subselected->selected = -1;
- subselected->subselected = 0;
- }
- if ((subselected = i->GetSub())) {
- subselected->SetVisible(true);
- subselected->selected = -1;
- subselected->subselected = 0;
- }
- }
- }
- }
- add_out_move();
- return true;
- case E_MOUSE_CLICK:
- a = 0;
- if (selected != -1) {
- if ((a = nodes[selected].GetAction()) && nodes[selected].GetEnabled()) {
- a->do_action(this);
- in_click = false;
- SetVisible(false);
- return true;
- }
- }
- in_click = true;
- break;
- case E_MOUSE_DOWN:
- in_click = true;
- break;
- case E_MOUSE_OUT:
- selected = -1;
- remove_out_move();
- in_click = false;
- return true;
- case E_MOUSE_OUT_CLICK:
- if (iin_click())
- return true;
- selected = -1;
- subselected = 0;
- SetVisible(false);
- return true;
- }
-
- return false;
-}
-
-bool mogltk::widgets::ContextMenu::iin_click() {
- if (in_click)
- return true;
-
- if (subselected)
- return subselected->iin_click();
-
- return false;
-}
-
-
-/********************
-* The Menu topframe *
-********************/
-
-mogltk::widgets::Menu::node::node(const String & _caption, mogltk::widgets::ContextMenu * _sub, mogltk::widgets::action * _a, int _x) : caption(_caption), sub(_sub), a(_a), x(_x) {
-}
-
-String mogltk::widgets::Menu::node::GetCaption() {
- return caption;
-}
-
-void mogltk::widgets::Menu::node::SetCaption(const String & s) {
- caption = s;
-}
-
-mogltk::widgets::ContextMenu * mogltk::widgets::Menu::node::GetSub() {
- return sub;
-}
-
-mogltk::widgets::action * mogltk::widgets::Menu::node::GetAction() {
- return a;
-}
-
-int mogltk::widgets::Menu::node::GetX() {
- return x;
-}
-
-bool mogltk::widgets::Menu::node::GetEnabled() {
- return enabled;
-}
-
-void mogltk::widgets::Menu::node::SetEnabled(bool _enabled) {
- enabled = _enabled;
-}
-
-mogltk::widgets::Menu::Menu(shape * sh, mogltk::widget * father) : widget(father, 0, 0, 0, 0, 0, "Menu", sh), cur_x(0), selected(-1) {
- rect r = father->GetDrawRect();
- move(r.x, r.y);
- resize(r.w, 16);
-}
-
-void mogltk::widgets::Menu::resize_notify() {
- rect r = Father()->GetDrawRect();
- resize(r.w, 16);
-}
-
-void mogltk::widgets::Menu::addnode(const String & caption, mogltk::widgets::action * a) {
- nodes.push_back(node(caption, 0, a, cur_x));
- cur_x += SystemFont->singletextsize(caption) + 6;
-}
-
-void mogltk::widgets::Menu::addsub(const String & caption, mogltk::widgets::ContextMenu * sub) {
- nodes.push_back(node(caption, sub, 0, cur_x));
- cur_x += SystemFont->singletextsize(caption) + 6;
-}
-
-mogltk::widgets::ContextMenu * mogltk::widgets::Menu::createsub(const String & caption) {
- ContextMenu * r = new ContextMenu(Shaper(), Father(), GetX() + cur_x, GetY() + 16);
- addsub(caption, r);
- r->SetVisible(false);
- return r;
-}
-
-void mogltk::widgets::Menu::SetEnabled(int i, bool e) {
- nodes[i].SetEnabled(e);
-}
-
-void mogltk::widgets::Menu::SetCaption(int i, const String & s) {
- nodes[i].SetCaption(s);
-}
-
-void mogltk::widgets::Menu::draw(void) {
- std::vector<node>::iterator i;
- int n;
-
- Shaper()->box(GetAX(), GetAY(), GetAX2(), GetAY2(), DOS_WHITE);
-
- for (i = nodes.begin(), n = 0; i != nodes.end(); i++, n++) {
- if (selected == n) {
- if ((i + 1) == nodes.end()) {
- Shaper()->box(GetAX() + i->GetX(), GetAY(), cur_x, GetAY2(), DOS_MAGENTA);
- } else {
- Shaper()->box(GetAX() + i->GetX(), GetAY(), GetAX() + i[1].GetX(), GetAY2(), DOS_MAGENTA);
- }
- }
- Shaper()->text(GetAX() + i->GetX() + 3, GetAY(), i->GetCaption(), BLACK);
- }
-}
-
-bool mogltk::widgets::Menu::process_event(int mx, int my, mogltk::event_t event) {
- std::vector<node>::iterator i;
- action * a;
- ContextMenu * sub;
- int n;
-
- switch (event) {
- case E_MOUSE_MOVE:
- selected = -1;
- for (i = nodes.begin(), n = 0; i != nodes.end(); i++, n++) {
- int ax, ax2, ay, ay2;
-
- ax = GetAX() + i->GetX();
- ay = GetAY();
- if ((i + 1) != nodes.end()) {
- ax2 = GetAX() + i[1].GetX();
- } else {
- ax2 = GetAX() + cur_x;
- }
- ay2 = GetAY2();
-
- if (!((mx < ax) || (mx > ax2) || (my < ay) || (my > ay2))) {
- selected = n;
- }
- }
- add_out_move();
- return true;
- case E_MOUSE_CLICK:
- a = 0;
- if (selected != -1) {
- if ((a = nodes[selected].GetAction()) && nodes[selected].GetEnabled()) {
- a->do_action(this);
- return true;
- } else if ((sub = nodes[selected].GetSub()) && nodes[selected].GetEnabled()) {
- sub->StickyDisplay();
- return true;
- }
- }
- break;
- case E_MOUSE_OUT:
- selected = -1;
- remove_out_move();
- return true;
- }
- return false;
-}
-
-
-/*
- * The mainloop widget thing.
- */
-
-void mogltk::widget::mainloop() {
- bool end_event_loop = false;
- widget_mouse_event * mouse = new widget_mouse_event(this);
- widget * w;
- int mx, my;
-
- while (!end_event_loop && !engine::quitrequested()) {
- root->fulldraw();
- mx = mogltk::engine::mouseX();
- my = mogltk::engine::mouseY();
-
- mogltk::ColorP::Max.A = 50;
- Sprite::Cursor->draw(mx - 6, my - 3, BLACK);
- mogltk::ColorP::Max.A = 255;
- Sprite::Cursor->draw(mx - 8, my - 6);
-
- if (w = root->find_widget(mx, my)) {
- sh->box(w->GetAX(), w->GetAY(), w->GetAX2(), w->GetAY2(), Color(100, 150, 60, 50));
- }
-
- engine::base_o->Flip();
- widget::check_timed_events();
- }
-
- delete mouse;
-}
+/*
+ * mogltk
+ * Copyright (C) 1999-2004 Nicolas "Pixel" Noble
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: widgets.cc,v 1.10 2004-11-27 21:48:03 pixel Exp $ */
+
+#include <SDL.h>
+#include <vector>
+#include <Input.h>
+#include "font.h"
+#include "engine.h"
+#include "widgets.h"
+#include "sprite.h"
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gettext.h"
+
+mogltk::widget * dragged_widget = 0;
+
+std::vector<mogltk::widget *> out_move, out_click;
+std::vector<mogltk::widget::timed_event> mogltk::widget::timed_events;
+
+
+class widget_mouse_event : public mogltk::engine::mouseevent {
+ public:
+ widget_mouse_event(mogltk::widget *);
+ virtual void move(SDL_MouseMotionEvent);
+ virtual void action(SDL_MouseButtonEvent);
+ private:
+ mogltk::widget * root;
+ int mouse_x_down, mouse_y_down;
+ bool mouse_down, mouse_drag;
+ Uint32 old_click;
+};
+
+widget_mouse_event::widget_mouse_event(mogltk::widget * _root) : root(_root), mouse_down(false), mouse_drag(false) {
+}
+
+void widget_mouse_event::move(SDL_MouseMotionEvent m) {
+ int mx, my;
+ bool out_threshold;
+ std::vector<mogltk::widget *>::iterator i;
+ std::vector<mogltk::widget *> out_move_stack;
+
+ mx = mogltk::engine::mouseX();
+ my = mogltk::engine::mouseY();
+
+ if (mouse_down) {
+ int dx, dy;
+
+ dx = ABS(mouse_x_down - mx);
+ dy = ABS(mouse_y_down - my);
+
+ out_threshold = (dx <= 1) && (dy <= 1);
+ }
+
+ if (mouse_down && (out_threshold || mouse_drag)) {
+ if (!mouse_drag) {
+ printm(M_INFO, "mouse_start_drag\n");
+ // generate a mouse_start_drag event
+ root->m_event(mouse_x_down, mouse_y_down, mogltk::E_MOUSE_START_DRAG);
+ }
+ if (dragged_widget) {
+ printm(M_INFO, "mouse_drag_over");
+ // generate a mouse_drag_over event
+ dragged_widget->m_event(mx, my, mogltk::E_MOUSE_DRAG_OVER);
+ }
+
+ printm(M_INFO, "mouse_drag\n");
+ // generate a mouse_drag event
+ root->m_event(mx, my, mogltk::E_MOUSE_DRAG);
+ mouse_drag = true;
+ } else {
+ printm(M_INFO, "mouse_move\n");
+ root->m_event(mx, my, mogltk::E_MOUSE_MOVE);
+ // generate a mouse_move event
+ }
+
+ for (i = out_move.begin(); i != out_move.end(); i++) {
+ out_move_stack.push_back(*i);
+ }
+
+ for (i = out_move_stack.begin(); i != out_move_stack.end(); i++) {
+ if (!(*i)->inside(mx, my)) {
+ (*i)->m_event(mx, my, mogltk::E_MOUSE_OUT);
+ // generate a mouse_out event
+ }
+ }
+
+ out_move_stack.empty();
+}
+
+void widget_mouse_event::action(SDL_MouseButtonEvent b) {
+ int mx, my;
+ std::vector<mogltk::widget *>::iterator i;
+ std::vector<mogltk::widget *> out_click_stack;
+
+ mx = mogltk::engine::mouseX();
+ my = mogltk::engine::mouseY();
+
+ if (b.button == 1) {
+ if (b.state) {
+ mouse_x_down = mx;
+ mouse_y_down = my;
+ mouse_down = true;
+ printm(M_INFO, "mouse_down\n");
+ root->m_event(mx, my, mogltk::E_MOUSE_DOWN);
+ // generate a mouse_down event;
+ for (i = out_click.begin(); i != out_click.end(); i++) {
+ out_click_stack.push_back(*i);
+ }
+
+ for (i = out_click_stack.begin(); i != out_click_stack.end(); i++) {
+ if (!(*i)->inside(mx, my)) {
+ (*i)->m_event(mx, my, mogltk::E_MOUSE_OUT_CLICK);
+ // generate a mouse_out_click event
+ }
+ }
+
+ out_click_stack.empty();
+
+ } else {
+ mouse_down = false;
+ if (mouse_drag) {
+ mouse_drag = false;
+ printm(M_INFO, "mouse_end_drag\n");
+ root->m_event(mx, my, mogltk::E_MOUSE_END_DRAG);
+ // generate a mouse_end_drag event
+ if (dragged_widget) {
+ printm(M_INFO, "mouse_end_drag_over");
+ dragged_widget->m_event(mx, my, mogltk::E_MOUSE_END_DRAG_OVER);
+ // generate a mouse_end_drag_over event
+ dragged_widget = 0;
+ }
+ } else {
+ printm(M_INFO, "mouse_click\n");
+ root->m_event(mx, my, mogltk::E_MOUSE_CLICK);
+ // generate a mouse_click event
+
+ for (i = out_click.begin(); i != out_click.end(); i++) {
+ out_click_stack.push_back(*i);
+ }
+
+ for (i = out_click_stack.begin(); i != out_click_stack.end(); i++) {
+ if (!(*i)->inside(mx, my)) {
+ (*i)->m_event(mx, my, mogltk::E_MOUSE_OUT_CLICK);
+ // generate a mouse_out_click event
+ }
+ }
+
+ out_click_stack.empty();
+
+ if ((SDL_GetTicks() - old_click) < 500) {
+ printm(M_INFO, "mouse_dbl_click\n");
+ root->m_event(mx, my, mogltk::E_MOUSE_DBL_CLICK);
+ // generate a mouse_dbl_click event
+ }
+
+ old_click = SDL_GetTicks();
+ }
+ printm(M_INFO, "mouse_up\n");
+ root->m_event(mx, my, mogltk::E_MOUSE_UP);
+ // generate a mouse_up event.
+ }
+ }
+}
+
+mogltk::widget * mogltk::widget::focused = 0;
+
+mogltk::widget::widget(widget * _father, int _x, int _y, int _sx, int _sy, int _type, String _name, mogltk::shape * _sh) :
+ x(_x), y(_y), sx(_sx), sy(_sy), father(_father), prev(0), child(0), last(0), panel(0), type(_type), name(_name), sh(_sh), exclusive(0), visible(true), enabled(true) {
+ if (!father) {
+ root = this;
+ father = this;
+ next = 0;
+ x = 0;
+ y = 0;
+ sx = engine::base_o->GetWidth();
+ sy = engine::base_o->GetHeight();
+ } else {
+ next = father->child;
+ if (next)
+ next->prev = this;
+ if (!father->last)
+ father->last = this;
+ father->child = this;
+ root = father->root;
+ }
+
+ computeabs();
+}
+
+mogltk::widget::~widget() {
+ while(child)
+ delete child;
+
+ if (prev)
+ prev->next = next;
+ else
+ father->child = next;
+
+ if (next)
+ next->prev = prev;
+ else
+ father->last = prev;
+}
+
+void mogltk::widget::computeabs() {
+ if (father != this) {
+ ax = father->ax + x;
+ ay = father->ay + y;
+ } else {
+ ax = x;
+ ay = y;
+ }
+ ax2 = ax + sx;
+ ay2 = ay + sy;
+}
+
+void mogltk::widget::move(int nx, int ny) {
+ x = nx;
+ y = ny;
+
+ computeabs();
+
+ if (child)
+ child->icomputeabs();
+}
+
+void mogltk::widget::resize(int nsx, int nsy) {
+ sx = nsx;
+ sy = nsy;
+
+ ax2 = ax + sx;
+ ay2 = ay + sy;
+
+ if (child)
+ child->iresize_notify();
+}
+
+int mogltk::widget::GetX() {
+ return x;
+}
+
+int mogltk::widget::GetY() {
+ return y;
+}
+
+int mogltk::widget::GetH() {
+ return sy;
+}
+
+int mogltk::widget::GetW() {
+ return sx;
+}
+
+int mogltk::widget::GetAX() {
+ return ax;
+}
+
+int mogltk::widget::GetAY() {
+ return ay;
+}
+
+int mogltk::widget::GetAX2() {
+ return ax2;
+}
+
+int mogltk::widget::GetAY2() {
+ return ay2;
+}
+
+mogltk::rect mogltk::widget::GetDrawRect() {
+ rect r;
+ r.x = 0;
+ r.y = 0;
+ r.w = GetW();
+ r.h = GetH();
+
+ return r;
+}
+
+mogltk::widget * mogltk::widget::Father() {
+ return father;
+}
+
+mogltk::widget * mogltk::widget::Child() {
+ return child;
+}
+
+mogltk::widget * mogltk::widget::Next() {
+ return next;
+}
+
+mogltk::widget * mogltk::widget::Prev() {
+ return prev;
+}
+
+mogltk::widget * mogltk::widget::InnerPanel() {
+ if (!panel)
+ panel = create_panel();
+ return panel;
+}
+
+mogltk::widget * mogltk::widget::find_widget(int _x, int _y) {
+ widget * r = 0;
+
+ if (visible && enabled && (_x >= ax) && (_y >= ay) && (_x <= ax2) && (_y <= ay2)) {
+ if (child)
+ r = child->find_widget(_x, _y);
+ if (!r)
+ r = this;
+ }
+
+ if (!r && next) {
+ r = next->find_widget(_x, _y);
+ }
+
+ return r;
+}
+
+mogltk::shape * mogltk::widget::Shaper() {
+ return sh;
+}
+
+void mogltk::widget::fulldraw() {
+ bool was2D = true;
+
+ if (mogltk::engine::glbase_o)
+ if (!(was2D = mogltk::engine::glbase_o->is2D()))
+ mogltk::engine::glbase_o->Enter2DMode();
+
+ texture::Unbind();
+ mogltk::ColorP::Max = WHITE;
+ mogltk::ColorP::Min = BLACK;
+ mogltk::ColorP::Min.A = 0;
+
+ root->idraw();
+
+ if (!was2D)
+ mogltk::engine::glbase_o->Leave2DMode();
+}
+
+void mogltk::widget::idraw() {
+ int x1, y1, x2, y2;
+
+ if (next)
+ next->idraw();
+
+ if (!visible)
+ return;
+
+ x1 = MAX(GetAX(), father->GetAX());
+ y1 = MAX(GetAY(), father->GetAY());
+
+ x2 = MIN(GetAX2(), father->GetAX2());
+ y2 = MIN(GetAY2(), father->GetAY2());
+
+ engine::base_o->changeviewport(x1, y1, x2 - x1, y2 - y1);
+
+ draw();
+
+ if (child)
+ child->idraw();
+}
+
+bool mogltk::widget::inside(int xe, int ye) {
+ if (!visible)
+ return false;
+ return !((xe < ax) || (xe > ax2) || (ye < ay) || (ye > ay2));
+}
+
+void mogltk::widget::m_event(int x, int y, mogltk::event_t event) {
+ switch (event) {
+ case E_MOUSE_DRAG_OVER:
+ case E_MOUSE_END_DRAG_OVER:
+ case E_MOUSE_OUT:
+ case E_MOUSE_OUT_CLICK:
+ process_event(x, y, event);
+ break;
+ default:
+ ievent(x, y, event);
+ }
+}
+
+bool mogltk::widget::ievent(int xe, int ye, mogltk::event_t event) {
+ if (prev)
+ if (prev->ievent(xe, ye, event))
+ return true;
+
+ if (!inside(xe, ye))
+ return false;
+
+ if (exclusive)
+ return exclusive->ievent(xe, ye, event);
+
+ if (last)
+ if (last->ievent(xe, ye, event))
+ return true;
+
+ if (!enabled || !visible)
+ return false;
+
+ return process_event(xe, ye, event);
+}
+
+void mogltk::widget::draw() {
+}
+
+bool mogltk::widget::process_event(int, int, mogltk::event_t) {
+ return false;
+}
+
+void mogltk::widget::resize_notify() {
+}
+
+mogltk::widget * mogltk::widget::create_panel() {
+ mogltk::rect r = GetDrawRect();
+ return new widgets::Panel(Shaper(), this, r.x, r.y, r.w, r.h);
+}
+
+void mogltk::widget::icomputeabs() {
+ computeabs();
+
+ if (next)
+ next->computeabs();
+
+ if (child)
+ child->computeabs();
+}
+
+void mogltk::widget::iresize_notify() {
+ if (next)
+ next->iresize_notify();
+ if (child)
+ child->iresize_notify();
+ resize_notify();
+}
+
+void mogltk::widget::set_exclusive(mogltk::widget * w) {
+ w->exclusive = this;
+}
+
+void mogltk::widget::unset_exclusive(mogltk::widget * w) {
+ w->exclusive = 0;
+}
+
+bool mogltk::widget::GetVisible() {
+ return visible;
+}
+
+void mogltk::widget::SetVisible(bool _visible) {
+ visible = _visible;
+}
+
+bool mogltk::widget::GetEnabled() {
+ return enabled;
+}
+
+void mogltk::widget::SetEnabled(bool _enabled) {
+ enabled = _enabled;
+}
+
+void mogltk::widget::MoveOnTop() {
+ if (!prev)
+ return;
+
+ if (!next) {
+ father->last = prev;
+ } else {
+ next->prev = prev;
+ }
+ prev->next = next;
+ prev = 0;
+ next = father->child;
+
+ next->prev = this;
+ father->child = this;
+}
+
+void mogltk::widget::check_timed_events() {
+ std::vector<timed_event>::iterator i;
+ Uint32 t = SDL_GetTicks();
+ widget * w;
+
+ for (i = timed_events.begin(); i != timed_events.end(); i++) {
+ if (i->t <= t) {
+ w = i->w;
+ timed_events.erase(i);
+ w->process_event(engine::mouseX(), engine::mouseY(), E_TIMER);
+ i = timed_events.begin();
+ if (i == timed_events.end())
+ return ;
+ }
+ }
+}
+
+void mogltk::widget::add_out_move() {
+ std::vector<widget *>::iterator i;
+
+ for (i = out_move.begin(); i != out_move.end(); i++) {
+ if (*i == this)
+ return;
+ }
+
+ out_move.push_back(this);
+}
+
+void mogltk::widget::remove_out_move() {
+ std::vector<widget *>::iterator i;
+
+ for (i = out_move.begin(); i != out_move.end(); i++) {
+ if (*i == this) {
+ out_move.erase(i);
+ return;
+ }
+ }
+}
+
+void mogltk::widget::add_out_click() {
+ std::vector<widget *>::iterator i;
+
+ for (i = out_click.begin(); i != out_click.end(); i++) {
+ if (*i == this)
+ return;
+ }
+
+ out_click.push_back(this);
+}
+
+void mogltk::widget::remove_out_click() {
+ std::vector<widget *>::iterator i;
+
+ for (i = out_click.begin(); i != out_click.end(); i++) {
+ if (*i == this) {
+ out_click.erase(i);
+ return;
+ }
+ }
+}
+
+void mogltk::widget::set_timed_event(Uint32 t) {
+ timed_events.push_back(timed_event(this, SDL_GetTicks() + t));
+}
+
+void mogltk::widget::set_absolute_timed_event(Uint32 t) {
+ timed_events.push_back(timed_event(this, t));
+}
+
+
+/*
+ * Predefined widgets.
+ */
+
+/***************
+* Here is Root *
+***************/
+
+mogltk::widgets::Root::Root(mogltk::shape * sh, mogltk::widgets::drawer * _dr) : widget(0, 0, 0, 0, 0, 0, "Root", sh), dr(_dr) {
+ if (engine::root)
+ delete engine::root;
+ engine::root = this;
+}
+
+void mogltk::widgets::Root::draw() {
+ if (dr)
+ dr->draw(this);
+ else
+ Shaper()->box(GetAX(), GetAY(), GetAX2(), GetAY2());
+}
+
+void mogltk::widgets::Root::setdrawer(drawer * _dr) {
+ dr = _dr;
+}
+
+
+/**************************
+* A simple clipping Panel *
+**************************/
+
+mogltk::widgets::Panel::Panel(shape * sh, widget * father, int x, int y, int w, int h) : widget(father, x, y, w, h, 0, "Panel", sh) {
+}
+
+
+/***********************
+* The classical Button *
+***********************/
+
+mogltk::widgets::Button::Button(action * _a, shape * sh, widget * father, int x, int y, int w, int h, const String & _caption) : widget(father, x, y, w, h, 0, "Button", sh), bevel(false), dragging(false), a(_a) {
+ caption = _caption;
+}
+
+void mogltk::widgets::Button::draw() {
+ Shaper()->button(GetAX() + 1, GetAY() + 1, GetAX2() - 1, GetAY2() - 1, caption, bevel);
+}
+
+bool mogltk::widgets::Button::process_event(int xe, int ye, mogltk::event_t event) {
+ switch (event) {
+ case E_MOUSE_DOWN:
+ bevel = true;
+ return true;
+ case E_MOUSE_CLICK:
+ bevel = false;
+ // action here.
+ if (a)
+ a->do_action(this);
+ return true;
+ case E_MOUSE_START_DRAG:
+ dragged_widget = this;
+ dragging = true;
+ return true;
+ case E_MOUSE_DRAG_OVER:
+ bevel = inside(xe, ye);
+ return true;
+ case E_MOUSE_END_DRAG_OVER:
+ dragging = false;
+ if (bevel)
+ // action here.
+ if (a)
+ a->do_action(this);
+ bevel = false;
+ return true;
+ }
+ return false;
+}
+
+
+/**********************
+* The SmartBox window *
+**********************/
+
+mogltk::widgets::SmartBox::SmartBox(shape * sh, mogltk::widget * father, int x, int y, int w, int h, const String & _caption) : widget(father, x, y, w, h, 0, "SmartBox", sh) {
+ caption = _caption;
+}
+
+void mogltk::widgets::SmartBox::draw() {
+ Shaper()->window(GetAX(), GetAY(), GetAX2(), GetAY2(), caption);
+}
+
+bool mogltk::widgets::SmartBox::process_event(int x, int y, mogltk::event_t event) {
+ switch (event) {
+ case E_MOUSE_START_DRAG:
+ if ((GetAY() + 20) > y) {
+ dragged_widget = this;
+ ox = x;
+ oy = y;
+ oax = GetX();
+ oay = GetY();
+ return true;
+ }
+ break;
+ case E_MOUSE_DRAG_OVER:
+ move(x - ox + oax, y - oy + oay);
+ MoveOnTop();
+ return true;
+ }
+ return false;
+}
+
+mogltk::rect mogltk::widgets::SmartBox::GetDrawRect() {
+ rect r;
+
+ r.x = 2;
+ r.y = 21;
+ r.w = GetW() - 4;
+ r.h = GetH() - 23;
+
+ return r;
+}
+
+
+/***********************
+* The MessageBox child *
+***********************/
+
+class MessageBoxAction : public mogltk::widgets::action {
+ public:
+ MessageBoxAction(mogltk::widget * _parent) : parent(_parent) { }
+ virtual void do_action(mogltk::widget *) {
+ delete parent;
+ delete this;
+ }
+ private:
+ mogltk::widget * parent;
+};
+
+mogltk::widgets::MsgBox::MsgBox(shape * sh, mogltk::widget * father, const String & caption, const String & text) : SmartBox(sh, father, 0, 0, 0, 0, caption) {
+ rect size = SystemFont->size(text);
+ rect lsize = size;
+
+ size.w += 12;
+ size.h += 60;
+
+ size.x = (father->GetW() - size.w) / 2;
+ size.y = (father->GetH() - size.h) / 2;
+ resize(size.w, size.h);
+ move(size.x, size.y);
+
+ new Button(new MessageBoxAction(this), sh, this, size.w / 2 - 25, size.h - 30, 50, 24, "Ok");
+ new Label(sh, this, 6, 24, lsize.w, lsize.h, text, BLACK);
+
+ set_exclusive(father);
+}
+
+mogltk::widgets::MsgBox::~MsgBox() {
+ unset_exclusive(Father());
+}
+
+
+/*****************
+* A simple Label *
+*****************/
+
+mogltk::widgets::Label::Label(shape * sh, mogltk::widget * father, int x, int y, int w, int h, const String & _caption, const ColorP & _color) : widget(father, x, y, w, h, 0, "Label", sh), color(_color) {
+ caption = _caption;
+}
+
+void mogltk::widgets::Label::draw() {
+ Shaper()->text(GetAX(), GetAY(), caption, color);
+}
+
+
+/*************************
+* The classical 3D Frame *
+*************************/
+
+mogltk::widgets::Frame::Frame(shape * sh, widget * father, int x, int y, int w, int h) : widget(father, x, y, w, h, 0, "Frame", sh) {
+}
+
+void mogltk::widgets::Frame::draw() {
+ Shaper()->obox3d(GetAX(), GetAY(), GetAX2(), GetAY2());
+}
+
+mogltk::rect mogltk::widgets::Frame::GetDrawRect() {
+ rect r;
+
+ r.x = 4;
+ r.y = 4;
+ r.w = GetW() - 8;
+ r.h = GetH() - 8;
+
+ return r;
+}
+
+
+/***********************************
+* The huge and bloated ContextMenu *
+***********************************/
+
+mogltk::widgets::ContextMenu::node::node(const String & _caption, int _x, int _y, int _w, int _h, mogltk::widgets::action * _a, mogltk::widgets::ContextMenu * _sub, mogltk::widgets::ContextMenu * _father, bool _line) : caption(_caption), x(_x), y(_y), w(_w), h(_h), a(_a), sub(_sub), father(_father), line(_line), enabled(true) {
+}
+
+String mogltk::widgets::ContextMenu::node::GetCaption() {
+ return caption;
+}
+
+mogltk::widgets::action * mogltk::widgets::ContextMenu::node::GetAction() {
+ return a;
+}
+
+mogltk::widgets::ContextMenu * mogltk::widgets::ContextMenu::node::GetFather() {
+ return father;
+}
+
+mogltk::widgets::ContextMenu * mogltk::widgets::ContextMenu::node::GetSub() {
+ return sub;
+}
+
+bool mogltk::widgets::ContextMenu::node::GetLine() {
+ return line;
+}
+
+bool mogltk::widgets::ContextMenu::node::GetEnabled() {
+ return enabled;
+}
+
+void mogltk::widgets::ContextMenu::node::SetEnabled(bool _enabled) {
+ enabled = _enabled;
+}
+
+int mogltk::widgets::ContextMenu::node::GetX() {
+ return x;
+}
+
+int mogltk::widgets::ContextMenu::node::GetY() {
+ return y;
+}
+
+int mogltk::widgets::ContextMenu::node::GetW() {
+ return w;
+}
+
+int mogltk::widgets::ContextMenu::node::GetH() {
+ return h;
+}
+
+mogltk::widgets::ContextMenu::ContextMenu(shape * sh, mogltk::widget * father, int x, int y) : widget(father, x, y, 8, 4, 1, "ContextMenu", sh), selected(-1), subselected(0), in_click(false), sticky(false) {
+}
+
+mogltk::widgets::ContextMenu::~ContextMenu() {
+ std::vector<node>::iterator i;
+ ContextMenu * sub;
+
+ for (i = nodes.begin(); i != nodes.end(); i++) {
+ if ((sub = i->GetSub()))
+ delete sub;
+ }
+}
+
+void mogltk::widgets::ContextMenu::addnode(const String & caption, mogltk::widgets::action * a) {
+ rect size;
+
+ size = SystemFont->size(caption);
+ nodes.push_back(node(caption, 4, GetH() - 2, size.w, size.h, a, 0, this, false));
+ size.w += 8;
+ if (GetW() > size.w)
+ size.w = GetW();
+ resize(size.w, GetH() + size.h);
+}
+
+void mogltk::widgets::ContextMenu::addsub(const String & caption, mogltk::widgets::ContextMenu * sub) {
+ rect size;
+
+ size = SystemFont->size(caption + " >");
+ nodes.push_back(node(caption + " >", 4, GetH() - 2, size.w, size.h, 0, sub, this, false));
+ size.w += 8;
+ if (GetW() > size.w)
+ size.w = GetW();
+ resize(size.w, GetH() + size.h);
+}
+
+void mogltk::widgets::ContextMenu::addline() {
+ nodes.push_back(node("", 2, GetH() - 1, 0, 0, 0, 0, this, true));
+ resize(GetW(), GetH() + 4);
+}
+
+mogltk::widgets::ContextMenu * mogltk::widgets::ContextMenu::createsub(const String & caption) {
+ ContextMenu * r;
+
+ r = new ContextMenu(Shaper(), Father(), GetX() + GetW(), GetY() + GetH());
+ r->SetVisible(false);
+
+ addsub(caption, r);
+
+ return r;
+}
+
+void mogltk::widgets::ContextMenu::move(int x, int y) {
+ int dx, dy;
+ std::vector<node>::iterator i;
+ ContextMenu * sub;
+
+ dx = x - GetX();
+ dy = y - GetY();
+ widget::move(x, y);
+
+ for (i = nodes.begin(); i != nodes.end(); i++) {
+ if ((sub = i->GetSub()))
+ sub->move(sub->GetX() + dx, sub->GetY() + dy);
+ }
+}
+
+void mogltk::widgets::ContextMenu::resize(int w, int h) {
+ int dw;
+ std::vector<node>::iterator i;
+ ContextMenu * sub;
+
+ dw = w - GetW();
+ widget::resize(w, h);
+
+ for (i = nodes.begin(); i != nodes.end(); i++) {
+ if ((sub = i->GetSub()))
+ sub->move(sub->GetX() + dw, sub->GetY());
+ }
+}
+
+void mogltk::widgets::ContextMenu::SetVisible(bool visible) {
+ if (!visible && sticky)
+ return;
+ widget::SetVisible(visible);
+ if (!visible && subselected) {
+ subselected->SetVisible(false);
+ }
+
+ if (visible) {
+ add_out_click();
+ MoveOnTop();
+ }
+}
+
+void mogltk::widgets::ContextMenu::SetEnabled(int i, bool e) {
+ nodes[i].SetEnabled(e);
+}
+
+void mogltk::widgets::ContextMenu::StickyDisplay() {
+ sticky = true;
+ SetVisible(true);
+}
+
+void mogltk::widgets::ContextMenu::draw() {
+ std::vector<node>::iterator i;
+ int n;
+ rect size;
+
+ Shaper()->box3d(GetAX(), GetAY(), GetAX2(), GetAY2());
+
+ for (i = nodes.begin(), n = 0; i != nodes.end(); i++, n++) {
+ size = SystemFont->size(i->GetCaption());
+ if (i->GetLine()) {
+ Shaper()->hline3d(GetAX() + i->GetX(), GetAX() + i->GetX() + GetW() - 4, GetAY() + i->GetY());
+ } else {
+ if (n == selected) {
+ Shaper()->box(GetAX() + 2, GetAY() + i->GetY(), GetAX() + GetW() - 2, GetAY() + i->GetY() + i->GetH(), DOS_MAGENTA);
+ }
+ Shaper()->text(GetAX() + i->GetX(), GetAY() + i->GetY(), i->GetCaption(), i->GetEnabled() ? BLACK : DOS_GRAY);
+ }
+ }
+}
+
+bool mogltk::widgets::ContextMenu::process_event(int xe, int ye, mogltk::event_t event) {
+ std::vector<node>::iterator i;
+ action * a;
+ int n;
+
+ switch (event) {
+ case E_MOUSE_MOVE:
+ sticky = false;
+ selected = -1;
+ for (i = nodes.begin(), n = 0; i != nodes.end(); i++, n++) {
+ if (!i->GetLine()) {
+ int ax, ax2, ay, ay2;
+
+ ax = GetAX() + 2;
+ ay = GetAY() + i->GetY();
+ ax2 = GetAX() + GetW() - 2;
+ ay2 = GetAY() + i->GetY() + i->GetH();
+
+ if (!((xe < ax) || (xe > ax2) || (ye < ay) || (ye > ay2))) {
+ selected = n;
+ if (subselected) {
+ subselected->SetVisible(false);
+ subselected->selected = -1;
+ subselected->subselected = 0;
+ }
+ if ((subselected = i->GetSub())) {
+ subselected->SetVisible(true);
+ subselected->selected = -1;
+ subselected->subselected = 0;
+ }
+ }
+ }
+ }
+ add_out_move();
+ return true;
+ case E_MOUSE_CLICK:
+ a = 0;
+ if (selected != -1) {
+ if ((a = nodes[selected].GetAction()) && nodes[selected].GetEnabled()) {
+ a->do_action(this);
+ in_click = false;
+ SetVisible(false);
+ return true;
+ }
+ }
+ in_click = true;
+ break;
+ case E_MOUSE_DOWN:
+ in_click = true;
+ break;
+ case E_MOUSE_OUT:
+ selected = -1;
+ remove_out_move();
+ in_click = false;
+ return true;
+ case E_MOUSE_OUT_CLICK:
+ if (iin_click())
+ return true;
+ selected = -1;
+ subselected = 0;
+ SetVisible(false);
+ return true;
+ }
+
+ return false;
+}
+
+bool mogltk::widgets::ContextMenu::iin_click() {
+ if (in_click)
+ return true;
+
+ if (subselected)
+ return subselected->iin_click();
+
+ return false;
+}
+
+
+/********************
+* The Menu topframe *
+********************/
+
+mogltk::widgets::Menu::node::node(const String & _caption, mogltk::widgets::ContextMenu * _sub, mogltk::widgets::action * _a, int _x) : caption(_caption), sub(_sub), a(_a), x(_x) {
+}
+
+String mogltk::widgets::Menu::node::GetCaption() {
+ return caption;
+}
+
+void mogltk::widgets::Menu::node::SetCaption(const String & s) {
+ caption = s;
+}
+
+mogltk::widgets::ContextMenu * mogltk::widgets::Menu::node::GetSub() {
+ return sub;
+}
+
+mogltk::widgets::action * mogltk::widgets::Menu::node::GetAction() {
+ return a;
+}
+
+int mogltk::widgets::Menu::node::GetX() {
+ return x;
+}
+
+bool mogltk::widgets::Menu::node::GetEnabled() {
+ return enabled;
+}
+
+void mogltk::widgets::Menu::node::SetEnabled(bool _enabled) {
+ enabled = _enabled;
+}
+
+mogltk::widgets::Menu::Menu(shape * sh, mogltk::widget * father) : widget(father, 0, 0, 0, 0, 0, "Menu", sh), cur_x(0), selected(-1) {
+ rect r = father->GetDrawRect();
+ move(r.x, r.y);
+ resize(r.w, 16);
+}
+
+void mogltk::widgets::Menu::resize_notify() {
+ rect r = Father()->GetDrawRect();
+ resize(r.w, 16);
+}
+
+void mogltk::widgets::Menu::addnode(const String & caption, mogltk::widgets::action * a) {
+ nodes.push_back(node(caption, 0, a, cur_x));
+ cur_x += SystemFont->singletextsize(caption) + 6;
+}
+
+void mogltk::widgets::Menu::addsub(const String & caption, mogltk::widgets::ContextMenu * sub) {
+ nodes.push_back(node(caption, sub, 0, cur_x));
+ cur_x += SystemFont->singletextsize(caption) + 6;
+}
+
+mogltk::widgets::ContextMenu * mogltk::widgets::Menu::createsub(const String & caption) {
+ ContextMenu * r = new ContextMenu(Shaper(), Father(), GetX() + cur_x, GetY() + 16);
+ addsub(caption, r);
+ r->SetVisible(false);
+ return r;
+}
+
+void mogltk::widgets::Menu::SetEnabled(int i, bool e) {
+ nodes[i].SetEnabled(e);
+}
+
+void mogltk::widgets::Menu::SetCaption(int i, const String & s) {
+ nodes[i].SetCaption(s);
+}
+
+void mogltk::widgets::Menu::draw(void) {
+ std::vector<node>::iterator i;
+ int n;
+
+ Shaper()->box(GetAX(), GetAY(), GetAX2(), GetAY2(), DOS_WHITE);
+
+ for (i = nodes.begin(), n = 0; i != nodes.end(); i++, n++) {
+ if (selected == n) {
+ if ((i + 1) == nodes.end()) {
+ Shaper()->box(GetAX() + i->GetX(), GetAY(), cur_x, GetAY2(), DOS_MAGENTA);
+ } else {
+ Shaper()->box(GetAX() + i->GetX(), GetAY(), GetAX() + i[1].GetX(), GetAY2(), DOS_MAGENTA);
+ }
+ }
+ Shaper()->text(GetAX() + i->GetX() + 3, GetAY(), i->GetCaption(), BLACK);
+ }
+}
+
+bool mogltk::widgets::Menu::process_event(int mx, int my, mogltk::event_t event) {
+ std::vector<node>::iterator i;
+ action * a;
+ ContextMenu * sub;
+ int n;
+
+ switch (event) {
+ case E_MOUSE_MOVE:
+ selected = -1;
+ for (i = nodes.begin(), n = 0; i != nodes.end(); i++, n++) {
+ int ax, ax2, ay, ay2;
+
+ ax = GetAX() + i->GetX();
+ ay = GetAY();
+ if ((i + 1) != nodes.end()) {
+ ax2 = GetAX() + i[1].GetX();
+ } else {
+ ax2 = GetAX() + cur_x;
+ }
+ ay2 = GetAY2();
+
+ if (!((mx < ax) || (mx > ax2) || (my < ay) || (my > ay2))) {
+ selected = n;
+ }
+ }
+ add_out_move();
+ return true;
+ case E_MOUSE_CLICK:
+ a = 0;
+ if (selected != -1) {
+ if ((a = nodes[selected].GetAction()) && nodes[selected].GetEnabled()) {
+ a->do_action(this);
+ return true;
+ } else if ((sub = nodes[selected].GetSub()) && nodes[selected].GetEnabled()) {
+ sub->StickyDisplay();
+ return true;
+ }
+ }
+ break;
+ case E_MOUSE_OUT:
+ selected = -1;
+ remove_out_move();
+ return true;
+ }
+ return false;
+}
+
+
+/*
+ * The mainloop widget thing.
+ */
+
+void mogltk::widget::mainloop() {
+ bool end_event_loop = false;
+ widget_mouse_event * mouse = new widget_mouse_event(this);
+ widget * w;
+ int mx, my;
+
+ while (!end_event_loop && !engine::quitrequested()) {
+ root->fulldraw();
+ mx = mogltk::engine::mouseX();
+ my = mogltk::engine::mouseY();
+
+ mogltk::ColorP::Max.A = 50;
+ Sprite::Cursor->draw(mx - 6, my - 3, BLACK);
+ mogltk::ColorP::Max.A = 255;
+ Sprite::Cursor->draw(mx - 8, my - 6);
+
+ if (w = root->find_widget(mx, my)) {
+ sh->box(w->GetAX(), w->GetAY(), w->GetAX2(), w->GetAY2(), Color(100, 150, 60, 50));
+ }
+
+ engine::base_o->Flip();
+ widget::check_timed_events();
+ }
+
+ delete mouse;
+}