/**
* THIS IS CREATED BY tom_mai78101. PLEASE GIVE CREDIT FOR WORKING ON A CLONE.
*
* ALL WORKS COPYRIGHTED TO The Pokémon Company and Nintendo. I REPEAT, THIS IS A CLONE.
*
* YOU MAY NOT SELL COMMERCIALLY, OR YOU WILL BE PROSECUTED BY The Pokémon Company AND Nintendo.
*
* THE CREATOR IS NOT LIABLE FOR ANY DAMAGES DONE. FOLLOW LOCAL LAWS, BE RESPECTFUL, AND HAVE A GOOD DAY!
* */
package screen;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.util.Arrays;
import java.util.Random;
import level.PixelData;
import level.WorldConstants;
import resources.Art;
import resources.Mod;
public class BaseScreen extends BaseBitmap {
// TODO: Add more drawing functions that enable more controls when it comes to rendering assets.
protected BufferedImage image;
protected int xOffset;
protected int yOffset;
private byte tick = 0x7;
// private boolean cutScreen;
public BaseScreen(int w, int h) {
super(w, h);
this.image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
this.pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
}
public void loadResources() {
Art.loadAllResources(this);
Mod.loadModdedResources();
}
public BufferedImage getBufferedImage() {
return image;
}
public void clear(int color) {
Arrays.fill(pixels, color);
}
public void blit(BaseBitmap bitmap, int x, int y) {
if (bitmap != null)
this.blit(bitmap, x + this.xOffset, y + this.yOffset, bitmap.width, bitmap.height);
}
public void blitBiome(BaseBitmap bitmap, int x, int y, PixelData data) {
if (bitmap != null) {
this.blitBiome(bitmap, x + this.xOffset, y + this.yOffset, bitmap.width, bitmap.height, data);
}
}
public void npcBlit(BaseBitmap bitmap, int x, int y) {
if (bitmap != null)
this.blit(bitmap, x + this.xOffset, y + this.yOffset - 4, bitmap.width, bitmap.height);
}
public void blit(BaseBitmap bitmap, int x, int y, int w, int h) {
// This directly blits the bitmap to the X and Y coordinates within the screen area.
// The Rect adjusts the blitting area to within the screen area.
if (w <= -1)
w = bitmap.width;
if (h <= -1)
h = bitmap.height;
Rect blitArea = new Rect(x, y, w, h).adjust(this);
int blitWidth = blitArea.bottomRightCorner_X - blitArea.topLeftCorner_X;
for (int yy = blitArea.topLeftCorner_Y; yy < blitArea.bottomRightCorner_Y; yy++) {
int tgt = yy * this.width + blitArea.topLeftCorner_X;
int src = (yy - y) * bitmap.width + (blitArea.topLeftCorner_X - x);
tgt -= src;
for (int xx = src; xx < src + blitWidth; xx++) {
int color = bitmap.pixels[xx];
int alpha = (color >> 24) & 0xFF;
if (alpha == 0xFF) {
this.pixels[tgt + xx] = color;
}
}
}
}
public void blitBiome(BaseBitmap bitmap, int x, int y, int w, int h, PixelData data) {
// This directly blits the bitmap to the X and Y coordinates within the screen area.
// The Rect adjusts the blitting area to within the screen area.
if (w <= -1)
w = bitmap.width;
if (h <= -1)
h = bitmap.height;
Rect blitArea = new Rect(x, y, w, h).adjust(this);
int blitWidth = blitArea.bottomRightCorner_X - blitArea.topLeftCorner_X;
int dataColor = data.getColor();
int tileID = (dataColor >> 24) & 0xFF;
int red = (dataColor >> 16) & 0xFF;
int green = (dataColor >> 8) & 0xFF;
int blue = dataColor & 0xFF;
int biomeColor = getBiomeBaseColor(tileID, red, green, blue);
int tick = 0;
for (int yy = blitArea.topLeftCorner_Y; yy < blitArea.bottomRightCorner_Y; yy++) {
int tgt = yy * this.width + blitArea.topLeftCorner_X;
int src = (yy - y) * bitmap.width + (blitArea.topLeftCorner_X - x);
tgt -= src;
for (int xx = src; xx < src + blitWidth; xx++) {
int color = bitmap.pixels[xx];
int alpha = (color >> 24) & 0xFF;
// This alpha value determines the areas in the bitmap what to draw.
// Has nothing to do with pixel data properties.
switch (alpha) {
case 0x0:
// Biome Color with a bit of speckled light/dark patches.
if ((tick++ % 17 < 7) && (tick++ % 21 < 2))
this.pixels[tgt + xx] = lighten(biomeColor, 0.07f);
else if ((tick++ % 23 < 4) && (tick++ % 19 < 3))
this.pixels[tgt + xx] = BaseScreen.darken(biomeColor, 0.07f);
else
this.pixels[tgt + xx] = biomeColor;
tick++;
if (tick > w * w)
tick = 0;
break;
case 0x32:
this.pixels[tgt + xx] = lighten(biomeColor, 0.003f);
break;
case 0x64:
this.pixels[tgt + xx] = lighten(biomeColor, 0.006f);
break;
default:
this.pixels[tgt + xx] = color;
break;
}
}
}
}
public void setOffset(int xOff, int yOff) {
this.xOffset = xOff;
this.yOffset = yOff;
}
public void createStaticNoise(Random r) {
for (int p = 0; p < pixels.length; p++)
pixels[p] = r.nextInt();
}
public int getXOffset() {
return xOffset;
}
public int getYOffset() {
return yOffset;
}
public boolean invert() {
if (this.tick < 0x2) {
for (int i = 0; i < this.pixels.length; i++)
this.pixels[i] = 0xFF000000 | (0xAAAAAA - (this.pixels[i] & 0xFFFFFF));
this.tick++;
return true;
}
if (this.tick < 0x6) {
for (int i = 0; i < this.pixels.length; i++)
this.pixels[i] = 0xFFAAAAAA;
this.tick++;
return true;
}
this.tick = 0x7;
return false;
}
public boolean flashing() {
if (this.tick < 0x2) {
for (int i = 0; i < this.pixels.length; i++)
this.pixels[i] = 0xFFAAAAAA;
this.tick++;
return true;
}
else if (this.tick < 0x4) {
for (int i = 0; i < this.pixels.length; i++)
this.pixels[i] = 0xFFF7F7F7;
this.tick++;
return true;
}
else if (this.tick < 0x6) {
for (int i = 0; i < this.pixels.length; i++)
this.pixels[i] = 0xFFAAAAAA;
this.tick++;
return true;
}
this.tick = 0x7;
return false;
}
public void setRenderingEffectTick(byte value) {
this.tick = value;
}
public byte getRenderingEffectTick() {
return this.tick;
}
// -------------------------------------------
// Private methods
private int getBiomeBaseColor(int tileID, int red, int green, int blue) {
int color = WorldConstants.GRASS_GREEN;
switch (tileID) {
case 0x01: // Grass
switch (red) {
case 0x00:
switch (green) {
case 0x00:
break;
default:
break;
}
break;
case 0x01: // Mountain ground
for (int i = 0; i < blue; i++) {
color = lighten(color, 0.1f);
}
break;
default:
break;
}
break;
case 0x02: // Ledges
switch (green) {
case 0x00:
break;
case 0x01:
color = WorldConstants.MOUNTAIN_BROWN;
break;
}
break;
case 0x06: // Stairs
switch (green) {
case 0x00:
break;
case 0x01:
color = WorldConstants.MOUNTAIN_BROWN;
break;
}
break;
default:
break;
}
return color;
}
public void reload() {
this.tick = 0x7;
}
public static int lighten(int color, float amount) {
// int a = (color >> 24) & 0xFF;
int r = (color >> 16) & 0xFF;
int g = (color >> 8) & 0xFF;
int b = color & 0xFF;
return 0xFF000000 | ((int) Math.min(255, r + 255 * amount) & 0xFF) << 16 | ((int) Math.min(255, g + 255 * amount) & 0xFF) << 8 | (int) Math.min(255, b + 255 * amount) & 0xFF;
}
public static int darken(int color, float amount) {
int r = (color >> 16) & 0xFF;
int g = (color >> 8) & 0xFF;
int b = color & 0xFF;
return 0xFF000000 | ((int) Math.min(255, r - 255 * amount) & 0xFF) << 16 | ((int) Math.min(255, g - 255 * amount) & 0xFF) << 8 | (int) Math.min(255, b - 255 * amount) & 0xFF;
}
}