⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 blitbuf.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/************************************************************
 * Blitbuf.cpp - BlitBuf Functions V2.16.001 - HiColor
 *
 * (c) Copyright 1996-2000 Sabarasa Entertainment
 * For internal use only.					
 ************************************************************/               

/* 
	'When you steal from one author, it's plagiarism; if you steal from many, it's research.'  

													-Wilson Mizner
*/

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#include <ddraw.h>
#include <stdlib.h>
#include <stdarg.h>

#include <dos.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <conio.h>

#include "mymalloc.h" 
#include "fplog.h"

#include "blitbuf.hpp"
#include "support.hpp"
#include "prim.hpp"

/* Pure Color LUTs para load_blitbufPCX() */

static int LUTinicializado=0;
static pixelT PureRedLUT[256];
static pixelT PureGreenLUT[256];
static pixelT PureBlueLUT[256];

/* ----- Funciones privadas */

/* Pone un pixel en un blitbuf - Poco Eficiente */

void
blitbuf_putPixel(blitbuf *buf, int x, int y, pixelT color)
{
	RECT rect;
	DDBLTFX ddbltfx;

	rect.left=x;
	rect.top=y;
	rect.right=x+1;
	rect.bottom=y+1;

	ddbltfx.dwSize = sizeof( ddbltfx );
	ddbltfx.dwFillColor = color;

	buf->surface->Blt( &rect, NULL, NULL,
		DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx );
}

/* Inicializa los LUTs que se usan en load_blitbufPCX() */
void
initLUTs( void )
{
	int x;

	fplog( "initLUTs()\n" ); 

	for( x=0; x<256; x++ )
	{
		PureRedLUT[x]=Make16(x,0,0);
		PureGreenLUT[x]=Make16(0,x,0);
		PureBlueLUT[x]=Make16(0,0,x);
	}

	LUTinicializado=1;
}

/* -------------- Public BlitBuf Functions */

/* Limpia y borra el blitbuf */

void
clear_blitbuf(blitbuf *buf) 
{
	if( buf->surface )
	{
		buf->surface->Release();
		buf->surface=NULL;
	}
}

/* Llena el blitbuf con determinado color */

void
fill_blitbuf(pixelT color, blitbuf *buf)
{
	DDBLTFX ddbltfx;

	ddbltfx.dwSize= sizeof( ddbltfx );
	ddbltfx.dwFillColor=color;

	buf->surface->Blt( NULL, NULL, NULL,
		DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx );    
}

// alloc_blitbuf
// Creamos el nuevo BlitBuf
//
// donde	0 en vidmem
//			1 en sysmem

void
alloc_blitbuf(blitbuf *buf, unsigned short xsize, unsigned short ysize,
			  unsigned int donde ) 
{
    DDSURFACEDESC2		ddsd;
	HRESULT				ddrval;
	DDSCAPS2			ddscaps;

	if( donde==0 ) // En vidmem
	{
		// Creo la superficie principal
		ZeroMemory( &ddsd, sizeof(ddsd) );
	    ddsd.dwSize = sizeof( ddsd );
		ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_CKSRCBLT;
		ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
		ddsd.dwHeight=ysize;
		ddsd.dwWidth=xsize;

		ddsd.ddckCKSrcBlt.dwColorSpaceLowValue=0;
		ddsd.ddckCKSrcBlt.dwColorSpaceHighValue=0;
    
		ddrval = lpDD->CreateSurface( &ddsd, &(buf->surface), NULL );
		if( ddrval != DD_OK )
	    {
			chau();
		}
	}
	else		
	{
		// Creo la superficie en sysmem
		ZeroMemory( &ddsd, sizeof(ddsd) );
	    ddsd.dwSize = sizeof( ddsd );
		ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_CKSRCBLT;
		ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
		ddsd.dwHeight=ysize;
		ddsd.dwWidth=xsize;

		ddsd.ddckCKSrcBlt.dwColorSpaceLowValue=0;
		ddsd.ddckCKSrcBlt.dwColorSpaceHighValue=0;
    
		ddrval = lpDD->CreateSurface( &ddsd, &(buf->surface), NULL );
		if( ddrval != DD_OK )
		{
			chau();
		}
	}

	buf->surface->GetSurfaceDesc( &ddsd );

//	fplog( "Superficie creada en %s Memory: %d\n", (ddsd.ddsCaps.dwCaps&DDSCAPS_SYSTEMMEMORY)? "System":"Video",
//		xsize*ysize*sizeof(pixelT) );
	buf->xsize=xsize;
	buf->ysize=ysize;
	buf->insystem=ddsd.ddsCaps.dwCaps&DDSCAPS_SYSTEMMEMORY;

	// Veo cuanta vidmem tengo
	unsigned long dwTotal, dwFree;

	ZeroMemory( &ddscaps, sizeof( ddscaps ) );
	ddscaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY |
					DDSCAPS_LOCALVIDMEM;

	lpDD->GetAvailableVidMem( &ddscaps, &dwTotal, &dwFree );

//	fplog( "Vidmem Total: %ld, Free: %ld\n", dwTotal, dwFree );
}

/* Copia seccion del BlitBuf a virtual screen */

void
blitbuf2vs(blitbuf *buf, unsigned short x1, unsigned short y1, 	
	unsigned short x2, unsigned short y2,
	unsigned short destx, unsigned short desty)
{
	RECT source;

	source.left=x1;
	source.top=y1;
	source.bottom=y2;
	source.right=x2;

	vscreen->BltFast( destx, desty, buf->surface, &source, DDBLTFAST_WAIT );
}	

/* Copia seccion del Virtual Screen a un Blitbuf */

void
vs2blitbuf(blitbuf *buf, signed short x, signed short y)
{
	RECT source;

	source.left=x;
	source.top=y;
	source.bottom=y+buf->ysize;
	source.right=x+buf->xsize;

	buf->surface->BltFast( 0, 0, vscreen, &source, DDBLTFAST_WAIT );
}

/* Copia BlitBuf a virtual screen */

void
display_blitbuf(blitbuf *buf, signed short x1, signed short y1)
{
	RECT r_origen;
	RECT r_dest;

	r_dest.left=x1;
	r_dest.top=y1;
	r_dest.right=x1+buf->xsize;
	r_dest.bottom=y1+buf->ysize;

	r_origen.left=0;
	r_origen.top=0;
	r_origen.right=buf->xsize;
	r_origen.bottom=buf->ysize;

	if( x1<0 )
	{
		r_dest.left=0;
		r_origen.left=(-x1);
	}
	if( y1<0 )
	{
		r_dest.top=0;
		r_origen.top=(-y1);
	}
	if( (x1+buf->xsize)>PhysicalWidth )
	{
		r_dest.right=PhysicalWidth;
		r_origen.right=PhysicalWidth-x1;
	}
	if( (y1+buf->ysize)>PhysicalHeight )
	{
		r_dest.bottom=PhysicalHeight;
		r_origen.bottom=PhysicalHeight-y1;
	}

	vscreen->Blt( &r_dest, buf->surface, &r_origen, DDBLT_WAIT, NULL );
}

/* Copia BlitBuf a virtual screen TRANSPARENTE con el color 0 */

void
t_blitbuf(blitbuf *buf, signed short x1, signed short y1)
{
	RECT r_origen;
	RECT r_dest;

	r_dest.left=x1;
	r_dest.top=y1;
	r_dest.right=x1+buf->xsize;
	r_dest.bottom=y1+buf->ysize;

	r_origen.left=0;
	r_origen.top=0;
	r_origen.right=buf->xsize;
	r_origen.bottom=buf->ysize;

	if( x1<0 )
	{
		r_dest.left=0;
		r_origen.left=(-x1);
	}
	if( y1<0 )
	{
		r_dest.top=0;
		r_origen.top=(-y1);
	}
	if( (x1+buf->xsize)>PhysicalWidth )
	{
		r_dest.right=PhysicalWidth;
		r_origen.right=PhysicalWidth-x1;
	}
	if( (y1+buf->ysize)>PhysicalHeight )
	{
		r_dest.bottom=PhysicalHeight;
		r_origen.bottom=PhysicalHeight-y1;
	}

	vscreen->Blt( &r_dest, buf->surface, &r_origen, DDBLT_WAIT | DDBLT_KEYSRC, NULL );
}

/* Copia BlitBuf a virtual screen TRANSPARENTE con el color 0 a mitad de tama駉 */
/* ESTA FUNCION NO ANDA BIEN EN LOS BORDES!!!!! */

void
s_blitbuf(blitbuf *buf, signed short x1, signed short y1)
{
	RECT dest;

	dest.top=y1;
	dest.left=x1;
	dest.bottom=y1+buf->ysize/2;
	dest.right=x1+buf->xsize/2;

	vscreen->Blt( &dest, buf->surface, NULL, DDBLT_WAIT | DDBLT_KEYSRC, NULL );
}

/* Copia BlitBuf a virtual screen enmascarado con el color col */

void
m_blitbuf(blitbuf *buf, signed short x1, signed short y1, pixelT col)
{
	DDSURFACEDESC2 origen, dest;
	pixelT *buf_origen, *buf_dest;
	int deltax, deltay;

	// Defino limites
	RECT r_origen;
	RECT r_dest;

	r_dest.left=x1;
	r_dest.top=y1;
	r_dest.right=x1+buf->xsize;
	r_dest.bottom=y1+buf->ysize;

	r_origen.left=0;
	r_origen.top=0;
	r_origen.right=buf->xsize;
	r_origen.bottom=buf->ysize;

	if( x1<0 )
	{
		r_dest.left=0;
		r_origen.left=(-x1);
	}
	if( y1<0 )
	{
		r_dest.top=0;
		r_origen.top=(-y1);
	}
	if( (x1+buf->xsize)>PhysicalWidth )
	{
		r_dest.right=PhysicalWidth;
		r_origen.right=PhysicalWidth-x1;
	}
	if( (y1+buf->ysize)>PhysicalHeight )
	{
		r_dest.bottom=PhysicalHeight;
		r_origen.bottom=PhysicalHeight-y1;
	}

	deltax=r_origen.right-r_origen.left;
	deltay=r_origen.bottom-r_origen.top;

	// Preparo variables
	ZeroMemory( &origen, sizeof( origen ) );
	origen.dwSize=sizeof(origen);

	ZeroMemory( &dest, sizeof( dest ) );
	dest.dwSize=sizeof(dest);

	// Lockeo superficies
	if(buf->surface->Lock( &r_origen, &origen, DDLOCK_WAIT, NULL )!=DD_OK)
		return;
	if(vscreen->Lock( &r_dest, &dest, DDLOCK_WAIT, NULL )!=DD_OK)
		return;

	// Tomo punteros
	buf_dest=(pixelT *)dest.lpSurface;
	buf_origen=(pixelT *)origen.lpSurface;

	// Armo los pixels correspondientes
	for( int y=0; y<deltay; y++ )
	{
		for( int x=0; x<deltax; x++ )
		{
			if( *(buf_origen+x) )
				*(buf_dest+x)=col;
		}
		buf_dest+=dest.lPitch/sizeof(pixelT);
		buf_origen+=origen.lPitch/sizeof(pixelT);
	}

	// Deslockeo superficies
	buf->surface->Unlock( &r_origen );
	vscreen->Unlock( &r_dest );
}

/* Copia seccion del BlitBuf a otra seccion de otro BlitBuf */

void
copy_blitbuf(blitbuf *source, blitbuf *dest, 
		unsigned short x1, unsigned short y1, 	
		unsigned short x2, unsigned short y2,
		unsigned short destx, unsigned short desty)
{
	RECT rect;

	rect.left=x1;
	rect.top=y1;
	rect.right=x2;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -