aboutsummaryrefslogtreecommitdiff
path: root/engines/sword25/util/glsprites/internal/sprite.c
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sword25/util/glsprites/internal/sprite.c')
-rwxr-xr-xengines/sword25/util/glsprites/internal/sprite.c156
1 files changed, 156 insertions, 0 deletions
diff --git a/engines/sword25/util/glsprites/internal/sprite.c b/engines/sword25/util/glsprites/internal/sprite.c
new file mode 100755
index 0000000000..261ce207e6
--- /dev/null
+++ b/engines/sword25/util/glsprites/internal/sprite.c
@@ -0,0 +1,156 @@
+/******************************************************************************/
+/* This file is part of Broken Sword 2.5 */
+/* Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdörfer */
+/* */
+/* Broken Sword 2.5 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. */
+/* */
+/* Broken Sword 2.5 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 Broken Sword 2.5; if not, write to the Free Software */
+/* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+/******************************************************************************/
+
+/* --------------------------------------------------------------------------
+ INCLUDES
+ -------------------------------------------------------------------------- */
+
+
+#include <malloc.h>
+
+#include "glinclude.h"
+#include "util.h"
+#include "core.h"
+#include "sprite.h"
+#include "sprite_rectangle.h"
+#include "sprite_pow2.h"
+#include "sprite_tiled.h"
+
+/* -------------------------------------------------------------------------- */
+
+typedef struct
+{
+ /* These first three members are present at the start of each sprite type.
+ Therefore it is safe to cast all sprite to this. */
+ GLS_spriteFunctionTable * functionTable;
+ GLS_UInt32 width;
+ GLS_UInt32 height;
+} spriteBase;
+
+/* -------------------------------------------------------------------------- */
+
+#define MAX_WASTED_TEXTURE_MEMORY_PERCENT 30
+
+/* -------------------------------------------------------------------------- */
+
+GLS_Result GLS_NewSprite(GLS_UInt32 width, GLS_UInt32 height, GLS_Bool useAlphachannel, void * data, GLS_Sprite ** pSprite)
+{
+ //* The sprite needs to be at least 1x1 pixel in size */
+ if (width == 0 || height == 0) return GLS_INVALID_SPRITE_DIMENSIONS;
+
+ /* If both dimensions are powers of 2 a power of 2 texture will be used for the sprite */
+ if (GLS_IsPowerOf2(width) && GLS_IsPowerOf2(height)) return GLS_NewSpritePow2(width, height, useAlphachannel, data, pSprite);
+
+ /* Use TEXTURE_RECTANGLE_ARB for non power of 2 dimensions whenever possible */
+ if (GLS_TheOGLCaps.textureRectanglesSupported &&
+ GLS_TheOGLCaps.maxTextureRectangleSize >= width &&
+ GLS_TheOGLCaps.maxTextureRectangleSize >= height)
+ return GLS_NewSpriteRectangle(width, height, useAlphachannel, data, pSprite);
+
+ /* Use a power of 2 texture if TEXTURE_RECTANGLE_ARB is not possible, the image is small enough and the amount of wasted texture memory
+ is not too big */
+ if ((width <= GLS_TheOGLCaps.maxTextureSize && height <= GLS_TheOGLCaps.maxTextureSize) &&
+ (GLS_NextPowerOf2(width) * GLS_NextPowerOf2(height) * 100) / (width * height) <= MAX_WASTED_TEXTURE_MEMORY_PERCENT)
+ return GLS_NewSpritePow2(width, height, useAlphachannel, data, pSprite);
+
+ /* Otherwise use tiled power of 2 textures */
+ return GLS_NewSpriteTiled(width, height, useAlphachannel, data, pSprite);
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+GLS_Result GLS_DeleteSprite(GLS_Sprite * sprite)
+{
+ /* Poor mans polymorphism. */
+ spriteBase * s = (spriteBase *) sprite;
+ return s->functionTable->Delete(sprite);
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+GLS_Result GLS_Blit(GLS_Sprite * sprite,
+ GLS_SInt32 x, GLS_SInt32 y,
+ const GLS_Rect * subImage,
+ const GLS_Color * color,
+ GLS_Bool flipH, GLS_Bool flipV,
+ GLS_Float scaleX, GLS_Float scaleY)
+{
+ spriteBase * s = (spriteBase *) sprite;
+ GLS_Rect localSubImage;
+ const GLS_Rect * subImagePtr;
+ GLS_Result result;
+
+ /* Check parameters for validity. */
+ if (subImage && (subImage->x2 > s->width || subImage->y2 > s->height)) return GLS_INVALID_SUB_IMAGE;
+
+ /* If no subimage was supplied, create one that covers the whole sprite. */
+ if (subImage)
+ subImagePtr = subImage;
+ else
+ {
+ localSubImage.x1 = 0;
+ localSubImage.y1 = 0;
+ localSubImage.x2 = s->width;
+ localSubImage.y2 = s->height;
+ subImagePtr = &localSubImage;
+ }
+
+ /* Modify the Modelview-Matrix to reflect the sprites position, flip settings, and scale. */
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+ glTranslatef((GLfloat) x, (GLfloat) y, 0);
+ if (flipH == GLS_True || flipV == GLS_True || scaleX != 1.0f || scaleY != 1.0f)
+ {
+ glScalef(scaleX * (flipH == GLS_True ? -1.0f : 1.0f), scaleY * (flipV == GLS_True ? -1.0f : 1.0f), 1.0f);
+ glTranslatef(flipH == GLS_True ? (subImagePtr->x2 - subImagePtr->x1) * -1.0f : 0.0f,
+ flipV == GLS_True ? (subImagePtr->y2 - subImagePtr->y1) * -1.0f : 0.0f, 0.0f);
+ }
+
+ /* Set the color to be used. Use white if no color was provided. */
+ if (color)
+ glColor4ub(color->r, color->g, color->b, color->a);
+ else
+ glColor4ub(255, 255, 255, 255);
+
+ /* Display the sprite by calling the Blit() function of the specific sprite type. */
+ result = s->functionTable->Blit(sprite, subImagePtr);
+
+ /* Restore the old matrix. */
+ glPopMatrix();
+
+ return result;
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+GLS_Result GLS_SetSpriteData(GLS_Sprite sprite, GLS_UInt32 width, GLS_UInt32 height, const void * data, GLS_UInt32 stride)
+{
+ spriteBase * s = (spriteBase *) sprite;
+
+ /* Check parameters for validity. */
+ if (width == 0 || height == 0 || width > s->width || height > s->height) return GLS_INVALID_DATA_DIMENSIONS;
+ if (data == 0) return GLS_INVALID_DATA_POINTER;
+
+ /* Poor mans polymorphism. */
+ return s->functionTable->SetData(sprite, width, height, data, stride);
+}