1111#include "ft2_random.h"
1212
1313#define NUM_STARS 1500
14- #define STARSHINE_ALPHA_PERCENTAGE 33
14+ #define STARSHINE_ALPHA_PERCENTAGE 31
1515#define ABOUT_SCREEN_X 3
1616#define ABOUT_SCREEN_Y 3
1717#define ABOUT_SCREEN_W 626
1818#define ABOUT_SCREEN_H 167
1919#define ABOUT_LOGO_W 541
2020#define ABOUT_LOGO_H 78
21+ #define BG_COLORKEY 0xFF000000
22+ #define STAR_PIXEL_ID 0xFE000000
2123
2224typedef struct
2325{
24- float x , y , z ;
26+ int16_t x , y , z ;
2527} vector_t ;
2628
29+ typedef struct
30+ {
31+ float x , y , z ;
32+ } rotate_t ;
33+
2734typedef struct
2835{
2936 vector_t x , y , z ;
@@ -35,10 +42,32 @@ static char *customText2 = "https://16-bits.org";
3542static char customText3 [128 ];
3643static int16_t customText0X , customText0Y , customText1X , customText1Y ;
3744static int16_t customText2X , customText2Y , customText3X , customText3Y ;
45+ static int32_t lastStarPos [NUM_STARS ];
3846static const uint16_t starShineAlpha16 = (65535 * STARSHINE_ALPHA_PERCENTAGE ) / 100 ;
39- static vector_t starPoints [NUM_STARS ], starRotation ;
47+ static vector_t starPoints [NUM_STARS ];
48+ static rotate_t starRotation ;
4049static matrix_t starMatrix ;
4150
51+ static void clearPixel (uint32_t x , uint32_t y )
52+ {
53+ if (x >= ABOUT_SCREEN_X + ABOUT_SCREEN_W || y >= ABOUT_SCREEN_Y + ABOUT_SCREEN_H )
54+ return ;
55+
56+ const uint32_t pos = (y * SCREEN_W ) + x ;
57+ if ((video .frameBuffer [pos ] & 0xFF000000 ) == STAR_PIXEL_ID )
58+ video .frameBuffer [pos ] = BG_COLORKEY ;
59+ }
60+
61+ static void putPixel (uint32_t x , uint32_t y , uint32_t color )
62+ {
63+ if (x >= ABOUT_SCREEN_X + ABOUT_SCREEN_W || y >= ABOUT_SCREEN_Y + ABOUT_SCREEN_H )
64+ return ;
65+
66+ const uint32_t pos = (y * SCREEN_W ) + x ;
67+ if (video .frameBuffer [pos ] == BG_COLORKEY )
68+ video .frameBuffer [pos ] = color | STAR_PIXEL_ID ;
69+ }
70+
4271static void blendPixelsXY (uint32_t x , uint32_t y , uint32_t pixelB_r , uint32_t pixelB_g , uint32_t pixelB_b , uint16_t alpha )
4372{
4473 uint32_t * p = & video .frameBuffer [(y * SCREEN_W ) + x ];
@@ -49,33 +78,57 @@ static void blendPixelsXY(uint32_t x, uint32_t y, uint32_t pixelB_r, uint32_t pi
4978 const int32_t g = ((RGB32_G (pixelA ) * invAlpha ) + (pixelB_g * alpha )) >> 16 ;
5079 const int32_t b = ((RGB32_B (pixelA ) * invAlpha ) + (pixelB_b * alpha )) >> 16 ;
5180
52- * p = RGB32 (r , g , b );
81+ if (* p == BG_COLORKEY )
82+ * p = RGB32 (r , g , b ) | STAR_PIXEL_ID ;
5383}
5484
5585static void starfield (void )
5686{
5787 vector_t * star = starPoints ;
5888 for (int16_t i = 0 ; i < NUM_STARS ; i ++ , star ++ )
5989 {
60- star -> z += 0.0001f ;
61- if (star -> z >= 0.5f )
62- star -> z -= 1.0f ;
63-
64- const float z = (starMatrix .x .z * star -> x ) + (starMatrix .y .z * star -> y ) + (starMatrix .z .z * star -> z ) + 0.5f ;
65- if (z <= 0.0f )
90+ // erase previous star
91+ if (lastStarPos [i ] != -1 )
92+ {
93+ const int32_t x = lastStarPos [i ] >> 16 , y = lastStarPos [i ] & 0xFFFF ;
94+ lastStarPos [i ] = -1 ;
95+
96+ // center
97+ clearPixel (x , y );
98+
99+ // sides
100+ clearPixel (x - 1 , y );
101+ clearPixel (x + 1 , y );
102+ clearPixel (x , y - 1 );
103+ clearPixel (x , y + 1 );
104+ }
105+
106+ star -> z += 3 ;
107+ if (star -> z > 16384 )
108+ star -> z -= 32768 ;
109+
110+ int32_t z = (((starMatrix .x .z * star -> x ) + (starMatrix .y .z * star -> y ) + (starMatrix .z .z * star -> z )) >> 15 ) + 16384 ;
111+ if (z <= 0 )
112+ continue ;
113+
114+ int32_t y = ((((starMatrix .x .y * star -> x ) + (starMatrix .y .y * star -> y ) + (starMatrix .z .y * star -> z )) >> 15 ) * 400 ) / z ;
115+ y += ABOUT_SCREEN_H / 2 ;
116+ if ((uint32_t )y >= ABOUT_SCREEN_H )
66117 continue ;
67118
68- float y = (((starMatrix .x .y * star -> x ) + (starMatrix .y .y * star -> y ) + (starMatrix .z .y * star -> z )) / z ) * 400.0f ;
69- const int32_t outY = ( ABOUT_SCREEN_Y + ( ABOUT_SCREEN_H / 2 )) + ( int32_t ) y ;
70- if (outY < ABOUT_SCREEN_Y || outY >= ABOUT_SCREEN_Y + ABOUT_SCREEN_H )
119+ int32_t x = (((( starMatrix .x .x * star -> x ) + (starMatrix .y .x * star -> y ) + (starMatrix .z .x * star -> z )) >> 15 ) * 400 ) / z ;
120+ x += ABOUT_SCREEN_W / 2 ;
121+ if (( uint32_t ) x >= ABOUT_SCREEN_W )
71122 continue ;
72123
73- float x = (((starMatrix .x .x * star -> x ) + (starMatrix .y .x * star -> y ) + (starMatrix .z .x * star -> z )) / z ) * 400.0f ;
74- const int32_t outX = (ABOUT_SCREEN_X + (ABOUT_SCREEN_W /2 )) + (int32_t )x ;
75- if (outX < ABOUT_SCREEN_X || outX >= ABOUT_SCREEN_X + ABOUT_SCREEN_W )
124+ const int32_t outX = ABOUT_SCREEN_X + x ;
125+ const int32_t outY = ABOUT_SCREEN_Y + y ;
126+
127+ // only draw star if it's not over logo and text
128+ if (video .frameBuffer [(outY * SCREEN_W ) + outX ] != BG_COLORKEY )
76129 continue ;
77130
78- int32_t intensity255 = ( int32_t )( z * 256.0f ) ;
131+ int32_t intensity255 = z >> 7 ;
79132 if (intensity255 > 255 )
80133 intensity255 = 255 ;
81134 intensity255 ^= 255 ;
@@ -94,6 +147,9 @@ static void starfield(void)
94147 if (b > 255 )
95148 b = 255 ;
96149
150+ // plot center pixel
151+ putPixel (outX , outY , RGB32 (r , g , b ));
152+
97153 // plot and blend sides of star (basic shine effect)
98154
99155 if (outX - 1 >= ABOUT_SCREEN_X )
@@ -108,69 +164,58 @@ static void starfield(void)
108164 if (outY + 1 < ABOUT_SCREEN_Y + ABOUT_SCREEN_H )
109165 blendPixelsXY (outX , outY + 1 , r , g , b , starShineAlpha16 );
110166
111- // plot center pixel
112- video .frameBuffer [(outY * SCREEN_W ) + outX ] = RGB32 (r , g , b );
167+ lastStarPos [i ] = (outX << 16 ) | outY ;
113168 }
114169}
115170
116171static void rotateStarfieldMatrix (void )
117172{
118173#define F_2PI (float)(2.0 * PI)
174+ #define SCALE 32767.0f
119175
120- const float xrad = starRotation .x * F_2PI ;
121- const float xsin = sinf (xrad );
122- const float xcos = cosf (xrad );
176+ const float rx2p = starRotation .x * F_2PI ;
177+ const float xsin = sinf (rx2p );
178+ const float xcos = cosf (rx2p );
123179
124- const float yrad = starRotation .y * F_2PI ;
125- const float ysin = sinf (yrad );
126- const float ycos = cosf (yrad );
180+ const float ry2p = starRotation .y * F_2PI ;
181+ const float ysin = sinf (ry2p );
182+ const float ycos = cosf (ry2p );
127183
128- const float zrad = starRotation .z * F_2PI ;
129- const float zsin = sinf (zrad );
130- const float zcos = cosf (zrad );
184+ const float rz2p = starRotation .z * F_2PI ;
185+ const float zsin = sinf (rz2p );
186+ const float zcos = cosf (rz2p );
131187
132188 // x
133- starMatrix .x .x = (xcos * zcos ) + (zsin * xsin * ysin );
134- starMatrix .y .x = xsin * ycos ;
135- starMatrix .z .x = (zcos * xsin * ysin ) - (xcos * zsin );
189+ starMatrix .x .x = (int16_t )( SCALE * (( xcos * zcos ) + (zsin * xsin * ysin )) );
190+ starMatrix .y .x = ( int16_t )( SCALE * ( xsin * ycos )) ;
191+ starMatrix .z .x = (int16_t )( SCALE * (( zcos * xsin * ysin ) - (xcos * zsin )) );
136192
137193 // y
138- starMatrix .x .y = (zsin * xcos * ysin ) - (xsin * zcos );
139- starMatrix .y .y = xcos * ycos ;
140- starMatrix .z .y = (xsin * zsin ) + (zcos * xcos * ysin );
194+ starMatrix .x .y = (int16_t )( SCALE * (( zsin * xcos * ysin ) - (xsin * zcos )) );
195+ starMatrix .y .y = ( int16_t )( SCALE * ( xcos * ycos )) ;
196+ starMatrix .z .y = (int16_t )( SCALE * (( xsin * zsin ) + (zcos * xcos * ysin )) );
141197
142198 // z
143- starMatrix .x .z = ycos * zsin ;
144- starMatrix .y .z = 0.0f - ysin ;
145- starMatrix .z .z = ycos * zcos ;
199+ starMatrix .x .z = ( int16_t )( SCALE * ( ycos * zsin )) ;
200+ starMatrix .y .z = ( int16_t )( SCALE * ( 0.0f - ysin )) ;
201+ starMatrix .z .z = ( int16_t )( SCALE * ( ycos * zcos )) ;
146202}
147203
148204void renderAboutScreenFrame (void )
149205{
150- clearRect (ABOUT_SCREEN_X , ABOUT_SCREEN_Y , ABOUT_SCREEN_W , ABOUT_SCREEN_H );
151-
152- // 3D starfield
153-
154206 starfield ();
155207 starRotation .x -= 0.0003f ;
156208 starRotation .y -= 0.0002f ;
157209 starRotation .z += 0.0001f ;
158210 rotateStarfieldMatrix ();
159211
160- // FT2 logo
161- blit32 ((SCREEN_W - ABOUT_LOGO_W ) / 2 , 30 , bmp .ft2AboutLogo , ABOUT_LOGO_W , ABOUT_LOGO_H );
162-
163- // render static texts
164- textOut (customText0X , customText0Y , PAL_FORGRND , customText0 );
165- textOut (customText1X , customText1Y , PAL_FORGRND , customText1 );
166- textOut (customText2X , customText2Y , PAL_FORGRND , customText2 );
167- textOut (customText3X , customText3Y , PAL_FORGRND , customText3 );
168-
169212 showPushButton (PB_EXIT_ABOUT ); // yes, we also have to redraw the exit button per frame :)
170213}
171214
172215void showAboutScreen (void ) // called once when about screen is opened
173216{
217+ memset (lastStarPos , -1 , NUM_STARS * sizeof (int32_t ));
218+
174219 if (ui .extendedPatternEditor )
175220 exitPatternEditorExtended ();
176221
@@ -179,6 +224,21 @@ void showAboutScreen(void) // called once when about screen is opened
179224 drawFramework (0 , 0 , 632 , 173 , FRAMEWORK_TYPE1 );
180225 drawFramework (2 , 2 , 628 , 169 , FRAMEWORK_TYPE2 );
181226
227+ for (int32_t y = ABOUT_SCREEN_Y ; y < ABOUT_SCREEN_Y + ABOUT_SCREEN_H ; y ++ )
228+ {
229+ for (int32_t x = ABOUT_SCREEN_X ; x < ABOUT_SCREEN_X + ABOUT_SCREEN_W ; x ++ )
230+ video .frameBuffer [(y * SCREEN_W ) + x ] = BG_COLORKEY ;
231+ }
232+
233+ // FT2 logo
234+ blit32 ((SCREEN_W - ABOUT_LOGO_W ) / 2 , 30 , bmp .ft2AboutLogo , ABOUT_LOGO_W , ABOUT_LOGO_H );
235+
236+ // render static texts
237+ textOut (customText0X , customText0Y , PAL_FORGRND , customText0 );
238+ textOut (customText1X , customText1Y , PAL_FORGRND , customText1 );
239+ textOut (customText2X , customText2Y , PAL_FORGRND , customText2 );
240+ textOut (customText3X , customText3Y , PAL_FORGRND , customText3 );
241+
182242 showPushButton (PB_EXIT_ABOUT );
183243 ui .aboutScreenShown = true;
184244}
@@ -188,9 +248,9 @@ void initAboutScreen(void)
188248 vector_t * s = starPoints ;
189249 for (int32_t i = 0 ; i < NUM_STARS ; i ++ , s ++ )
190250 {
191- s -> x = (float )(( randoml (INT32_MAX ) - ( INT32_MAX / 2 )) * ( 1.0 / INT32_MAX ) );
192- s -> y = (float )(( randoml (INT32_MAX ) - ( INT32_MAX / 2 )) * ( 1.0 / INT32_MAX ) );
193- s -> z = (float )(( randoml (INT32_MAX ) - ( INT32_MAX / 2 )) * ( 1.0 / INT32_MAX ) );
251+ s -> x = (int16_t )( randoml (32768 ) - 16384 );
252+ s -> y = (int16_t )( randoml (32768 ) - 16384 );
253+ s -> z = (int16_t )( randoml (32768 ) - 16384 );
194254 }
195255
196256 sprintf (customText3 , "v%s (%s)" , PROG_VER_STR , __DATE__ );
0 commit comments