| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707 |
- //
- // Copyright 2020 Electronic Arts Inc.
- //
- // TiberianDawn.DLL and RedAlert.dll and corresponding source code 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.
- // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
- // in the hope that it will be useful, but with permitted additional restrictions
- // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
- // distributed with this program. You should have received a copy of the
- // GNU General Public License along with permitted additional restrictions
- // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
- /***************************************************************************
- ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
- ***************************************************************************
- * *
- * Project Name : Westwood 32 bit Library *
- * *
- * File Name : GBUFFER.CPP *
- * *
- * Programmer : Phil W. Gorrow *
- * *
- * Start Date : May 3, 1994 *
- * *
- * Last Update : October 9, 1995 [] *
- * *
- *-------------------------------------------------------------------------*
- * Functions: *
- * VVPC::VirtualViewPort -- Default constructor for a virtual viewport *
- * VVPC:~VirtualViewPortClass -- Destructor for a virtual viewport *
- * VVPC::Clear -- Clears a graphic page to correct color *
- * VBC::VideoBufferClass -- Lowlevel constructor for video buffer class *
- * GVPC::Change -- Changes position and size of a Graphic View Port *
- * VVPC::Change -- Changes position and size of a Video View Port *
- * Set_Logic_Page -- Sets LogicPage to new buffer *
- * GBC::DD_Init -- Inits a direct draw surface for a GBC *
- * GBC::Init -- Core function responsible for initing a GBC *
- * GBC::Lock -- Locks a Direct Draw Surface *
- * GBC::Unlock -- Unlocks a direct draw surface *
- * GBC::GraphicBufferClass -- Default constructor (requires explicit init)*
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #ifndef GBUFFER_H
- #include "gbuffer.h"
- #include "misc.h"
- #endif
- //#pragma inline
- int TotalLocks;
- BOOL AllowHardwareBlitFills = TRUE;
- //int CacheAllowed;
- /*=========================================================================*/
- /* The following PRIVATE functions are in this file: */
- /*=========================================================================*/
- /*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
- /***************************************************************************
- * GVPC::GRAPHICVIEWPORTCLASS -- Constructor for basic view port class *
- * m *
- * INPUT: GraphicBufferClass * gbuffer - buffer to attach to *
- * int x - x offset into buffer *
- * int y - y offset into buffer *
- * int w - view port width in pixels *
- * int h - view port height in pixels *
- * *
- * OUTPUT: Constructors may not have a return value *
- * *
- * HISTORY: *
- * 05/09/1994 PWG : Created. *
- *=========================================================================*/
- GraphicViewPortClass::GraphicViewPortClass(GraphicBufferClass *gbuffer, int x, int y, int w, int h) :
- LockCount(0),
- GraphicBuff(NULL)
- {
- Attach(gbuffer, x, y, w, h);
- }
- /***************************************************************************
- * GVPC::GRAPHICVIEWPORTCLASS -- Default constructor for view port class *
- * *
- * INPUT: none *
- * *
- * OUTPUT: none *
- * *
- * HISTORY: *
- * 05/09/1994 PWG : Created. *
- *=========================================================================*/
- GraphicViewPortClass::GraphicViewPortClass(void)
- {
- }
- /***************************************************************************
- * GVPC::~GRAPHICVIEWPORTCLASS -- Destructor for GraphicViewPortClass *
- * *
- * INPUT: none *
- * *
- * OUTPUT: A destructor may not return a value. *
- * *
- * HISTORY: *
- * 05/10/1994 PWG : Created. *
- *=========================================================================*/
- GraphicViewPortClass::~GraphicViewPortClass(void)
- {
- Offset = 0;
- Width = 0; // Record width of Buffer
- Height = 0; // Record height of Buffer
- XAdd = 0; // Record XAdd of Buffer
- XPos = 0; // Record XPos of Buffer
- YPos = 0; // Record YPos of Buffer
- Pitch = 0; // Record width of Buffer
- IsDirectDraw = FALSE;
- LockCount = 0;
- GraphicBuff = NULL;
- }
- /***************************************************************************
- * GVPC::ATTACH -- Attaches a viewport to a buffer class *
- * *
- * INPUT: GraphicBufferClass *g_buff - pointer to gbuff to attach to *
- * int x - x position to attach to *
- * int y - y position to attach to *
- * int w - width of the view port *
- * int h - height of the view port *
- * *
- * OUTPUT: none *
- * *
- * HISTORY: *
- * 05/10/1994 PWG : Created. *
- *=========================================================================*/
- void GraphicViewPortClass::Attach(GraphicBufferClass *gbuffer, int x, int y, int w, int h)
- {
- /*======================================================================*/
- /* Can not attach a Graphic View Port if it is actually the physical */
- /* representation of a Graphic Buffer. */
- /*======================================================================*/
- if (this == Get_Graphic_Buffer()) {
- return;
- }
- /*======================================================================*/
- /* Verify that the x and y coordinates are valid and placed within the */
- /* physical buffer. */
- /*======================================================================*/
- if (x < 0) // you cannot place view port off
- x = 0; // the left edge of physical buf
- if (x >= gbuffer->Get_Width()) // you cannot place left edge off
- x = gbuffer->Get_Width() - 1; // the right edge of physical buf
- if (y < 0) // you cannot place view port off
- y = 0; // the top edge of physical buf
- if (y >= gbuffer->Get_Height()) // you cannot place view port off
- y = gbuffer->Get_Height() - 1; // bottom edge of physical buf
- /*======================================================================*/
- /* Adjust the width and height of necessary */
- /*======================================================================*/
- if (x + w > gbuffer->Get_Width()) // if the x plus width is larger
- w = gbuffer->Get_Width() - x; // than physical, fix width
- if (y + h > gbuffer->Get_Height()) // if the y plus height is larger
- h = gbuffer->Get_Height() - y; // than physical, fix height
- /*======================================================================*/
- /* Get a pointer to the top left edge of the buffer. */
- /*======================================================================*/
- Offset = gbuffer->Get_Offset() + ((gbuffer->Get_Width()+gbuffer->Get_Pitch()) * y) + x;
- /*======================================================================*/
- /* Copy over all of the variables that we need to store. */
- /*======================================================================*/
- XPos = x;
- YPos = y;
- XAdd = gbuffer->Get_Width() - w;
- Width = w;
- Height = h;
- Pitch = gbuffer->Get_Pitch();
- GraphicBuff = gbuffer;
- IsDirectDraw= gbuffer->IsDirectDraw;
- }
- /***************************************************************************
- * GVPC::CHANGE -- Changes position and size of a Graphic View Port *
- * *
- * INPUT: int the new x pixel position of the graphic view port *
- * int the new y pixel position of the graphic view port *
- * int the new width of the viewport in pixels *
- * int the new height of the viewport in pixels *
- * *
- * OUTPUT: BOOL whether the Graphic View Port could be sucessfully *
- * resized. *
- * *
- * WARNINGS: You may not resize a Graphic View Port which is derived *
- * from a Graphic View Port Buffer, *
- * *
- * HISTORY: *
- * 09/14/1994 SKB : Created. *
- *=========================================================================*/
- BOOL GraphicViewPortClass::Change(int x, int y, int w, int h)
- {
- /*======================================================================*/
- /* Can not change a Graphic View Port if it is actually the physical */
- /* representation of a Graphic Buffer. */
- /*======================================================================*/
- if (this == Get_Graphic_Buffer()) {
- return(FALSE);
- }
- /*======================================================================*/
- /* Since there is no allocated information, just re-attach it to the */
- /* existing graphic buffer as if we were creating the */
- /* GraphicViewPort. */
- /*======================================================================*/
- Attach(Get_Graphic_Buffer(), x, y, w, h);
- return(TRUE);
- }
- /***************************************************************************
- * GBC::DD_INIT -- Inits a direct draw surface for a GBC *
- * *
- * INPUT: none *
- * *
- * OUTPUT: none *
- * *
- * HISTORY: *
- * 10/09/1995 : Created. *
- *=========================================================================*/
- void GraphicBufferClass::DD_Init(GBC_Enum flags)
- {
- //
- // Create the direct draw surface description
- //
- memset (&VideoSurfaceDescription , 0 , sizeof ( VideoSurfaceDescription ));
- VideoSurfaceDescription.dwSize = sizeof( VideoSurfaceDescription );
- VideoSurfaceDescription.dwFlags = DDSD_CAPS;
- VideoSurfaceDescription.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
- if (!(flags & GBC_VISIBLE)) {
- VideoSurfaceDescription.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
- VideoSurfaceDescription.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH;
- VideoSurfaceDescription.dwHeight = Height;
- VideoSurfaceDescription.dwWidth = Width;
- }
- //
- // Need to set the DDSCAPS_MODEX flag if we want a 320 wide mode
- //
- if ( Width == 320 ) {
- VideoSurfaceDescription.ddsCaps.dwCaps |= DDSCAPS_MODEX;
- }
- //
- // Call CreateSurface
- //
- DirectDrawObject->CreateSurface( &VideoSurfaceDescription , &VideoSurfacePtr , NULL);
- AllSurfaces.Add_DD_Surface (VideoSurfacePtr);
- if ( GBC_VISIBLE & flags ){
- PaletteSurface=VideoSurfacePtr;
- }
- Allocated = FALSE; // even if system alloced, dont flag it cuz
- // we dont want it freed.
- IsDirectDraw = TRUE; // flag it as a video surface
- Offset = NOT_LOCKED; // flag it as unavailable for reading or writing
- LockCount = 0; // surface is not locked
- }
- void GraphicBufferClass::Attach_DD_Surface (GraphicBufferClass * attach_buffer)
- {
- VideoSurfacePtr->AddAttachedSurface (attach_buffer->Get_DD_Surface());
- }
- /***************************************************************************
- * GBC::INIT -- Core function responsible for initing a GBC *
- * *
- * INPUT: int - the width in pixels of the GraphicBufferClass *
- * int - the heigh in pixels of the GraphicBufferClass *
- * void * - pointer to user supplied buffer (system will *
- * allocate space if buffer is NULL) *
- * long - size of the user provided buffer *
- * GBC_Enum - flags if this is defined as a direct draw *
- * surface *
- * *
- * OUTPUT: none *
- * *
- * HISTORY: *
- * 10/09/1995 : Created. *
- *=========================================================================*/
- void GraphicBufferClass::Init(int w, int h, void *buffer, long size, GBC_Enum flags)
- {
- Size = size; // find size of physical buffer
- Width = w; // Record width of Buffer
- Height = h; // Record height of Buffer
- //
- // If the surface we are creating is a direct draw object then
- // we need to do a direct draw init. Otherwise we will do
- // a normal alloc.
- //
- if (flags & (GBC_VIDEOMEM | GBC_VISIBLE)) {
- DD_Init(flags);
- } else {
- if (buffer) { // if buffer is specified
- Buffer = (BYTE *)buffer; // point to it and mark
- Allocated = FALSE; // it as user allocated
- } else {
- if (!Size) Size = w*h;
- Buffer = new BYTE[Size]; // otherwise allocate it and
- Allocated = TRUE; // mark it system alloced
- }
- Offset = (long)Buffer; // Get offset to the buffer
- IsDirectDraw = FALSE;
- }
- Pitch = 0; // Record width of Buffer
- XAdd = 0; // Record XAdd of Buffer
- XPos = 0; // Record XPos of Buffer
- YPos = 0; // Record YPos of Buffer
- GraphicBuff = this; // Get a pointer to our self
- }
- /***********************************************************************************************
- * GBC::Un_Init -- releases the video surface belonging to this gbuffer *
- * *
- * *
- * *
- * INPUT: Nothing *
- * *
- * OUTPUT: Nothing *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 6/6/96 12:44PM ST : Created *
- *=============================================================================================*/
- void GraphicBufferClass::Un_Init (void)
- {
- if ( IsDirectDraw ){
- if ( VideoSurfacePtr ){
- while ( LockCount ){
- if (VideoSurfacePtr->Unlock ( NULL ) == DDERR_SURFACELOST){
- if (Gbuffer_Focus_Loss_Function){
- Gbuffer_Focus_Loss_Function();
- }
- AllSurfaces.Restore_Surfaces();
- }
- }
- AllSurfaces.Remove_DD_Surface (VideoSurfacePtr);
- VideoSurfacePtr->Release();
- VideoSurfacePtr = NULL;
- }
- }
- }
- /***************************************************************************
- * GBC::GRAPHICBUFFERCLASS -- Default constructor (requires explicit init) *
- * *
- * INPUT: none *
- * *
- * OUTPUT: none *
- * *
- * HISTORY: *
- * 10/09/1995 : Created. *
- *=========================================================================*/
- GraphicBufferClass::GraphicBufferClass(void)
- {
- GraphicBuff = this; // Get a pointer to our self
- VideoSurfacePtr = NULL;
- memset(&VideoSurfaceDescription, 0, sizeof(DDSURFACEDESC));
- }
- /***************************************************************************
- * GBC::GRAPHICBUFFERCLASS -- Constructor for fixed size buffers *
- * *
- * INPUT: long size - size of the buffer to create *
- * int w - width of buffer in pixels (default = 320) *
- * int h - height of buffer in pixels (default = 200) *
- * void *buffer - a pointer to the buffer if any (optional) *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 05/13/1994 PWG : Created. *
- *=========================================================================*/
- GraphicBufferClass::GraphicBufferClass(int w, int h, void *buffer, long size)
- {
- Init(w, h, buffer, size, GBC_NONE);
- }
- /*=========================================================================*
- * GBC::GRAPHICBUFFERCLASS -- inline constructor for GraphicBufferClass *
- * *
- * INPUT: int w - width of buffer in pixels (default = 320) *
- * int h - height of buffer in pixels (default = 200) *
- * void *buffer - a pointer to the buffer if any (optional) *
- * *
- * OUTPUT: none *
- * *
- * HISTORY: *
- * 05/03/1994 PWG : Created. *
- *=========================================================================*/
- GraphicBufferClass::GraphicBufferClass(int w, int h, void *buffer)
- {
- Init(w, h, buffer, w * h, GBC_NONE);
- }
- /*====================================================================================*
- * GBC::GRAPHICBUFFERCLASS -- contructor for GraphicsBufferClass with special flags *
- * *
- * INPUT: int w - width of buffer in pixels (default = 320) *
- * int h - height of buffer in pixels (default = 200) *
- * void *buffer - unused *
- * unsigned flags - flags for creation of special buffer types *
- * GBC_VISIBLE - buffer is a visible screen surface *
- * GBC_VIDEOMEM - buffer resides in video memory *
- * *
- * OUTPUT: none *
- * *
- * HISTORY: *
- * 09-21-95 04:19pm ST : Created *
- *====================================================================================*/
- GraphicBufferClass::GraphicBufferClass(int w, int h, GBC_Enum flags)
- {
- Init(w, h, NULL, w * h, flags);
- }
- /*=========================================================================*
- * GBC::~GRAPHICBUFFERCLASS -- Destructor for the graphic buffer class *
- * *
- * INPUT: none *
- * *
- * OUTPUT: none *
- * *
- * HISTORY: *
- * 05/03/1994 PWG : Created. *
- *=========================================================================*/
- GraphicBufferClass::~GraphicBufferClass()
- {
- //
- // Release the direct draw surface if it exists
- //
- Un_Init();
- }
- /***************************************************************************
- * SET_LOGIC_PAGE -- Sets LogicPage to new buffer *
- * *
- * INPUT: GraphicBufferClass * the buffer we are going to set *
- * *
- * OUTPUT: GraphicBufferClass * the previous buffer type *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 02/23/1995 PWG : Created. *
- *=========================================================================*/
- GraphicViewPortClass *Set_Logic_Page(GraphicViewPortClass *ptr)
- {
- GraphicViewPortClass *old = LogicPage;
- LogicPage = ptr;
- return(old);
- }
- /***************************************************************************
- * SET_LOGIC_PAGE -- Sets LogicPage to new buffer *
- * *
- * INPUT: GraphicBufferClass & the buffer we are going to set *
- * *
- * OUTPUT: GraphicBufferClass * the previous buffer type *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 02/23/1995 PWG : Created. *
- *=========================================================================*/
- GraphicViewPortClass *Set_Logic_Page(GraphicViewPortClass &ptr)
- {
- GraphicViewPortClass *old = LogicPage;
- LogicPage = &ptr;
- return(old);
- }
- /***************************************************************************
- * GBC::LOCK -- Locks a Direct Draw Surface *
- * *
- * INPUT: none *
- * *
- * OUTPUT: none *
- * *
- * HISTORY: *
- * 10/09/1995 : Created. *
- * 10/09/1995 : Code stolen from Steve Tall *
- *=========================================================================*/
- extern void Colour_Debug (int call_number);
- extern bool GameInFocus;
- extern void Block_Mouse(GraphicBufferClass *buffer);
- extern void Unblock_Mouse(GraphicBufferClass *buffer);
- BOOL GraphicBufferClass::Lock(void)
- {
- HRESULT result;
- int restore_attempts=0;
- //
- // If its not a direct draw surface then the lock is always sucessful.
- //
- if (!IsDirectDraw) return(TRUE);
- /*
- ** If the video surface pointer is null then return
- */
- if (!VideoSurfacePtr) return (FALSE);
- /*
- ** If we dont have focus then return failure
- */
- if (!GameInFocus) return (FALSE);
- Block_Mouse(this);
- //
- // If surface is already locked then inc the lock count and return true
- //
- if (LockCount){
- LockCount++;
- Unblock_Mouse(this);
- return(TRUE);
- }
- //
- // If it isn't locked at all then we will have to request that Direct
- // Draw actually lock the surface.
- //
- if (VideoSurfacePtr){
- while (!LockCount && restore_attempts<2) {
- result = VideoSurfacePtr->Lock ( NULL
- , &(VideoSurfaceDescription)
- , DDLOCK_WAIT
- , NULL);
- switch (result){
- case DD_OK :
- Offset = (unsigned long)VideoSurfaceDescription.lpSurface;
- Pitch = VideoSurfaceDescription.lPitch;
- Pitch -= Width;
- LockCount++; // increment count so we can track if
- TotalLocks++; // Total number of times we have locked (for debugging)
- //Colour_Debug (1);
- Unblock_Mouse(this);
- return (TRUE); // we locked it multiple times.
- case DDERR_SURFACELOST :
- if (Gbuffer_Focus_Loss_Function){
- Gbuffer_Focus_Loss_Function();
- }
- AllSurfaces.Restore_Surfaces();
- restore_attempts++;
- break;
- default :
- Unblock_Mouse(this);
- return (FALSE);
- }
- }
- }
- //Colour_Debug(1);
- Unblock_Mouse(this);
- return (FALSE); //Return false because we couldnt lock or restore the surface
- }
- /***************************************************************************
- * GBC::UNLOCK -- Unlocks a direct draw surface *
- * *
- * INPUT: none *
- * *
- * OUTPUT: none *
- * *
- * HISTORY: *
- * 10/09/1995 : Created. *
- * 10/09/1995 : Code stolen from Steve Tall *
- *=========================================================================*/
- BOOL GraphicBufferClass::Unlock(void)
- {
- //
- // If there is no lock count or this is not a direct draw surface
- // then just return true as there is no harm done.
- //
- if (!(LockCount && IsDirectDraw)) {
- return(TRUE);
- }
- //
- // If lock count is directly equal to one then we actually need to
- // unlock so just give it a shot.
- //
- if (LockCount == 1 && VideoSurfacePtr) {
- Block_Mouse(this);
- if ( VideoSurfacePtr->Unlock ( NULL ) != DD_OK ){
- Unblock_Mouse(this);
- return(FALSE);
- } else {
- Offset=NOT_LOCKED;
- LockCount--;
- Unblock_Mouse(this);
- return(TRUE);
- }
- }
- //Colour_Debug (0);
- LockCount--;
- return(TRUE);
- }
- /***********************************************************************************************
- * GVPC::DD_Linear_Blit_To_Linear -- blit using the hardware blitter *
- * *
- * *
- * *
- * INPUT: destination vvpc *
- * x coord to blit from *
- * y coord to blit from *
- * x coord to blit to *
- * y coord to blit to *
- * width to blit *
- * height to blit *
- * *
- * OUTPUT: DD_OK if successful *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 09-22-95 11:05am ST : Created *
- *=============================================================================================*/
- HRESULT GraphicViewPortClass::DD_Linear_Blit_To_Linear (
- GraphicViewPortClass &dest
- , int source_x
- , int source_y
- , int dest_x
- , int dest_y
- , int width
- , int height
- , BOOL mask )
- {
- RECT source_rectangle;
- RECT dest_rectangle;
- int key_source=0;
- if ( mask ){
- key_source=DDBLT_KEYSRC;
- }
- source_rectangle.left = source_x;
- source_rectangle.top = source_y;
- source_rectangle.right = source_x+width;
- source_rectangle.bottom = source_y+height;
- dest_rectangle.left = dest_x;
- dest_rectangle.top = dest_y;
- dest_rectangle.right = dest_x+width;
- dest_rectangle.bottom = dest_y+height;
- return ( dest.GraphicBuff->Get_DD_Surface()->Blt ( &dest_rectangle,
- GraphicBuff->Get_DD_Surface(),
- &source_rectangle,
- key_source | DDBLT_WAIT | DDBLT_ASYNC,
- NULL ) );
- }
|