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(PVBackground) 17 #pragma stateRaster(parent) 18 #pragma stateFragment(PFBackground) 19 20 #define RSID_NOISESRC1 1 21 #define RSID_NOISESRC2 2 22 #define RSID_NOISESRC3 3 23 #define RSID_NOISESRC4 4 24 #define RSID_NOISESRC5 5 25 #define RSID_NOISEDST1 6 26 #define RSID_NOISEDST2 7 27 #define RSID_NOISEDST3 8 28 #define RSID_NOISEDST4 9 29 #define RSID_NOISEDST5 10 30 31 float xshift[5]; 32 float rotation[5]; 33 float scale[5]; 34 float alphafactor; 35 int currentpreset; 36 int lastuptime; 37 float timedelta; 38 39 void drawCloud(float *ident, int id, int idx) { 40 float mat1[16]; 41 float z = -8.f * idx; 42 matrixLoadMat(mat1,ident); 43 matrixTranslate(mat1, -State->mXOffset * 8.f * idx, -State->mTilt * idx / 3.f, 0.f); 44 matrixRotate(mat1, rotation[idx], 0.f, 0.f, 1.f); 45 vpLoadModelMatrix(mat1); 46 47 bindTexture(NAMED_PFBackground, 0, id); 48 drawQuadTexCoords( 49 -1200.0f, -1200.0f, z, // space 50 0.f + xshift[idx], 0.f, // texture 51 1200, -1200.0f, z, // space 52 scale[idx] + xshift[idx], 0.f, // texture 53 1200, 1200.0f, z, // space 54 scale[idx] + xshift[idx], scale[idx], // texture 55 -1200.0f, 1200.0f, z, // space 56 0.f + xshift[idx], scale[idx]); // texture 57 } 58 59 void drawClouds(float* ident) { 60 61 int i; 62 63 float mat1[16]; 64 65 matrixLoadMat(mat1,ident); 66 67 if (State->mRotate != 0) { 68 rotation[0] += 0.10 * timedelta; 69 rotation[1] += 0.102f * timedelta; 70 rotation[2] += 0.106f * timedelta; 71 rotation[3] += 0.114f * timedelta; 72 rotation[4] += 0.123f * timedelta; 73 } 74 75 int mask = State->mTextureMask; 76 if (mask & 1) { 77 xshift[0] += 0.0010f * timedelta; 78 if (State->mTextureSwap != 0) { 79 drawCloud(mat1, NAMED_Tnoise5, 0); 80 } else { 81 drawCloud(mat1, NAMED_Tnoise1, 0); 82 } 83 } 84 85 if (mask & 2) { 86 xshift[1] += 0.00106 * timedelta; 87 drawCloud(mat1, NAMED_Tnoise2, 1); 88 } 89 90 if (mask & 4) { 91 xshift[2] += 0.00114f * timedelta; 92 drawCloud(mat1, NAMED_Tnoise3, 2); 93 } 94 95 if (mask & 8) { 96 xshift[3] += 0.00118f * timedelta; 97 drawCloud(mat1, NAMED_Tnoise4, 3); 98 } 99 100 if (mask & 16) { 101 xshift[4] += 0.00127f * timedelta; 102 drawCloud(mat1, NAMED_Tnoise5, 4); 103 } 104 105 // Make sure the texture coordinates don't continuously increase 106 for(i = 0; i < 5; i++) { 107 while (xshift[i] >= 1.f) { 108 xshift[i] -= 1.f; 109 } 110 } 111 // Make sure the rotation angles don't continuously increase 112 for(i = 0; i < 5; i++) { 113 while (rotation[i] >= 360.f) { 114 rotation[i] -= 360.f; 115 } 116 } 117 } 118 119 int premul(int rgb, int a) { 120 int r = (rgb >> 16) * a + 1; 121 r = (r + (r >> 8)) >> 8; 122 int g = ((rgb >> 8) & 0xff) * a + 1; 123 g = (g + (g >> 8)) >> 8; 124 int b = (rgb & 0xff) * a + 1; 125 b = (b + (b >> 8)) >> 8; 126 return r << 16 | g << 8 | b; 127 } 128 129 void makeTexture(int *src, int *dst, int rsid) { 130 131 int x; 132 int y; 133 int pm = State->mPreMul; 134 135 if (State->mProcessTextureMode == 1) { 136 int lowcol = State->mLowCol; 137 int highcol = State->mHighCol; 138 139 for (y=0;y<256;y++) { 140 for (x=0;x<256;x++) { 141 int pix = src[y*256+x]; 142 int lum = pix & 0x00ff; 143 int newpix; 144 if (lum < 128) { 145 newpix = lowcol; 146 int newalpha = 255 - (lum * 2); 147 newalpha /= alphafactor; 148 if (pm) newpix = premul(newpix, newalpha); 149 newpix = newpix | (newalpha << 24); 150 } else { 151 newpix = highcol; 152 int newalpha = (lum - 128) * 2; 153 newalpha /= alphafactor; 154 if (pm) newpix = premul(newpix, newalpha); 155 newpix = newpix | (newalpha << 24); 156 } 157 // have ARGB, need ABGR 158 newpix = (newpix & 0xff00ff00) | ((newpix & 0xff) << 16) | ((newpix >> 16) & 0xff); 159 dst[y*256+x] = newpix; 160 } 161 } 162 alphafactor *= State->mAlphaMul; 163 } else if (State->mProcessTextureMode == 2) { 164 int lowcol = State->mLowCol; 165 int highcol = State->mHighCol; 166 float scale = 255.f / (255.f - lowcol); 167 168 for (y=0;y<256;y++) { 169 for (x=0;x<256;x++) { 170 int pix = src[y*256+x]; 171 int alpha = pix & 0x00ff; 172 if (alpha < lowcol) { 173 alpha = 0; 174 } else { 175 alpha = (alpha - lowcol) * scale; 176 } 177 alpha /= alphafactor; 178 int newpix = highcol; 179 if (pm) newpix = premul(newpix, alpha); 180 newpix = newpix | (alpha << 24); 181 // have ARGB, need ABGR 182 newpix = (newpix & 0xff00ff00) | ((newpix & 0xff) << 16) | ((newpix >> 16) & 0xff); 183 dst[y*256+x] = newpix; 184 } 185 } 186 alphafactor *= State->mAlphaMul; 187 } else if (State->mProcessTextureMode == 3) { 188 int lowcol = State->mLowCol; 189 int highcol = State->mHighCol; 190 float scale = 255.f / (255.f - lowcol); 191 192 for (y=0;y<256;y++) { 193 for (x=0;x<256;x++) { 194 int pix = src[y*256+x]; 195 int lum = pix & 0x00ff; 196 int newpix; 197 if (lum < 128) lum *= 2; 198 else lum = (255 - (lum - 128) * 2); 199 if (lum < 128) { 200 newpix = lowcol; 201 int newalpha = 255 - (lum * 2); 202 newalpha /= alphafactor; 203 if (pm) newpix = premul(newpix, newalpha); 204 newpix = newpix | (newalpha << 24); 205 } else { 206 newpix = highcol; 207 int newalpha = (lum - 128) * 2; 208 newalpha /= alphafactor; 209 if (pm) newpix = premul(newpix, newalpha); 210 newpix = newpix | (newalpha << 24); 211 } 212 // have ARGB, need ABGR 213 newpix = (newpix & 0xff00ff00) | ((newpix & 0xff) << 16) | ((newpix >> 16) & 0xff); 214 dst[y*256+x] = newpix; 215 } 216 } 217 alphafactor *= State->mAlphaMul; 218 } else { 219 220 for (y=0;y<256;y++) { 221 for (x=0;x<256;x++) { 222 int rgb = *src++; 223 int a = (rgb >> 24) & 0xff; 224 rgb &= 0x00ffffff; 225 rgb = premul(rgb, a); 226 int newpix = (a << 24) | rgb; 227 newpix = (newpix & 0xff00ff00) | ((newpix & 0xff) << 16) | ((newpix >> 16) & 0xff); 228 *dst++ = newpix; 229 } 230 } 231 } 232 uploadToTexture(rsid, 0); 233 } 234 235 void makeTextures() { 236 debugI32("makeTextures", State->mPreset); 237 alphafactor = 1.f; 238 makeTexture((int*)noisesrc1, (int*)noisedst1, NAMED_Tnoise1); 239 makeTexture((int*)noisesrc2, (int*)noisedst2, NAMED_Tnoise2); 240 makeTexture((int*)noisesrc3, (int*)noisedst3, NAMED_Tnoise3); 241 makeTexture((int*)noisesrc4, (int*)noisedst4, NAMED_Tnoise4); 242 makeTexture((int*)noisesrc5, (int*)noisedst5, NAMED_Tnoise5); 243 } 244 245 246 247 struct color { 248 float r; 249 float g; 250 float b; 251 }; 252 253 void init() { 254 int i; 255 for (i=0;i<4;i++) { 256 xshift[i] = 0.f; 257 rotation[i] = 360.f * i / 5.f; 258 } 259 scale[0] = 4.0f; // changed below based on preset 260 scale[1] = 3.0f; 261 scale[2] = 3.4f; 262 scale[3] = 3.8f; 263 scale[4] = 4.2f; 264 265 currentpreset = -1; 266 lastuptime = uptimeMillis(); 267 timedelta = 0; 268 } 269 270 271 int main(int launchID) { 272 273 int i; 274 float ident[16]; 275 float masterscale = 0.0041f;// / (State->mXOffset * 4.f + 1.f); 276 matrixLoadIdentity(ident); 277 matrixTranslate(ident, -State->mXOffset, 0.f, 0.f); 278 matrixScale(ident, masterscale, masterscale, masterscale); 279 //matrixRotate(ident, 0.f, 0.f, 0.f, 1.f); 280 matrixRotate(ident, -State->mTilt, 1.f, 0.f, 0.f); 281 282 if (State->mBlendFunc) { 283 bindProgramStore(NAMED_PFSBackgroundOne); 284 } else { 285 bindProgramStore(NAMED_PFSBackgroundSrc); 286 } 287 288 int now = uptimeMillis(); 289 timedelta = ((float)(now - lastuptime)) / 44.f; 290 lastuptime = now; 291 if (timedelta > 3) { 292 // Limit the step adjustment factor to 3, so we don't get a sudden jump 293 // after coming back from sleep. 294 timedelta = 3; 295 } 296 297 i = State->mPreset; 298 if (i != currentpreset) { 299 currentpreset = i; 300 int rgb = State->mBackCol; 301 pfClearColor( 302 ((float)((rgb >> 16) & 0xff)) / 255.0f, 303 ((float)((rgb >> 8) & 0xff)) / 255.0f, 304 ((float)(rgb & 0xff)) / 255.0f, 305 1.0f); 306 makeTextures(); 307 } 308 309 if (State->mTextureSwap != 0) { 310 scale[0] = .25f; 311 } else { 312 scale[0] = 4.f; 313 } 314 drawClouds(ident); 315 316 return 55; 317 } 318