10 #include <RleBitmap.h>
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 = (unsigned short *)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 = (time_msec - lastFrameTime) / 1000.0f;
50 lastFrameTime = time_msec;
52 int clearColor = 0x888888;
53 unsigned short clearColor16 = ((clearColor << 8) & 0xF800) /* R */
54 | ((clearColor >> 5) & 0x07E0) /* G */
55 | ((clearColor >> 19) & 0x001F); /* B */
56 for (int i=0; i<FB_WIDTH * FB_HEIGHT; i++) {
57 backBuffer[i] = clearColor16;
60 /* For now create / destroy in each frame. We will manage these later */
61 RleBitmap *rle = rleCreate(32, 32);
63 updatePropeller(time_msec / 1000.0f, rle);
64 int stride = FB_WIDTH;
66 rleBlit(rle, backBuffer, FB_WIDTH, FB_HEIGHT, stride,
70 rleBlitScale(rle, backBuffer, FB_WIDTH, FB_HEIGHT, stride, 50,
75 /* Blit effect to framebuffer */
76 memcpy(fb_pixels, backBuffer, FB_WIDTH * FB_HEIGHT * sizeof(unsigned short));
81 #define PROPELLER_CIRCLE_RADIUS 18
82 #define PROPELLER_CIRCLE_RADIUS_SQ (PROPELLER_CIRCLE_RADIUS * PROPELLER_CIRCLE_RADIUS)
89 static void updatePropeller(float t, RleBitmap *rle) {
91 t *= 0.1; /* Slow-mo to see what happens */
93 int cx, cy, count = 0;
99 static float sin120 = 0.86602540378f;
100 static float cos120 = -0.5f;
105 nx = x * cost - y * sint;
106 ny = y * cost + x * sint;
109 propellerState.circleX[0] = (int)(x + 0.5f) + 16;
110 propellerState.circleY[0] = (int)(y + 0.5f) + 16;
112 /* Rotate by 120 degrees, for the second circle */
113 nx = x * cos120 - y * sin120;
114 ny = y * cos120 + x * sin120;
117 propellerState.circleX[1] = (int)(x + 0.5f) + 16;
118 propellerState.circleY[1] = (int)(y + 0.5f) + 16;
121 nx = x * cos120 - y * sin120;
122 ny = y * cos120 + x * sin120;
125 propellerState.circleX[2] = (int)(x + 0.5f) + 16;
126 propellerState.circleY[2] = (int)(y + 0.5f) + 16;
128 /* Write effect to the mini fx buffer*/
130 for (j = 0; j < 32; j++) {
131 for (i = 0; i < 32; i++) {
135 cx = propellerState.circleX[0] - i;
136 cy = propellerState.circleY[0] - j;
137 if (cx * cx + cy * cy < PROPELLER_CIRCLE_RADIUS_SQ)
141 cx = propellerState.circleX[1] - i;
142 cy = propellerState.circleY[1] - j;
143 if (cx * cx + cy * cy < PROPELLER_CIRCLE_RADIUS_SQ)
147 cx = propellerState.circleX[2] - i;
148 cy = propellerState.circleY[2] - j;
149 if (cx * cx + cy * cy < PROPELLER_CIRCLE_RADIUS_SQ)
156 /* Then, encode to rle */
157 rleEncode(rle, miniFXBuffer, 32, 32);
159 /* Distribute the produced streaks so that they don't produce garbage when interpolated */
160 rleDistributeStreaks(rle);