Initial commit
This commit is contained in:
266
engines/hpl1/engine/resources/FrameBitmap.cpp
Normal file
266
engines/hpl1/engine/resources/FrameBitmap.cpp
Normal file
@@ -0,0 +1,266 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2010 - Frictional Games
|
||||
*
|
||||
* This file is part of HPL1 Engine.
|
||||
*/
|
||||
|
||||
#include "hpl1/engine/resources/FrameBitmap.h"
|
||||
#include "hpl1/engine/graphics/Texture.h"
|
||||
#include "hpl1/engine/graphics/bitmap2D.h"
|
||||
#include "hpl1/engine/math/Math.h"
|
||||
#include "hpl1/engine/resources/FrameTexture.h"
|
||||
#include "hpl1/engine/resources/ResourceImage.h"
|
||||
#include "hpl1/engine/system/low_level_system.h"
|
||||
|
||||
namespace hpl {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CONSTRUCTORS
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cFrameBitmap::cFrameBitmap(Bitmap2D *apBitmap, cFrameTexture *apFrmTex, int alHandle) : iFrameBase() {
|
||||
mpBitmap = apBitmap;
|
||||
mpFrameTexture = apFrmTex;
|
||||
mpBitmap->fillRect(cRect2l(0, 0, 0, 0), cColor(1, 1));
|
||||
mlMinHole = 6;
|
||||
mlHandle = alHandle;
|
||||
mbIsFull = false;
|
||||
mbIsLocked = false;
|
||||
|
||||
// Root node in rect tree
|
||||
mRects.Insert(cFBitmapRect(0, 0, mpBitmap->getWidth(), mpBitmap->getHeight(), -1));
|
||||
}
|
||||
|
||||
cFrameBitmap::~cFrameBitmap() {
|
||||
hplDelete(mpBitmap);
|
||||
mpBitmap = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// PUBLIC METHODS
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#define DEBUG_BTREE (false)
|
||||
|
||||
cResourceImage *cFrameBitmap::AddBitmap(Bitmap2D *apSrc) {
|
||||
cResourceImage *pImage = NULL;
|
||||
// source size
|
||||
//+2 because we are gonna have a border to get rid if some antialiasing problems
|
||||
int lSW = apSrc->getWidth() + 2;
|
||||
int lSH = apSrc->getHeight() + 2;
|
||||
|
||||
// destination size
|
||||
// int lDW = mpBitmap->getWidth();
|
||||
// int lDH = mpBitmap->getHeight();
|
||||
|
||||
cVector2l vPos;
|
||||
|
||||
bool bFoundEmptyNode = false;
|
||||
bool bFoundNode = false;
|
||||
// Debug
|
||||
int node = 0;
|
||||
|
||||
if (DEBUG_BTREE)
|
||||
Log("**** Image %d *****\n", mlPicCount);
|
||||
|
||||
// Get the leaves of the tree and search it for a good pos.
|
||||
tRectTreeNodeList lstNodes = mRects.GetLeafList();
|
||||
tRectTreeNodeListIt it;
|
||||
for (it = lstNodes.begin(); it != lstNodes.end(); ++it) {
|
||||
if (DEBUG_BTREE)
|
||||
Log("Checking node %d:\n", node++);
|
||||
tRectTreeNode *TopNode = *it;
|
||||
cFBitmapRect *pData = TopNode->GetData();
|
||||
|
||||
// Check if the space is free
|
||||
if (pData->mlHandle < 0) {
|
||||
if (DEBUG_BTREE)
|
||||
Log("Found free node\n");
|
||||
bFoundEmptyNode = true; // An empty node was found.. bitmap not full yet.
|
||||
|
||||
// Check if the Image fits in the rect
|
||||
cRect2l NewRect = cRect2l(pData->mRect.x, pData->mRect.y, lSW, lSH);
|
||||
if (DEBUG_BTREE)
|
||||
Log("Fit: [%d:%d:%d:%d] in [%d:%d:%d:%d]\n",
|
||||
NewRect.x, NewRect.y, NewRect.w, NewRect.h,
|
||||
pData->mRect.x, pData->mRect.y, pData->mRect.w, pData->mRect.h);
|
||||
|
||||
if (cMath::BoxFit(NewRect, pData->mRect)) {
|
||||
if (DEBUG_BTREE)
|
||||
Log("The node fits!\n");
|
||||
bFoundNode = true;
|
||||
|
||||
// If the bitmap fits perfectly add the node without splitting
|
||||
if (MinimumFit(NewRect, pData->mRect)) {
|
||||
if (DEBUG_BTREE)
|
||||
Log("Minimum fit!\n");
|
||||
pData->mRect = NewRect;
|
||||
pData->mlHandle = 1;
|
||||
}
|
||||
// If there is still space left, make new nodes.
|
||||
else {
|
||||
if (DEBUG_BTREE)
|
||||
Log("Normal fit!\n");
|
||||
// Insert 2 children for the top node (lower and upper part.
|
||||
tRectTreeNode *UpperNode;
|
||||
// Upper
|
||||
UpperNode = mRects.InsertAt(cFBitmapRect(NewRect.x, NewRect.y,
|
||||
pData->mRect.w, NewRect.h, -2),
|
||||
TopNode,
|
||||
eBinTreeNode_Left);
|
||||
|
||||
// Lower
|
||||
mRects.InsertAt(cFBitmapRect(NewRect.x, NewRect.y + NewRect.h,
|
||||
pData->mRect.w, pData->mRect.h - NewRect.h, -3),
|
||||
TopNode,
|
||||
eBinTreeNode_Right);
|
||||
|
||||
// Split the Upper Node into 2 nodes.
|
||||
pData = UpperNode->GetData(); // Get the data for the upper node.
|
||||
// Upper split, this is the new bitmap
|
||||
mRects.InsertAt(cFBitmapRect(NewRect.x, NewRect.y,
|
||||
NewRect.w, NewRect.h, 2),
|
||||
UpperNode,
|
||||
eBinTreeNode_Left);
|
||||
|
||||
// Lower split, this is empty
|
||||
mRects.InsertAt(cFBitmapRect(NewRect.x + NewRect.w, NewRect.y,
|
||||
pData->mRect.w - NewRect.w, NewRect.h, -4),
|
||||
UpperNode,
|
||||
eBinTreeNode_Right);
|
||||
}
|
||||
|
||||
vPos = cVector2l(NewRect.x + 1, NewRect.y + 1); //+1 for the right pos
|
||||
|
||||
// Draw 4 times so we get a nice extra border
|
||||
for (int i = 0; i < 2; i++)
|
||||
for (int j = 0; j < 2; j++) {
|
||||
apSrc->drawToBitmap(*mpBitmap, cVector2l(NewRect.x + i * 2, NewRect.y + j * 2));
|
||||
}
|
||||
// Fix the border a little more:
|
||||
for (int i = -1; i < 2; i++)
|
||||
for (int j = -1; j < 2; j++)
|
||||
if ((i == 0 || j == 0) && (i != j)) {
|
||||
apSrc->drawToBitmap(*mpBitmap, cVector2l(NewRect.x + 1 + i, NewRect.y + 1 + j));
|
||||
}
|
||||
// Draw the final
|
||||
apSrc->drawToBitmap(*mpBitmap, cVector2l(NewRect.x + 1, NewRect.y + 1));
|
||||
|
||||
mlPicCount++;
|
||||
mpFrameTexture->SetPicCount(mlPicCount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bFoundNode) {
|
||||
// Create the image resource
|
||||
pImage = hplNew(cResourceImage, (apSrc->getFileName(), mpFrameTexture, this,
|
||||
cRect2l(vPos, cVector2l(lSW - 2, lSH - 2)), //-2 to get the correct size.
|
||||
cVector2l(mpBitmap->getWidth(), mpBitmap->getHeight()),
|
||||
mlHandle));
|
||||
|
||||
if (!bFoundEmptyNode) {
|
||||
mbIsFull = true;
|
||||
}
|
||||
|
||||
mbIsUpdated = true;
|
||||
}
|
||||
|
||||
/// LAST DEBUG ///
|
||||
if (DEBUG_BTREE) {
|
||||
Log("Current Tree begin:\n");
|
||||
tRectTreeNodeList lstNodes2 = mRects.GetNodeList();
|
||||
tRectTreeNodeListIt it2;
|
||||
int node2 = 0;
|
||||
for (it2 = lstNodes2.begin(); it2 != lstNodes2.end(); ++it) {
|
||||
cRect2l Rect = (*it2)->GetData()->mRect;
|
||||
int h = (*it)->GetData()->mlHandle;
|
||||
Log(" %d: [%d:%d:%d:%d]:%d\n", node2, Rect.x, Rect.y, Rect.w, Rect.h, h);
|
||||
node2++;
|
||||
}
|
||||
Log("Current Tree end:\n");
|
||||
Log("-----------------\n");
|
||||
|
||||
Log("Current Leaves begin:\n");
|
||||
lstNodes2 = mRects.GetLeafList();
|
||||
node2 = 0;
|
||||
for (it2 = lstNodes2.begin(); it2 != lstNodes2.end(); ++it) {
|
||||
cRect2l Rect = (*it2)->GetData()->mRect;
|
||||
int h = (*it2)->GetData()->mlHandle;
|
||||
Log(" %d: [%d:%d:%d:%d]: %d\n", node2, Rect.x, Rect.y, Rect.w, Rect.h, h);
|
||||
node2++;
|
||||
}
|
||||
Log("Current Tree end:\n");
|
||||
Log("-----------------\n");
|
||||
}
|
||||
|
||||
return pImage;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool cFrameBitmap::MinimumFit(cRect2l aSrc, cRect2l aDest) {
|
||||
if (aDest.w - aSrc.w < mlMinHole && aDest.h - aSrc.h < mlMinHole)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool cFrameBitmap::IsUpdated() {
|
||||
return mbIsUpdated;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool cFrameBitmap::IsFull() {
|
||||
return mbIsFull;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool cFrameBitmap::FlushToTexture() {
|
||||
if (mbIsUpdated) {
|
||||
mpFrameTexture->GetTexture()->CreateFromBitmap(mpBitmap);
|
||||
mpFrameTexture->GetTexture()->SetWrapS(eTextureWrap_ClampToEdge);
|
||||
mpFrameTexture->GetTexture()->SetWrapT(eTextureWrap_ClampToEdge);
|
||||
|
||||
// mpFrameTexture->SetPicCount(mlPicCount);
|
||||
mbIsUpdated = false;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
} // namespace hpl
|
||||
Reference in New Issue
Block a user