summaryrefslogtreecommitdiff
path: root/lib/texture.cc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/texture.cc')
-rw-r--r--lib/texture.cc194
1 files changed, 194 insertions, 0 deletions
diff --git a/lib/texture.cc b/lib/texture.cc
new file mode 100644
index 0000000..36297ac
--- /dev/null
+++ b/lib/texture.cc
@@ -0,0 +1,194 @@
+#include <sys/types.h>
+#include <SDL.h>
+#include <generic.h>
+#include "texture.h"
+#include "engine.h"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "gettext.h"
+
+#ifdef TRACE_TEXTURES
+mogltk::texture * mogltk::texture::header = 0;
+mogltk::texture * mogltk::texture::footer = 0;
+#endif
+
+mogltk::texture * mogltk::texture::active = 0;
+
+mogltk::texture::texture(int w, int h) throw (GeneralException) : width(w), height(h),
+ texture_allocated(false), planar(plane), tainted(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"));
+ }
+
+#ifdef TRACE_TEXTURES
+ next = 0;
+ prev = footer;
+ footer = this;
+ if (!header) {
+ header = this;
+ }
+ if (prev) {
+ prev->next = this;
+ }
+#endif
+}
+
+mogltk::texture::texture(Handle * h) throw (GeneralException) {
+ 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);
+
+#ifdef TRACE_TEXTURES
+ next = 0;
+ prev = footer;
+ footer = this;
+ if (!header) {
+ header = this;
+ }
+ if (prev) {
+ prev->next = this;
+ }
+#endif
+}
+
+mogltk::texture::~texture() {
+ if (surface) {
+ SDL_FreeSurface(surface);
+ }
+
+#ifdef TRACE_TEXTURES
+ if (prev) {
+ prev->next = next;
+ }
+
+ if (next) {
+ next->prev = prev;
+ }
+
+ if (this == footer) {
+ footer = prev;
+ }
+
+ if (this == header) {
+ header = next;
+ }
+#endif
+}
+
+Uint32 * mogltk::texture::GetPixels() {
+ return (Uint32 *) surface->pixels;
+}
+
+SDL_Surface * mogltk::texture::GetSurface() {
+ return surface;
+}
+
+Uint32 mogltk::texture::GetWidth() {
+ return width;
+}
+
+Uint32 mogltk::texture::GetHeight() {
+ return height;
+}
+
+#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[4];
+ 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;
+}