Skip to content

Commit

Permalink
TiledLayer + PlatformGraphics: Cleanups and optimizations.
Browse files Browse the repository at this point in the history
TiledLayer rendering should be a bit faster now that there's less
work being done by its paint() method, and drawRegion is seeing
the return of the "no manupulation" check to skip a temp image
creation and directly render the given region.

Furthermore, the "renderHint" comment has been moved from
PlatformImage to PlatformGraphics, as it makes more sense there.

Aside from this, the processInputs() code was slightly rearranged,
but shouldn't amount to much.
  • Loading branch information
AShiningRay committed Mar 1, 2025
1 parent ad129a8 commit a6cc9a1
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 160 deletions.
2 changes: 0 additions & 2 deletions src/com/siemens/mp/color_game/Layer.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,6 @@ public void setHeight(int height)

public Image getLayerImage() { return image; }

public void render() { this.paint(image.platformImage.getGraphics()); }

protected void copyAllLayerVariables(Layer l) { Mobile.log(Mobile.LOG_WARNING, Layer.class.getPackage().getName() + "." + Layer.class.getSimpleName() + ": " + "Siemens: color_game.Layer: copyAllLayerVariables()"); } // TODO

}
1 change: 0 additions & 1 deletion src/com/siemens/mp/color_game/LayerManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ public void paint(Graphics g, int xdest, int ydest)

for (int i = layers-1; i >= 0; i--)
{
Layer comp = component[i];
if (component[i].visible) { component[i].paint(g); }
}

Expand Down
77 changes: 27 additions & 50 deletions src/com/siemens/mp/color_game/TiledLayer.java
Original file line number Diff line number Diff line change
Expand Up @@ -157,58 +157,35 @@ public void setStaticTileSet(Image baseimage, int tileWidth, int tileHeight)
public final void paint(Graphics g)
{
if (g == null) { throw new NullPointerException(); }

if (visible)

if (!visible) { return; }

// Drawing is restricted to target's clip rect bounds
int clipX = g.getClipX();
int clipY = g.getClipY();
int clipWidth = g.getClipWidth();
int clipHeight = g.getClipHeight();

int startColumn = Math.max(0, (clipX - this.x) / tileWidth);
int endColumn = Math.min(this.cols, (clipX + clipWidth - this.x + tileWidth - 1) / tileWidth);
int startRow = Math.max(0, (clipY - this.y) / tileHeight);
int endRow = Math.min(this.rows, (clipY + clipHeight - this.y + tileHeight - 1) / tileHeight);

int tileIndex;
int tx, ty;

for (int row = startRow; row < endRow; row++)
{
int startColumn = 0;
int endColumn = this.cols;
int startRow = 0;
int endRow = this.rows;

// calculate the number of columns left of the clip
int number = (g.getClipX() - this.x) / tileWidth;
if (number > 0) { startColumn = number; }

// calculate the number of columns right of the clip
int endX = this.x + (this.cols * tileWidth);
int endClipX = g.getClipX() + g.getClipWidth();
number = (endX - endClipX) / tileWidth;
if (number > 0) { endColumn -= number; }

// calculate the number of rows above the clip
number = (g.getClipY() - this.y) / tileHeight;
if (number > 0) { startRow = number; }

// calculate the number of rows below the clip
int endY = this.y + (this.rows * tileHeight);
int endClipY = g.getClipY() + g.getClipHeight();
number = (endY - endClipY) / tileHeight;
if (number > 0) { endRow -= number; }

// paint all visible cells
int tileIndex = 0;

// y-coordinate
int ty = this.y + (startRow * tileHeight);

for (int row = startRow; row < endRow; row++, ty += tileHeight)
ty = y + (row * tileHeight);
for (int column = startColumn; column < endColumn; column++)
{
// reset the x-coordinate at the beginning of every row
// x-coordinate to draw tile into
int tx = this.x + (startColumn * tileWidth);
for (int column = startColumn; column < endColumn; column++, tx += tileWidth)
{
tileIndex = tiles[row][column];
// check the indices
// if animated get the corresponding
// static index from animatedTiles table

// tileIndex = 0 is a transparent tile
if (tileIndex == 0) { continue; }
else if (tileIndex < 0) { tileIndex = getAnimatedTile(tileIndex); }

g.drawRegion(image, tileSetX[tileIndex], tileSetY[tileIndex], tileWidth, tileHeight, Sprite.TRANS_NONE, tx, ty, Graphics.TOP | Graphics.LEFT);
}
tileIndex = tiles[row][column];

if (tileIndex == 0) { continue; } // Skip the transparent tile
if (tileIndex < 0) { tileIndex = getAnimatedTile(tileIndex); }

tx = x + (column * tileWidth);
g.drawRegion(image, tileSetX[tileIndex], tileSetY[tileIndex], tileWidth, tileHeight, Sprite.TRANS_NONE, tx, ty, Graphics.TOP | Graphics.LEFT);
}
}
}
Expand Down
2 changes: 0 additions & 2 deletions src/javax/microedition/lcdui/game/Layer.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,4 @@ public void setHeight(int height)

public Image getLayerImage() { return image; }

public void render() { this.paint(image.platformImage.getGraphics()); }

}
1 change: 0 additions & 1 deletion src/javax/microedition/lcdui/game/LayerManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ public void paint(Graphics g, int xdest, int ydest)

for (int i = layers-1; i >= 0; i--)
{
Layer comp = component[i];
if (component[i].visible) { component[i].paint(g); }
}

Expand Down
13 changes: 0 additions & 13 deletions src/javax/microedition/lcdui/game/Sprite.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@

public class Sprite extends Layer
{

public static final int TRANS_NONE = 0;
public static final int TRANS_ROT90 = 5;
public static final int TRANS_ROT180 = 3;
Expand Down Expand Up @@ -120,18 +119,6 @@ public Sprite(Sprite s)
y = s.getRefPixelY() - getTransformedPos(dRefY, t_currentTransformation, false);
}

public void defineReferencePixel(int x, int y)
{
dRefX = x;
dRefY = y;
}

public void setRefPixelPosition(int x, int y)
{
this.x = x - getTransformedPos(dRefX, this.t_currentTransformation, true);
this.y = y - getTransformedPos(dRefY, this.t_currentTransformation, false);
}

public int getRefPixelX() { return (this.x + getTransformedPos(dRefX, this.t_currentTransformation, true)); }

public int getRefPixelY() { return (this.y + getTransformedPos(dRefY, this.t_currentTransformation, false)); }
Expand Down
77 changes: 27 additions & 50 deletions src/javax/microedition/lcdui/game/TiledLayer.java
Original file line number Diff line number Diff line change
Expand Up @@ -157,58 +157,35 @@ public void setStaticTileSet(Image baseimage, int tileWidth, int tileHeight)
public final void paint(Graphics g)
{
if (g == null) { throw new NullPointerException(); }

if (visible)

if (!visible) { return; }

// Drawing is restricted to target's clip rect bounds
int clipX = g.getClipX();
int clipY = g.getClipY();
int clipWidth = g.getClipWidth();
int clipHeight = g.getClipHeight();

int startColumn = Math.max(0, (clipX - this.x) / tileWidth);
int endColumn = Math.min(this.cols, (clipX + clipWidth - this.x + tileWidth - 1) / tileWidth);
int startRow = Math.max(0, (clipY - this.y) / tileHeight);
int endRow = Math.min(this.rows, (clipY + clipHeight - this.y + tileHeight - 1) / tileHeight);

int tileIndex;
int tx, ty;

for (int row = startRow; row < endRow; row++)
{
int startColumn = 0;
int endColumn = this.cols;
int startRow = 0;
int endRow = this.rows;

// calculate the number of columns left of the clip
int number = (g.getClipX() - this.x) / tileWidth;
if (number > 0) { startColumn = number; }

// calculate the number of columns right of the clip
int endX = this.x + (this.cols * tileWidth);
int endClipX = g.getClipX() + g.getClipWidth();
number = (endX - endClipX) / tileWidth;
if (number > 0) { endColumn -= number; }

// calculate the number of rows above the clip
number = (g.getClipY() - this.y) / tileHeight;
if (number > 0) { startRow = number; }

// calculate the number of rows below the clip
int endY = this.y + (this.rows * tileHeight);
int endClipY = g.getClipY() + g.getClipHeight();
number = (endY - endClipY) / tileHeight;
if (number > 0) { endRow -= number; }

// paint all visible cells
int tileIndex = 0;

// y-coordinate
int ty = this.y + (startRow * tileHeight);

for (int row = startRow; row < endRow; row++, ty += tileHeight)
ty = y + (row * tileHeight);
for (int column = startColumn; column < endColumn; column++)
{
// reset the x-coordinate at the beginning of every row
// x-coordinate to draw tile into
int tx = this.x + (startColumn * tileWidth);
for (int column = startColumn; column < endColumn; column++, tx += tileWidth)
{
tileIndex = tiles[row][column];
// check the indices
// if animated get the corresponding
// static index from animatedTiles table

// tileIndex = 0 is a transparent tile
if (tileIndex == 0) { continue; }
else if (tileIndex < 0) { tileIndex = getAnimatedTile(tileIndex); }

g.drawRegion(image, tileSetX[tileIndex], tileSetY[tileIndex], tileWidth, tileHeight, Sprite.TRANS_NONE, tx, ty, Graphics.TOP | Graphics.LEFT);
}
tileIndex = tiles[row][column];

if (tileIndex == 0) { continue; } // Skip the transparent tile
if (tileIndex < 0) { tileIndex = getAnimatedTile(tileIndex); }

tx = x + (column * tileWidth);
g.drawRegion(image, tileSetX[tileIndex], tileSetY[tileIndex], tileWidth, tileHeight, Sprite.TRANS_NONE, tx, ty, Graphics.TOP | Graphics.LEFT);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/org/recompile/mobile/MobilePlatform.java
Original file line number Diff line number Diff line change
Expand Up @@ -298,9 +298,9 @@ public final void flushGraphics(Image img, int x, int y, int width, int height)

if(!showFPS.equals("Off")) { showFPS();}
painter.run(); // Update the frontend's painter first to then process inputs
processInputs();

limitFps();

processInputs();
}

public final void processInputs()
Expand Down
87 changes: 54 additions & 33 deletions src/org/recompile/mobile/PlatformGraphics.java
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ public PlatformGraphics(PlatformImage image)
setStrokeStyle(SOLID);
gc.setBackground(new Color(0, 0, 0, 0));
gc.setFont(font.platformFont.awtFont);

// Assuming we ever decide to implement configurable Java Graphics rendering options (2D smoothing, AA, etc), they should be applied here

// Example: Enable font AA (GASP uses font resource information to apply AA when appropriate)
//gc.getGraphics2D().setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
gc.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

platformGraphics = this;
Expand Down Expand Up @@ -183,11 +188,8 @@ public void drawImage(Image image, int x, int y, int anchor)
{
try
{
int imgWidth = image.getWidth();
int imgHeight = image.getHeight();

x = AnchorX(x, imgWidth, anchor);
y = AnchorY(y, imgHeight, anchor);
x = AnchorX(x, image.getWidth(), anchor);
y = AnchorY(y, image.getHeight(), anchor);

gc.drawImage(image.platformImage.getCanvas(), x, y, null);
}
Expand Down Expand Up @@ -227,6 +229,13 @@ public void flushGraphics(Image image, int x, int y, int width, int height)

try
{
final int startX = Math.max(getClipX() - x, 0);
final int endX = Math.min(getClipX() + getClipWidth() - x, width);
final int startY = Math.max(getClipY() - y, 0);
final int endY = Math.min(getClipY() + getClipHeight() - y, height);
final int canvasWidth = canvas.getWidth();
final int canvasHeight = canvas.getHeight();
final int imageWidth = image.getWidth();
final int[] pixels = ((DataBufferInt) image.platformImage.getCanvas().getRaster().getDataBuffer()).getData();
int[] overlayData = null;

Expand All @@ -238,18 +247,15 @@ public void flushGraphics(Image image, int x, int y, int width, int height)
}

// Render the resulting image
for (int j = y; j < height+y; j++)
for (int j = startY + y; j < endY + y; j++)
{
for (int i = x; i < width+x; i++)
{
int destIndex = j * canvas.getWidth() + i;
int srcIndex = j * image.getWidth() + i;
if (j < 0 || j >= canvasHeight) { continue; }

// The image data CAN go out of the destination bounds (and so can the clip rectangle), we just can't draw it whenever it does.
if (i < getClipX() || i >= getClipX() + getClipWidth() || i >= canvas.getWidth()) { continue; }
if (j < getClipY() || j >= getClipY() + getClipHeight() || j >= canvas.getHeight()) { continue; }
if (destIndex < 0 || destIndex >= canvasData.length) { continue; }
if (srcIndex < 0 || srcIndex >= pixels.length) { continue; }
for (int i = startX + x; i < endX + x; i++)
{
if (i < 0 || i >= canvasWidth) { continue; }
int destIndex = j * canvasWidth + i;
int srcIndex = j * imageWidth + i;

// Only apply the backlight mask if Display, nokia's DeviceControl, or others request it for backlight effects.
canvasData[destIndex] = pixels[srcIndex] & (Mobile.renderLCDMask ? Mobile.lcdMaskColors[Mobile.maskIndex] : 0xFFFFFFFF);
Expand Down Expand Up @@ -292,10 +298,19 @@ public void drawRegion(Image image, int subx, int suby, int subw, int subh, int

try
{
PlatformImage sub = new PlatformImage(image, subx, suby, subw, subh, transform);
x = AnchorX(x, sub.width, anchor);
y = AnchorY(y, sub.height, anchor);
gc.drawImage(sub.getCanvas(), x, y, null);
if(transform == 0)
{
x = AnchorX(x, subw, anchor);
y = AnchorY(y, subh, anchor);
gc.drawImage(image.platformImage.getCanvas().getSubimage(subx, suby, subw, subh), x, y, null);
}
else
{
PlatformImage sub = new PlatformImage(image, subx, suby, subw, subh, transform);
x = AnchorX(x, sub.width, anchor);
y = AnchorY(y, sub.height, anchor);
gc.drawImage(sub.getCanvas(), x, y, null);
}
}
catch (Exception e)
{
Expand Down Expand Up @@ -328,28 +343,34 @@ public void drawRGB(int[] rgbData, int offset, int scanlength, int x, int y, int

int canvasWidth = canvas.getWidth();
int canvasHeight = canvas.getHeight();
int clipX = getClipX();
int clipY = getClipY();
int clipWidth = getClipWidth();
int clipHeight = getClipHeight();

int startX = Math.max(clipX - x, 0);
int endX = Math.min(clipX + clipWidth - x, width);
int startY = Math.max(clipY - y, 0);
int endY = Math.min(clipY + clipHeight - y, height);

if (y + height > getClipY() + getClipHeight()) { height = (getClipY() + getClipHeight()) - y; }
if (x + width > getClipX() + getClipWidth()) { width = (getClipX() + getClipWidth()) - x; }

if (y + height > clipY + clipHeight) { height = (clipY + clipHeight) - y; }
if (x + width > clipX + clipWidth) { width = (clipX + clipWidth) - x; }
// Ensure adjusted width and height are still positive
if (width <= 0 || height <= 0) { return; }

// Directly manipulate the canvasData
for (int i = 0; i < height; i++)
for (int j = startY; j < endY; j++)
{
int rowOffset = offset + (i * scanlength); // Calculate the starting index for the current row
if ((y + j) < 0 || (y + j) >= canvasHeight) { continue; }
int rowOffset = offset + (j * scanlength); // Calculate the starting index for the current row

for (int j = 0; j < width; j++)
for (int i = startX; i < endX; i++)
{
int pixelIndex = rowOffset + j; // Source index in rgbData
int destIndex = (y + i) * canvasWidth + (x + j);

// Skip if the pixel isn't in the canvas bounds
if (x + j < 0 || x + j >= canvasWidth) { continue; }
if (y + i < getClipY() || y + i >= getClipY() + getClipHeight() || x + j < getClipX() || x + j >= getClipX() + getClipWidth()) { continue; }
if (destIndex < 0 || destIndex >= canvasData.length) { continue; }
if (pixelIndex < 0 || pixelIndex >= rgbData.length) { continue; }
if ((x + i) < 0 || (x + i) >= canvasWidth) { continue; }

int pixelIndex = rowOffset + i; // Source index in rgbData
int destIndex = (y + j) * canvasWidth + (x + i);

int pixel = rgbData[pixelIndex];
if (!processAlpha)
Expand Down
6 changes: 0 additions & 6 deletions src/org/recompile/mobile/PlatformImage.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,6 @@ public class PlatformImage extends javax.microedition.lcdui.Image
protected void createGraphics()
{
gc = new PlatformGraphics(this);


// Assuming we ever decide to implement configurable Java Graphics rendering options (2D smoothing, AA, etc), they should be applied here

// Example: Enable font AA (GASP uses font resource information to apply AA when appropriate)
//gc.getGraphics2D().setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);

gc.setColor(0x000000);
}
Expand Down

0 comments on commit a6cc9a1

Please sign in to comment.