📄 blitbuf.cpp
字号:
/************************************************************
* 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 + -