summaryrefslogtreecommitdiff
path: root/src/T2DLL/T2FireWork.cpp
diff options
context:
space:
mode:
authorAsh Wolf <ninji@wuffs.org>2023-06-28 22:22:32 +0100
committerAsh Wolf <ninji@wuffs.org>2023-06-28 22:22:32 +0100
commitc0c336500955a23e344651e5412c9d9d441ef4ee (patch)
tree790769c748db307cf3314f6e896e2f61c68561a2 /src/T2DLL/T2FireWork.cpp
parent37e364b2c6cc7487a1c888d256a73e5337bb7189 (diff)
downloadt2win-c0c336500955a23e344651e5412c9d9d441ef4ee.tar.gz
t2win-c0c336500955a23e344651e5412c9d9d441ef4ee.zip
first pass of T2DLL
Diffstat (limited to '')
-rw-r--r--src/T2DLL/T2FireWork.cpp348
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;
+ }
}