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

📄 bfbuf.c

📁 游戏编程精粹2第六章源码
💻 C
字号:
/******************************************************************************
File: 		 bfbuf.h
Tab stops: every 2 columns
Project:	 Game Programming Gems II
Copyright: 1998-2000 DiamondWare, Ltd.	Usage permitted for buyers of the book.
Written:	 by Keith Weiner
Purpose:	 Contains the BackFill Buffer manager
History:	 11/20/98 KW Started
					 02/20/01 KW modified (simplified) for book
******************************************************************************/



#include <stdlib.h>

#include "bfbuf.h"



void bfbuf_Eat(bfbuf_BUFFER *buf, UINT32 len)
{
	buf->datalen -= len;
}


void bfbuf_ChokeUp(bfbuf_BUFFER *buf, UINT32 newlen)
{
	UINT32 *lsrc;
	UINT32 *rsrc;
	UINT32 *ldst;
	UINT32 *rdst;

	if (buf->datalen - newlen)
	{
		bfbuf_GetBufStart(buf, &lsrc, &rsrc);

		buf->datalen = newlen;

		if (newlen)
		{
			bfbuf_GetBufStart(buf, &ldst, &rdst);

			memmove(ldst, lsrc, newlen * sizeof(*ldst));
			memmove(rdst, rsrc, newlen * sizeof(*rdst));
		}
	}
}


UINT32 bfbuf_MoveAll(bfbuf_BUFFER *dst, bfbuf_BUFFER *src)
{
	return (bfbuf_Move(dst, src, src->datalen));
}


UINT32 bfbuf_Move(bfbuf_BUFFER *dst, bfbuf_BUFFER *src, UINT32 len)
{
	UINT32 *lsrc;
	UINT32 *rsrc;
	UINT32 datalen;
	UINT32 buflen;
	UINT32 *ldst;
	UINT32 *rdst;
	UINT32 *lnew;
	UINT32 *rnew;

	if (!src->datalen)
	{
		return (bfbuf_SUCCESS); 				//okay...
	}

	datalen = dst->datalen + len; 		//new, final datalen in UINT32's

	if (dst->buflen < datalen)
	{
		/* New data won't fit into dst buffer, so use 125% of datalen */
		buflen = datalen + (datalen >> 2);

		/* We allocate new buffers (realloc wouldn't help a bfbuf anyways) */
		if ((lnew = malloc(buflen * sizeof(*lnew) * 2)) == NULL)
		{
			return (bfbuf_FAILURE);
		}

		if ((rnew = malloc(buflen * sizeof(*rnew) * 2)) == NULL)
		{
			free(lnew);

			return (bfbuf_FAILURE);
		}

		if (dst->buflen)
		{
			/* The old buffer was not NULL */

			if (dst->datalen)
			{
				/* The old buffer had data in it */
				ldst = lnew + buflen - dst->datalen;
				rdst = rnew + buflen - dst->datalen;

				bfbuf_GetBufStart(dst, &lsrc, &rsrc);

				memcpy(ldst, lsrc, dst->datalen * sizeof(*ldst));
				memcpy(rdst, rsrc, dst->datalen * sizeof(*rdst));
			}

			free(dst->lbuf);
			free(dst->rbuf);
		}

		dst->buflen = buflen;
		dst->lbuf 	= lnew;
		dst->rbuf 	= rnew;
	}

	dst->datalen = datalen;

	bfbuf_GetBufStart(src, &lsrc, &rsrc);
	bfbuf_GetBufStart(dst, &ldst, &rdst);

	/* Move data from src to dst */
	memcpy(ldst, lsrc, len * sizeof(*ldst));
	memcpy(rdst, rsrc, len * sizeof(*rdst));

	src->datalen -= len;

	return (bfbuf_SUCCESS);
}


void bfbuf_SetDataLen(bfbuf_BUFFER *buf, UINT32 len)
{
	UINT32 *tmp;

	buf->datalen = len;

	if (buf->buflen < buf->datalen)
	{
		if ((buf->buflen) && (buf->lbuf) != NULL)
		{
			free(buf->lbuf);
		}

		if ((buf->buflen) && (buf->rbuf) != NULL)
		{
			free(buf->rbuf);
		}

		buf->buflen = buf->datalen + (buf->datalen >> 2); 	//extra safety margin

		if ((buf->lbuf = malloc(buf->buflen * sizeof(*buf->lbuf) * 2)) != NULL)
		{
			if ((buf->rbuf = malloc(buf->buflen * sizeof(*buf->rbuf) * 2)) == NULL)
			{
				free(buf->lbuf);
			}
		}
	}
}


void bfbuf_GetBufStart(bfbuf_BUFFER *buf, UINT32 **left, UINT32 **right)
{
	*left  = buf->lbuf + (buf->buflen - buf->datalen);
	*right = buf->rbuf + (buf->buflen - buf->datalen);
}


void bfbuf_EndBuf(bfbuf_BUFFER *buf)
{
	if (buf->lbuf != NULL)
	{
		free(buf->lbuf);
	}

	if (buf->rbuf != NULL)
	{
		free(buf->rbuf);
	}
}


UINT32 bfbuf_BeginBuf(bfbuf_BUFFER *buf, UINT32 buflen)
{
	UINT32 len;

	len = buflen * (sizeof(*(buf->lbuf)));	//my kingdom for a typeof operator!

	if (len)
	{
		if ((buf->lbuf = malloc(len * 2)) == NULL)
		{
			return (bfbuf_FAILURE);
		}

		if ((buf->rbuf = malloc(len * 2)) == NULL)
		{
			free(buf->lbuf);

			return (bfbuf_FAILURE);
		}
	}
	else
	{
		buf->lbuf = NULL;
		buf->rbuf = NULL;
	}

	buf->buflen  = buflen;
	buf->datalen = 0;

	return (bfbuf_SUCCESS);
}

⌨️ 快捷键说明

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