Skip to content

Commit

Permalink
PlatformGraphics: Fix up some regressions from WritableRaster usage
Browse files Browse the repository at this point in the history
DirectGraphics' drawPixels(short[]) was broken in Crash Bandicoot
Part 1 (96x65), and drawPixels(int[]) probably was as well, but
i couldn't find a jar that used it. So both methods, AND drawRGB
are now usinga similar logic to account for scanlength.
  • Loading branch information
AShiningRay committed Nov 10, 2024
1 parent 37d9fe2 commit c706f15
Showing 1 changed file with 68 additions and 41 deletions.
109 changes: 68 additions & 41 deletions src/org/recompile/mobile/PlatformGraphics.java
Original file line number Diff line number Diff line change
Expand Up @@ -205,39 +205,37 @@ public void drawRegion(Image image, int subx, int suby, int subw, int subh, int
}

/* Based on J2ME-Loader */
public void drawRGB(int[] rgbData, int offset, int scanlength, int x, int y, int width, int height, boolean processAlpha) {
public void drawRGB(int[] rgbData, int offset, int scanlength, int x, int y, int width, int height, boolean processAlpha)
{
if (width <= 0 || height <= 0) { return; }

if (rgbData == null) { throw new NullPointerException(); }

if (offset < 0 || offset >= rgbData.length) { throw new ArrayIndexOutOfBoundsException(); }

if (scanlength > 0)
{
if (offset + scanlength * (height - 1) + width > rgbData.length) { throw new ArrayIndexOutOfBoundsException(); }
}
}
else
{
if (offset + width > rgbData.length || offset + scanlength * (height - 1) < 0) { throw new ArrayIndexOutOfBoundsException(); }
}


BufferedImage temp = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
raster = temp.getRaster();
final int[] pixels = new int[width * height];

for (int i = 0; i < height; i++) {

for (int i = 0; i < height; i++)
{
int s = offset + i * scanlength;
int d = i * width;
for (int j = 0; j < width; j++) {
for (int j = 0; j < width; j++)
{
int pixel = rgbData[s++];
if (!processAlpha) {
// Set fully opaque
pixel = (pixel & 0x00FFFFFF) | 0xFF000000; // Set alpha to 255
}
if (!processAlpha) { pixel = (pixel & 0x00FFFFFF) | 0xFF000000; } // Set alpha to 255
pixels[d + j] = pixel; // Store the pixel
}
}

final BufferedImage temp = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
raster = temp.getRaster();

raster.setDataElements(0, 0, width, height, pixels);

gc.drawImage(temp, x, y, null);
Expand Down Expand Up @@ -452,8 +450,9 @@ public void drawPixels(byte[] pixels, byte[] transparencyMask, int offset, int s
{
int[] Type1 = {0xFFFFFFFF, 0xFF000000, 0x00FFFFFF, 0x00000000};
int c = 0;
int[] data;
BufferedImage temp;
int[] data = null;
BufferedImage temp = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
raster = temp.getRaster();
switch(format)
{
case -1: // TYPE_BYTE_1_GRAY_VERTICAL // used by Monkiki's Castles
Expand All @@ -474,14 +473,9 @@ public void drawPixels(byte[] pixels, byte[] transparencyMask, int offset, int s
b++;
if(b>7) b=0;
}

temp = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
raster = temp.getRaster();
raster.setDataElements(0, 0, width, height, data);
gc.drawImage(manipulateImage(temp, manipulation), x, y, null);
break;

case 1: // TYPE_BYTE_1_GRAY // used by Monkiki's Castles
case 1: // TYPE_BYTE_1_GRAY // used by Munkiki's Castles
data = new int[pixels.length*8];

for(int i=(offset/8); i<pixels.length; i++)
Expand All @@ -493,39 +487,72 @@ public void drawPixels(byte[] pixels, byte[] transparencyMask, int offset, int s
data[(i*8)+(7-j)] = Type1[c];
}
}
temp = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
raster = temp.getRaster();
raster.setDataElements(0, 0, width, height, data);
gc.drawImage(manipulateImage(temp, manipulation), x, y, null);
break;

default: Mobile.log(Mobile.LOG_WARNING, PlatformGraphics.class.getPackage().getName() + "." + PlatformGraphics.class.getSimpleName() + ": " + "drawPixels A : Format " + format + " Not Implemented");
}

raster.setDataElements(0, 0, width, height, data);
gc.drawImage(manipulateImage(temp, manipulation), x, y, null);
}

public void drawPixels(int[] pixels, boolean transparency, int offset, int scanlength, int x, int y, int width, int height, int manipulation, int format)
public void drawPixels(int[] pixels, boolean transparency, int offset, int scanlength, int x, int y, int width, int height, int manipulation, int format)
{
if (width <= 0 || height <= 0) { return; }
if (pixels == null) { throw new NullPointerException(); }
if (offset < 0 || offset >= pixels.length) { throw new ArrayIndexOutOfBoundsException(); }

if (scanlength > 0)
{
if (offset + scanlength * (height - 1) + width > pixels.length) { throw new ArrayIndexOutOfBoundsException(); }
}
else
{
if (offset + width > pixels.length || offset + scanlength * (height - 1) < 0) { throw new ArrayIndexOutOfBoundsException(); }
}

// Create the temporary BufferedImage and get its WritableRaster
BufferedImage temp = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
raster = temp.getRaster();
raster.setDataElements(0, 0, width, height, pixels); // Untested, potentially safe
//temp.setRGB(0, 0, width, height, pixels, offset, scanlength);
BufferedImage temp2 = manipulateImage(temp, manipulation);
gc.drawImage(temp2, x, y, null);
}

public void drawPixels(short[] pixels, boolean transparency, int offset, int scanlength, int x, int y, int width, int height, int manipulation, int format)
{
int[] data = new int[pixels.length];
for(int i=0; i<pixels.length; i++)
// Prepare pixel data
final int[] data = new int[width * height];

for (int row = 0; row < height; row++)
{
data[i] = pixelToColor(pixels[i], format);
if(!transparency) { data[i] &=0x00FFFFFF; }
int srcIndex = offset + row * scanlength;
for (int col = 0; col < width; col++)
{
int pixel = pixels[srcIndex + col];
if (!transparency) { pixel = (pixel & 0x00FFFFFF) | 0xFF000000; } // Set alpha to 255
data[row * width + col] = pixel;
}
}

raster.setDataElements(0, 0, width, height, data);
gc.drawImage(manipulateImage(temp, manipulation), x, y, null);
}

public void drawPixels(short[] pixels, boolean transparency, int offset, int scanlength, int x, int y, int width, int height, int manipulation, int format)
{
BufferedImage temp = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
raster = temp.getRaster();
raster.setDataElements(0, 0, width, height, data); // Untested, potentially safe
//temp.setRGB(0, 0, width, height, data, offset, scanlength);

final int[] data = new int[pixels.length];
// Prepare the pixel data
for (int row = 0; row < height; row++)
{
for (int col = 0; col < width; col++)
{
int index = offset + row * scanlength + col;
data[row * width + col] = pixelToColor(pixels[index], format);
if (!transparency) { data[row * width + col] &= 0x00FFFFFF; } // Clear the alpha channel

}
}

// Set the pixel data directly into the raster
raster.setDataElements(0, 0, width, height, data);
gc.drawImage(manipulateImage(temp, manipulation), x, y, null);
}

Expand Down

0 comments on commit c706f15

Please sign in to comment.