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 float scale; 41 int active; 42 }; 43 struct pulse_s gPulses[MAX_PULSES]; 44 45 struct pulse_s gExtras[MAX_EXTRAS]; 46 47 int gNow; 48 49 50 void setColor(int c) { 51 if (State->mode == 1) { 52 // sholes red 53 color(0.9f, 0.1f, 0.1f, 0.8f); 54 } else if (c == 0) { 55 // red 56 color(1.0f, 0.0f, 0.0f, 0.8f); 57 } else if (c == 1) { 58 // green 59 color(0.0f, 0.8f, 0.0f, 0.8f); 60 } else if (c == 2) { 61 // blue 62 color(0.0f, 0.4f, 0.9f, 0.8f); 63 } else if (c == 3) { 64 // yellow 65 color(1.0f, 0.8f, 0.0f, 0.8f); 66 } 67 } 68 69 void initPulse(struct pulse_s * pulse, int pulseType) { 70 float scale = randf2(0.7f, 1.7f); 71 pulse->scale = scale; 72 if (randf(1) > 0.5f) { 73 pulse->originX = (int)randf(State->width * 2 / PULSE_SIZE) * PULSE_SIZE; 74 pulse->dx = 0; 75 if (randf(1) > 0.5f) { 76 // Top 77 pulse->originY = 0; 78 pulse->dy = scale; 79 } else { 80 // Bottom 81 pulse->originY = State->height / scale; 82 pulse->dy = -scale; 83 } 84 } else { 85 pulse->originY = (int)randf(State->height / PULSE_SIZE) * PULSE_SIZE; 86 pulse->dy = 0; 87 if (randf(1) > 0.5f) { 88 // Left 89 pulse->originX = 0; 90 pulse->dx = scale; 91 } else { 92 // Right 93 pulse->originX = State->width * 2 / scale; 94 pulse->dx = -scale; 95 } 96 } 97 pulse->startTime = gNow + (int)randf(MAX_DELAY); 98 99 pulse->color = (int)randf(4.0f); 100 101 pulse->pulseType = pulseType; 102 if (pulseType == PULSE_EXTRA) { 103 pulse->active = 0; 104 } else { 105 pulse->active = 1; 106 } 107 } 108 109 void initPulses() { 110 gNow = uptimeMillis(); 111 int i; 112 for (i=0; i<MAX_PULSES; i++) { 113 initPulse(&gPulses[i], PULSE_NORMAL); 114 } 115 for (i=0; i<MAX_EXTRAS; i++) { 116 struct pulse_s * p = &gExtras[i]; 117 p->pulseType = PULSE_EXTRA; 118 p->active = 0; 119 } 120 } 121 122 void drawBackground(int width, int height) { 123 bindProgramFragment(NAMED_PFTextureBG); 124 bindTexture(NAMED_PFTextureBG, 0, NAMED_TBackground); 125 color(1.0f, 1.0f, 1.0f, 1.0f); 126 if (State->rotate) { 127 drawRect(0.0f, 0.0f, height*2, width, 0.0f); 128 } else { 129 drawRect(0.0f, 0.0f, width*2, height, 0.0f); 130 } 131 } 132 133 void drawPulses(struct pulse_s * pulseSet, int setSize) { 134 bindProgramFragment(NAMED_PFTexture); 135 bindProgramFragmentStore(NAMED_PSBlend); 136 137 float matrix[16]; 138 float modelMatrix[16]; 139 140 int i; 141 for (i=0; i<setSize; i++) { 142 struct pulse_s * p = &pulseSet[i]; 143 144 int delta = gNow - p->startTime; 145 146 if (p->active != 0 && delta >= 0) { 147 148 matrixLoadIdentity(modelMatrix); 149 if (State->rotate) { 150 //matrixLoadRotate(modelMatrix, 90.0f, 0.0f, 0.0f, 1.0f); 151 //matrixTranslate(modelMatrix, 0.0f, -height, 1.0f); 152 // XXX: HAX: do not slide display in landscape 153 } else { 154 matrixTranslate(modelMatrix, -(State->xOffset * State->width), 0, 0); 155 } 156 matrixScale(modelMatrix, p->scale, p->scale, 1.0f); 157 vpLoadModelMatrix(modelMatrix); 158 159 float x = p->originX + (p->dx * SPEED * delta); 160 float y = p->originY + (p->dy * SPEED * delta); 161 162 matrixLoadIdentity(matrix); 163 if (p->dx < 0) { 164 vpLoadTextureMatrix(matrix); 165 float xx = x + (TRAIL_SIZE * PULSE_SIZE); 166 if (xx <= 0) { 167 initPulse(p, p->pulseType); 168 } else { 169 setColor(p->color); 170 bindTexture(NAMED_PFTexture, 0, NAMED_TPulse); 171 drawRect(x, y, xx, y + PULSE_SIZE, 0.0f); 172 bindTexture(NAMED_PFTexture, 0, NAMED_TGlow); 173 drawRect(x + HALF_PULSE_SIZE - HALF_GLOW_SIZE, 174 y + HALF_PULSE_SIZE - HALF_GLOW_SIZE, 175 x + HALF_PULSE_SIZE + HALF_GLOW_SIZE, 176 y + HALF_PULSE_SIZE + HALF_GLOW_SIZE, 177 0.0f); 178 } 179 } else if (p->dx > 0) { 180 x += PULSE_SIZE; // need to start on the other side of this cell 181 vpLoadTextureMatrix(matrix); 182 float xx = x - (TRAIL_SIZE * PULSE_SIZE); 183 if (xx >= State->width * 2) { 184 initPulse(p, p->pulseType); 185 } else { 186 setColor(p->color); 187 bindTexture(NAMED_PFTexture, 0, NAMED_TPulse); 188 drawRect(x, y, xx, y + PULSE_SIZE, 0.0f); 189 bindTexture(NAMED_PFTexture, 0, NAMED_TGlow); 190 drawRect(x - HALF_PULSE_SIZE - HALF_GLOW_SIZE, 191 y + HALF_PULSE_SIZE - HALF_GLOW_SIZE, 192 x - HALF_PULSE_SIZE + HALF_GLOW_SIZE, 193 y + HALF_PULSE_SIZE + HALF_GLOW_SIZE, 194 0.0f); 195 } 196 } else if (p->dy < 0) { 197 vpLoadTextureMatrix(matrix); 198 float yy = y + (TRAIL_SIZE * PULSE_SIZE); 199 if (yy <= 0) { 200 initPulse(p, p->pulseType); 201 } else { 202 setColor(p->color); 203 bindTexture(NAMED_PFTexture, 0, NAMED_TPulseVert); 204 drawRect(x, yy, x + PULSE_SIZE, y, 0.0f); 205 bindTexture(NAMED_PFTexture, 0, NAMED_TGlow); 206 drawRect(x + HALF_PULSE_SIZE - HALF_GLOW_SIZE, 207 y + HALF_PULSE_SIZE - HALF_GLOW_SIZE, 208 x + HALF_PULSE_SIZE + HALF_GLOW_SIZE, 209 y + HALF_PULSE_SIZE + HALF_GLOW_SIZE, 210 0.0f); 211 } 212 } else if (p->dy > 0) { 213 y += PULSE_SIZE; // need to start on the other side of this cell 214 vpLoadTextureMatrix(matrix); 215 float yy = y - (TRAIL_SIZE * PULSE_SIZE); 216 if (yy >= State->height) { 217 initPulse(p, p->pulseType); 218 } else { 219 setColor(p->color); 220 bindTexture(NAMED_PFTexture, 0, NAMED_TPulseVert); 221 drawRect(x, yy, x + PULSE_SIZE, y, 0.0f); 222 bindTexture(NAMED_PFTexture, 0, NAMED_TGlow); 223 drawRect(x + HALF_PULSE_SIZE - HALF_GLOW_SIZE, 224 y - HALF_PULSE_SIZE - HALF_GLOW_SIZE, 225 x + HALF_PULSE_SIZE + HALF_GLOW_SIZE, 226 y - HALF_PULSE_SIZE + HALF_GLOW_SIZE, 227 0.0f); 228 } 229 } 230 } 231 } 232 233 234 matrixLoadIdentity(matrix); 235 vpLoadTextureMatrix(matrix); 236 } 237 238 void addTap(int x, int y) { 239 int i; 240 int count = 0; 241 int color = (int)randf(4.0f); 242 float scale = randf2(0.9f, 1.9f); 243 x = (int)(x / PULSE_SIZE) * PULSE_SIZE; 244 y = (int)(y / PULSE_SIZE) * PULSE_SIZE; 245 for (i=0; i<MAX_EXTRAS; i++) { 246 struct pulse_s * p = &gExtras[i]; 247 if (p->active == 0) { 248 p->originX = x/scale; 249 p->originY = y/scale; 250 p->scale = scale; 251 252 if (count == 0) { 253 p->dx = scale; 254 p->dy = 0.0f; 255 } else if (count == 1) { 256 p->dx = -scale; 257 p->dy = 0.0f; 258 } else if (count == 2) { 259 p->dx = 0.0f; 260 p->dy = scale; 261 } else if (count == 3) { 262 p->dx = 0.0f; 263 p->dy = -scale; 264 } 265 266 p->active = 1; 267 p->color = color; 268 color++; 269 if (color >= 4) { 270 color = 0; 271 } 272 p->startTime = gNow; 273 count++; 274 if (count == 4) { 275 break; 276 } 277 } 278 } 279 } 280 281 int main(int index) { 282 283 gNow = uptimeMillis(); 284 285 if (Command->command != 0) { 286 //debugF("x", Command->x); 287 //debugF("y", Command->y); 288 Command->command = 0; 289 addTap(Command->x, Command->y); 290 } 291 292 int width = State->width; 293 int height = State->height; 294 295 float matrix[16]; 296 matrixLoadIdentity(matrix); 297 if (State->rotate) { 298 //matrixLoadRotate(matrix, 90.0f, 0.0f, 0.0f, 1.0f); 299 //matrixTranslate(matrix, 0.0f, -height, 1.0f); 300 // XXX: HAX: do not slide display in landscape 301 } else { 302 matrixTranslate(matrix, -(State->xOffset * width), 0, 0); 303 } 304 305 vpLoadModelMatrix(matrix); 306 307 drawBackground(width, height); 308 309 drawPulses(gPulses, MAX_PULSES); 310 drawPulses(gExtras, MAX_EXTRAS); 311 312 return 45; 313 } 314