1 Star 0 Fork 0

vsf-linux / sdlpal

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
palcommon.c 23.31 KB
一键复制 编辑 原始数据 按行查看 历史
Wei Mingzhi 提交于 2022-01-09 17:30 . Update copyright.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136
/* -*- mode: c; tab-width: 4; c-basic-offset: 4; c-file-style: "linux" -*- */
//
// Copyright (c) 2009-2011, Wei Mingzhi <whistler_wmz@users.sf.net>.
// Copyright (c) 2011-2022, SDLPAL development team.
// All rights reserved.
//
// This file is part of SDLPAL.
//
// SDLPAL is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License, version 3
// as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#include "palcommon.h"
#include "global.h"
#include "palcfg.h"
PAL_FORCE_INLINE
BYTE
PAL_CalcShadowColor(
BYTE bSourceColor
)
{
return ((bSourceColor&0xF0)|((bSourceColor&0x0F)>>1));
}
INT
PAL_RLEBlitToSurface(
LPCBITMAPRLE lpBitmapRLE,
SDL_Surface *lpDstSurface,
PAL_POS pos
)
{
return PAL_RLEBlitToSurfaceWithShadow ( lpBitmapRLE, lpDstSurface, pos, FALSE );
}
INT
PAL_RLEBlitToSurfaceWithShadow(
LPCBITMAPRLE lpBitmapRLE,
SDL_Surface *lpDstSurface,
PAL_POS pos,
BOOL bShadow
)
/*++
Purpose:
Blit an RLE-compressed bitmap to an SDL surface.
NOTE: Assume the surface is already locked, and the surface is a 8-bit one.
Parameters:
[IN] lpBitmapRLE - pointer to the RLE-compressed bitmap to be decoded.
[OUT] lpDstSurface - pointer to the destination SDL surface.
[IN] pos - position of the destination area.
[IN] bShadow - flag to mention whether blit source color or just shadow.
Return value:
0 = success, -1 = error.
--*/
{
UINT i, j, k, sx;
INT x, y;
UINT uiLen = 0;
UINT uiWidth = 0;
UINT uiHeight = 0;
UINT uiSrcX = 0;
BYTE T;
INT dx = PAL_X(pos);
INT dy = PAL_Y(pos);
LPBYTE p;
//
// Check for NULL pointer.
//
if (lpBitmapRLE == NULL || lpDstSurface == NULL)
{
return -1;
}
//
// Skip the 0x00000002 in the file header.
//
if (lpBitmapRLE[0] == 0x02 && lpBitmapRLE[1] == 0x00 &&
lpBitmapRLE[2] == 0x00 && lpBitmapRLE[3] == 0x00)
{
lpBitmapRLE += 4;
}
//
// Get the width and height of the bitmap.
//
uiWidth = lpBitmapRLE[0] | (lpBitmapRLE[1] << 8);
uiHeight = lpBitmapRLE[2] | (lpBitmapRLE[3] << 8);
//
// Check whether bitmap intersects the surface.
//
if (uiWidth + dx <= 0 || dx >= lpDstSurface->w ||
uiHeight + dy <= 0 || dy >= lpDstSurface->h)
{
goto end;
}
//
// Calculate the total length of the bitmap.
// The bitmap is 8-bpp, each pixel will use 1 byte.
//
uiLen = uiWidth * uiHeight;
//
// Start decoding and blitting the bitmap.
//
lpBitmapRLE += 4;
for (i = 0; i < uiLen;)
{
T = *lpBitmapRLE++;
if ((T & 0x80) && T <= 0x80 + uiWidth)
{
i += T - 0x80;
uiSrcX += T - 0x80;
if (uiSrcX >= uiWidth)
{
uiSrcX -= uiWidth;
dy++;
}
}
else
{
//
// Prepare coordinates.
//
j = 0;
sx = uiSrcX;
x = dx + uiSrcX;
y = dy;
//
// Skip the points which are out of the surface.
//
if (y < 0)
{
j += -y * uiWidth;
y = 0;
}
else if (y >= lpDstSurface->h)
{
goto end; // No more pixels needed, break out
}
while (j < T)
{
//
// Skip the points which are out of the surface.
//
if (x < 0)
{
j += -x;
if (j >= T) break;
sx += -x;
x = 0;
}
else if (x >= lpDstSurface->w)
{
j += uiWidth - sx;
x -= sx;
sx = 0;
y++;
if (y >= lpDstSurface->h)
{
goto end; // No more pixels needed, break out
}
continue;
}
//
// Put the pixels in row onto the surface
//
k = T - j;
if (lpDstSurface->w - x < k) k = lpDstSurface->w - x;
if (uiWidth - sx < k) k = uiWidth - sx;
sx += k;
p = ((LPBYTE)lpDstSurface->pixels) + y * lpDstSurface->pitch;
if(bShadow)
{
j += k;
for (; k != 0; k--)
{
p[x] = PAL_CalcShadowColor(p[x]);
x++;
}
}
else
{
for (; k != 0; k--)
{
p[x] = lpBitmapRLE[j];
j++;
x++;
}
}
if (sx >= uiWidth)
{
sx -= uiWidth;
x -= uiWidth;
y++;
if (y >= lpDstSurface->h)
{
goto end; // No more pixels needed, break out
}
}
}
lpBitmapRLE += T;
i += T;
uiSrcX += T;
while (uiSrcX >= uiWidth)
{
uiSrcX -= uiWidth;
dy++;
}
}
}
end:
//
// Success
//
return 0;
}
INT
PAL_RLEBlitWithColorShift(
LPCBITMAPRLE lpBitmapRLE,
SDL_Surface *lpDstSurface,
PAL_POS pos,
INT iColorShift
)
/*++
Purpose:
Blit an RLE-compressed bitmap to an SDL surface.
NOTE: Assume the surface is already locked, and the surface is a 8-bit one.
Parameters:
[IN] lpBitmapRLE - pointer to the RLE-compressed bitmap to be decoded.
[OUT] lpDstSurface - pointer to the destination SDL surface.
[IN] pos - position of the destination area.
[IN] iColorShift - shift the color by this value.
Return value:
0 = success, -1 = error.
--*/
{
UINT i, j, k, sx;
INT x, y;
UINT uiLen = 0;
UINT uiWidth = 0;
UINT uiHeight = 0;
UINT uiSrcX = 0;
BYTE T, b;
INT dx = PAL_X(pos);
INT dy = PAL_Y(pos);
LPBYTE p;
//
// Check for NULL pointer.
//
if (lpBitmapRLE == NULL || lpDstSurface == NULL)
{
return -1;
}
//
// Skip the 0x00000002 in the file header.
//
if (lpBitmapRLE[0] == 0x02 && lpBitmapRLE[1] == 0x00 &&
lpBitmapRLE[2] == 0x00 && lpBitmapRLE[3] == 0x00)
{
lpBitmapRLE += 4;
}
//
// Get the width and height of the bitmap.
//
uiWidth = lpBitmapRLE[0] | (lpBitmapRLE[1] << 8);
uiHeight = lpBitmapRLE[2] | (lpBitmapRLE[3] << 8);
//
// Check whether bitmap intersects the surface.
//
if (uiWidth + dx <= 0 || dx >= lpDstSurface->w ||
uiHeight + dy <= 0 || dy >= lpDstSurface->h)
{
goto end;
}
//
// Calculate the total length of the bitmap.
// The bitmap is 8-bpp, each pixel will use 1 byte.
//
uiLen = uiWidth * uiHeight;
//
// Start decoding and blitting the bitmap.
//
lpBitmapRLE += 4;
for (i = 0; i < uiLen;)
{
T = *lpBitmapRLE++;
if ((T & 0x80) && T <= 0x80 + uiWidth)
{
i += T - 0x80;
uiSrcX += T - 0x80;
if (uiSrcX >= uiWidth)
{
uiSrcX -= uiWidth;
dy++;
}
}
else
{
//
// Prepare coordinates.
//
j = 0;
sx = uiSrcX;
x = dx + uiSrcX;
y = dy;
//
// Skip the points which are out of the surface.
//
if (y < 0)
{
j += -y * uiWidth;
y = 0;
}
else if (y >= lpDstSurface->h)
{
goto end; // No more pixels needed, break out
}
while (j < T)
{
//
// Skip the points which are out of the surface.
//
if (x < 0)
{
j += -x;
if (j >= T) break;
sx += -x;
x = 0;
}
else if (x >= lpDstSurface->w)
{
j += uiWidth - sx;
x -= sx;
sx = 0;
y++;
if (y >= lpDstSurface->h)
{
goto end; // No more pixels needed, break out
}
continue;
}
//
// Put the pixels in row onto the surface
//
k = T - j;
if (lpDstSurface->w - x < k) k = lpDstSurface->w - x;
if (uiWidth - sx < k) k = uiWidth - sx;
sx += k;
p = ((LPBYTE)lpDstSurface->pixels) + y * lpDstSurface->pitch;
for (; k != 0; k--)
{
b = (lpBitmapRLE[j] & 0x0F);
if ((INT)b + iColorShift > 0x0F)
{
b = 0x0F;
}
else if ((INT)b + iColorShift < 0)
{
b = 0;
}
else
{
b += iColorShift;
}
p[x] = (b | (lpBitmapRLE[j] & 0xF0));
j++;
x++;
}
if (sx >= uiWidth)
{
sx -= uiWidth;
x -= uiWidth;
y++;
if (y >= lpDstSurface->h)
{
goto end; // No more pixels needed, break out
}
}
}
lpBitmapRLE += T;
i += T;
uiSrcX += T;
while (uiSrcX >= uiWidth)
{
uiSrcX -= uiWidth;
dy++;
}
}
}
end:
//
// Success
//
return 0;
}
INT
PAL_RLEBlitMonoColor(
LPCBITMAPRLE lpBitmapRLE,
SDL_Surface *lpDstSurface,
PAL_POS pos,
BYTE bColor,
INT iColorShift
)
/*++
Purpose:
Blit an RLE-compressed bitmap to an SDL surface in mono-color form.
NOTE: Assume the surface is already locked, and the surface is a 8-bit one.
Parameters:
[IN] lpBitmapRLE - pointer to the RLE-compressed bitmap to be decoded.
[OUT] lpDstSurface - pointer to the destination SDL surface.
[IN] pos - position of the destination area.
[IN] bColor - the color to be used while drawing.
[IN] iColorShift - shift the color by this value.
Return value:
0 = success, -1 = error.
--*/
{
UINT i, j, k, sx;
INT x, y;
UINT uiLen = 0;
UINT uiWidth = 0;
UINT uiHeight = 0;
UINT uiSrcX = 0;
BYTE T, b;
INT dx = PAL_X(pos);
INT dy = PAL_Y(pos);
LPBYTE p;
//
// Check for NULL pointer.
//
if (lpBitmapRLE == NULL || lpDstSurface == NULL)
{
return -1;
}
//
// Skip the 0x00000002 in the file header.
//
if (lpBitmapRLE[0] == 0x02 && lpBitmapRLE[1] == 0x00 &&
lpBitmapRLE[2] == 0x00 && lpBitmapRLE[3] == 0x00)
{
lpBitmapRLE += 4;
}
//
// Get the width and height of the bitmap.
//
uiWidth = lpBitmapRLE[0] | (lpBitmapRLE[1] << 8);
uiHeight = lpBitmapRLE[2] | (lpBitmapRLE[3] << 8);
//
// Check whether bitmap intersects the surface.
//
if (uiWidth + dx <= 0 || dx >= lpDstSurface->w ||
uiHeight + dy <= 0 || dy >= lpDstSurface->h)
{
goto end;
}
//
// Calculate the total length of the bitmap.
// The bitmap is 8-bpp, each pixel will use 1 byte.
//
uiLen = uiWidth * uiHeight;
//
// Start decoding and blitting the bitmap.
//
lpBitmapRLE += 4;
bColor &= 0xF0;
for (i = 0; i < uiLen;)
{
T = *lpBitmapRLE++;
if ((T & 0x80) && T <= 0x80 + uiWidth)
{
i += T - 0x80;
uiSrcX += T - 0x80;
if (uiSrcX >= uiWidth)
{
uiSrcX -= uiWidth;
dy++;
}
}
else
{
//
// Prepare coordinates.
//
j = 0;
sx = uiSrcX;
x = dx + uiSrcX;
y = dy;
//
// Skip the points which are out of the surface.
//
if (y < 0)
{
j += -y * uiWidth;
y = 0;
}
else if (y >= lpDstSurface->h)
{
goto end; // No more pixels needed, break out
}
while (j < T)
{
//
// Skip the points which are out of the surface.
//
if (x < 0)
{
j += -x;
if (j >= T) break;
sx += -x;
x = 0;
}
else if (x >= lpDstSurface->w)
{
j += uiWidth - sx;
x -= sx;
sx = 0;
y++;
if (y >= lpDstSurface->h)
{
goto end; // No more pixels needed, break out
}
continue;
}
//
// Put the pixels in row onto the surface
//
k = T - j;
if (lpDstSurface->w - x < k) k = lpDstSurface->w - x;
if (uiWidth - sx < k) k = uiWidth - sx;
sx += k;
p = ((LPBYTE)lpDstSurface->pixels) + y * lpDstSurface->pitch;
for (; k != 0; k--)
{
b = lpBitmapRLE[j] & 0x0F;
if ((INT)b + iColorShift > 0x0F)
{
b = 0x0F;
}
else if ((INT)b + iColorShift < 0)
{
b = 0;
}
else
{
b += iColorShift;
}
p[x] = (b | bColor);
j++;
x++;
}
if (sx >= uiWidth)
{
sx -= uiWidth;
x -= uiWidth;
y++;
if (y >= lpDstSurface->h)
{
goto end; // No more pixels needed, break out
}
}
}
lpBitmapRLE += T;
i += T;
uiSrcX += T;
while (uiSrcX >= uiWidth)
{
uiSrcX -= uiWidth;
dy++;
}
}
}
end:
//
// Success
//
return 0;
}
INT
PAL_FBPBlitToSurface(
LPBYTE lpBitmapFBP,
SDL_Surface *lpDstSurface
)
/*++
Purpose:
Blit an uncompressed bitmap in FBP.MKF to an SDL surface.
NOTE: Assume the surface is already locked, and the surface is a 8-bit 320x200 one.
Parameters:
[IN] lpBitmapFBP - pointer to the RLE-compressed bitmap to be decoded.
[OUT] lpDstSurface - pointer to the destination SDL surface.
Return value:
0 = success, -1 = error.
--*/
{
int x, y;
LPBYTE p;
if (lpBitmapFBP == NULL || lpDstSurface == NULL ||
lpDstSurface->w != 320 || lpDstSurface->h != 200)
{
return -1;
}
//
// simply copy everything to the surface
//
for (y = 0; y < 200; y++)
{
p = (LPBYTE)(lpDstSurface->pixels) + y * lpDstSurface->pitch;
for (x = 0; x < 320; x++)
{
*(p++) = *(lpBitmapFBP++);
}
}
return 0;
}
INT
PAL_RLEGetWidth(
LPCBITMAPRLE lpBitmapRLE
)
/*++
Purpose:
Get the width of an RLE-compressed bitmap.
Parameters:
[IN] lpBitmapRLE - pointer to an RLE-compressed bitmap.
Return value:
Integer value which indicates the height of the bitmap.
--*/
{
if (lpBitmapRLE == NULL)
{
return 0;
}
//
// Skip the 0x00000002 in the file header.
//
if (lpBitmapRLE[0] == 0x02 && lpBitmapRLE[1] == 0x00 &&
lpBitmapRLE[2] == 0x00 && lpBitmapRLE[3] == 0x00)
{
lpBitmapRLE += 4;
}
//
// Return the width of the bitmap.
//
return lpBitmapRLE[0] | (lpBitmapRLE[1] << 8);
}
INT
PAL_RLEGetHeight(
LPCBITMAPRLE lpBitmapRLE
)
/*++
Purpose:
Get the height of an RLE-compressed bitmap.
Parameters:
[IN] lpBitmapRLE - pointer of an RLE-compressed bitmap.
Return value:
Integer value which indicates the height of the bitmap.
--*/
{
if (lpBitmapRLE == NULL)
{
return 0;
}
//
// Skip the 0x00000002 in the file header.
//
if (lpBitmapRLE[0] == 0x02 && lpBitmapRLE[1] == 0x00 &&
lpBitmapRLE[2] == 0x00 && lpBitmapRLE[3] == 0x00)
{
lpBitmapRLE += 4;
}
//
// Return the height of the bitmap.
//
return lpBitmapRLE[2] | (lpBitmapRLE[3] << 8);
}
WORD
PAL_SpriteGetNumFrames(
LPCSPRITE lpSprite
)
/*++
Purpose:
Get the total number of frames of a sprite.
Parameters:
[IN] lpSprite - pointer to the sprite.
Return value:
Number of frames of the sprite.
--*/
{
if (lpSprite == NULL)
{
return 0;
}
return (lpSprite[0] | (lpSprite[1] << 8)) - 1;
}
LPCBITMAPRLE
PAL_SpriteGetFrame(
LPCSPRITE lpSprite,
INT iFrameNum
)
/*++
Purpose:
Get the pointer to the specified frame from a sprite.
Parameters:
[IN] lpSprite - pointer to the sprite.
[IN] iFrameNum - number of the frame.
Return value:
Pointer to the specified frame. NULL if the frame does not exist.
--*/
{
int imagecount, offset;
if (lpSprite == NULL)
{
return NULL;
}
//
// Hack for broken sprites like the Bloody-Mouth Bug
//
// imagecount = (lpSprite[0] | (lpSprite[1] << 8)) - 1;
imagecount = (lpSprite[0] | (lpSprite[1] << 8));
if (iFrameNum < 0 || iFrameNum >= imagecount)
{
//
// The frame does not exist
//
return NULL;
}
//
// Get the offset of the frame
//
iFrameNum <<= 1;
offset = ((lpSprite[iFrameNum] | (lpSprite[iFrameNum + 1] << 8)) << 1);
if (offset == 0x18444) offset = (WORD)offset;
return &lpSprite[offset];
}
INT
PAL_MKFGetChunkCount(
FILE *fp
)
/*++
Purpose:
Get the number of chunks in an MKF archive.
Parameters:
[IN] fp - pointer to an fopen'ed MKF file.
Return value:
Integer value which indicates the number of chunks in the specified MKF file.
--*/
{
INT iNumChunk;
if (fp == NULL)
{
return 0;
}
fseek(fp, 0, SEEK_SET);
if (fread(&iNumChunk, sizeof(INT), 1, fp) == 1)
return (SDL_SwapLE32(iNumChunk) - 4) >> 2;
else
return 0;
}
INT
PAL_MKFGetChunkSize(
UINT uiChunkNum,
FILE *fp
)
/*++
Purpose:
Get the size of a chunk in an MKF archive.
Parameters:
[IN] uiChunkNum - the number of the chunk in the MKF archive.
[IN] fp - pointer to the fopen'ed MKF file.
Return value:
Integer value which indicates the size of the chunk.
-1 if the chunk does not exist.
--*/
{
UINT uiOffset = 0;
UINT uiNextOffset = 0;
UINT uiChunkCount = 0;
//
// Get the total number of chunks.
//
uiChunkCount = PAL_MKFGetChunkCount(fp);
if (uiChunkNum >= uiChunkCount)
{
return -1;
}
//
// Get the offset of the specified chunk and the next chunk.
//
fseek(fp, 4 * uiChunkNum, SEEK_SET);
PAL_fread(&uiOffset, sizeof(UINT), 1, fp);
PAL_fread(&uiNextOffset, sizeof(UINT), 1, fp);
uiOffset = SDL_SwapLE32(uiOffset);
uiNextOffset = SDL_SwapLE32(uiNextOffset);
//
// Return the length of the chunk.
//
return uiNextOffset - uiOffset;
}
INT
PAL_MKFReadChunk(
LPBYTE lpBuffer,
UINT uiBufferSize,
UINT uiChunkNum,
FILE *fp
)
/*++
Purpose:
Read a chunk from an MKF archive into lpBuffer.
Parameters:
[OUT] lpBuffer - pointer to the destination buffer.
[IN] uiBufferSize - size of the destination buffer.
[IN] uiChunkNum - the number of the chunk in the MKF archive to read.
[IN] fp - pointer to the fopen'ed MKF file.
Return value:
Integer value which indicates the size of the chunk.
-1 if there are error in parameters.
-2 if buffer size is not enough.
--*/
{
UINT uiOffset = 0;
UINT uiNextOffset = 0;
UINT uiChunkCount;
UINT uiChunkLen;
if (lpBuffer == NULL || fp == NULL || uiBufferSize == 0)
{
return -1;
}
//
// Get the total number of chunks.
//
uiChunkCount = PAL_MKFGetChunkCount(fp);
if (uiChunkNum >= uiChunkCount)
{
return -1;
}
//
// Get the offset of the chunk.
//
fseek(fp, 4 * uiChunkNum, SEEK_SET);
PAL_fread(&uiOffset, 4, 1, fp);
PAL_fread(&uiNextOffset, 4, 1, fp);
uiOffset = SDL_SwapLE32(uiOffset);
uiNextOffset = SDL_SwapLE32(uiNextOffset);
//
// Get the length of the chunk.
//
uiChunkLen = uiNextOffset - uiOffset;
if (uiChunkLen > uiBufferSize)
{
return -2;
}
if (uiChunkLen != 0)
{
fseek(fp, uiOffset, SEEK_SET);
return (int)fread(lpBuffer, 1, uiChunkLen, fp);
}
return -1;
}
INT
PAL_MKFGetDecompressedSize(
UINT uiChunkNum,
FILE *fp
)
/*++
Purpose:
Get the decompressed size of a compressed chunk in an MKF archive.
Parameters:
[IN] uiChunkNum - the number of the chunk in the MKF archive.
[IN] fp - pointer to the fopen'ed MKF file.
Return value:
Integer value which indicates the size of the chunk.
-1 if the chunk does not exist.
--*/
{
DWORD buf[2];
UINT uiOffset;
UINT uiChunkCount;
if (fp == NULL)
{
return -1;
}
//
// Get the total number of chunks.
//
uiChunkCount = PAL_MKFGetChunkCount(fp);
if (uiChunkNum >= uiChunkCount)
{
return -1;
}
//
// Get the offset of the chunk.
//
fseek(fp, 4 * uiChunkNum, SEEK_SET);
PAL_fread(&uiOffset, 4, 1, fp);
uiOffset = SDL_SwapLE32(uiOffset);
//
// Read the header.
//
fseek(fp, uiOffset, SEEK_SET);
if (gConfig.fIsWIN95)
{
PAL_fread(buf, sizeof(DWORD), 1, fp);
buf[0] = SDL_SwapLE32(buf[0]);
return (INT)buf[0];
}
else
{
PAL_fread(buf, sizeof(DWORD), 2, fp);
buf[0] = SDL_SwapLE32(buf[0]);
buf[1] = SDL_SwapLE32(buf[1]);
return (buf[0] != 0x315f4a59) ? -1 : (INT)buf[1];
}
}
INT
PAL_MKFDecompressChunk(
LPBYTE lpBuffer,
UINT uiBufferSize,
UINT uiChunkNum,
FILE *fp
)
/*++
Purpose:
Decompress a compressed chunk from an MKF archive into lpBuffer.
Parameters:
[OUT] lpBuffer - pointer to the destination buffer.
[IN] uiBufferSize - size of the destination buffer.
[IN] uiChunkNum - the number of the chunk in the MKF archive to read.
[IN] fp - pointer to the fopen'ed MKF file.
Return value:
Integer value which indicates the size of the chunk.
-1 if there are error in parameters, or buffer size is not enough.
-3 if cannot allocate memory for decompression.
--*/
{
LPBYTE buf;
int len;
len = PAL_MKFGetChunkSize(uiChunkNum, fp);
if (len <= 0)
{
return len;
}
buf = (LPBYTE)malloc(len);
if (buf == NULL)
{
return -3;
}
PAL_MKFReadChunk(buf, len, uiChunkNum, fp);
len = Decompress(buf, lpBuffer, uiBufferSize);
free(buf);
return len;
}
1
https://gitee.com/vsf-linux/sdlpal.git
git@gitee.com:vsf-linux/sdlpal.git
vsf-linux
sdlpal
sdlpal
master

搜索帮助