mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
* Merged Source Code from Development Trunk: Revision 4063 * ************************************************************ - Source Code is merged from: https://81.169.133.124/source/ja2/branches/Wanne/JA2%201.13%20MP - This will be the Source for the Beta 2011 Test git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@4064 3b4a5df2-a311-0410-b5c6-a8a6f20db521
1747 lines
49 KiB
C++
1747 lines
49 KiB
C++
#ifdef JA2_PRECOMPILED_HEADERS
|
|
#include "JA2 SGP ALL.H"
|
|
#elif defined( WIZ8_PRECOMPILED_HEADERS )
|
|
#include "WIZ8 SGP ALL.H"
|
|
#else
|
|
#include "DirectDraw Calls.h"
|
|
#include <stdio.h>
|
|
#include "debug.h"
|
|
#if defined( JA2 ) || defined( UTIL )
|
|
#include "video.h"
|
|
#else
|
|
#include "video2.h"
|
|
#endif
|
|
#include "himage.h"
|
|
#include "vobject.h"
|
|
#include "vobject_private.h"
|
|
#include "video_private.h"
|
|
#include "wcheck.h"
|
|
#include "vobject_blitters.h"
|
|
#include "sgp.h"
|
|
#endif
|
|
|
|
// ******************************************************************************
|
|
//
|
|
// Video Object SGP Module
|
|
//
|
|
// Video Objects are used to contain any imagery which requires blitting. The data
|
|
// is contained within a Direct Draw surface. Palette information is in both
|
|
// a Direct Draw Palette and a 16BPP palette structure for 8->16 BPP Blits.
|
|
// Blitting is done via Direct Draw as well as custum blitters. Regions are
|
|
// used to define local coordinates within the surface
|
|
//
|
|
// Second Revision: Dec 10, 1996, Andrew Emmons
|
|
//
|
|
// *******************************************************************************
|
|
|
|
|
|
// *******************************************************************************
|
|
// Defines
|
|
// *******************************************************************************
|
|
|
|
// This define is sent to CreateList SGP function. It dynamically re-sizes if
|
|
// the list gets larger
|
|
#define DEFAULT_VIDEO_OBJECT_LIST_SIZE 10
|
|
|
|
#define COMPRESS_TRANSPARENT 0x80
|
|
#define COMPRESS_RUN_MASK 0x7F
|
|
|
|
// *******************************************************************************
|
|
// External Functions and variables
|
|
// *******************************************************************************
|
|
|
|
// *******************************************************************************
|
|
// LOCAL functions
|
|
// *******************************************************************************
|
|
|
|
|
|
// *******************************************************************************
|
|
// LOCAL global variables
|
|
// *******************************************************************************
|
|
|
|
|
|
|
|
HLIST ghVideoObjects = NULL;
|
|
BOOLEAN gfVideoObjectsInit=FALSE;
|
|
|
|
typedef struct VOBJECT_NODE
|
|
{
|
|
HVOBJECT hVObject;
|
|
UINT32 uiIndex;
|
|
struct VOBJECT_NODE *next, *prev;
|
|
|
|
#ifdef SGP_VIDEO_DEBUGGING
|
|
STR8 pName;
|
|
STR8 pCode;
|
|
#endif
|
|
|
|
}VOBJECT_NODE;
|
|
|
|
VOBJECT_NODE *gpVObjectHead = NULL;
|
|
VOBJECT_NODE *gpVObjectTail = NULL;
|
|
UINT32 guiVObjectIndex = 1;
|
|
UINT32 guiVObjectSize = 0;
|
|
UINT32 guiVObjectTotalAdded = 0;
|
|
|
|
#ifdef _DEBUG
|
|
enum
|
|
{
|
|
DEBUGSTR_NONE,
|
|
DEBUGSTR_SETVIDEOOBJECTTRANSPARENCY,
|
|
DEBUGSTR_BLTVIDEOOBJECTFROMINDEX,
|
|
DEBUGSTR_SETOBJECTHANDLESHADE,
|
|
DEBUGSTR_GETVIDEOOBJECTETRLESUBREGIONPROPERTIES,
|
|
DEBUGSTR_GETVIDEOOBJECTETRLEPROPERTIESFROMINDEX,
|
|
DEBUGSTR_SETVIDEOOBJECTPALETTE8BPP,
|
|
DEBUGSTR_GETVIDEOOBJECTPALETTE16BPP,
|
|
DEBUGSTR_COPYVIDEOOBJECTPALETTE16BPP,
|
|
DEBUGSTR_BLTVIDEOOBJECTOUTLINEFROMINDEX,
|
|
DEBUGSTR_BLTVIDEOOBJECTOUTLINESHADOWFROMINDEX,
|
|
DEBUGSTR_DELETEVIDEOOBJECTFROMINDEX
|
|
};
|
|
|
|
UINT8 gubVODebugCode = 0;
|
|
|
|
void CheckValidVObjectIndex( UINT32 uiIndex );
|
|
#endif
|
|
|
|
// **************************************************************
|
|
//
|
|
// Video Object Manager functions
|
|
//
|
|
// **************************************************************
|
|
|
|
int filter(unsigned int code, struct _EXCEPTION_POINTERS *ep)
|
|
{
|
|
puts("in filter.");
|
|
if (code == EXCEPTION_ACCESS_VIOLATION) {
|
|
puts("caught AV as expected.");
|
|
return EXCEPTION_EXECUTE_HANDLER;
|
|
}
|
|
|
|
else
|
|
{
|
|
puts("didn't catch AV, unexpected.");
|
|
return EXCEPTION_CONTINUE_SEARCH;
|
|
};
|
|
}
|
|
|
|
BOOLEAN InitializeVideoObjectManager( )
|
|
{
|
|
//Shouldn't be calling this if the video object manager already exists.
|
|
//Call shutdown first...
|
|
Assert( !gpVObjectHead );
|
|
Assert( !gpVObjectTail );
|
|
RegisterDebugTopic(TOPIC_VIDEOOBJECT, "Video Object Manager");
|
|
gpVObjectHead = gpVObjectTail = NULL;
|
|
gfVideoObjectsInit=TRUE;
|
|
return TRUE ;
|
|
}
|
|
|
|
BOOLEAN ShutdownVideoObjectManager( )
|
|
{
|
|
VOBJECT_NODE *curr;
|
|
while( gpVObjectHead )
|
|
{
|
|
curr = gpVObjectHead;
|
|
gpVObjectHead = gpVObjectHead->next;
|
|
DeleteVideoObject( curr->hVObject );
|
|
#ifdef SGP_VIDEO_DEBUGGING
|
|
if( curr->pName )
|
|
MemFree( curr->pName );
|
|
if( curr->pCode )
|
|
MemFree( curr->pCode );
|
|
#endif
|
|
MemFree( curr );
|
|
}
|
|
gpVObjectHead = NULL;
|
|
gpVObjectTail = NULL;
|
|
guiVObjectIndex = 1;
|
|
guiVObjectSize = 0;
|
|
guiVObjectTotalAdded = 0;
|
|
UnRegisterDebugTopic(TOPIC_VIDEOOBJECT, "Video Objects");
|
|
gfVideoObjectsInit=FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
UINT32 CountVideoObjectNodes()
|
|
{
|
|
VOBJECT_NODE *curr;
|
|
UINT32 i = 0;
|
|
curr = gpVObjectHead;
|
|
while( curr )
|
|
{
|
|
i++;
|
|
curr = curr->next;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
BOOLEAN AddStandardVideoObject( VOBJECT_DESC *pVObjectDesc, UINT32 *puiIndex )
|
|
{
|
|
|
|
HVOBJECT hVObject;
|
|
|
|
// Assertions
|
|
Assert( puiIndex );
|
|
Assert( pVObjectDesc );
|
|
|
|
// Create video object
|
|
hVObject = CreateVideoObject( pVObjectDesc );
|
|
|
|
if( !hVObject )
|
|
{
|
|
// Video Object will set error condition.
|
|
return FALSE ;
|
|
}
|
|
|
|
// Set transparency to default
|
|
SetVideoObjectTransparencyColor( hVObject, FROMRGB( 0, 0, 0 ) );
|
|
|
|
// Set into video object list
|
|
if( gpVObjectHead )
|
|
{ //Add node after tail
|
|
gpVObjectTail->next = (VOBJECT_NODE*)MemAlloc( sizeof( VOBJECT_NODE ) );
|
|
Assert( gpVObjectTail->next ); //out of memory?
|
|
gpVObjectTail->next->prev = gpVObjectTail;
|
|
gpVObjectTail->next->next = NULL;
|
|
gpVObjectTail = gpVObjectTail->next;
|
|
}
|
|
else
|
|
{ //new list
|
|
gpVObjectHead = (VOBJECT_NODE*)MemAlloc( sizeof( VOBJECT_NODE ) );
|
|
Assert( gpVObjectHead ); //out of memory?
|
|
gpVObjectHead->prev = gpVObjectHead->next = NULL;
|
|
gpVObjectTail = gpVObjectHead;
|
|
}
|
|
#ifdef SGP_VIDEO_DEBUGGING
|
|
gpVObjectTail->pName = NULL;
|
|
gpVObjectTail->pCode = NULL;
|
|
#endif
|
|
//Set the hVObject into the node.
|
|
gpVObjectTail->hVObject = hVObject;
|
|
gpVObjectTail->uiIndex = guiVObjectIndex+=2;
|
|
*puiIndex = gpVObjectTail->uiIndex;
|
|
Assert( guiVObjectIndex < 0xfffffff0 ); //unlikely that we will ever use 2 billion vobjects!
|
|
//We would have to create about 70 vobjects per second for 1 year straight to achieve this...
|
|
guiVObjectSize++;
|
|
guiVObjectTotalAdded++;
|
|
|
|
#ifdef JA2TESTVERSION
|
|
if( CountVideoObjectNodes() != guiVObjectSize )
|
|
{
|
|
guiVObjectSize = guiVObjectSize;
|
|
}
|
|
#endif
|
|
|
|
return TRUE ;
|
|
}
|
|
|
|
|
|
BOOLEAN SetVideoObjectTransparency( UINT32 uiIndex, COLORVAL TransColor )
|
|
{
|
|
HVOBJECT hVObject;
|
|
|
|
// Get video object
|
|
#ifdef _DEBUG
|
|
gubVODebugCode = DEBUGSTR_SETVIDEOOBJECTTRANSPARENCY;
|
|
#endif
|
|
CHECKF( GetVideoObject( &hVObject, uiIndex ) );
|
|
|
|
// Set transparency
|
|
SetVideoObjectTransparencyColor( hVObject, TransColor );
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
BOOLEAN GetVideoObject( HVOBJECT *hVObject, UINT32 uiIndex )
|
|
{
|
|
VOBJECT_NODE *curr;
|
|
|
|
#ifdef _DEBUG
|
|
CheckValidVObjectIndex( uiIndex );
|
|
#endif
|
|
|
|
curr = gpVObjectHead;
|
|
while( curr )
|
|
{
|
|
if( curr->uiIndex == uiIndex )
|
|
{
|
|
*hVObject = curr->hVObject;
|
|
return TRUE;
|
|
}
|
|
curr = curr->next;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOLEAN BltVideoObjectFromIndex(UINT32 uiDestVSurface, UINT32 uiSrcVObject, UINT16 usRegionIndex, INT32 iDestX, INT32 iDestY, UINT32 fBltFlags, blt_fx *pBltFx )
|
|
{
|
|
UINT16 *pBuffer;
|
|
UINT32 uiPitch;
|
|
HVOBJECT hSrcVObject;
|
|
|
|
// Lock video surface
|
|
pBuffer = (UINT16*)LockVideoSurface( uiDestVSurface, &uiPitch );
|
|
|
|
if ( pBuffer == NULL )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
// Get video object
|
|
#ifdef _DEBUG
|
|
gubVODebugCode = DEBUGSTR_BLTVIDEOOBJECTFROMINDEX;
|
|
#endif
|
|
if( !GetVideoObject( &hSrcVObject, uiSrcVObject ) )
|
|
{
|
|
UnLockVideoSurface( uiDestVSurface );
|
|
return FALSE;
|
|
}
|
|
|
|
// Now we have the video object and surface, call the VO blitter function
|
|
if ( !BltVideoObjectToBuffer( pBuffer, uiPitch, hSrcVObject, usRegionIndex, iDestX, iDestY, fBltFlags, pBltFx ) )
|
|
{
|
|
UnLockVideoSurface( uiDestVSurface );
|
|
// VO Blitter will set debug messages for error conditions
|
|
return FALSE;
|
|
}
|
|
|
|
UnLockVideoSurface( uiDestVSurface );
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
BOOLEAN DeleteVideoObjectFromIndex( UINT32 uiVObject )
|
|
{
|
|
VOBJECT_NODE *curr;
|
|
|
|
#ifdef _DEBUG
|
|
gubVODebugCode = DEBUGSTR_DELETEVIDEOOBJECTFROMINDEX;
|
|
CheckValidVObjectIndex( uiVObject );
|
|
#endif
|
|
|
|
curr = gpVObjectHead;
|
|
while( curr )
|
|
{
|
|
if( curr->uiIndex == uiVObject )
|
|
{ //Found the node, so detach it and delete it.
|
|
|
|
//Deallocate the memory for the video object
|
|
DeleteVideoObject( curr->hVObject );
|
|
|
|
if( curr == gpVObjectHead )
|
|
{ //Advance the head, because we are going to remove the head node.
|
|
gpVObjectHead = gpVObjectHead->next;
|
|
}
|
|
if( curr == gpVObjectTail )
|
|
{ //Back up the tail, because we are going to remove the tail node.
|
|
gpVObjectTail = gpVObjectTail->prev;
|
|
}
|
|
//Detach the node from the vobject list
|
|
if( curr->next )
|
|
{ //Make the prev node point to the next
|
|
curr->next->prev = curr->prev;
|
|
}
|
|
if( curr->prev )
|
|
{ //Make the next node point to the prev
|
|
curr->prev->next = curr->next;
|
|
}
|
|
//The node is now detached. Now deallocate it.
|
|
#ifdef SGP_VIDEO_DEBUGGING
|
|
if( curr->pName )
|
|
MemFree( curr->pName );
|
|
if( curr->pCode )
|
|
MemFree( curr->pCode );
|
|
#endif
|
|
MemFree( curr );
|
|
curr = NULL;
|
|
guiVObjectSize--;
|
|
#ifdef JA2TESTVERSION
|
|
if( CountVideoObjectNodes() != guiVObjectSize )
|
|
{
|
|
guiVObjectSize = guiVObjectSize;
|
|
}
|
|
#endif
|
|
return TRUE;
|
|
}
|
|
curr = curr->next;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
// Given an index to the dest and src vobject contained in ghVideoObjects
|
|
// Based on flags, blit accordingly
|
|
// There are two types, a BltFast and a Blt. BltFast is 10% faster, uses no
|
|
// clipping lists
|
|
BOOLEAN BltVideoObject( UINT32 uiDestVSurface,
|
|
HVOBJECT hSrcVObject,
|
|
UINT16 usRegionIndex,
|
|
INT32 iDestX,
|
|
INT32 iDestY,
|
|
UINT32 fBltFlags,
|
|
blt_fx *pBltFx )
|
|
{
|
|
|
|
UINT16 *pBuffer;
|
|
UINT32 uiPitch;
|
|
|
|
// Lock video surface
|
|
pBuffer = (UINT16*)LockVideoSurface( uiDestVSurface, &uiPitch );
|
|
|
|
if ( pBuffer == NULL )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
// Now we have the video object and surface, call the VO blitter function
|
|
if ( !BltVideoObjectToBuffer( pBuffer, uiPitch, hSrcVObject, usRegionIndex, iDestX, iDestY, fBltFlags, pBltFx ) )
|
|
{
|
|
UnLockVideoSurface( uiDestVSurface );
|
|
// VO Blitter will set debug messages for error conditions
|
|
return( FALSE );
|
|
}
|
|
|
|
UnLockVideoSurface( uiDestVSurface );
|
|
return( TRUE );
|
|
}
|
|
|
|
// *******************************************************************************
|
|
// Video Object Manipulation Functions
|
|
// *******************************************************************************
|
|
|
|
|
|
HVOBJECT CreateVideoObject( VOBJECT_DESC *VObjectDesc )
|
|
{
|
|
HVOBJECT hVObject;
|
|
HIMAGE hImage;
|
|
ETRLEData TempETRLEData;
|
|
// UINT32 count;
|
|
|
|
// Allocate memory for video object data and initialize
|
|
hVObject = (HVOBJECT) MemAlloc( sizeof( SGPVObject ) );
|
|
CHECKF( hVObject != NULL );
|
|
memset( hVObject, 0, sizeof( SGPVObject ) );
|
|
|
|
// default of all members of the vobject is 0
|
|
|
|
// Check creation options
|
|
// do
|
|
// {
|
|
if ( VObjectDesc->fCreateFlags & VOBJECT_CREATE_FROMFILE || VObjectDesc->fCreateFlags & VOBJECT_CREATE_FROMHIMAGE )
|
|
{
|
|
if ( VObjectDesc->fCreateFlags & VOBJECT_CREATE_FROMFILE )
|
|
{
|
|
ImageFileType::TestOrder order = ImageFileType::JPC_FALLBACK;
|
|
|
|
if(VObjectDesc->fCreateFlags & VOBJECT_CREATE_FROMJPC) {
|
|
order = ImageFileType::JPC;
|
|
} else if(VObjectDesc->fCreateFlags & VOBJECT_CREATE_FROMJPC_FALLBACK) {
|
|
order = ImageFileType::JPC_FALLBACK;
|
|
} else if(VObjectDesc->fCreateFlags & VOBJECT_CREATE_FROMPNG) {
|
|
order = ImageFileType::PNG_FALLBACK;
|
|
} else if(VObjectDesc->fCreateFlags & VOBJECT_CREATE_FROMPNG_FALLBACK) {
|
|
order = ImageFileType::PNG_FALLBACK;
|
|
}
|
|
// Create himage object from file
|
|
hImage = CreateImage( VObjectDesc->ImageFile, IMAGE_ALLIMAGEDATA, order );
|
|
|
|
if ( hImage == NULL )
|
|
{
|
|
MemFree( hVObject );
|
|
DbgMessage( TOPIC_VIDEOOBJECT, DBG_LEVEL_2, "Invalid Image Filename given" );
|
|
return( NULL );
|
|
}
|
|
}
|
|
else
|
|
{ // create video object from provided hImage
|
|
hImage = VObjectDesc->hImage;
|
|
if ( hImage == NULL )
|
|
{
|
|
MemFree( hVObject );
|
|
DbgMessage( TOPIC_VIDEOOBJECT, DBG_LEVEL_2, "Invalid hImage pointer given" );
|
|
return( NULL );
|
|
}
|
|
}
|
|
|
|
if(hImage->ubBitDepth == 32)
|
|
{
|
|
SGP_THROW_IFFALSE(hImage->usNumberOfObjects > 0, L"bad himage");
|
|
|
|
// create one 16bpp object (that contains 32bpp data)
|
|
hVObject->p16BPPObject = (SixteenBPPObjectInfo*)MemAlloc(sizeof(SixteenBPPObjectInfo));
|
|
if(!hVObject->p16BPPObject)
|
|
{
|
|
SGP_THROW(L"bad alloc");
|
|
}
|
|
memset(hVObject->p16BPPObject, 0, sizeof(SixteenBPPObjectInfo));
|
|
|
|
int SIZE = hImage->pETRLEObject[0].usHeight * hImage->pETRLEObject[0].usWidth * sizeof(UINT32);
|
|
hVObject->p16BPPObject->p16BPPData = (UINT16*)MemAlloc(SIZE); // UINT32*
|
|
if(!hVObject->p16BPPObject->p16BPPData)
|
|
{
|
|
MemFree(hVObject->p16BPPObject);
|
|
SGP_THROW(L"bad alloc");
|
|
}
|
|
memcpy(hVObject->p16BPPObject->p16BPPData, hImage->p32BPPData, SIZE);
|
|
|
|
hVObject->p16BPPObject->sOffsetX = hImage->pETRLEObject[0].sOffsetX;
|
|
hVObject->p16BPPObject->sOffsetY = hImage->pETRLEObject[0].sOffsetY;
|
|
hVObject->p16BPPObject->ubShadeLevel = 0;
|
|
hVObject->p16BPPObject->usHeight = hImage->pETRLEObject[0].usHeight;
|
|
hVObject->p16BPPObject->usWidth = hImage->pETRLEObject[0].usWidth;
|
|
hVObject->p16BPPObject->usRegionIndex = 0;
|
|
|
|
hVObject->usNumberOf16BPPObjects = 1;
|
|
hVObject->ubBitDepth = hImage->ubBitDepth;
|
|
|
|
if ( VObjectDesc->fCreateFlags & VOBJECT_CREATE_FROMFILE )
|
|
{
|
|
DestroyImage( hImage );
|
|
}
|
|
|
|
return hVObject;
|
|
}
|
|
else if(hImage->ubBitDepth == 16)
|
|
{
|
|
SGP_THROW_IFFALSE(hImage->usNumberOfObjects > 0, L"bad himage");
|
|
|
|
// create one 16bpp object (that contains 32bpp data)
|
|
hVObject->p16BPPObject = (SixteenBPPObjectInfo*)MemAlloc(sizeof(SixteenBPPObjectInfo));
|
|
if(!hVObject->p16BPPObject)
|
|
{
|
|
SGP_THROW(L"bad alloc");
|
|
}
|
|
memset(hVObject->p16BPPObject, 0, sizeof(SixteenBPPObjectInfo));
|
|
|
|
int SIZE = hImage->pETRLEObject[0].usHeight * hImage->pETRLEObject[0].usWidth * sizeof(UINT16);
|
|
hVObject->p16BPPObject->p16BPPData = (UINT16*)MemAlloc(SIZE);
|
|
if(!hVObject->p16BPPObject->p16BPPData)
|
|
{
|
|
MemFree(hVObject->p16BPPObject);
|
|
SGP_THROW(L"bad alloc");
|
|
}
|
|
memcpy(hVObject->p16BPPObject->p16BPPData, hImage->p16BPPData, SIZE);
|
|
|
|
hVObject->p16BPPObject->sOffsetX = hImage->pETRLEObject[0].sOffsetX;
|
|
hVObject->p16BPPObject->sOffsetY = hImage->pETRLEObject[0].sOffsetY;
|
|
hVObject->p16BPPObject->ubShadeLevel = 0;
|
|
hVObject->p16BPPObject->usHeight = hImage->pETRLEObject[0].usHeight;
|
|
hVObject->p16BPPObject->usWidth = hImage->pETRLEObject[0].usWidth;
|
|
hVObject->p16BPPObject->usRegionIndex = 0;
|
|
|
|
hVObject->usNumberOf16BPPObjects = 1;
|
|
hVObject->ubBitDepth = hImage->ubBitDepth;
|
|
|
|
if ( VObjectDesc->fCreateFlags & VOBJECT_CREATE_FROMFILE )
|
|
{
|
|
DestroyImage( hImage );
|
|
}
|
|
|
|
return hVObject;
|
|
}
|
|
|
|
// Check if returned himage is TRLE compressed - return error if not
|
|
if ( ! (hImage->fFlags & IMAGE_TRLECOMPRESSED ) )
|
|
{
|
|
MemFree( hVObject );
|
|
DbgMessage( TOPIC_VIDEOOBJECT, DBG_LEVEL_2, "Invalid Image format given." );
|
|
DestroyImage( hImage );
|
|
return( NULL );
|
|
}
|
|
|
|
// Set values from himage
|
|
hVObject->ubBitDepth = hImage->ubBitDepth;
|
|
|
|
// Get TRLE data
|
|
CHECKF( GetETRLEImageData( hImage, &TempETRLEData ) );
|
|
|
|
// Set values
|
|
hVObject->usNumberOfObjects = TempETRLEData.usNumberOfObjects;
|
|
hVObject->pETRLEObject = TempETRLEData.pETRLEObject;
|
|
hVObject->pPixData = TempETRLEData.pPixData;
|
|
hVObject->uiSizePixData = TempETRLEData.uiSizePixData;
|
|
|
|
// Set palette from himage
|
|
if ( hImage->ubBitDepth == 8 )
|
|
{
|
|
hVObject->pShade8=ubColorTables[DEFAULT_SHADE_LEVEL];
|
|
hVObject->pGlow8=ubColorTables[0];
|
|
|
|
SetVideoObjectPalette( hVObject, hImage->pPalette );
|
|
|
|
}
|
|
|
|
if ( VObjectDesc->fCreateFlags & VOBJECT_CREATE_FROMFILE )
|
|
{
|
|
// Delete himage object
|
|
DestroyImage( hImage );
|
|
}
|
|
// break;
|
|
}
|
|
else
|
|
{
|
|
MemFree( hVObject );
|
|
DbgMessage( TOPIC_VIDEOOBJECT, DBG_LEVEL_2, "Invalid VObject creation flags given." );
|
|
return( NULL );
|
|
}
|
|
|
|
// If here, no special options given, use structure given in paraneters
|
|
// TO DO:
|
|
|
|
// }
|
|
// while( FALSE );
|
|
|
|
// All is well
|
|
// DbgMessage( TOPIC_VIDEOOBJECT, DBG_LEVEL_3, String("Success in Creating Video Object" ) );
|
|
|
|
return( hVObject );
|
|
}
|
|
|
|
|
|
// Palette setting is expensive, need to set both DDPalette and create 16BPP palette
|
|
BOOLEAN SetVideoObjectPalette( HVOBJECT hVObject, SGPPaletteEntry *pSrcPalette )
|
|
{
|
|
|
|
Assert( hVObject != NULL );
|
|
Assert( pSrcPalette != NULL );
|
|
|
|
// Create palette object if not already done so
|
|
if ( hVObject->pPaletteEntry == NULL )
|
|
{
|
|
// Create palette
|
|
hVObject->pPaletteEntry = (SGPPaletteEntry *) MemAlloc( sizeof( SGPPaletteEntry ) * 256 );
|
|
CHECKF( hVObject->pPaletteEntry != NULL );
|
|
|
|
// Copy src into palette
|
|
memcpy( hVObject->pPaletteEntry, pSrcPalette, sizeof( SGPPaletteEntry ) * 256 );
|
|
|
|
}
|
|
else
|
|
{
|
|
// Just Change entries
|
|
memcpy( hVObject->pPaletteEntry, pSrcPalette, sizeof( SGPPaletteEntry ) * 256 );
|
|
}
|
|
|
|
// Delete 16BPP Palette if one exists
|
|
if ( hVObject->p16BPPPalette != NULL )
|
|
{
|
|
MemFree( hVObject->p16BPPPalette );
|
|
hVObject->p16BPPPalette = NULL;
|
|
}
|
|
|
|
// Create 16BPP Palette
|
|
hVObject->p16BPPPalette = Create16BPPPalette( pSrcPalette );
|
|
hVObject->pShadeCurrent = hVObject->p16BPPPalette;
|
|
|
|
// DbgMessage(TOPIC_VIDEOOBJECT, DBG_LEVEL_3, String("Video Object Palette change successfull" ));
|
|
return( TRUE );
|
|
}
|
|
|
|
// Transparency needs to take RGB value and find best fit and place it into DD Surface
|
|
// colorkey value.
|
|
BOOLEAN SetVideoObjectTransparencyColor( HVOBJECT hVObject, COLORVAL TransColor )
|
|
{
|
|
|
|
// Assertions
|
|
Assert( hVObject != NULL );
|
|
|
|
//Set trans color into video object
|
|
hVObject->TransparentColor = TransColor;
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
// Deletes all palettes, surfaces and region data
|
|
BOOLEAN DeleteVideoObject( HVOBJECT hVObject )
|
|
{
|
|
UINT16 usLoop;
|
|
|
|
// Assertions
|
|
CHECKF( hVObject != NULL );
|
|
|
|
DestroyObjectPaletteTables(hVObject);
|
|
|
|
// Release palette
|
|
if ( hVObject->pPaletteEntry != NULL )
|
|
{
|
|
MemFree( hVObject->pPaletteEntry );
|
|
// hVObject->pPaletteEntry = NULL;
|
|
}
|
|
|
|
|
|
if ( hVObject->pPixData != NULL )
|
|
{
|
|
MemFree( hVObject->pPixData );
|
|
// hVObject->pPixData = NULL;
|
|
}
|
|
|
|
if ( hVObject->pETRLEObject != NULL )
|
|
{
|
|
MemFree( hVObject->pETRLEObject );
|
|
// hVObject->pETRLEObject = NULL;
|
|
}
|
|
|
|
if ( hVObject->ppZStripInfo != NULL )
|
|
{
|
|
for (usLoop = 0; usLoop < hVObject->usNumberOfObjects; usLoop++)
|
|
{
|
|
if (hVObject->ppZStripInfo[usLoop] != NULL)
|
|
{
|
|
MemFree( hVObject->ppZStripInfo[usLoop]->pbZChange );
|
|
MemFree( hVObject->ppZStripInfo[usLoop] );
|
|
}
|
|
}
|
|
MemFree( hVObject->ppZStripInfo );
|
|
// hVObject->ppZStripInfo = NULL;
|
|
}
|
|
|
|
if ( hVObject->usNumberOf16BPPObjects > 0)
|
|
{
|
|
for( usLoop = 0; usLoop < hVObject->usNumberOf16BPPObjects; usLoop++)
|
|
{
|
|
MemFree( hVObject->p16BPPObject[usLoop].p16BPPData );
|
|
}
|
|
MemFree( hVObject->p16BPPObject );
|
|
}
|
|
|
|
// Release object
|
|
MemFree( hVObject );
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
/**********************************************************************************************
|
|
CreateObjectPaletteTables
|
|
|
|
Creates the shading tables for 8-bit brushes. One highlight table is created, based on
|
|
the object-type, 3 brightening tables, 1 normal, and 11 darkening tables. The entries are
|
|
created iteratively, rather than in a loop to allow hand-tweaking of the values. If you
|
|
change the HVOBJECT_SHADE_TABLES symbol, remember to add/delete entries here, it won't
|
|
adjust automagically.
|
|
|
|
**********************************************************************************************/
|
|
|
|
UINT16 CreateObjectPaletteTables(HVOBJECT pObj, UINT32 uiType)
|
|
{
|
|
UINT32 count;
|
|
|
|
// this creates the highlight table. Specify the glow-type when creating the tables
|
|
// through uiType, symbols are from VOBJECT.H
|
|
for( count = 0; count < 16; count++ )
|
|
{
|
|
if ( (count == 4) && (pObj->p16BPPPalette == pObj->pShades[ count ]) )
|
|
pObj->pShades[ count ] = NULL;
|
|
else if ( pObj->pShades[ count ] != NULL )
|
|
{
|
|
MemFree( pObj->pShades[ count ] );
|
|
pObj->pShades[ count ] = NULL;
|
|
}
|
|
}
|
|
|
|
switch(uiType)
|
|
{
|
|
case HVOBJECT_GLOW_GREEN: // green glow
|
|
pObj->pShades[0]=Create16BPPPaletteShaded( pObj->pPaletteEntry, 0, 255, 0, TRUE);
|
|
break;
|
|
case HVOBJECT_GLOW_BLUE: // blue glow
|
|
pObj->pShades[0]=Create16BPPPaletteShaded( pObj->pPaletteEntry, 0, 0, 255, TRUE);
|
|
break;
|
|
case HVOBJECT_GLOW_YELLOW: // yellow glow
|
|
pObj->pShades[0]=Create16BPPPaletteShaded( pObj->pPaletteEntry, 255, 255, 0, TRUE);
|
|
break;
|
|
case HVOBJECT_GLOW_RED: // red glow
|
|
pObj->pShades[0]=Create16BPPPaletteShaded( pObj->pPaletteEntry, 255, 0, 0, TRUE);
|
|
break;
|
|
}
|
|
|
|
// these are the brightening tables, 115%-150% brighter than original
|
|
pObj->pShades[1]=Create16BPPPaletteShaded( pObj->pPaletteEntry, 293, 293, 293, FALSE);
|
|
pObj->pShades[2]=Create16BPPPaletteShaded( pObj->pPaletteEntry, 281, 281, 281, FALSE);
|
|
pObj->pShades[3]=Create16BPPPaletteShaded( pObj->pPaletteEntry, 268, 268, 268, FALSE);
|
|
|
|
// palette 4 is the non-modified palette.
|
|
// if the standard one has already been made, we'll use it
|
|
if(pObj->p16BPPPalette!=NULL)
|
|
pObj->pShades[4]=pObj->p16BPPPalette;
|
|
else
|
|
{
|
|
// or create our own, and assign it to the standard one
|
|
pObj->pShades[4]=Create16BPPPaletteShaded( pObj->pPaletteEntry, 255, 255, 255, FALSE);
|
|
pObj->p16BPPPalette=pObj->pShades[4];
|
|
}
|
|
|
|
// the rest are darkening tables, right down to all-black.
|
|
pObj->pShades[5]=Create16BPPPaletteShaded( pObj->pPaletteEntry, 195, 195, 195, FALSE);
|
|
pObj->pShades[6]=Create16BPPPaletteShaded( pObj->pPaletteEntry, 165, 165, 165, FALSE);
|
|
pObj->pShades[7]=Create16BPPPaletteShaded( pObj->pPaletteEntry, 135, 135, 135, FALSE);
|
|
pObj->pShades[8]=Create16BPPPaletteShaded( pObj->pPaletteEntry, 105, 105, 105, FALSE);
|
|
pObj->pShades[9]=Create16BPPPaletteShaded( pObj->pPaletteEntry, 75, 75, 75, FALSE);
|
|
pObj->pShades[10]=Create16BPPPaletteShaded( pObj->pPaletteEntry, 45, 45, 45, FALSE);
|
|
pObj->pShades[11]=Create16BPPPaletteShaded( pObj->pPaletteEntry, 36, 36, 36, FALSE);
|
|
pObj->pShades[12]=Create16BPPPaletteShaded( pObj->pPaletteEntry, 27, 27, 27, FALSE);
|
|
pObj->pShades[13]=Create16BPPPaletteShaded( pObj->pPaletteEntry, 18, 18, 18, FALSE);
|
|
pObj->pShades[14]=Create16BPPPaletteShaded( pObj->pPaletteEntry, 9, 9, 9, FALSE);
|
|
pObj->pShades[15]=Create16BPPPaletteShaded( pObj->pPaletteEntry, 0, 0, 0, FALSE);
|
|
|
|
// Set current shade table to neutral color
|
|
pObj->pShadeCurrent=pObj->pShades[4];
|
|
|
|
// check to make sure every table got a palette
|
|
for(count=0; (count < HVOBJECT_SHADE_TABLES) && (pObj->pShades[count]!=NULL); count++);
|
|
|
|
|
|
// return the result of the check
|
|
return(count==HVOBJECT_SHADE_TABLES);
|
|
}
|
|
|
|
// *******************************************************************
|
|
//
|
|
// Blitting Functions
|
|
//
|
|
// *******************************************************************
|
|
|
|
// High level blit function encapsolates ALL effects and BPP
|
|
BOOLEAN BltVideoObjectToBuffer( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, UINT16 usIndex, INT32 iDestX, INT32 iDestY, INT32 fBltFlags, blt_fx *pBltFx )
|
|
{
|
|
// Sometimes an exception is thrown in that method.
|
|
//BF __try
|
|
{
|
|
// Assertions
|
|
//Assert( pBuffer != NULL );
|
|
SGP_THROW_IFFALSE( pBuffer != NULL, L"No Destination Buffer" );
|
|
|
|
if ( hSrcVObject == NULL )
|
|
{
|
|
//int breakpoint=0;
|
|
}
|
|
|
|
//Assert( hSrcVObject != NULL );
|
|
SGP_THROW_IFFALSE( hSrcVObject != NULL, L"No Source Object" )
|
|
|
|
SixteenBPPObjectInfo *image = NULL;
|
|
// Check For Flags and bit depths
|
|
switch( hSrcVObject->ubBitDepth )
|
|
{
|
|
case 32:
|
|
SGP_THROW_IFFALSE(usIndex < hSrcVObject->usNumberOf16BPPObjects, L"index larger that number images");
|
|
image = &hSrcVObject->p16BPPObject[usIndex];
|
|
#if 0
|
|
Blt16BPPTo16BPPTrans( pBuffer, uiDestPitchBYTES,
|
|
image->p16BPPData, image->usWidth * sizeof(UINT16),
|
|
iDestX, iDestY,
|
|
0, 0, image->usWidth, image->usHeight,
|
|
0 );
|
|
#else
|
|
Blt32BPPTo16BPPTrans( pBuffer, uiDestPitchBYTES,
|
|
(UINT32*)image->p16BPPData, image->usWidth * sizeof(UINT32),
|
|
iDestX, iDestY,
|
|
0, 0, image->usWidth, image->usHeight);
|
|
#endif
|
|
break;
|
|
|
|
case 16:
|
|
SGP_THROW_IFFALSE(usIndex < hSrcVObject->usNumberOf16BPPObjects, L"index larger that number images");
|
|
image = &hSrcVObject->p16BPPObject[usIndex];
|
|
if ( fBltFlags & VO_BLT_SRCTRANSPARENCY )
|
|
{
|
|
Blt16BPPTo16BPPTrans( pBuffer, uiDestPitchBYTES,
|
|
image->p16BPPData, image->usWidth * sizeof(UINT16),
|
|
iDestX, iDestY,
|
|
0, 0, image->usWidth, image->usHeight, 0x1F ); // 0x1f = 5 bits of blue
|
|
}
|
|
else
|
|
{
|
|
Blt16BPPTo16BPP( pBuffer, uiDestPitchBYTES,
|
|
image->p16BPPData, image->usWidth * sizeof(UINT16),
|
|
iDestX, iDestY,
|
|
0, 0, image->usWidth, image->usHeight );
|
|
}
|
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
SGP_THROW_IFFALSE( hSrcVObject->usNumberOfObjects > usIndex, L"Video object index is larger than the number of subimages");
|
|
// Switch based on flags given
|
|
do
|
|
{
|
|
if(gbPixelDepth==16)
|
|
{
|
|
#ifndef JA2
|
|
if ( fBltFlags & VO_BLT_MIRROR_Y)
|
|
{
|
|
if(!BltIsClipped(hSrcVObject, iDestX, iDestY, usIndex, &ClippingRect))
|
|
Blt8BPPDataTo16BPPBufferTransMirror( pBuffer, uiDestPitchBYTES, hSrcVObject, iDestX, iDestY, usIndex );
|
|
// CLipping version not done -- DB
|
|
// Blt8BPPDataTo16BPPBufferTransMirrorClip( pBuffer, uiDestPitchBYTES, hSrcVObject, iDestX, iDestY, usIndex, &ClippingRect);
|
|
break;
|
|
}
|
|
else
|
|
#endif
|
|
if ( fBltFlags & VO_BLT_SRCTRANSPARENCY )
|
|
{
|
|
if(BltIsClipped(hSrcVObject, iDestX, iDestY, usIndex, &ClippingRect))
|
|
Blt8BPPDataTo16BPPBufferTransparentClip( pBuffer, uiDestPitchBYTES, hSrcVObject, iDestX, iDestY, usIndex, &ClippingRect);
|
|
else
|
|
Blt8BPPDataTo16BPPBufferTransparent( pBuffer, uiDestPitchBYTES, hSrcVObject, iDestX, iDestY, usIndex );
|
|
break;
|
|
}
|
|
else if ( fBltFlags & VO_BLT_SHADOW )
|
|
{
|
|
if(BltIsClipped(hSrcVObject, iDestX, iDestY, usIndex, &ClippingRect))
|
|
Blt8BPPDataTo16BPPBufferShadowClip( pBuffer, uiDestPitchBYTES, hSrcVObject, iDestX, iDestY, usIndex, &ClippingRect);
|
|
else
|
|
Blt8BPPDataTo16BPPBufferShadow( pBuffer, uiDestPitchBYTES, hSrcVObject, iDestX, iDestY, usIndex );
|
|
break;
|
|
}
|
|
|
|
}
|
|
else if(gbPixelDepth==8)
|
|
{
|
|
if ( fBltFlags & VO_BLT_SRCTRANSPARENCY )
|
|
{
|
|
if(BltIsClipped(hSrcVObject, iDestX, iDestY, usIndex, &ClippingRect))
|
|
Blt8BPPDataTo8BPPBufferTransparentClip( pBuffer, uiDestPitchBYTES, hSrcVObject, iDestX, iDestY, usIndex, &ClippingRect);
|
|
else
|
|
Blt8BPPDataTo8BPPBufferTransparent( pBuffer, uiDestPitchBYTES, hSrcVObject, iDestX, iDestY, usIndex );
|
|
break;
|
|
}
|
|
else if ( fBltFlags & VO_BLT_SHADOW )
|
|
{
|
|
if(BltIsClipped(hSrcVObject, iDestX, iDestY, usIndex, &ClippingRect))
|
|
Blt8BPPDataTo8BPPBufferShadowClip( pBuffer, uiDestPitchBYTES, hSrcVObject, iDestX, iDestY, usIndex, &ClippingRect);
|
|
else
|
|
Blt8BPPDataTo8BPPBufferShadow( pBuffer, uiDestPitchBYTES, hSrcVObject, iDestX, iDestY, usIndex );
|
|
break;
|
|
}
|
|
}
|
|
// Use default blitter here
|
|
//Blt8BPPDataTo16BPPBuffer( hDestVObject, hSrcVObject, (UINT16)iDestX, (UINT16)iDestY, (SGPRect*)&SrcRect );
|
|
|
|
} while( FALSE );
|
|
|
|
break;
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
//BF
|
|
//__except(filter(GetExceptionCode(), GetExceptionInformation()))
|
|
//{
|
|
// return ( TRUE );
|
|
//}
|
|
}
|
|
|
|
BOOLEAN PixelateVideoObjectRect( UINT32 uiDestVSurface, INT32 X1, INT32 Y1, INT32 X2, INT32 Y2)
|
|
{
|
|
UINT16 *pBuffer;
|
|
UINT32 uiPitch;
|
|
SGPRect area;
|
|
UINT8 uiPattern[8][8]={ {0,1,0,1,0,1,0,1},
|
|
{1,0,1,0,1,0,1,0},
|
|
{0,1,0,1,0,1,0,1},
|
|
{1,0,1,0,1,0,1,0},
|
|
{0,1,0,1,0,1,0,1},
|
|
{1,0,1,0,1,0,1,0},
|
|
{0,1,0,1,0,1,0,1},
|
|
{1,0,1,0,1,0,1,0}};
|
|
|
|
// Lock video surface
|
|
pBuffer = (UINT16*)LockVideoSurface( uiDestVSurface, &uiPitch );
|
|
|
|
if ( pBuffer == NULL )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
area.iTop=Y1;
|
|
area.iBottom=Y2;
|
|
area.iLeft=X1;
|
|
area.iRight=X2;
|
|
|
|
// Now we have the video object and surface, call the shadow function
|
|
if(!Blt16BPPBufferPixelateRect(pBuffer, uiPitch, &area, uiPattern))
|
|
{
|
|
UnLockVideoSurface( uiDestVSurface );
|
|
// Blit has failed if false returned
|
|
return( FALSE );
|
|
}
|
|
|
|
// Mark as dirty if it's the backbuffer
|
|
//if ( uiDestVSurface == BACKBUFFER )
|
|
//{
|
|
// InvalidateBackbuffer( );
|
|
//}
|
|
|
|
UnLockVideoSurface( uiDestVSurface );
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
/**********************************************************************************************
|
|
DestroyObjectPaletteTables
|
|
|
|
Destroys the palette tables of a video object. All memory is deallocated, and
|
|
the pointers set to NULL. Be careful not to try and blit this object until new
|
|
tables are calculated, or things WILL go boom.
|
|
|
|
**********************************************************************************************/
|
|
BOOLEAN DestroyObjectPaletteTables(HVOBJECT hVObject)
|
|
{
|
|
UINT32 x;
|
|
BOOLEAN f16BitPal;
|
|
|
|
for ( x = 0; x < HVOBJECT_SHADE_TABLES; x++ )
|
|
{
|
|
if ( !( hVObject->fFlags & VOBJECT_FLAG_SHADETABLE_SHARED ) )
|
|
{
|
|
if ( hVObject->pShades[x] != NULL )
|
|
{
|
|
if ( hVObject->pShades[x] == hVObject->p16BPPPalette )
|
|
f16BitPal = TRUE;
|
|
else
|
|
f16BitPal = FALSE;
|
|
|
|
MemFree( hVObject->pShades[x] );
|
|
hVObject->pShades[x] = NULL;
|
|
|
|
if ( f16BitPal )
|
|
hVObject->p16BPPPalette = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( hVObject->p16BPPPalette != NULL )
|
|
{
|
|
MemFree( hVObject->p16BPPPalette );
|
|
hVObject->p16BPPPalette = NULL;
|
|
}
|
|
|
|
hVObject->pShadeCurrent=NULL;
|
|
hVObject->pGlow=NULL;
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
UINT16 SetObjectShade(HVOBJECT pObj, UINT32 uiShade)
|
|
{
|
|
Assert(pObj!=NULL);
|
|
Assert(uiShade >= 0);
|
|
Assert(uiShade < HVOBJECT_SHADE_TABLES);
|
|
|
|
if(pObj->pShades[uiShade]==NULL)
|
|
{
|
|
DbgMessage(TOPIC_VIDEOOBJECT, DBG_LEVEL_2, String("Attempt to set shade level to NULL table"));
|
|
return(FALSE);
|
|
}
|
|
|
|
pObj->pShadeCurrent=pObj->pShades[uiShade];
|
|
return(TRUE);
|
|
}
|
|
|
|
UINT16 SetObjectHandleShade(UINT32 uiHandle, UINT32 uiShade)
|
|
{
|
|
HVOBJECT hObj;
|
|
|
|
#ifdef _DEBUG
|
|
gubVODebugCode = DEBUGSTR_SETOBJECTHANDLESHADE;
|
|
#endif
|
|
if(!GetVideoObject(&hObj, uiHandle))
|
|
{
|
|
DbgMessage(TOPIC_VIDEOOBJECT, DBG_LEVEL_2, String("Invalid object handle for setting shade level"));
|
|
return(FALSE);
|
|
}
|
|
return(SetObjectShade(hObj, uiShade));
|
|
}
|
|
|
|
/*
|
|
UINT16 FillObjectRect(UINT32 iObj, INT32 x1, INT32 y1, INT32 x2, INT32 y2, COLORVAL color32)
|
|
{
|
|
UINT16 *pBuffer;
|
|
UINT32 uiPitch;
|
|
//HVSURFACE pSurface;
|
|
|
|
// Lock video surface
|
|
pBuffer = (UINT16*)LockVideoSurface(iObj, &uiPitch );
|
|
//UnLockVideoSurface(iObj);
|
|
|
|
|
|
if (pBuffer == NULL)
|
|
return( FALSE );
|
|
|
|
FillRect16BPP(pBuffer, uiPitch, x1, y1, x2, y2, Get16BPPColor(color32));
|
|
|
|
// Mark as dirty if it's the backbuffer
|
|
if(iObj == BACKBUFFER)
|
|
InvalidateBackbuffer();
|
|
|
|
UnLockVideoSurface(iObj);
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
/********************************************************************************************
|
|
GetETRLEPixelValue
|
|
|
|
Given a VOBJECT and ETRLE image index, retrieves the value of the pixel located at the
|
|
given image coordinates. The value returned is an 8-bit palette index
|
|
********************************************************************************************/
|
|
BOOLEAN GetETRLEPixelValue( UINT8 * pDest, HVOBJECT hVObject, UINT16 usETRLEIndex, UINT16 usX, UINT16 usY )
|
|
{
|
|
UINT8 * pCurrent;
|
|
UINT16 usLoopX = 0;
|
|
UINT16 usLoopY = 0;
|
|
UINT16 ubRunLength;
|
|
ETRLEObject * pETRLEObject;
|
|
|
|
// Do a bunch of checks
|
|
CHECKF( hVObject != NULL );
|
|
CHECKF( usETRLEIndex < hVObject->usNumberOfObjects );
|
|
|
|
pETRLEObject = &(hVObject->pETRLEObject[usETRLEIndex]);
|
|
|
|
CHECKF( usX < pETRLEObject->usWidth );
|
|
CHECKF( usY < pETRLEObject->usHeight );
|
|
|
|
// Assuming everything's okay, go ahead and look...
|
|
pCurrent = &((UINT8 *)hVObject->pPixData)[pETRLEObject->uiDataOffset];
|
|
|
|
// Skip past all uninteresting scanlines
|
|
while( usLoopY < usY )
|
|
{
|
|
while( *pCurrent != 0 )
|
|
{
|
|
if (*pCurrent & COMPRESS_TRANSPARENT)
|
|
{
|
|
pCurrent++;
|
|
}
|
|
else
|
|
{
|
|
pCurrent += *pCurrent & COMPRESS_RUN_MASK;
|
|
}
|
|
}
|
|
usLoopY++;
|
|
}
|
|
|
|
// Now look in this scanline for the appropriate byte
|
|
do
|
|
{
|
|
ubRunLength = *pCurrent & COMPRESS_RUN_MASK;
|
|
|
|
if (*pCurrent & COMPRESS_TRANSPARENT)
|
|
{
|
|
if (usLoopX + ubRunLength >= usX)
|
|
{
|
|
*pDest = 0;
|
|
return( TRUE );
|
|
}
|
|
else
|
|
{
|
|
pCurrent++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (usLoopX + ubRunLength >= usX)
|
|
{
|
|
// skip to the correct byte; skip at least 1 to get past the byte defining the run
|
|
pCurrent += (usX - usLoopX) + 1;
|
|
*pDest = *pCurrent;
|
|
return( TRUE );
|
|
}
|
|
else
|
|
{
|
|
pCurrent += ubRunLength + 1;
|
|
}
|
|
}
|
|
usLoopX += ubRunLength;
|
|
}
|
|
while( usLoopX < usX );
|
|
// huh???
|
|
return( FALSE );
|
|
}
|
|
|
|
BOOLEAN GetVideoObjectETRLEProperties( HVOBJECT hVObject, ETRLEObject *pETRLEObject, UINT16 usIndex )
|
|
{
|
|
CHECKF( usIndex >= 0 );
|
|
CHECKF( usIndex < hVObject->usNumberOfObjects );
|
|
|
|
memcpy( pETRLEObject, &( hVObject->pETRLEObject[ usIndex ] ), sizeof( ETRLEObject ) );
|
|
|
|
return( TRUE );
|
|
|
|
}
|
|
|
|
BOOLEAN GetVideoObjectETRLESubregionProperties( UINT32 uiVideoObject, UINT16 usIndex, UINT16 *pusWidth, UINT16 *pusHeight )
|
|
{
|
|
HVOBJECT hVObject;
|
|
ETRLEObject ETRLEObject;
|
|
|
|
// Get video object
|
|
#ifdef _DEBUG
|
|
gubVODebugCode = DEBUGSTR_GETVIDEOOBJECTETRLESUBREGIONPROPERTIES;
|
|
#endif
|
|
CHECKF( GetVideoObject( &hVObject, uiVideoObject ) );
|
|
|
|
CHECKF( GetVideoObjectETRLEProperties( hVObject, &ETRLEObject, usIndex ) );
|
|
|
|
*pusWidth = ETRLEObject.usWidth;
|
|
*pusHeight = ETRLEObject.usHeight;
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
BOOLEAN GetVideoObjectETRLEPropertiesFromIndex( UINT32 uiVideoObject, ETRLEObject *pETRLEObject, UINT16 usIndex )
|
|
{
|
|
HVOBJECT hVObject;
|
|
|
|
// Get video object
|
|
#ifdef _DEBUG
|
|
gubVODebugCode = DEBUGSTR_GETVIDEOOBJECTETRLEPROPERTIESFROMINDEX;
|
|
#endif
|
|
CHECKF( GetVideoObject( &hVObject, uiVideoObject ) );
|
|
|
|
CHECKF( GetVideoObjectETRLEProperties( hVObject, pETRLEObject, usIndex ) );
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
BOOLEAN SetVideoObjectPalette8BPP(INT32 uiVideoObject, SGPPaletteEntry *pPal8)
|
|
{
|
|
HVOBJECT hVObject;
|
|
|
|
// Get video object
|
|
#ifdef _DEBUG
|
|
gubVODebugCode = DEBUGSTR_SETVIDEOOBJECTPALETTE8BPP;
|
|
#endif
|
|
CHECKF( GetVideoObject( &hVObject, uiVideoObject ) );
|
|
|
|
return( SetVideoObjectPalette( hVObject, pPal8 ) );
|
|
}
|
|
|
|
|
|
BOOLEAN GetVideoObjectPalette16BPP(INT32 uiVideoObject, UINT16 **ppPal16)
|
|
{
|
|
HVOBJECT hVObject;
|
|
|
|
// Get video object
|
|
#ifdef _DEBUG
|
|
gubVODebugCode = DEBUGSTR_GETVIDEOOBJECTPALETTE16BPP;
|
|
#endif
|
|
CHECKF( GetVideoObject( &hVObject, uiVideoObject ) );
|
|
|
|
*ppPal16 = hVObject->p16BPPPalette;
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
BOOLEAN CopyVideoObjectPalette16BPP(INT32 uiVideoObject, UINT16 *ppPal16)
|
|
{
|
|
HVOBJECT hVObject;
|
|
|
|
// Get video object
|
|
#ifdef _DEBUG
|
|
gubVODebugCode = DEBUGSTR_COPYVIDEOOBJECTPALETTE16BPP;
|
|
#endif
|
|
CHECKF( GetVideoObject( &hVObject, uiVideoObject ) );
|
|
|
|
memcpy(ppPal16, hVObject->p16BPPPalette, 256*2);
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
BOOLEAN CheckFor16BPPRegion( HVOBJECT hVObject, UINT16 usRegionIndex, UINT8 ubShadeLevel, UINT16 * pusIndex )
|
|
{
|
|
UINT16 usLoop;
|
|
SixteenBPPObjectInfo * p16BPPObject;
|
|
|
|
if (hVObject->usNumberOf16BPPObjects > 0)
|
|
{
|
|
for (usLoop = 0; usLoop < hVObject->usNumberOf16BPPObjects; usLoop++)
|
|
{
|
|
p16BPPObject = &(hVObject->p16BPPObject[usLoop]);
|
|
if (p16BPPObject->usRegionIndex == usRegionIndex && p16BPPObject->ubShadeLevel == ubShadeLevel)
|
|
{
|
|
if (pusIndex != NULL)
|
|
{
|
|
*pusIndex = usLoop;
|
|
}
|
|
return( TRUE );
|
|
}
|
|
}
|
|
}
|
|
return( FALSE );
|
|
}
|
|
|
|
BOOLEAN ConvertVObjectRegionTo16BPP( HVOBJECT hVObject, UINT16 usRegionIndex, UINT8 ubShadeLevel )
|
|
{
|
|
SixteenBPPObjectInfo * p16BPPObject;
|
|
UINT8 * pInput;
|
|
UINT8 * pOutput;
|
|
UINT16 * p16BPPPalette;
|
|
UINT32 uiDataLoop;
|
|
UINT32 uiDataLength;
|
|
UINT8 ubRunLoop;
|
|
//UINT8 ubRunLength;
|
|
INT8 bData;
|
|
UINT32 uiLen;
|
|
|
|
// check for existing 16BPP region and then allocate memory
|
|
if (usRegionIndex >= hVObject->usNumberOfObjects || ubShadeLevel >= HVOBJECT_SHADE_TABLES)
|
|
{
|
|
return( FALSE );
|
|
}
|
|
if (CheckFor16BPPRegion( hVObject, usRegionIndex, ubShadeLevel, NULL) == TRUE)
|
|
{
|
|
// it already exists; no need to do anything!
|
|
return( TRUE );
|
|
}
|
|
|
|
if (hVObject->usNumberOf16BPPObjects > 0)
|
|
{
|
|
// have to reallocate memory
|
|
hVObject->p16BPPObject = (SixteenBPPObjectInfo *) MemRealloc( hVObject->p16BPPObject, sizeof( SixteenBPPObjectInfo ) * (hVObject->usNumberOf16BPPObjects + 1) );
|
|
}
|
|
else
|
|
{
|
|
// allocate memory for the first 16BPPObject
|
|
hVObject->p16BPPObject = (SixteenBPPObjectInfo *) MemAlloc( sizeof( SixteenBPPObjectInfo ) );
|
|
}
|
|
if (hVObject->p16BPPObject == NULL)
|
|
{
|
|
hVObject->usNumberOf16BPPObjects = 0;
|
|
return( FALSE );
|
|
}
|
|
|
|
// the new object is the last one in the array
|
|
p16BPPObject = &(hVObject->p16BPPObject[hVObject->usNumberOf16BPPObjects]);
|
|
|
|
// need twice as much memory because of going from 8 to 16 bits
|
|
p16BPPObject->p16BPPData = (UINT16 *) MemAlloc( hVObject->pETRLEObject[usRegionIndex].uiDataLength * 2 );
|
|
if (p16BPPObject->p16BPPData == NULL)
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
p16BPPObject->usRegionIndex = usRegionIndex;
|
|
p16BPPObject->ubShadeLevel = ubShadeLevel;
|
|
p16BPPObject->usHeight = hVObject->pETRLEObject[ usRegionIndex ].usHeight;
|
|
p16BPPObject->usWidth = hVObject->pETRLEObject[ usRegionIndex ].usWidth;
|
|
p16BPPObject->sOffsetX=hVObject->pETRLEObject[ usRegionIndex ].sOffsetX;
|
|
p16BPPObject->sOffsetY=hVObject->pETRLEObject[ usRegionIndex ].sOffsetY;
|
|
|
|
// get the palette
|
|
p16BPPPalette = hVObject->pShades[ubShadeLevel];
|
|
pInput = (UINT8 *) hVObject->pPixData + hVObject->pETRLEObject[ usRegionIndex ].uiDataOffset;
|
|
|
|
uiDataLength=hVObject->pETRLEObject[usRegionIndex].uiDataLength;
|
|
|
|
// now actually do the conversion
|
|
|
|
uiLen=0;
|
|
pOutput = (UINT8 *)p16BPPObject->p16BPPData;
|
|
for (uiDataLoop = 0; uiDataLoop < uiDataLength; uiDataLoop++)
|
|
{
|
|
bData= *pInput;
|
|
if(bData&0x80)
|
|
{
|
|
// transparent
|
|
*pOutput = *pInput;
|
|
pOutput++;
|
|
pInput++;
|
|
//uiDataLoop++;
|
|
uiLen+=(UINT32)(bData&0x7f);
|
|
}
|
|
else if(bData > 0)
|
|
{
|
|
// nontransparent
|
|
*pOutput = *pInput;
|
|
pOutput++;
|
|
pInput++;
|
|
//uiDataLoop++;
|
|
for(ubRunLoop=0; ubRunLoop < bData; ubRunLoop++)
|
|
{
|
|
*((UINT16 *)pOutput) = p16BPPPalette[*pInput];
|
|
pOutput++;
|
|
pOutput++;
|
|
pInput++;
|
|
uiDataLoop++;
|
|
}
|
|
uiLen+=(UINT32)bData;
|
|
}
|
|
else
|
|
{
|
|
// eol
|
|
*pOutput = *pInput;
|
|
pOutput++;
|
|
pInput++;
|
|
//uiDataLoop++;
|
|
if(uiLen!=p16BPPObject->usWidth)
|
|
DbgMessage(TOPIC_VIDEOOBJECT, DBG_LEVEL_1, String( "Actual pixel width different from header width" ));
|
|
uiLen=0;
|
|
}
|
|
|
|
// copy the run-length byte
|
|
/* *pOutput = *pInput;
|
|
pOutput++;
|
|
if (((*pInput) & COMPRESS_TRANSPARENT) == 0 && *pInput > 0)
|
|
{
|
|
// non-transparent run; deal with the pixel data
|
|
ubRunLoop = 0;
|
|
ubRunLength = ((*pInput) & COMPRESS_RUN_LIMIT);
|
|
// skip to the next input byte
|
|
pInput++;
|
|
for (ubRunLoop = 0; ubRunLoop < ubRunLength; ubRunLoop++)
|
|
{
|
|
*((UINT16 *)pOutput) = p16BPPPalette[*pInput];
|
|
// advance two bytes in output, one in input
|
|
pOutput++;
|
|
pOutput++;
|
|
pInput++;
|
|
uiDataLoop++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// transparent run or end of scanline; skip to the next input byte
|
|
pInput++;
|
|
} */
|
|
}
|
|
hVObject->usNumberOf16BPPObjects++;
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
BOOLEAN BltVideoObjectOutlineFromIndex(UINT32 uiDestVSurface, UINT32 uiSrcVObject, UINT16 usIndex, INT32 iDestX, INT32 iDestY, INT16 s16BPPColor, BOOLEAN fDoOutline )
|
|
{
|
|
UINT16 *pBuffer;
|
|
UINT32 uiPitch;
|
|
HVOBJECT hSrcVObject;
|
|
|
|
// Lock video surface
|
|
pBuffer = (UINT16*)LockVideoSurface( uiDestVSurface, &uiPitch );
|
|
|
|
if ( pBuffer == NULL )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
// Get video object
|
|
#ifdef _DEBUG
|
|
gubVODebugCode = DEBUGSTR_BLTVIDEOOBJECTOUTLINEFROMINDEX;
|
|
#endif
|
|
CHECKF( GetVideoObject( &hSrcVObject, uiSrcVObject ) );
|
|
|
|
if( BltIsClipped( hSrcVObject, iDestX, iDestY, usIndex, &ClippingRect) )
|
|
{
|
|
Blt8BPPDataTo16BPPBufferOutlineClip((UINT16*)pBuffer, uiPitch, hSrcVObject, iDestX, iDestY, usIndex, s16BPPColor, fDoOutline, &ClippingRect );
|
|
}
|
|
else
|
|
{
|
|
Blt8BPPDataTo16BPPBufferOutline((UINT16*)pBuffer, uiPitch, hSrcVObject, iDestX, iDestY, usIndex, s16BPPColor, fDoOutline );
|
|
}
|
|
|
|
// Now we have the video object and surface, call the VO blitter function
|
|
|
|
UnLockVideoSurface( uiDestVSurface );
|
|
return( TRUE );
|
|
}
|
|
|
|
BOOLEAN BltVideoObjectOutline(UINT32 uiDestVSurface, HVOBJECT hSrcVObject, UINT16 usIndex, INT32 iDestX, INT32 iDestY, INT16 s16BPPColor, BOOLEAN fDoOutline )
|
|
{
|
|
UINT16 *pBuffer;
|
|
UINT32 uiPitch;
|
|
// Lock video surface
|
|
pBuffer = (UINT16*)LockVideoSurface( uiDestVSurface, &uiPitch );
|
|
|
|
if ( pBuffer == NULL )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
if( BltIsClipped( hSrcVObject, iDestX, iDestY, usIndex, &ClippingRect) )
|
|
{
|
|
Blt8BPPDataTo16BPPBufferOutlineClip((UINT16*)pBuffer, uiPitch, hSrcVObject, iDestX, iDestY, usIndex, s16BPPColor, fDoOutline, &ClippingRect );
|
|
}
|
|
else
|
|
{
|
|
Blt8BPPDataTo16BPPBufferOutline((UINT16*)pBuffer, uiPitch, hSrcVObject, iDestX, iDestY, usIndex, s16BPPColor, fDoOutline );
|
|
}
|
|
|
|
// Now we have the video object and surface, call the VO blitter function
|
|
|
|
UnLockVideoSurface( uiDestVSurface );
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN BltVideoObjectOutlineShadowFromIndex(UINT32 uiDestVSurface, UINT32 uiSrcVObject, UINT16 usIndex, INT32 iDestX, INT32 iDestY )
|
|
{
|
|
UINT16 *pBuffer;
|
|
UINT32 uiPitch;
|
|
HVOBJECT hSrcVObject;
|
|
|
|
// Lock video surface
|
|
pBuffer = (UINT16*)LockVideoSurface( uiDestVSurface, &uiPitch );
|
|
|
|
if ( pBuffer == NULL )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
// Get video object
|
|
#ifdef _DEBUG
|
|
gubVODebugCode = DEBUGSTR_BLTVIDEOOBJECTOUTLINESHADOWFROMINDEX;
|
|
#endif
|
|
CHECKF( GetVideoObject( &hSrcVObject, uiSrcVObject ) );
|
|
|
|
if(hSrcVObject->ubBitDepth == 8)
|
|
{
|
|
if( BltIsClipped( hSrcVObject, iDestX, iDestY, usIndex, &ClippingRect) )
|
|
{
|
|
Blt8BPPDataTo16BPPBufferOutlineShadowClip((UINT16*)pBuffer, uiPitch, hSrcVObject, iDestX, iDestY, usIndex, &ClippingRect );
|
|
}
|
|
else
|
|
{
|
|
Blt8BPPDataTo16BPPBufferOutlineShadow((UINT16*)pBuffer, uiPitch, hSrcVObject, iDestX, iDestY, usIndex );
|
|
}
|
|
}
|
|
else if(hSrcVObject->ubBitDepth == 16)
|
|
{
|
|
SGP_THROW_IFFALSE(usIndex < hSrcVObject->usNumberOf16BPPObjects, L"index larger that number images");
|
|
SixteenBPPObjectInfo &image = hSrcVObject->p16BPPObject[0];
|
|
Blt16BPPTo16BPPTransShadow(pBuffer, uiPitch, image.p16BPPData, image.usWidth * sizeof(UINT16),
|
|
iDestX, iDestY, 0, 0, image.usWidth, image.usHeight, 0x1F);
|
|
}
|
|
else if(hSrcVObject->ubBitDepth == 32)
|
|
{
|
|
SGP_THROW_IFFALSE(usIndex < hSrcVObject->usNumberOf16BPPObjects, L"index larger that number images");
|
|
SixteenBPPObjectInfo &image = hSrcVObject->p16BPPObject[0];
|
|
Blt32BPPTo16BPPTransShadow(pBuffer, uiPitch, (UINT32*)image.p16BPPData, image.usWidth * sizeof(UINT32),
|
|
iDestX, iDestY, 0, 0, image.usWidth, image.usHeight);
|
|
}
|
|
|
|
// Now we have the video object and surface, call the VO blitter function
|
|
|
|
UnLockVideoSurface( uiDestVSurface );
|
|
return( TRUE );
|
|
}
|
|
|
|
BOOLEAN BltVideoObjectOutlineShadow(UINT32 uiDestVSurface, HVOBJECT hSrcVObject, UINT16 usIndex, INT32 iDestX, INT32 iDestY )
|
|
{
|
|
UINT16 *pBuffer;
|
|
UINT32 uiPitch;
|
|
// Lock video surface
|
|
pBuffer = (UINT16*)LockVideoSurface( uiDestVSurface, &uiPitch );
|
|
|
|
if ( pBuffer == NULL )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
if( BltIsClipped( hSrcVObject, iDestX, iDestY, usIndex, &ClippingRect) )
|
|
{
|
|
Blt8BPPDataTo16BPPBufferOutlineShadowClip((UINT16*)pBuffer, uiPitch, hSrcVObject, iDestX, iDestY, usIndex, &ClippingRect );
|
|
}
|
|
else
|
|
{
|
|
Blt8BPPDataTo16BPPBufferOutlineShadow((UINT16*)pBuffer, uiPitch, hSrcVObject, iDestX, iDestY, usIndex );
|
|
}
|
|
|
|
// Now we have the video object and surface, call the VO blitter function
|
|
|
|
UnLockVideoSurface( uiDestVSurface );
|
|
return( TRUE );
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
void CheckValidVObjectIndex( UINT32 uiIndex )
|
|
{
|
|
BOOLEAN fAssertError = FALSE;
|
|
if( uiIndex == 0xffffffff )
|
|
{ //-1 index -- deleted
|
|
fAssertError = TRUE;
|
|
}
|
|
if( !(uiIndex % 2) && uiIndex < 0xfffffff0 || uiIndex >= 0xfffffff0 )
|
|
{ //even numbers are reserved for vsurfaces as well as the 0xfffffff0+ values
|
|
fAssertError = TRUE;
|
|
}
|
|
|
|
if( fAssertError )
|
|
{
|
|
CHAR8 str[60];
|
|
switch( gubVODebugCode )
|
|
{
|
|
case DEBUGSTR_SETVIDEOOBJECTTRANSPARENCY:
|
|
sprintf( str, "SetVideoObjectTransparency" );
|
|
break;
|
|
case DEBUGSTR_BLTVIDEOOBJECTFROMINDEX:
|
|
sprintf( str, "BltVideoObjectFromIndex" );
|
|
break;
|
|
case DEBUGSTR_SETOBJECTHANDLESHADE:
|
|
sprintf( str, "SetObjectHandleShade" );
|
|
break;
|
|
case DEBUGSTR_GETVIDEOOBJECTETRLESUBREGIONPROPERTIES:
|
|
sprintf( str, "GetVideoObjectETRLESubRegionProperties" );
|
|
break;
|
|
case DEBUGSTR_GETVIDEOOBJECTETRLEPROPERTIESFROMINDEX:
|
|
sprintf( str, "GetVideoObjectETRLEPropertiesFromIndex" );
|
|
break;
|
|
case DEBUGSTR_SETVIDEOOBJECTPALETTE8BPP:
|
|
sprintf( str, "SetVideoObjectPalette8BPP" );
|
|
break;
|
|
case DEBUGSTR_GETVIDEOOBJECTPALETTE16BPP:
|
|
sprintf( str, "GetVideoObjectPalette16BPP" );
|
|
break;
|
|
case DEBUGSTR_COPYVIDEOOBJECTPALETTE16BPP:
|
|
sprintf( str, "CopyVideoObjectPalette16BPP" );
|
|
break;
|
|
case DEBUGSTR_BLTVIDEOOBJECTOUTLINEFROMINDEX:
|
|
sprintf( str, "BltVideoObjectOutlineFromIndex" );
|
|
break;
|
|
case DEBUGSTR_BLTVIDEOOBJECTOUTLINESHADOWFROMINDEX:
|
|
sprintf( str, "BltVideoObjectOutlineShadowFromIndex" );
|
|
break;
|
|
case DEBUGSTR_DELETEVIDEOOBJECTFROMINDEX:
|
|
sprintf( str, "DeleteVideoObjectFromIndex" );
|
|
break;
|
|
case DEBUGSTR_NONE:
|
|
default:
|
|
sprintf( str, "GetVideoObject" );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#ifdef SGP_VIDEO_DEBUGGING
|
|
|
|
typedef struct DUMPFILENAME
|
|
{
|
|
CHAR8 str[256];
|
|
}DUMPFILENAME;
|
|
|
|
void DumpVObjectInfoIntoFile( const STR8 filename, BOOLEAN fAppend )
|
|
{
|
|
VOBJECT_NODE *curr;
|
|
FILE *fp;
|
|
DUMPFILENAME *pName, *pCode;
|
|
UINT32 *puiCounter;
|
|
CHAR8 tempName[ 256 ];
|
|
CHAR8 tempCode[ 256 ];
|
|
UINT32 i, uiUniqueID;
|
|
BOOLEAN fFound;
|
|
if( !guiVObjectSize )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if( fAppend )
|
|
{
|
|
fp = fopen( filename, "a" );
|
|
}
|
|
else
|
|
{
|
|
fp = fopen( filename, "w" );
|
|
}
|
|
Assert( fp );
|
|
|
|
//Allocate enough strings and counters for each node.
|
|
pName = (DUMPFILENAME*)MemAlloc( sizeof( DUMPFILENAME ) * guiVObjectSize );
|
|
pCode = (DUMPFILENAME*)MemAlloc( sizeof( DUMPFILENAME ) * guiVObjectSize );
|
|
memset( pName, 0, sizeof( DUMPFILENAME ) * guiVObjectSize );
|
|
memset( pCode, 0, sizeof( DUMPFILENAME ) * guiVObjectSize );
|
|
puiCounter = (UINT32*)MemAlloc( 4 * guiVObjectSize );
|
|
memset( puiCounter, 0, 4 * guiVObjectSize );
|
|
|
|
//Loop through the list and record every unique filename and count them
|
|
uiUniqueID = 0;
|
|
curr = gpVObjectHead;
|
|
while( curr )
|
|
{
|
|
strcpy( tempName, curr->pName );
|
|
strcpy( tempCode, curr->pCode );
|
|
fFound = FALSE;
|
|
for( i = 0; i < uiUniqueID; i++ )
|
|
{
|
|
if( !_stricmp( tempName, pName[i].str ) && !_stricmp( tempCode, pCode[i].str ) )
|
|
{ //same string
|
|
fFound = TRUE;
|
|
(puiCounter[ i ])++;
|
|
break;
|
|
}
|
|
}
|
|
if( !fFound )
|
|
{
|
|
strcpy( pName[i].str, tempName );
|
|
strcpy( pCode[i].str, tempCode );
|
|
(puiCounter[ i ])++;
|
|
uiUniqueID++;
|
|
}
|
|
curr = curr->next;
|
|
}
|
|
|
|
//Now dump the info.
|
|
fprintf( fp, "-----------------------------------------------\n" );
|
|
fprintf( fp, "%d unique vObject names exist in %d VObjects\n", uiUniqueID, guiVObjectSize );
|
|
fprintf( fp, "-----------------------------------------------\n\n" );
|
|
for( i = 0; i < uiUniqueID; i++ )
|
|
{
|
|
fprintf( fp, "%d occurrences of %s\n", puiCounter[i], pName[i].str );
|
|
fprintf( fp, "%s\n\n", pCode[i].str );
|
|
}
|
|
fprintf( fp, "\n-----------------------------------------------\n\n" );
|
|
|
|
//Free all memory associated with this operation.
|
|
MemFree( pName );
|
|
MemFree( pCode );
|
|
MemFree( puiCounter );
|
|
fclose( fp );
|
|
}
|
|
|
|
//Debug wrapper for adding vObjects
|
|
BOOLEAN _AddAndRecordVObject( VOBJECT_DESC *VObjectDesc, UINT32 *uiIndex, UINT32 uiLineNum, const STR8 pSourceFile )
|
|
{
|
|
UINT16 usLength;
|
|
CHAR8 str[256];
|
|
if( !AddStandardVideoObject( VObjectDesc, uiIndex ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
//record the filename of the vObject (some are created via memory though)
|
|
usLength = strlen( VObjectDesc->ImageFile ) + 1;
|
|
gpVObjectTail->pName = (STR8)MemAlloc( usLength );
|
|
memset( gpVObjectTail->pName, 0, usLength );
|
|
strcpy( gpVObjectTail->pName, VObjectDesc->ImageFile );
|
|
|
|
//record the code location of the calling creating function.
|
|
sprintf( str, "%s -- line(%d)", pSourceFile, uiLineNum );
|
|
usLength = strlen( str ) + 1;
|
|
gpVObjectTail->pCode = (STR8)MemAlloc( usLength );
|
|
memset( gpVObjectTail->pCode, 0, usLength );
|
|
strcpy( gpVObjectTail->pCode, str );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void PerformVideoInfoDumpIntoFile( const STR8 filename, BOOLEAN fAppend )
|
|
{
|
|
DumpVObjectInfoIntoFile( filename, fAppend );
|
|
DumpVSurfaceInfoIntoFile( filename, TRUE );
|
|
}
|
|
|
|
#endif
|
|
|
|
|