From 23bc5994688ef50c370ee5a5d8f4487b9d624e30 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 25 Dec 2019 18:57:08 +0100 Subject: [PATCH] - fixed recursion issues caused by the plasma generator function performing a busy wait. --- source/common/menu/menu.cpp | 1 + source/exhumed/src/menu.cpp | 365 ++++++++++++++++++------------------ 2 files changed, 184 insertions(+), 182 deletions(-) diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index 3b05f6933..7285771d8 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -887,6 +887,7 @@ void M_Drawer (void) } if (!going) { + assert(DMenu::CurrentMenu); DMenu::CurrentMenu->origin = { 0,0 }; // else if (DrawBackground) Menu_DrawBackground(origin); DMenu::CurrentMenu->Drawer(); diff --git a/source/exhumed/src/menu.cpp b/source/exhumed/src/menu.cpp index 6ee7610c5..3f54780a2 100644 --- a/source/exhumed/src/menu.cpp +++ b/source/exhumed/src/menu.cpp @@ -309,223 +309,224 @@ int nLogoTile; #define kPlasmaWidth 320 #define kPlasmaHeight 80 +int nextPlasmaTic; + void menu_DoPlasma() { - if (!nLogoTile) - nLogoTile = EXHUMED ? kExhumedLogo : kPowerslaveLogo; - - if (!PlasmaBuffer) + int ptile = nPlasmaTile; + if (totalclock >= nextPlasmaTic || !PlasmaBuffer) { - auto pixels = TileFiles.tileCreate(kTile4092, kPlasmaWidth, kPlasmaHeight); - memset(pixels, 96, kPlasmaWidth*kPlasmaHeight); + nextPlasmaTic = (int)totalclock + 4; - PlasmaBuffer = TileFiles.tileCreate(kTile4093, kPlasmaWidth, kPlasmaHeight); - memset(PlasmaBuffer, 96, kPlasmaWidth * kPlasmaHeight); + if (!nLogoTile) + nLogoTile = EXHUMED ? kExhumedLogo : kPowerslaveLogo; - 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++) + if (!PlasmaBuffer) { - int logoWidth = tilesiz[nLogoTile].x; - plasma_C[i] = (nSmokeLeft + rand() % logoWidth) << 16; - plasma_B[i] = (menu_RandomLong2() % 327680) + 0x10000; + auto pixels = TileFiles.tileCreate(kTile4092, kPlasmaWidth, kPlasmaHeight); + memset(pixels, 96, kPlasmaWidth * kPlasmaHeight); - if (menu_RandomBit2()) { - plasma_B[i] = -plasma_B[i]; + PlasmaBuffer = TileFiles.tileCreate(kTile4093, kPlasmaWidth, kPlasmaHeight); + 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(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); - - uint8_t* plasmapix = const_cast(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++) + for (int j = 0; j < 5; j++) { - 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) { - *r_ebx = al - 1; - } - else { - *r_ebx = 96; + 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 { - if (menu_RandomBit2()) { - *r_ebx = *r_edx; - } - else + nSmokeOffset = nSmokeBottom; + + ptr3 += tilesiz[nLogoTile].y - 1; + + while (nSmokeOffset > nSmokeTop) { - uint8_t al = *(r_edx + 1); - uint8_t cl = *(r_edx - 1); - - if (al <= cl) { - al = cl; + uint8_t al = *ptr3; + if (al != 255 && al != 96) { + break; } - 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; - } + nSmokeOffset--; + ptr3--; } } - // before restarting inner loop - r_edx++; - r_ebx++; + uint8_t* v28 = plasmapix + (80 * (plasma_C[j] >> 16)); + v28[nSmokeOffset] = 175; } - // before restarting outer loop - r_edx += 2; - r_ebx += 2; + tileInvalidate(nPlasmaTile, -1, -1); + + // flip between tile 4092 and 4093 + if (nPlasmaTile == kTile4092) { + nPlasmaTile = kTile4093; + } + else if (nPlasmaTile == kTile4093) { + nPlasmaTile = kTile4092; + } } - - 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(0, 0, ptile, 0, 2, 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 int dword_9AB5F = ((int)totalclock/16) & 3; overwritesprite(50, 150, kTile3512 + dword_9AB5F, 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(); - } }