diff options
author | Ash Wolf <ninji@wuffs.org> | 2023-06-28 22:22:32 +0100 |
---|---|---|
committer | Ash Wolf <ninji@wuffs.org> | 2023-06-28 22:22:32 +0100 |
commit | c0c336500955a23e344651e5412c9d9d441ef4ee (patch) | |
tree | 790769c748db307cf3314f6e896e2f61c68561a2 /src/T2DLL/T2FireWork.cpp | |
parent | 37e364b2c6cc7487a1c888d256a73e5337bb7189 (diff) | |
download | t2win-c0c336500955a23e344651e5412c9d9d441ef4ee.tar.gz t2win-c0c336500955a23e344651e5412c9d9d441ef4ee.zip |
first pass of T2DLL
Diffstat (limited to '')
-rw-r--r-- | src/T2DLL/T2FireWork.cpp | 348 |
1 files changed, 343 insertions, 5 deletions
diff --git a/src/T2DLL/T2FireWork.cpp b/src/T2DLL/T2FireWork.cpp index abddcf4..38a27a5 100644 --- a/src/T2DLL/T2FireWork.cpp +++ b/src/T2DLL/T2FireWork.cpp @@ -1,28 +1,366 @@ +#include "GlobalFunc.h" +#include "T2BitImage.h" #include "T2FireWork.h" +#include "T2SoundPlayer.h" -T2FireWork::T2FireWork(int, int, CPalette*) { +T2FireWork::T2FireWork(int inWidth, int inHeight, CPalette* inPalette) { + Sounds->AddSound("Firework:Don", SoundPriority_0, 1000, AfxGetResourceHandle()); + + RECT rect; + rect.top = 0; + rect.left = 0; + rect.bottom = inHeight; + rect.right = inWidth; + + mImage = new T2BitImage(rect); + memset(mImage->mData, 0, mImage->mBitmap.header.biSizeImage); +#define ALIGN_ROW_SIZE(s) ((((s) + 3) / 4) * 4) + mRowSize = ALIGN_ROW_SIZE(inWidth); + + SetRect(&mRect, 0, 0, inWidth, inHeight); + + mIsActive = false; + + int i; + for (i = 0; i < 5; i++) { + for (int j = 0; j < 8; j++) { + int r, g, b; + if (i == 0) { + r = ((j + 1) * 255) / 8; + g = ((j + 1) * 255) / 8; + b = ((j + 1) * 100) / 8; + } else if (i == 1) { + r = ((j + 1) * 255) / 8; + g = ((j + 1) * 186) / 8; + b = ((j + 1) * 100) / 8; + } else if (i == 2) { + r = ((j + 1) * 255) / 8; + g = ((j + 1) * 50) / 8; + b = ((j + 1) * 50) / 8; + } else if (i == 3) { + r = ((j + 1) * 80) / 8; + g = ((j + 1) * 80) / 8; + b = ((j + 1) * 255) / 8; + } else if (i == 4) { + r = ((j + 1) * 255) / 8; + g = ((j + 1) * 255) / 8; + b = ((j + 1) * 200) / 8; + } + + mPalettes[i][j] = inPalette->GetNearestPaletteIndex(RGB(r, g, b)); + } + } + + for (i = 0; i < 20; i++) + mUsed[i] = false; } T2FireWork::~T2FireWork() { + delete mImage; + + for (int i = 0; i < 20; i++) { + if (mUsed[i]) + free(mStarInfo[i]); + } } T2BitImage* T2FireWork::GetBitImage() { + return mImage; } void T2FireWork::Start() { + mIsActive = true; } void T2FireWork::Stop() { + mIsActive = false; } -int T2FireWork::IsDisposable() { +BOOL T2FireWork::IsDisposable() { + if (mIsActive) + return false; + + for (int i = 0; i < 20; i++) { + if (mUsed[i]) + return false; + } + + return true; } -int T2FireWork::Idle() { +BOOL T2FireWork::Idle() { + static DWORD lastUpdate; + static DWORD counter; + + BOOL anyChange = false; + DWORD now = GetTickCount(); + int ind, ind2; + + if (mIsActive && lastUpdate != now) { + if ((counter % 35) == 0 || (rand() % 80) == 0) { + for (ind = 0; ind < 20; ind++) { + if (!mUsed[ind]) { +#pragma var_order(var24, var28, var2C, bufferSize, var34, var38) + float var24 = (((rand() % 40) - 20) / 100.0f) + 0.0f; + float var38 = var24; + float var28 = int((var38 * 6.283186) / 0.18) / 4; + int var34 = 1; + + for (float var2C = 0.0f; var2C <= var28; var2C += 1.0f) { +#pragma var_order(var3C, var40, var44) + float var3C = var38 * cos((var2C * 1.5707965) / var28); + float var40 = int((var3C * 6.283186) / 0.095); + + for (float var44 = 0.0f; var44 < var40 || var40 == 0.0f; var44 += 1.0f) { + var34++; + if (var40 == 0.0f) + break; + } + } + +#pragma var_order(var24, var28, var2C, bufferSize, var34, var38) + mUsed[ind] = true; + + int bufferSize = (var34 + 2) * sizeof(FIREWORK_STARINFO); + mStarInfo[ind] = (FIREWORK_STARINFO *) malloc(bufferSize); + memset(mStarInfo[ind], 0, bufferSize); + + mStarInfo[ind]->m0 = (rand() % 200) / 100.0f - 1.0f; + mStarInfo[ind]->m4 = (rand() % 400) / 200.0f + -9.5f - 2.0f; + mStarInfo[ind]->m8 = ((mRect.right / 2) + (rand() % (mRect.right / 3))) - (mRect.right / 6); + mStarInfo[ind]->mC = mRect.bottom; + mStarInfo[ind]->m10 = 0.0f; + mStarInfo[ind]->m14 = 0.01f; + mStarInfo[ind]->m18 = 50.0f; + mStarInfo[ind]->m1C = 15.0f; + mStarInfo[ind]->m24 = var24; + mStarInfo[ind]->mFlags = 0x101; + break; + } + } + } + counter++; + } + + lastUpdate = now; + + for (ind = 0; ind < 20; ind++) { + if (mUsed[ind]) { + FIREWORK_STARINFO *info = mStarInfo[ind]; + BOOL changed = false; + + for (ind2 = 0; info[ind2].mFlags != 0; ind2++) { +#pragma var_order(x, y, star, size, pixel) + FIREWORK_STARINFO *star = info + ind2; + int x, y, pixel, size; + + if (CalcStarData(star, star->m10 - star->m1C, &x, &y, &pixel, &size)) { + PutDot(x, y, size, 0); + changed = true; + } + + if (CalcStarData(star, star->m10, &x, &y, &pixel, &size)) { + PutDot(x, y, size, mPalettes[HIBYTE(pixel)][LOBYTE(pixel)]); + changed = true; + } + + star->m10 += 1.0f; + } + + if (!(info->mFlags & 0x8000) && (info->m10 >= info->m18)) { +#pragma var_order(var64, var68, var6C, var70, var74, origInfo, var7C, var80, var84, var88) + Sounds->Play("Firework:Don", SoundMask_10, SoundFlags_10, NULL, PlayMode_2, 100); + + FIREWORK_STARINFO *origInfo = info; + origInfo->mFlags |= 0x8000; + + unsigned short var88 = 0; + float var74 = 10.0f; + float var64 = 0.0f; + float var6C = rand() % 10 + 25; + float var84 = mStarInfo[ind]->m24; + switch (rand() % 10) { + case 0: + var88 = 8; + break; + case 1: + var88 = 0xC8; + break; + case 2: + var88 = 0x84; + break; + case 3: + var88 = 0x88; + break; + case 4: + var88 = 4; + break; + case 5: + var88 = 2; + break; + case 6: + var88 = 0x10; + break; + case 7: + case 8: + var88 = 0x28; + break; + case 9: + var88 = 0xD0; + break; + } + + float var68 = int((var84 * 6.283186) / 0.18) / 4; + int var80 = 1; + float var7C = mRect.bottom * 0.016; + + for (float var70 = 0.0f; var70 <= var68; var70 += 1.0f) { +#pragma var_order(var8C, var90, var94) + float var8C = var84 * cos((var70 * 1.5707965) / var68); + float var90 = int((var8C * 6.283186) / 0.095); + + for (float var94 = 0.0f; var94 < var90 || var90 == 0.0f; var94 += 1.0f) { +#pragma var_order(var98, var9C, varA0, varA4, varA8, varAC, varB0) + float var98 = (var94 * 6.283186) / ((var90 != 0.0f) ? var90 : 1.0f); + float varA0 = float(cos(var98)) * var8C * var7C; + float varA4 = float(sin(var98)) * var8C * var7C; + int var9C, varA8, varB0, varAC; + CalcStarData(origInfo, origInfo->m10 - 1.0f, &var9C, &varA8, &varB0, &varAC); + + info[var80].m0 = varA0; + info[var80].m4 = varA4; + info[var80].m8 = var9C; + info[var80].mC = varA8; + info[var80].m10 = 0.0f; + info[var80].m14 = var64; + info[var80].m18 = var6C; + info[var80].m1C = var74; + info[var80].mFlags = var88; + var80++; + + if (var90 == 0.0f) + break; + } + } + } + + anyChange |= changed; + + if (!changed) { + free(mStarInfo[ind]); + mUsed[ind] = false; + } + } + } + + return anyChange; } -int T2FireWork::CalcStarData(FIREWORK_STARINFO*, float, int*, int*, int*, int*) { +BOOL T2FireWork::CalcStarData(FIREWORK_STARINFO* inInfo, float inTime, int* outX, int* outY, int* outPixel, int* outSize) { + if (inTime >= 0.0f && inTime < inInfo->m18) { + float blend = 0.01f; + blend = 1.0f - (1.0f / ((inTime / 8.0f) + 1.0f)); + + float mult = inInfo->m0 * 30.0f; + *outX = (mult * blend) + inInfo->m8; + + mult = inInfo->m4 * 30.0f; + *outY = (mult * blend) + inInfo->mC + (inInfo->m14 * inTime * inTime); + + int group = 0; + int color = 7; + + if (inInfo->mFlags & 2) + group = 0; + else if (inInfo->mFlags & 4) + group = 1; + else if (inInfo->mFlags & 8) + group = 2; + else if (inInfo->mFlags & 0x10) + group = 3; + else if (inInfo->mFlags & 1) + group = 4; + + if (inInfo->mFlags & 0x20) { + if ((inInfo->m18 / 2.0f) < inTime) + group++; + } else if (inInfo->mFlags & 0x40) { + if ((inInfo->m18 - 2.0f) < inTime) + group++; + } + + while (group >= 5) + group -= 5; + + if (inInfo->mFlags & 0x100) { + color = (inTime * 10.0f) / inInfo->m18; + if (color >= 8) + color = 7; + } else if (inInfo->mFlags & 0x200) { + if ((inInfo->m18 / 2.0f) < inTime) + color = ((inInfo->m18 - inTime) * 8.0f) / (inInfo->m18 / 2.0f); + if (inTime >= 8.0f) + inTime = 7.0f; + } else { + color = (((inTime * 8.0f) / 2.0f) / inInfo->m18) + 4.0f; + } + + *outPixel = (group << 8) | color; + + if (inInfo->mFlags & 0x40) { + if (inTime > (inInfo->m18 - 2.0f)) + *outSize = 3; + else + *outSize = 1; + } else { + *outSize = 1; + } + + return true; + } + + return false; } -void T2FireWork::PutDot(int, int, int, unsigned char) { +void T2FireWork::PutDot(int inX, int inY, int inSize, unsigned char inCol) { + RECT theDotRect, theSubRect; + + if (inSize == 1) + SetRect(&theDotRect, inX, inY, inX + 1, inY + 1); + else if (inSize == 2) + SetRect(&theDotRect, inX, inY, inX + 2, inY + 2); + else if (inSize == 3 || inSize == 4) + SetRect(&theDotRect, inX - 1, inY - 1, inX + 2, inY + 2); + + SubtractRect(&theSubRect, &theDotRect, &mRect); + if (!IsRectEmpty(&theSubRect)) + return; + + int p = inX + (mRowSize * inY); + unsigned char *theData = mImage->mData; + + if (inSize == 1) { + theData[p] = inCol; + } else if (inSize == 2) { + theData[p] = inCol; + theData[p + 1] = inCol; + theData[p + mRowSize] = inCol; + theData[p + mRowSize + 1] = inCol; + } else if (inSize == 3) { + theData[p - 1] = inCol; + theData[p] = inCol; + theData[p + 1] = inCol; + theData[p - mRowSize] = inCol; + theData[p + mRowSize] = inCol; + } else if (inSize == 4) { + theData[p - mRowSize - 1] = inCol; + theData[p - mRowSize] = inCol; + theData[p - mRowSize + 1] = inCol; + theData[p - 1] = inCol; + theData[p] = inCol; + theData[p + 1] = inCol; + theData[p + mRowSize - 1] = inCol; + theData[p + mRowSize] = inCol; + theData[p + mRowSize + 1] = inCol; + } } |