/*
* JAME 6.2.1
* http://jame.sourceforge.net
*
* Copyright 2001, 2016 Andrea Medeghini
*
* This file is part of JAME.
*
* JAME is an application for creating fractals and other graphics artifacts.
*
* JAME is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* JAME is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with JAME. If not, see <http://www.gnu.org/licenses/>.
*
*/
package net.sf.jame.core.media.gfx;
public final class EffectFactory {
private EffectFactory() {
}
public static void waterFX(final WaterData FX, final int[] s, final int[] d, final int f, final int w, final int h) {
if ((w > 0) && (h > 0) && (f >= 0) && (f < 64)) {
for (int i = 0; i < h; i++) {
final int j = FX.data[f][i];
if ((i + j) < 0) {
final int a = i * w;
System.arraycopy(s, a, d, 0, w);
}
else if ((i + j) < h) {
final int b = i * w;
final int a = (j * w) + b;
System.arraycopy(s, a, d, b, w);
}
}
}
}
public static void waterFX(final WaterData FX, final byte[] s, final byte[] d, final int f, final int w, final int h) {
if ((w > 0) && (h > 0) && (f >= 0) && (f < 64)) {
for (int i = 0; i < h; i++) {
final int j = FX.data[f][i];
if ((i + j) < 0) {
final int a = i * w;
System.arraycopy(s, a, d, 0, w);
}
else if ((i + j) < h) {
final int b = i * w;
final int a = (j * w) + b;
System.arraycopy(s, a, d, b, w);
}
}
}
}
public static void spotFX(final SpotData FX, final int[] f, final int[] s, final int[] d, final int image_w, final int image_h) {
int a;
int b;
int a1;
int r1;
int g1;
int b1;
// int a2;
int r2;
int g2;
int b2;
int a3;
int r3;
int g3;
int b3;
int rgb1 = 0;
int rgb2 = 0;
int rgb3 = 0;
a = 0;
for (int i = 0; i < image_h; i++) {
for (int j = 0; j < image_w; j++) {
b = a + j;
rgb1 = d[b];
a1 = 0xFF & (rgb1 >> 24);
r1 = 0xFF & (rgb1 >> 16);
g1 = 0xFF & (rgb1 >> 8);
b1 = 0xFF & (rgb1 >> 0);
a1 = (a1 > 1) ? (a1 - 1) : 0;
r1 = (r1 > 1) ? (r1 - 1) : 0;
g1 = (g1 > 1) ? (g1 - 1) : 0;
b1 = (b1 > 1) ? (b1 - 1) : 0;
d[b] = (a1 << 24) | (r1 << 16) | (g1 << 8) | b1;
rgb2 = s[b];
// a2 = 0xFF & (rgb2 >> 24);
r2 = 0xFF & (rgb2 >> 16);
g2 = 0xFF & (rgb2 >> 8);
b2 = 0xFF & (rgb2 >> 0);
rgb3 = f[b];
a3 = 0xFF & (rgb3 >> 24);
r3 = 0xFF & (rgb3 >> 16);
g3 = 0xFF & (rgb3 >> 8);
b3 = 0xFF & (rgb3 >> 0);
// a3 = ((a2 * a3) + (a1 * (255 - a3))) >> 8;
// r3 = ((r2 * r3) + (r1 * (255 - r3))) >> 8;
// g3 = ((g2 * g3) + (g1 * (255 - g3))) >> 8;
// b3 = ((b2 * b3) + (b1 * (255 - b3))) >> 8;
// d[b] = s[b] = (a3 << 24) | (r3 << 16) | (g3 << 8) | b3;
a3 = 0xFF;
r3 = ((r2 * r3) + (r1 * (255 - r3))) >> 8;
g3 = ((g2 * g3) + (g1 * (255 - g3))) >> 8;
b3 = ((b2 * b3) + (b1 * (255 - b3))) >> 8;
d[b] = s[b] = (a3 << 24) | (r3 << 16) | (g3 << 8) | b3;
}
a += image_w;
}
}
public static void fireFX(final FireData FX, final byte[] d, final int f, final int w, final int h) {
if ((w > 0) && (h > 0) && (f >= 0) && (f < 256)) {
// setup flame buffer pitch
final int pitch = w << 1;
// flame vertical loop
for (int y = 1; y < (h - 4); y += 2) {
// setup current line index
final int line = y * w;
// flame horizontal loop
for (int x = 0; x < w; x++) {
// setup pixel out index
final int j = line + x;
// setup pixel in index
final int i = j + pitch;
// read in pixels
int l = d[i - 1];
int t = d[i];
int r = d[i + 1];
int b = d[i + pitch];
// adjust signed values
l &= 0xFF;
t &= 0xFF;
r &= 0xFF;
b &= 0xFF;
// setup top sum
final int top = l + t + r;
// setup bottom sum
final int bottom = b;
// combine top and bottom
int combined = (top + bottom) >> 2;
// cool down intensity
if (combined > 0) {
combined -= 1;
}
// interpolate intensity between top and bottom
final int interpolated = (combined + bottom) >> 1;
// store pixels
d[j] = (byte) combined;
d[j + w] = (byte) interpolated;
}
}
// setup flame generator start index
final int generator = w * (h - 4);
// update flame generator bar
for (int x = 0; x < w; x += 4) {
// random block color taking intensity into account
final byte color = (byte) (Math.random() * f);
for (int p = 0; p < 4; p++) {
d[generator + x + p] = color;
}
}
for (int y = 1; y < 4; y++) {
Lowlevel.copy_area(d, d, 0, h - 4, w, 1, 0, h - 4 + y, w, h, w, h);
}
}
}
}