12 /* APPROX. 170 FPS Minimum */
14 static int init(void);
15 static void destroy(void);
16 static void start(long trans_time);
17 static void stop(long trans_time);
18 static void draw(void);
20 static void updatePropeller(float t, RleBitmap *rle);
22 static unsigned short *backBuffer;
24 static unsigned char miniFXBuffer[1024];
26 static long lastFrameTime = 0;
28 static struct screen scr = {"minifx", init, destroy, start, 0, draw};
30 struct screen *minifx_screen(void) {
34 static int init(void) {
35 /* Allocate back buffer */
36 backBuffer = calloc(FB_WIDTH * FB_HEIGHT, sizeof(unsigned short));
41 static void destroy(void) {
46 static void start(long trans_time) { lastFrameTime = time_msec; }
48 static void draw(void) {
49 long lastFrameDuration;
53 unsigned short clearColor16;
55 lastFrameDuration = (time_msec - lastFrameTime) / 1000.0f;
56 lastFrameTime = time_msec;
58 clearColor = 0x888888;
59 clearColor16 = ((clearColor << 8) & 0xF800) /* R */
60 | ((clearColor >> 5) & 0x07E0) /* G */
61 | ((clearColor >> 19) & 0x001F); /* B */
63 for (i=0; i<FB_WIDTH * FB_HEIGHT; i++) {
64 backBuffer[i] = clearColor16;
67 /* For now create / destroy in each frame. We will manage these later */
68 rle = rleCreate(32, 32);
70 updatePropeller(time_msec / 1000.0f, rle);
73 rleBlit(rle, backBuffer, FB_WIDTH, FB_HEIGHT, stride,
77 rleBlitScale(rle, backBuffer, FB_WIDTH, FB_HEIGHT, stride, 50,
82 /* Blit effect to framebuffer */
83 memcpy(fb_pixels, backBuffer, FB_WIDTH * FB_HEIGHT * sizeof(unsigned short));
88 #define PROPELLER_CIRCLE_RADIUS 18
89 #define PROPELLER_CIRCLE_RADIUS_SQ (PROPELLER_CIRCLE_RADIUS * PROPELLER_CIRCLE_RADIUS)
96 static void updatePropeller(float t, RleBitmap *rle) {
99 int cx, cy, count = 0;
105 static float sin120 = 0.86602540378f;
106 static float cos120 = -0.5f;
108 t *= 0.1; /* Slow-mo to see what happens */
113 nx = x * cost - y * sint;
114 ny = y * cost + x * sint;
117 propellerState.circleX[0] = (int)(x + 0.5f) + 16;
118 propellerState.circleY[0] = (int)(y + 0.5f) + 16;
120 /* Rotate by 120 degrees, for the second circle */
121 nx = x * cos120 - y * sin120;
122 ny = y * cos120 + x * sin120;
125 propellerState.circleX[1] = (int)(x + 0.5f) + 16;
126 propellerState.circleY[1] = (int)(y + 0.5f) + 16;
129 nx = x * cos120 - y * sin120;
130 ny = y * cos120 + x * sin120;
133 propellerState.circleX[2] = (int)(x + 0.5f) + 16;
134 propellerState.circleY[2] = (int)(y + 0.5f) + 16;
136 /* Write effect to the mini fx buffer*/
138 for (j = 0; j < 32; j++) {
139 for (i = 0; i < 32; i++) {
143 cx = propellerState.circleX[0] - i;
144 cy = propellerState.circleY[0] - j;
145 if (cx * cx + cy * cy < PROPELLER_CIRCLE_RADIUS_SQ)
149 cx = propellerState.circleX[1] - i;
150 cy = propellerState.circleY[1] - j;
151 if (cx * cx + cy * cy < PROPELLER_CIRCLE_RADIUS_SQ)
155 cx = propellerState.circleX[2] - i;
156 cy = propellerState.circleY[2] - j;
157 if (cx * cx + cy * cy < PROPELLER_CIRCLE_RADIUS_SQ)
164 /* Then, encode to rle */
165 rleEncode(rle, miniFXBuffer, 32, 32);
167 /* Distribute the produced streaks so that they don't produce garbage when interpolated */
168 rleDistributeStreaks(rle);