From: ShadowFlare Date: Sat, 9 Sep 2006 00:40:32 +0000 (+0000) Subject: GRP export works, but output is incorrect. X-Git-Url: https://sfsrealm.hopto.org/projects/gitweb.cgi?p=grpapi.git;a=commitdiff_plain;h=c483a082ba5c516a59a3ae91e3efee095f0f59a3 GRP export works, but output is incorrect. --- diff --git a/drawgrp/drawgrp.cpp b/drawgrp/drawgrp.cpp index d342525..9b5e286 100644 --- a/drawgrp/drawgrp.cpp +++ b/drawgrp/drawgrp.cpp @@ -1,6 +1,8 @@ // drawgrp.cpp : Defines the entry point for the console application. // +#define _CRT_RAND_S +#include #include "stdafx.h" @@ -20,17 +22,24 @@ int main(int argc, char* argv[]) struct BufferInfo { WORD nWidth; WORD nHeight; - LPDWORD pBuffer; + signed short *pBuffer; + WORD nFrame; }; COLORREF WINAPI ReadPixelFromBuffer(BufferInfo *pBI, int X, int Y) { - return pBI->pBuffer[(Y * pBI->nWidth) + X]; + if (pBI->nFrame == 0xFFFF) + return pBI->pBuffer[(Y * pBI->nWidth) + X]; + else + return pBI->pBuffer[(pBI->nFrame * pBI->nWidth * pBI->nHeight) + (Y * pBI->nWidth) + X]; } void WINAPI WritePixelToBuffer(BufferInfo *pBI, int X, int Y, COLORREF clrColor) { - pBI->pBuffer[(Y * pBI->nWidth) + X] = clrColor; + if (pBI->nFrame == 0xFFFF) + pBI->pBuffer[(Y * pBI->nWidth) + X] = (signed short)clrColor; + else + pBI->pBuffer[(pBI->nFrame * pBI->nWidth * pBI->nHeight) + (Y * pBI->nWidth) + X] = (signed short)clrColor; } int main(int argc, char* argv[]) @@ -49,11 +58,9 @@ int main(int argc, char* argv[]) memcpy(buffer,"Patch_rt.mpq",13); SFileOpenArchive(buffer,3000,0,&hMPQ3); } - SetFunctionGetPixel((GETPIXELPROC)ReadPixelFromBuffer); - SetFunctionSetPixel((SETPIXELPROC)WritePixelToBuffer); BufferInfo BI; LoadPalette("tileset\\Jungle.wpe",dwPalette); - HANDLE hGrp; + HANDLE hGrp, hGrp2; if (argc>1) hGrp = LoadGrp(argv[1]); else @@ -63,32 +70,58 @@ int main(int argc, char* argv[]) if (GetGrpInfo(hGrp,&GrpInfo)==0) {GrpInfo.nFrames=0;GrpInfo.wMaxWidth=0;GrpInfo.wMaxHeight=0;} BI.nWidth = GrpInfo.wMaxWidth; BI.nHeight = GrpInfo.wMaxHeight; - BI.pBuffer = (DWORD *)malloc(BI.nWidth * BI.nHeight * sizeof(DWORD)); + BI.pBuffer = (signed short *)malloc(GrpInfo.nFrames * BI.nWidth * BI.nHeight * sizeof(short)); WORD i,x,y; - DWORD j; - for (i = 0; i < BI.nWidth * BI.nHeight; i++) - BI.pBuffer[i] = 0xFFFFFFFF; + DWORD j, nGrpSize; + unsigned int u,v; + memset(BI.pBuffer, 0xFF, GrpInfo.nFrames * BI.nWidth * BI.nHeight * sizeof(short)); //for (DWORD j=0;j<16;j++){ /*for (WORD i=0;inFrames; FRAMEHEADER *GrpFrame = &((FRAMEHEADER *)(((char *)GrpFile)+6))[nFrame]; @@ -430,3 +437,153 @@ void __inline SetPix(HDC hDC, int X, int Y, COLORREF clrColor, DWORD *dwPalette, } MySetPixel(hDC,X,Y,clrColor); } + +HANDLE GRPAPI WINAPI CreateGrp(signed short *lpImageData, WORD nFrames, WORD wMaxWidth, WORD wMaxHeight, DWORD *nGrpSize) +{ + GRPHEADER GrpHeader; + FRAMEHEADER *lpFrameHeaders; + FRAMEDATA *lpFrameData; + LPBYTE lpGrpData; + int i, x, y, x1, x2, y1, y2; + + if (!lpImageData || !nGrpSize) return (HANDLE)-1; + + GrpHeader.nFrames = nFrames; + GrpHeader.wMaxWidth = wMaxWidth; + GrpHeader.wMaxHeight = wMaxHeight; + lpFrameHeaders = (FRAMEHEADER *)malloc((nFrames + 1) * sizeof(FRAMEHEADER)); + lpFrameData = (FRAMEDATA *)malloc(nFrames * sizeof(FRAMEDATA)); + + for (i = 0; i <= nFrames; i++) { + if (i == 0) { + lpFrameHeaders[i].Offset = sizeof(GRPHEADER) + nFrames * sizeof(FRAMEHEADER); + } + else { + y = lpFrameHeaders[i-1].Height; + if (y > 0) { + y--; + lpFrameHeaders[i].Offset = lpFrameHeaders[i-1].Offset + lpFrameData[i-1].lpRowOffsets[y] + lpFrameData[i-1].lpRowSizes[y]; + } + else { + lpFrameHeaders[i].Offset = lpFrameHeaders[i-1].Offset; + } + } + if (i == nFrames) continue; + + // Scan frame to find dimensions of used part + x1 = y1 = 0x10000; + x2 = y2 = -1; + for (y = 0; y < wMaxHeight; y++) { + for (x = 0; x < wMaxWidth; x++) { + if (lpImageData[i * wMaxWidth * wMaxHeight + y * wMaxWidth + x] >= 0) { + if (x < x1) x1 = x; + if (x > x2) x2 = x; + if (y < y1) y1 = y; + if (y > y2) y2 = y; + } + } + } + lpFrameHeaders[i].Left = x1; + lpFrameHeaders[i].Top = y1; + lpFrameHeaders[i].Width = x2 - x1 + 1; + lpFrameHeaders[i].Height = y2 - y1 + 1; + + EncodeFrameData(lpImageData, i, &GrpHeader, &lpFrameHeaders[i], &lpFrameData[i]); + } + + lpGrpData = (LPBYTE)malloc(lpFrameHeaders[nFrames].Offset); + + // Write completed GRP to buffer + memcpy(lpGrpData, &GrpHeader, sizeof(GRPHEADER)); + memcpy(lpGrpData + sizeof(GRPHEADER), lpFrameHeaders, nFrames * sizeof(FRAMEHEADER)); + + for (i = 0; i < nFrames; i++) { + memcpy(lpGrpData + lpFrameHeaders[i].Offset, lpFrameData[i].lpRowOffsets, lpFrameHeaders[i].Height * sizeof(WORD)); + + for (y = 0; y < lpFrameHeaders[i].Height; y++) { + memcpy(lpGrpData + lpFrameHeaders[i].Offset + lpFrameData[i].lpRowOffsets[y], lpFrameData[i].lpRowData[y], lpFrameData[i].lpRowSizes[y]); + free(lpFrameData[i].lpRowData[y]); + } + + free(lpFrameData[i].lpRowOffsets); + free(lpFrameData[i].lpRowSizes); + free(lpFrameData[i].lpRowData); + } + + *nGrpSize = lpFrameHeaders[nFrames].Offset; + free(lpFrameHeaders); + free(lpFrameData); + + return (HANDLE)lpGrpData; +} + +void EncodeFrameData(signed short *lpImageData, WORD nFrame, GRPHEADER *lpGrpHeader, FRAMEHEADER *lpFrameHeader, FRAMEDATA *lpFrameData) +{ + int x, y, i, nBufPos; + LPBYTE lpRowBuf; + + lpFrameData->lpRowOffsets = (WORD *)malloc(lpFrameHeader->Height * sizeof(WORD)); + lpFrameData->lpRowSizes = (WORD *)malloc(lpFrameHeader->Height * sizeof(WORD)); + lpFrameData->lpRowData = (LPBYTE *)malloc(lpFrameHeader->Height * sizeof(LPBYTE)); + lpRowBuf = (LPBYTE)malloc(lpFrameHeader->Width * 2); + + for (y = 0; y < lpFrameHeader->Height; y++) { + i = nFrame * lpGrpHeader->wMaxWidth * lpGrpHeader->wMaxHeight + (lpFrameHeader->Top + y) * lpGrpHeader->wMaxWidth; + nBufPos = 0; + if (lpFrameHeader->Width > 1) { + for (x = lpFrameHeader->Left; x < lpFrameHeader->Left + lpFrameHeader->Width - 1; x++) { + if (lpImageData[i+x] < 0) { + lpRowBuf[nBufPos] = 0x80; + for (; lpImageData[i+x] < 0 && x < lpFrameHeader->Left + lpFrameHeader->Width; x++) { + lpRowBuf[nBufPos]++; + } + x--; + nBufPos++; + } + else if (lpImageData[i+x] == lpImageData[i+x+1]) { + lpRowBuf[nBufPos] = 0x41; + lpRowBuf[nBufPos+1] = (BYTE)lpImageData[i+x]; + for (; lpImageData[i+x] == lpImageData[i+x+1] && x < lpFrameHeader->Left + lpFrameHeader->Width - 1; x++) { + lpRowBuf[nBufPos]++; + } + nBufPos += 2; + } + else { + lpRowBuf[nBufPos] = 1; + lpRowBuf[nBufPos+1] = (BYTE)lpImageData[i+x]; + x++; + for (; lpImageData[i+x] != lpImageData[i+x+1] && x < lpFrameHeader->Left + lpFrameHeader->Width - 1; x++) { + lpRowBuf[nBufPos]++; + lpRowBuf[nBufPos+lpRowBuf[nBufPos]] = (BYTE)lpImageData[i+x]; + } + x--; + nBufPos += 1 + lpRowBuf[nBufPos]; + } + } + } + else if (lpFrameHeader->Width == 1){ + if (lpImageData[i] < 0) { + lpRowBuf[nBufPos] = 0x81; + nBufPos++; + } + else { + lpRowBuf[nBufPos] = 1; + lpRowBuf[nBufPos+1] = (BYTE)lpImageData[i+1]; + nBufPos += 2; + } + } + + if (y == 0) { + lpFrameData->lpRowOffsets[y] = lpFrameHeader->Height * sizeof(WORD); + } + else { + lpFrameData->lpRowOffsets[y] = lpFrameData->lpRowOffsets[y-1] + lpFrameData->lpRowSizes[y-1]; + } + + lpFrameData->lpRowSizes[y] = nBufPos; + lpFrameData->lpRowData[y] = (LPBYTE)malloc(nBufPos); + memcpy(lpFrameData->lpRowData[y], lpRowBuf, nBufPos); + } + + free(lpRowBuf); +} diff --git a/grpapi/grpapi.def b/grpapi/grpapi.def index 131acb6..c791491 100644 --- a/grpapi/grpapi.def +++ b/grpapi/grpapi.def @@ -9,3 +9,4 @@ EXPORTS SetFunctionGetPixel @8 SetFunctionSetPixel @9 SetMpqDll @10 + CreateGrp @11 diff --git a/grpapi/grpapi.h b/grpapi/grpapi.h index 8a61f43..73070c8 100644 --- a/grpapi/grpapi.h +++ b/grpapi/grpapi.h @@ -63,6 +63,8 @@ BOOL GRPAPI WINAPI DestroyGrp(HANDLE hGrp); BOOL GRPAPI WINAPI DrawGrp(HANDLE hGrp, HDC hdcDest, int nXDest, int nYDest, WORD nFrame, DWORD *dwPalette, DWORD dwFlags, DWORD dwAlpha); BOOL GRPAPI WINAPI GetGrpInfo(HANDLE hGrp, GRPHEADER *GrpInfo); +HANDLE GRPAPI WINAPI CreateGrp(signed short *lpImageData, WORD nFrames, WORD wMaxWidth, WORD wMaxHeight, DWORD *nGrpSize); + typedef COLORREF (WINAPI* GETPIXELPROC)( HDC hDC, // same value as hdcDest from DrawGrp, // does not need to be used as an HDC, diff --git a/grpapi/grpapi_no-lib.cpp b/grpapi/grpapi_no-lib.cpp index 909d1c5..0b056ce 100644 --- a/grpapi/grpapi_no-lib.cpp +++ b/grpapi/grpapi_no-lib.cpp @@ -12,6 +12,7 @@ funcLoadGrp LoadGrp = 0; funcDestroyGrp DestroyGrp = 0; funcDrawGrp DrawGrp = 0; funcGetGrpInfo GetGrpInfo = 0; +funcCreateGrp CreateGrp = 0; funcSetFunctionGetPixel SetFunctionGetPixel = 0; funcSetFunctionSetPixel SetFunctionSetPixel = 0; funcSetMpqDll SetMpqDll = 0; @@ -29,6 +30,7 @@ GRPAPIMODULE::GRPAPIMODULE() DestroyGrp = (funcDestroyGrp)GetProcAddress(hGrpApi,"DestroyGrp"); DrawGrp = (funcDrawGrp)GetProcAddress(hGrpApi,"DrawGrp"); GetGrpInfo = (funcGetGrpInfo)GetProcAddress(hGrpApi,"GetGrpInfo"); + CreateGrp = (funcCreateGrp)GetProcAddress(hGrpApi,"CreateGrp"); SetFunctionGetPixel = (funcSetFunctionGetPixel)GetProcAddress(hGrpApi,"SetFunctionGetPixel"); SetFunctionSetPixel = (funcSetFunctionSetPixel)GetProcAddress(hGrpApi,"SetFunctionSetPixel"); SetMpqDll = (funcSetMpqDll)GetProcAddress(hGrpApi,"SetMpqDll"); @@ -44,6 +46,7 @@ GRPAPIMODULE::~GRPAPIMODULE() DestroyGrp = 0; DrawGrp = 0; GetGrpInfo = 0; + CreateGrp = 0; SetFunctionGetPixel = 0; SetFunctionSetPixel = 0; SetMpqDll = 0; diff --git a/grpapi/grpapi_no-lib.h b/grpapi/grpapi_no-lib.h index ac1b3d6..190beb5 100644 --- a/grpapi/grpapi_no-lib.h +++ b/grpapi/grpapi_no-lib.h @@ -66,6 +66,9 @@ extern funcDestroyGrp DestroyGrp; extern funcDrawGrp DrawGrp; extern funcGetGrpInfo GetGrpInfo; +typedef HANDLE (WINAPI* funcCreateGrp)(signed short *lpImageData, WORD nFrames, WORD wMaxWidth, WORD wMaxHeight, DWORD *nGrpSize); +extern funcCreateGrp CreateGrp; + typedef COLORREF (WINAPI* GETPIXELPROC)( HDC hDC, // same value as hdcDest from DrawGrp, // does not need to be used as an HDC,