shithub: ft²

Download patch

ref: fb2d7b8e8a87528b180a3cd55f8011336573ba7b
parent: 8391cc5ac8ad74fa3d08c7228cb4a30ac657c56f
author: Olav Sørensen <olav.sorensen@live.no>
date: Fri Feb 23 12:25:53 EST 2024

"about screen" changes

--- a/src/ft2_about.c
+++ b/src/ft2_about.c
@@ -2,19 +2,18 @@
 #include <math.h>
 #include "ft2_header.h"
 #include "ft2_gui.h"
-#include "ft2_pattern_ed.h"
 #include "ft2_bmp.h"
 #include "ft2_video.h"
 #include "ft2_structs.h"
+#include "ft2_pattern_ed.h" // exitPatternEditorExtended()
 
-#define NUM_STARS 3000
-#define ALPHA_FADE_MILLISECS 2000 /* amount of milliseconds until content is fully faded in */
+#define NUM_STARS 2000
+#define ABOUT_SCREEN_X 3
+#define ABOUT_SCREEN_Y 3
 #define ABOUT_SCREEN_W 626
 #define ABOUT_SCREEN_H 167
 #define ABOUT_LOGO_W 449
 #define ABOUT_LOGO_H 110
-#define ABOUT_TEXT_W 349
-#define ABOUT_TEXT_H 29
 
 typedef struct
 {
@@ -30,7 +29,7 @@
 static char *customText2 = "https://16-bits.org";
 static char customText3[256];
 static int16_t customText1Y, customText2Y, customText3Y, customText1X, customText2X, customText3X;
-static uint32_t logoTimer, alphaValue, randSeed, frameCounter;
+static uint32_t randSeed;
 static vector_t starPoints[NUM_STARS], rotation;
 static matrix_t matrix;
 
@@ -48,19 +47,19 @@
 
 static void rotateMatrix(void)
 {
-#define MY_PI_FLOAT 3.141592653589793f
+#define MY_2PI_FLOAT 6.2831853071796f
 
-	const float xx = rotation.x * MY_PI_FLOAT;
-	const float sa = sinf(xx);
-	const float ca = cosf(xx);
+	const float x2pi = rotation.x * MY_2PI_FLOAT;
+	const float sa = sinf(x2pi);
+	const float ca = cosf(x2pi);
 
-	const float yy = rotation.y * MY_PI_FLOAT;
-	const float sb = sinf(yy);
-	const float cb = cosf(yy);
+	const float y2pi = rotation.y * MY_2PI_FLOAT;
+	const float sb = sinf(y2pi);
+	const float cb = cosf(y2pi);
 
-	const float zz = rotation.z * MY_PI_FLOAT;
-	const float sc = sinf(zz);
-	const float cc = cosf(zz);
+	const float z2pi = rotation.z * MY_2PI_FLOAT;
+	const float sc = sinf(z2pi);
+	const float cc = cosf(z2pi);
 
 	// x
 	matrix.x.x = (ca * cc) + (sc * sa * sb);
@@ -78,7 +77,7 @@
 	matrix.z.z = cb * cc;
 }
 
-static void aboutInit(void)
+void initAboutScreen(void)
 {
 	vector_t *s = starPoints;
 	for (int32_t i = 0; i < NUM_STARS; i++, s++)
@@ -87,26 +86,21 @@
 		s->y = (float)(random32() * (1.0 / (UINT32_MAX+1.0)));
 		s->z = (float)(random32() * (1.0 / (UINT32_MAX+1.0)));
 	}
-
-	rotation.x = rotation.y = rotation.z = 0.0f;
-	alphaValue = 0;
-	frameCounter = 0;
-	logoTimer = 0;
 }
 
-static void blendPixel(int32_t x, int32_t y, int32_t r, int32_t g, int32_t b, int32_t alpha)
+static void blendPixel(int32_t x, int32_t y, uint32_t r, uint32_t g, uint32_t b, uint16_t alpha)
 {
 	uint32_t *p = &video.frameBuffer[(y * SCREEN_W) + x];
 
 	const uint32_t srcPixel = *p;
 
-	const int32_t srcR = RGB32_R(srcPixel);
-	const int32_t srcG = RGB32_G(srcPixel);
-	const int32_t srcB = RGB32_B(srcPixel);
+	const uint32_t srcR = RGB32_R(srcPixel);
+	const uint32_t srcG = RGB32_G(srcPixel);
+	const uint32_t srcB = RGB32_B(srcPixel);
 
-	r = ((srcR * (65536-alpha)) + (r * alpha)) >> 16;
-	g = ((srcG * (65536-alpha)) + (g * alpha)) >> 16;
-	b = ((srcB * (65536-alpha)) + (b * alpha)) >> 16;
+	r = ((srcR * (alpha ^ 65535)) + (r * alpha)) >> 16;
+	g = ((srcG * (alpha ^ 65535)) + (g * alpha)) >> 16;
+	b = ((srcB * (alpha ^ 65535)) + (b * alpha)) >> 16;
 
 	*p = RGB32(r, g, b);
 }
@@ -116,7 +110,7 @@
 	vector_t *star = starPoints;
 	for (int16_t i = 0; i < NUM_STARS; i++, star++)
 	{
-		star->z += 0.00015f;
+		star->z += 0.0001f;
 		if (star->z >= 0.5f)
 			star->z -= 1.0f;
 
@@ -124,18 +118,17 @@
 		if (z <= 0.0f)
 			continue;
 
-		float y = (ABOUT_SCREEN_H/2.0f) + ((((matrix.x.y * star->x) + (matrix.y.y * star->y) + (matrix.z.y * star->z)) / z) * 400.0f);
-		const int32_t outY = (int32_t)y;
-		if (outY < 3 || outY >= 3+ABOUT_SCREEN_H)
+		float y = (((matrix.x.y * star->x) + (matrix.y.y * star->y) + (matrix.z.y * star->z)) / z) * 400.0f;
+		const int32_t outY = (ABOUT_SCREEN_Y+(ABOUT_SCREEN_H/2)) + (int32_t)y;
+		if (outY < ABOUT_SCREEN_Y || outY >= ABOUT_SCREEN_Y+ABOUT_SCREEN_H)
 			continue;
 
-		float x = (ABOUT_SCREEN_W/2.0f) + ((((matrix.x.x * star->x) + (matrix.y.x * star->y) + (matrix.z.x * star->z)) / z) * 400.0f);
-
-		const int32_t outX = (int32_t)x;
-		if (outX < 3 || outX >= 3+ABOUT_SCREEN_W)
+		float x = (((matrix.x.x * star->x) + (matrix.y.x * star->y) + (matrix.z.x * star->z)) / z) * 400.0f;
+		const int32_t outX = (ABOUT_SCREEN_X+(ABOUT_SCREEN_W/2)) + (int32_t)x;
+		if (outX < ABOUT_SCREEN_X || outX >= ABOUT_SCREEN_X+ABOUT_SCREEN_W)
 			continue;
 
-		int32_t d = (int32_t)(z * 255.0f);
+		int32_t d = (int32_t)(z * 256.0f);
 		if (d > 255)
 			d = 255;
 		d ^= 255;
@@ -156,18 +149,18 @@
 
 		// blend sides of star
 
-		const int32_t sidesAlpha = 13000;
+		const uint16_t sidesAlpha = 13000;
 
-		if (outX-1 >= 3)
+		if (outX-1 >= ABOUT_SCREEN_X)
 			blendPixel(outX-1, outY, r, g, b, sidesAlpha);
 
-		if (outX+1 < 3+ABOUT_SCREEN_W)
+		if (outX+1 < ABOUT_SCREEN_X+ABOUT_SCREEN_W)
 			blendPixel(outX+1, outY, r, g, b, sidesAlpha);
 
-		if (outY-1 >= 3)
+		if (outY-1 >= ABOUT_SCREEN_Y)
 			blendPixel(outX, outY-1, r, g, b, sidesAlpha);
 
-		if (outY+1 < 3+ABOUT_SCREEN_H)
+		if (outY+1 < ABOUT_SCREEN_Y+ABOUT_SCREEN_H)
 			blendPixel(outX, outY+1, r, g, b, sidesAlpha);
 
 		// plot main star pixel
@@ -175,34 +168,23 @@
 	}
 }
 
-void aboutFrame(void) // called every frame when the about screen is shown
+void renderAboutScreenFrame(void)
 {
-	clearRect(3, 3, ABOUT_SCREEN_W, ABOUT_SCREEN_H);
+	// remember the good old days when you couldn't do this per frame?
+	clearRect(ABOUT_SCREEN_X, ABOUT_SCREEN_Y, ABOUT_SCREEN_W, ABOUT_SCREEN_H);
 
 	// 3D starfield
 	rotateMatrix();
+	rotation.x -= 0.00006f;
+	rotation.z += 0.00003f;
 	starfield();
-	rotation.x -= 0.00011f;
-	rotation.z += 0.00006f;
 
 	// logo + text
-	blit32Alpha(91, 31, bmp.ft2AboutLogo, ABOUT_LOGO_W, ABOUT_LOGO_H, alphaValue);
-	textOutAlpha(customText1X, customText1Y, PAL_FORGRND, customText1, alphaValue);
-	textOutAlpha(customText2X, customText2Y, PAL_FORGRND, customText2, alphaValue);
-	textOutAlpha(customText3X, customText3Y, PAL_FORGRND, customText3, alphaValue);
+	blit32(91, 31, bmp.ft2AboutLogo, ABOUT_LOGO_W, ABOUT_LOGO_H);
+	textOut(customText1X, customText1Y, PAL_FORGRND, customText1);
+	textOut(customText2X, customText2Y, PAL_FORGRND, customText2);
+	textOut(customText3X, customText3Y, PAL_FORGRND, customText3);
 
-	if (logoTimer > (int32_t)(VBLANK_HZ/4.0))
-	{
-		alphaValue += (uint32_t)((65536.0 / (ALPHA_FADE_MILLISECS / (1000.0 / VBLANK_HZ))) + 0.5);
-		if (alphaValue > 65536)
-			alphaValue = 65536;
-	}
-	else
-	{
-		logoTimer++;
-	}
-
-	// the exit button has to be redrawn since it gets overwritten :)
 	showPushButton(PB_EXIT_ABOUT);
 }
 
@@ -226,7 +208,6 @@
 	customText2Y = 157-12;
 	customText3Y = 157;
 
-	aboutInit();
 	ui.aboutScreenShown = true;
 }
 
--- a/src/ft2_about.h
+++ b/src/ft2_about.h
@@ -2,7 +2,8 @@
 
 #include <stdint.h>
 
-void aboutFrame(void);
+void initAboutScreen(void);
+void renderAboutScreenFrame(void);
 void seedAboutScreenRandom(uint32_t newseed);
 void showAboutScreen(void);
 void hideAboutScreen(void);
--- a/src/ft2_gui.c
+++ b/src/ft2_gui.c
@@ -370,52 +370,6 @@
 	}
 }
 
-void charOutAlpha(uint16_t xPos, uint16_t yPos, uint8_t paletteIndex, char chr, uint32_t alpha)
-{
-	assert(xPos < SCREEN_W && yPos < SCREEN_H);
-
-	chr &= 0x7F; // this is important to get the nordic glyphs in the font
-	if (chr == ' ')
-		return;
-
-	if (alpha > 65536)
-		alpha = 65536;
-
-	const uint32_t pixVal = video.palette[paletteIndex];
-	const uint32_t palNum = paletteIndex << 24;
-	const uint8_t *srcPtr = &bmp.font1[chr * FONT1_CHAR_W];
-	uint32_t *dstPtr = &video.frameBuffer[(yPos * SCREEN_W) + xPos];
-
-	for (int32_t y = 0; y < FONT1_CHAR_H; y++)
-	{
-		for (int32_t x = 0; x < FONT1_CHAR_W; x++)
-		{
-			const uint32_t srcPixel = srcPtr[x];
-			if (srcPixel == 0)
-				continue;
-
-			const uint32_t dstPixel = dstPtr[x];
-
-			const int32_t srcR = RGB32_R(pixVal);
-			const int32_t srcG = RGB32_G(pixVal);
-			const int32_t srcB = RGB32_B(pixVal);
-
-			int32_t dstR = RGB32_R(dstPixel);
-			int32_t dstG = RGB32_G(dstPixel);
-			int32_t dstB = RGB32_B(dstPixel);
-
-			dstR = ((dstR * (65536-alpha)) + (srcR * alpha)) >> 16;
-			dstG = ((dstG * (65536-alpha)) + (srcG * alpha)) >> 16;
-			dstB = ((dstB * (65536-alpha)) + (srcB * alpha)) >> 16;
-
-			dstPtr[x] = RGB32(dstR, dstG, dstB) | palNum;
-		}
-
-		srcPtr += FONT1_WIDTH;
-		dstPtr += SCREEN_W;
-	}
-}
-
 void charOutBg(uint16_t xPos, uint16_t yPos, uint8_t fgPalette, uint8_t bgPalette, char chr)
 {
 	assert(xPos < SCREEN_W && yPos < SCREEN_H);
@@ -585,31 +539,6 @@
 	}
 }
 
-void textOutAlpha(uint16_t x, uint16_t y, uint8_t paletteIndex, const char *textPtr, uint32_t alpha)
-{
-	char chr;
-	uint16_t currX;
-
-	assert(textPtr != NULL);
-
-	if (alpha >= 65536)
-	{
-		textOut(x, y, paletteIndex, textPtr);
-		return;
-	}
-
-	currX = x;
-	while (true)
-	{
-		chr = *textPtr++;
-		if (chr == '\0')
-			break;
-
-		charOutAlpha(currX, y, paletteIndex, chr, alpha);
-		currX += charWidth(chr);
-	}
-}
-
 void textOutBorder(uint16_t x, uint16_t y, uint8_t paletteIndex, uint8_t borderPaletteIndex, const char *textPtr)
 {
 	textOut(x,   y-1, borderPaletteIndex, textPtr); // top
@@ -805,47 +734,6 @@
 		{
 			if (srcPtr[x] != 0x00FF00)
 				dstPtr[x] = srcPtr[x] | 0xFF000000; // most significant 8 bits = palette number. 0xFF because no true palette
-		}
-
-		srcPtr += w;
-		dstPtr += SCREEN_W;
-	}
-}
-
-void blit32Alpha(uint16_t xPos, uint16_t yPos, const uint32_t *srcPtr, uint16_t w, uint16_t h, uint32_t alpha)
-{
-	assert(srcPtr != NULL && xPos < SCREEN_W && yPos < SCREEN_H && (xPos + w) <= SCREEN_W && (yPos + h) <= SCREEN_H);
-
-	if (alpha >= 65536)
-	{
-		blit32(xPos, yPos, srcPtr, w, h);
-		return;
-	}
-
-	uint32_t *dstPtr = &video.frameBuffer[(yPos * SCREEN_W) + xPos];
-	for (int32_t y = 0; y < h; y++)
-	{
-		for (int32_t x = 0; x < w; x++)
-		{
-			const uint32_t srcPixel = srcPtr[x];
-			if (srcPixel == 0x00FF00)
-				continue;
-
-			const uint32_t dstPixel = dstPtr[x];
-
-			const int32_t srcR = RGB32_R(srcPixel);
-			const int32_t srcG = RGB32_G(srcPixel);
-			const int32_t srcB = RGB32_B(srcPixel);
-
-			int32_t dstR = RGB32_R(dstPixel);
-			int32_t dstG = RGB32_G(dstPixel);
-			int32_t dstB = RGB32_B(dstPixel);
-
-			dstR = ((dstR * (65536-alpha)) + (srcR * alpha)) >> 16;
-			dstG = ((dstG * (65536-alpha)) + (srcG * alpha)) >> 16;
-			dstB = ((dstB * (65536-alpha)) + (srcB * alpha)) >> 16;
-
-			dstPtr[x] = RGB32(dstR, dstG, dstB) | 0xFF000000; // most significant 8 bits = palette number. 0xFF because no true palette
 		}
 
 		srcPtr += w;
--- a/src/ft2_gui.h
+++ b/src/ft2_gui.h
@@ -80,7 +80,6 @@
 void fillRect(uint16_t xPos, uint16_t yPos, uint16_t w, uint16_t h, uint8_t paletteIndex);
 void drawFramework(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint8_t type);
 void blit32(uint16_t xPos, uint16_t yPos, const uint32_t *srcPtr, uint16_t w, uint16_t h);
-void blit32Alpha(uint16_t xPos, uint16_t yPos, const uint32_t *srcPtr, uint16_t w, uint16_t h, uint32_t alpha);
 void blit(uint16_t xPos, uint16_t yPos, const uint8_t *srcPtr, uint16_t w, uint16_t h);
 void blitClipX(uint16_t xPos, uint16_t yPos, const uint8_t *srcPtr, uint16_t w, uint16_t h, uint16_t clipX);
 void blitFast(uint16_t xPos, uint16_t yPos, const uint8_t *srcPtr, uint16_t w, uint16_t h); // no transparency/colorkey
@@ -91,7 +90,6 @@
 void textOutTiny(int32_t xPos, int32_t yPos, char *str, uint32_t color); // A..Z/a..z and 0..9
 void textOutTinyOutline(int32_t xPos, int32_t yPos, char *str); // A..Z/a..z and 0..9
 void charOut(uint16_t xPos, uint16_t yPos, uint8_t paletteIndex, char chr);
-void charOutAlpha(uint16_t xPos, uint16_t yPos, uint8_t paletteIndex, char chr, uint32_t alpha);
 void charOutBg(uint16_t xPos, uint16_t yPos, uint8_t fgPalette, uint8_t bgPalette, char chr);
 void charOutShadow(uint16_t xPos, uint16_t yPos, uint8_t paletteIndex, uint8_t shadowPaletteIndex, char chr);
 void charOutClipX(uint16_t xPos, uint16_t yPos, uint8_t paletteIndex, char chr, uint16_t clipX);
@@ -99,7 +97,6 @@
 void charOutShadow(uint16_t x, uint16_t y, uint8_t paletteIndex, uint8_t shadowPaletteIndex, char chr);
 void charOutOutlined(uint16_t x, uint16_t y, uint8_t paletteIndex, char chr);
 void textOut(uint16_t x, uint16_t y, uint8_t paletteIndex, const char *textPtr);
-void textOutAlpha(uint16_t x, uint16_t y, uint8_t paletteIndex, const char *textPtr, uint32_t alpha);
 void textOutBorder(uint16_t x, uint16_t y, uint8_t paletteIndex, uint8_t borderPaletteIndex, const char *textPtr);
 void textOutFixed(uint16_t x, uint16_t y, uint8_t fgPaltete, uint8_t bgPalette, const char *textPtr);
 void bigTextOut(uint16_t x, uint16_t y, uint8_t paletteIndex, const char *textPtr);
--- a/src/ft2_main.c
+++ b/src/ft2_main.c
@@ -213,6 +213,7 @@
 		return 1;
 	}
 
+	initAboutScreen();
 	pauseAudio();
 	resumeAudio();
 	rescanAudioDevices();
--- a/src/ft2_video.c
+++ b/src/ft2_video.c
@@ -1055,7 +1055,7 @@
 	{
 		if (ui.aboutScreenShown)
 		{
-			aboutFrame();
+			renderAboutScreenFrame();
 		}
 		else if (ui.nibblesShown)
 		{