1 // Copyright (C) 2009 The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #pragma version(1) 16 #pragma stateVertex(PVOrtho) 17 #pragma stateStore(PSSolid) 18 19 #define MAX_PULSES 20 20 #define MAX_EXTRAS 40 21 #define PULSE_SIZE 14 // Size in pixels of a cell 22 #define HALF_PULSE_SIZE 7 23 #define GLOW_SIZE 64 // Size of the leading glow in pixels 24 #define HALF_GLOW_SIZE 32 25 #define SPEED 0.2f // (200 / 1000) Pixels per ms 26 #define SPEED_VARIANCE 0.3f 27 #define PULSE_NORMAL 0 28 #define PULSE_EXTRA 1 29 #define TRAIL_SIZE 40 // Number of cells in a trail 30 #define MAX_DELAY 2000 // Delay between a pulse going offscreen and restarting 31 32 struct pulse_s { 33 int pulseType; 34 float originX; 35 float originY; 36 int color; 37 int startTime; 38 float dx; 39 float dy; 40 int active; 41 }; 42 struct pulse_s gPulses[MAX_PULSES]; 43 44 struct pulse_s gExtras[MAX_EXTRAS]; 45 46 int gNow; 47 48 49 void setColor(int c) { 50 if (State->mode == 1) { 51 // sholes red 52 color(0.9f, 0.1f, 0.1f, 0.8f); 53 } else if (c == 0) { 54 // red 55 color(1.0f, 0.0f, 0.0f, 0.8f); 56 } else if (c == 1) { 57 // green 58 color(0.0f, 0.8f, 0.0f, 0.8f); 59 } else if (c == 2) { 60 // blue 61 color(0.0f, 0.4f, 0.9f, 0.8f); 62 } else if (c == 3) { 63 // yellow 64 color(1.0f, 0.8f, 0.0f, 0.8f); 65 } 66 } 67 68 void initPulse(struct pulse_s * pulse, int pulseType) { 69 if (randf(1) > 0.5f) { 70 pulse->originX = (int)randf(State->width * 2 / PULSE_SIZE) * PULSE_SIZE; 71 pulse->dx = 0; 72 if (randf(1) > 0.5f) { 73 // Top 74 pulse->originY = 0; 75 pulse->dy = randf2(1.0f - SPEED_VARIANCE, 1.0 + SPEED_VARIANCE); 76 } else { 77 // Bottom 78 pulse->originY = State->height; 79 pulse->dy = -randf2(1.0f - SPEED_VARIANCE, 1.0 + SPEED_VARIANCE); 80 } 81 } else { 82 pulse->originY = (int)randf(State->height / PULSE_SIZE) * PULSE_SIZE; 83 pulse->dy = 0; 84 if (randf(1) > 0.5f) { 85 // Left 86 pulse->originX = 0; 87 pulse->dx = randf2(1.0f - SPEED_VARIANCE, 1.0 + SPEED_VARIANCE); 88 } else { 89 // Right 90 pulse->originX = State->width * 2; 91 pulse->dx = -randf2(1.0f - SPEED_VARIANCE, 1.0 + SPEED_VARIANCE); 92 } 93 } 94 pulse->startTime = gNow + (int)randf(MAX_DELAY); 95 96 pulse->color = (int)randf(4.0f); 97 98 pulse->pulseType = pulseType; 99 if (pulseType == PULSE_EXTRA) { 100 pulse->active = 0; 101 } else { 102 pulse->active = 1; 103 } 104 } 105 106 void initPulses() { 107 gNow = uptimeMillis(); 108 int i; 109 for (i=0; i<MAX_PULSES; i++) { 110 initPulse(&gPulses[i], PULSE_NORMAL); 111 } 112 for (i=0; i<MAX_EXTRAS; i++) { 113 struct pulse_s * p = &gExtras[i]; 114 p->pulseType = PULSE_EXTRA; 115 p->active = 0; 116 } 117 } 118 119 void drawBackground(int width, int height) { 120 bindProgramFragment(NAMED_PFTextureBG); 121 bindTexture(NAMED_PFTextureBG, 0, NAMED_TBackground); 122 color(1.0f, 1.0f, 1.0f, 1.0f); 123 if (State->rotate) { 124 drawRect(0.0f, 0.0f, height*2, width, 0.0f); 125 } else { 126 drawRect(0.0f, 0.0f, width*2, height, 0.0f); 127 } 128 } 129 130 131 void drawPulses(struct pulse_s * pulseSet, int setSize) { 132 bindProgramFragment(NAMED_PFTexture); 133 bindProgramFragmentStore(NAMED_PSBlend); 134 135 float matrix[16]; 136 137 int i; 138 for (i=0; i<setSize; i++) { 139 struct pulse_s * p = &pulseSet[i]; 140 141 int delta = gNow - p->startTime; 142 143 if (p->active != 0 && delta >= 0) { 144 145 float x = p->originX + (p->dx * SPEED * delta); 146 float y = p->originY + (p->dy * SPEED * delta); 147 148 matrixLoadIdentity(matrix); 149 if (p->dx < 0) { 150 vpLoadTextureMatrix(matrix); 151 float xx = x + (TRAIL_SIZE * PULSE_SIZE); 152 if (xx <= 0) { 153 initPulse(p, p->pulseType); 154 } else { 155 setColor(p->color); 156 bindTexture(NAMED_PFTexture, 0, NAMED_TPulse); 157 drawRect(x, y, xx, y + PULSE_SIZE, 0.0f); 158 bindTexture(NAMED_PFTexture, 0, NAMED_TGlow); 159 drawRect(x + HALF_PULSE_SIZE - HALF_GLOW_SIZE, 160 y + HALF_PULSE_SIZE - HALF_GLOW_SIZE, 161 x + HALF_PULSE_SIZE + HALF_GLOW_SIZE, 162 y + HALF_PULSE_SIZE + HALF_GLOW_SIZE, 163 0.0f); 164 } 165 } else if (p->dx > 0) { 166 x += PULSE_SIZE; // need to start on the other side of this cell 167 vpLoadTextureMatrix(matrix); 168 float xx = x - (TRAIL_SIZE * PULSE_SIZE); 169 if (xx >= State->width * 2) { 170 initPulse(p, p->pulseType); 171 } else { 172 setColor(p->color); 173 bindTexture(NAMED_PFTexture, 0, NAMED_TPulse); 174 drawRect(x, y, xx, y + PULSE_SIZE, 0.0f); 175 bindTexture(NAMED_PFTexture, 0, NAMED_TGlow); 176 drawRect(x - HALF_PULSE_SIZE - HALF_GLOW_SIZE, 177 y + HALF_PULSE_SIZE - HALF_GLOW_SIZE, 178 x - HALF_PULSE_SIZE + HALF_GLOW_SIZE, 179 y + HALF_PULSE_SIZE + HALF_GLOW_SIZE, 180 0.0f); 181 } 182 } else if (p->dy < 0) { 183 vpLoadTextureMatrix(matrix); 184 float yy = y + (TRAIL_SIZE * PULSE_SIZE); 185 if (yy <= 0) { 186 initPulse(p, p->pulseType); 187 } else { 188 setColor(p->color); 189 bindTexture(NAMED_PFTexture, 0, NAMED_TPulseVert); 190 drawRect(x, yy, x + PULSE_SIZE, y, 0.0f); 191 bindTexture(NAMED_PFTexture, 0, NAMED_TGlow); 192 drawRect(x + HALF_PULSE_SIZE - HALF_GLOW_SIZE, 193 y + HALF_PULSE_SIZE - HALF_GLOW_SIZE, 194 x + HALF_PULSE_SIZE + HALF_GLOW_SIZE, 195 y + HALF_PULSE_SIZE + HALF_GLOW_SIZE, 196 0.0f); 197 } 198 } else if (p->dy > 0) { 199 y += PULSE_SIZE; // need to start on the other side of this cell 200 vpLoadTextureMatrix(matrix); 201 float yy = y - (TRAIL_SIZE * PULSE_SIZE); 202 if (yy >= State->height) { 203 initPulse(p, p->pulseType); 204 } else { 205 setColor(p->color); 206 bindTexture(NAMED_PFTexture, 0, NAMED_TPulseVert); 207 drawRect(x, yy, x + PULSE_SIZE, y, 0.0f); 208 bindTexture(NAMED_PFTexture, 0, NAMED_TGlow); 209 drawRect(x + HALF_PULSE_SIZE - HALF_GLOW_SIZE, 210 y - HALF_PULSE_SIZE - HALF_GLOW_SIZE, 211 x + HALF_PULSE_SIZE + HALF_GLOW_SIZE, 212 y - HALF_PULSE_SIZE + HALF_GLOW_SIZE, 213 0.0f); 214 } 215 } 216 } 217 } 218 219 220 matrixLoadIdentity(matrix); 221 vpLoadTextureMatrix(matrix); 222 } 223 224 void addTap(int x, int y) { 225 int i; 226 int count = 0; 227 int color = (int)randf(4.0f); 228 x = (int)(x / PULSE_SIZE) * PULSE_SIZE; 229 y = (int)(y / PULSE_SIZE) * PULSE_SIZE; 230 for (i=0; i<MAX_EXTRAS; i++) { 231 struct pulse_s * p = &gExtras[i]; 232 if (p->active == 0) { 233 p->originX = x; 234 p->originY = y; 235 236 if (count == 0) { 237 p->dx = 1.5f; 238 p->dy = 0.0f; 239 } else if (count == 1) { 240 p->dx = -1.5f; 241 p->dy = 0.0f; 242 } else if (count == 2) { 243 p->dx = 0.0f; 244 p->dy = 1.5f; 245 } else if (count == 3) { 246 p->dx = 0.0f; 247 p->dy = -1.5f; 248 } 249 250 p->active = 1; 251 p->color = color; 252 color++; 253 if (color >= 4) { 254 color = 0; 255 } 256 p->startTime = gNow; 257 count++; 258 if (count == 4) { 259 break; 260 } 261 } 262 } 263 } 264 265 int main(int index) { 266 267 gNow = uptimeMillis(); 268 269 if (Command->command != 0) { 270 //debugF("x", Command->x); 271 //debugF("y", Command->y); 272 Command->command = 0; 273 addTap(Command->x, Command->y); 274 } 275 276 int width = State->width; 277 int height = State->height; 278 279 float matrix[16]; 280 matrixLoadIdentity(matrix); 281 if (State->rotate) { 282 //matrixLoadRotate(matrix, 90.0f, 0.0f, 0.0f, 1.0f); 283 //matrixTranslate(matrix, 0.0f, -height, 1.0f); 284 // XXX: HAX: do not slide display in landscape 285 } else { 286 matrixTranslate(matrix, -(State->xOffset * width), 0, 0); 287 } 288 289 vpLoadModelMatrix(matrix); 290 291 drawBackground(width, height); 292 293 drawPulses(gPulses, MAX_PULSES); 294 drawPulses(gExtras, MAX_EXTRAS); 295 296 return 45; 297 } 298