- fixed recursion issues caused by the plasma generator function performing a busy wait.

This commit is contained in:
Christoph Oelckers 2019-12-25 18:57:08 +01:00
parent 28cbecea67
commit 23bc599468
2 changed files with 184 additions and 182 deletions

View File

@ -887,6 +887,7 @@ void M_Drawer (void)
} }
if (!going) if (!going)
{ {
assert(DMenu::CurrentMenu);
DMenu::CurrentMenu->origin = { 0,0 }; DMenu::CurrentMenu->origin = { 0,0 };
// else if (DrawBackground) Menu_DrawBackground(origin); // else if (DrawBackground) Menu_DrawBackground(origin);
DMenu::CurrentMenu->Drawer(); DMenu::CurrentMenu->Drawer();

View File

@ -309,223 +309,224 @@ int nLogoTile;
#define kPlasmaWidth 320 #define kPlasmaWidth 320
#define kPlasmaHeight 80 #define kPlasmaHeight 80
int nextPlasmaTic;
void menu_DoPlasma() void menu_DoPlasma()
{ {
if (!nLogoTile) int ptile = nPlasmaTile;
nLogoTile = EXHUMED ? kExhumedLogo : kPowerslaveLogo; if (totalclock >= nextPlasmaTic || !PlasmaBuffer)
if (!PlasmaBuffer)
{ {
auto pixels = TileFiles.tileCreate(kTile4092, kPlasmaWidth, kPlasmaHeight); nextPlasmaTic = (int)totalclock + 4;
memset(pixels, 96, kPlasmaWidth*kPlasmaHeight);
PlasmaBuffer = TileFiles.tileCreate(kTile4093, kPlasmaWidth, kPlasmaHeight); if (!nLogoTile)
memset(PlasmaBuffer, 96, kPlasmaWidth * kPlasmaHeight); nLogoTile = EXHUMED ? kExhumedLogo : kPowerslaveLogo;
nSmokeLeft = 160 - tilesiz[nLogoTile].x / 2; if (!PlasmaBuffer)
nSmokeRight = nSmokeLeft + tilesiz[nLogoTile].x;
nSmokeTop = 40 - tilesiz[nLogoTile].y / 2;
nSmokeBottom = nSmokeTop + tilesiz[nLogoTile].y - 1;
//uint32_t t = time(0) << 16;
//uint32_t t2 = time(0) | t;
nRandom = timerGetTicksU64();
for (int i = 0; i < 5; i++)
{ {
int logoWidth = tilesiz[nLogoTile].x; auto pixels = TileFiles.tileCreate(kTile4092, kPlasmaWidth, kPlasmaHeight);
plasma_C[i] = (nSmokeLeft + rand() % logoWidth) << 16; memset(pixels, 96, kPlasmaWidth * kPlasmaHeight);
plasma_B[i] = (menu_RandomLong2() % 327680) + 0x10000;
if (menu_RandomBit2()) { PlasmaBuffer = TileFiles.tileCreate(kTile4093, kPlasmaWidth, kPlasmaHeight);
plasma_B[i] = -plasma_B[i]; memset(PlasmaBuffer, 96, kPlasmaWidth * kPlasmaHeight);
nSmokeLeft = 160 - tilesiz[nLogoTile].x / 2;
nSmokeRight = nSmokeLeft + tilesiz[nLogoTile].x;
nSmokeTop = 40 - tilesiz[nLogoTile].y / 2;
nSmokeBottom = nSmokeTop + tilesiz[nLogoTile].y - 1;
//uint32_t t = time(0) << 16;
//uint32_t t2 = time(0) | t;
nRandom = timerGetTicksU64();
for (int i = 0; i < 5; i++)
{
int logoWidth = tilesiz[nLogoTile].x;
plasma_C[i] = (nSmokeLeft + rand() % logoWidth) << 16;
plasma_B[i] = (menu_RandomLong2() % 327680) + 0x10000;
if (menu_RandomBit2()) {
plasma_B[i] = -plasma_B[i];
}
plasma_A[i] = menu_RandomBit2();
}
}
videoClearScreen(overscanindex);
uint8_t* plasmapix = const_cast<uint8_t*>(tilePtr(nPlasmaTile));
uint8_t* r_ebx = plasmapix + 81;
const uint8_t* r_edx = tilePtr(nPlasmaTile ^ 1) + 81; // flip between value of 4092 and 4093 with xor
for (int x = 0; x < kPlasmaWidth - 2; x++)
// for (int x = 1; x < 318; x++)
{
// for (int y = 1; y < 79; y++)
for (int y = 0; y < kPlasmaHeight - 2; y++)
{
uint8_t al = *r_edx;
if (al != 96)
{
if (al > 158) {
*r_ebx = al - 1;
}
else {
*r_ebx = 96;
}
}
else
{
if (menu_RandomBit2()) {
*r_ebx = *r_edx;
}
else
{
uint8_t al = *(r_edx + 1);
uint8_t cl = *(r_edx - 1);
if (al <= cl) {
al = cl;
}
cl = al;
al = *(r_edx - 80);
if (cl <= al) {
cl = al;
}
al = *(r_edx + 80);
if (cl <= al) {
cl = al;
}
al = *(r_edx + 80);
if (cl <= al) {
cl = al;
}
al = *(r_edx + 80);
if (cl <= al) {
cl = al;
}
al = *(r_edx - 79);
if (cl > al) {
al = cl;
}
cl = *(r_edx - 81);
if (al <= cl) {
al = cl;
}
cl = al;
if (al <= 159) {
*r_ebx = 96;
}
else
{
if (!menu_RandomBit2()) {
cl--;
}
*r_ebx = cl;
}
}
}
// before restarting inner loop
r_edx++;
r_ebx++;
} }
plasma_A[i] = menu_RandomBit2(); // before restarting outer loop
r_edx += 2;
r_ebx += 2;
} }
}
videoClearScreen(overscanindex); auto logopix = tilePtr(nLogoTile);
for (int j = 0; j < 5; j++)
uint8_t* plasmapix = const_cast<uint8_t*>(tilePtr(nPlasmaTile));
uint8_t *r_ebx = plasmapix + 81;
const uint8_t *r_edx = tilePtr(nPlasmaTile ^ 1) + 81; // flip between value of 4092 and 4093 with xor
for (int x = 0; x < kPlasmaWidth - 2; x++)
// for (int x = 1; x < 318; x++)
{
// for (int y = 1; y < 79; y++)
for (int y = 0; y < kPlasmaHeight - 2; y++)
{ {
uint8_t al = *r_edx; int pB = plasma_B[j];
int pC = plasma_C[j];
int badOffset = (pC >> 16) < nSmokeLeft || (pC >> 16) >= nSmokeRight;
if (al != 96) const uint8_t* ptr3 = (logopix + ((pC >> 16) - nSmokeLeft)* tilesiz[nLogoTile].y);
plasma_C[j] += plasma_B[j];
if ((pB > 0 && (plasma_C[j] >> 16) >= nSmokeRight) || (pB < 0 && (plasma_C[j] >> 16) <= nSmokeLeft))
{ {
if (al > 158) { int esi = plasma_A[j];
*r_ebx = al - 1; plasma_B[j] = -plasma_B[j];
} plasma_A[j] = esi == 0;
else { }
*r_ebx = 96;
if (badOffset)
continue;
unsigned int nSmokeOffset = 0;
if (plasma_A[j])
{
nSmokeOffset = nSmokeTop;
while (nSmokeOffset < nSmokeBottom)
{
uint8_t al = *ptr3;
if (al != 255 && al != 96) {
break;
}
nSmokeOffset++;
ptr3++;
} }
} }
else else
{ {
if (menu_RandomBit2()) { nSmokeOffset = nSmokeBottom;
*r_ebx = *r_edx;
} ptr3 += tilesiz[nLogoTile].y - 1;
else
while (nSmokeOffset > nSmokeTop)
{ {
uint8_t al = *(r_edx + 1); uint8_t al = *ptr3;
uint8_t cl = *(r_edx - 1); if (al != 255 && al != 96) {
break;
if (al <= cl) {
al = cl;
} }
cl = al; nSmokeOffset--;
al = *(r_edx - 80); ptr3--;
if (cl <= al) {
cl = al;
}
al = *(r_edx + 80);
if (cl <= al) {
cl = al;
}
al = *(r_edx + 80);
if (cl <= al) {
cl = al;
}
al = *(r_edx + 80);
if (cl <= al) {
cl = al;
}
al = *(r_edx - 79);
if (cl > al) {
al = cl;
}
cl = *(r_edx - 81);
if (al <= cl) {
al = cl;
}
cl = al;
if (al <= 159) {
*r_ebx = 96;
}
else
{
if (!menu_RandomBit2()) {
cl--;
}
*r_ebx = cl;
}
} }
} }
// before restarting inner loop uint8_t* v28 = plasmapix + (80 * (plasma_C[j] >> 16));
r_edx++; v28[nSmokeOffset] = 175;
r_ebx++;
} }
// before restarting outer loop tileInvalidate(nPlasmaTile, -1, -1);
r_edx += 2;
r_ebx += 2; // flip between tile 4092 and 4093
if (nPlasmaTile == kTile4092) {
nPlasmaTile = kTile4093;
}
else if (nPlasmaTile == kTile4093) {
nPlasmaTile = kTile4092;
}
} }
overwritesprite(0, 0, ptile, 0, 2, kPalNormal);
auto logopix = tilePtr(nLogoTile);
for (int j = 0; j < 5; j++)
{
int pB = plasma_B[j];
int pC = plasma_C[j];
int badOffset = (pC>>16) < nSmokeLeft || (pC>>16) >= nSmokeRight;
const uint8_t *ptr3 = (logopix + ((pC >> 16) - nSmokeLeft) * tilesiz[nLogoTile].y);
plasma_C[j] += plasma_B[j];
if ((pB > 0 && (plasma_C[j] >> 16) >= nSmokeRight) || (pB < 0 && (plasma_C[j] >> 16) <= nSmokeLeft))
{
int esi = plasma_A[j];
plasma_B[j] = -plasma_B[j];
plasma_A[j] = esi == 0;
}
if (badOffset)
continue;
unsigned int nSmokeOffset = 0;
if (plasma_A[j])
{
nSmokeOffset = nSmokeTop;
while (nSmokeOffset < nSmokeBottom)
{
uint8_t al = *ptr3;
if (al != 255 && al != 96) {
break;
}
nSmokeOffset++;
ptr3++;
}
}
else
{
nSmokeOffset = nSmokeBottom;
ptr3 += tilesiz[nLogoTile].y - 1;
while (nSmokeOffset > nSmokeTop)
{
uint8_t al = *ptr3;
if (al != 255 && al != 96) {
break;
}
nSmokeOffset--;
ptr3--;
}
}
uint8_t *v28 = plasmapix + (80 * (plasma_C[j] >> 16));
v28[nSmokeOffset] = 175;
}
tileInvalidate(nPlasmaTile,-1,-1);
overwritesprite(0, 0, nPlasmaTile, 0, 2, kPalNormal);
overwritesprite(160, 40, nLogoTile, 0, 3, kPalNormal); overwritesprite(160, 40, nLogoTile, 0, 3, kPalNormal);
// flip between tile 4092 and 4093
if (nPlasmaTile == kTile4092) {
nPlasmaTile = kTile4093;
}
else if (nPlasmaTile == kTile4093) {
nPlasmaTile = kTile4092;
}
// draw the fire urn/lamp thingies // draw the fire urn/lamp thingies
int dword_9AB5F = ((int)totalclock/16) & 3; int dword_9AB5F = ((int)totalclock/16) & 3;
overwritesprite(50, 150, kTile3512 + dword_9AB5F, 0, 3, kPalNormal); overwritesprite(50, 150, kTile3512 + dword_9AB5F, 0, 3, kPalNormal);
overwritesprite(270, 150, kTile3512 + ((dword_9AB5F + 2) & 3), 0, 3, kPalNormal); overwritesprite(270, 150, kTile3512 + ((dword_9AB5F + 2) & 3), 0, 3, kPalNormal);
// TEMP
int time = (int)totalclock + 4;
while ((int)totalclock < time) {
HandleAsync();
}
} }