Skip to content

Commit

Permalink
Sprite rendering pipeline upgrade
Browse files Browse the repository at this point in the history
  • Loading branch information
ZILtoid1991 committed May 1, 2023
1 parent cb48771 commit 0024155
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 83 deletions.
2 changes: 1 addition & 1 deletion dub.sdl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ description "A 2D game engine for retro styled games"
authors "Laszlo Szeremi"
copyright "(C)2015-2021 Laszlo Szeremi"
license "BSL-1.0"
dependency "collections-d" version="==0.4.7"
dependency "collections-d" version="==0.5.0"
dependency "sdlang-d" version="*"
//dependency "undead" version="*"
dependency "newxml" version="==0.2.1"
Expand Down
2 changes: 1 addition & 1 deletion dub.selections.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"bindbc-sdl": "1.3.5",
"bitleveld": "0.1.0",
"bmfont": "0.1.0",
"collections-d": "0.4.7",
"collections-d": "0.5.0",
"cpublit": "0.6.1",
"derelict-fi": "2.0.3",
"derelict-sdl2": "2.1.4",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,27 +126,27 @@ public interface ITTL {
*/
public interface ISpriteLayer {
///Clears all sprite from the layer.
public void clear() @safe nothrow;
public void clear() @trusted nothrow;
///Removes the sprite with the given ID.
public void removeSprite(int n) @safe nothrow;
public void removeSprite(int n) @trusted nothrow;
/**
* Moves the sprite to the exact location.
* Params:
* n = The identifier of the sprite.
* x = New x position of the sprite.
* y = New y position of the sprite.
*/
public void moveSprite(int n, int x, int y) @safe nothrow;
public void moveSprite(int n, int x, int y) @trusted nothrow;
/**
* Relatively moves the sprite by the given values.
* Params:
* n = The identifier of the sprite.
* x = New x position of the sprite.
* y = New y position of the sprite.
*/
public void relMoveSprite(int n, int x, int y) @safe nothrow;
public void relMoveSprite(int n, int x, int y) @trusted nothrow;
///Gets the coordinate of the sprite.
public Box getSpriteCoordinate(int n) @nogc @safe nothrow;
public Box getSpriteCoordinate(int n) @nogc @trusted nothrow;
/**
* Creates a sprite from a bitmap with the given data, then places it to the display list. (New architecture)
* Params:
Expand All @@ -166,7 +166,7 @@ public interface ISpriteLayer {
*/
public Box addSprite(ABitmap sprt, int n, int x, int y, ushort paletteSel = 0, ubyte paletteSh = 0,
ubyte alpha = ubyte.max, int scaleHoriz = 1024, int scaleVert = 1024, RenderingMode renderMode = RenderingMode.init)
@safe nothrow;
@trusted nothrow;
/+
/**
* Places a new sprite onto the layer with the given parameters.
Expand All @@ -184,23 +184,23 @@ public interface ISpriteLayer {
public void addSprite(ABitmap s, int n, int x, int y, ushort paletteSel = 0, int scaleHoriz = 1024,
int scaleVert = 1024) @safe nothrow;+/
///Sets the rendering function for the sprite (defaults to the layer's rendering function)
public void setSpriteRenderingMode(int n, RenderingMode mode) @safe nothrow;
public RenderFunc setSpriteRenderingMode(int n, RenderingMode mode) @nogc @trusted pure nothrow;
///Replaces the sprite. If the new sprite has a different dimension, the old sprite's upper-left corner will be used.
public void replaceSprite(ABitmap s, int n) @safe nothrow;
public void replaceSprite(ABitmap s, int n) @trusted nothrow;
///Replaces the sprite and moves to the given position.
public void replaceSprite(ABitmap s, int n, int x, int y) @safe nothrow;
public void replaceSprite(ABitmap s, int n, int x, int y) @trusted nothrow;
///Replaces the sprite and moves to the given position.
public void replaceSprite(ABitmap s, int n, Box c) @safe nothrow;
public void replaceSprite(ABitmap s, int n, Box c) @trusted nothrow;
///Returns the displayed portion of the sprite.
public @nogc Box getSlice(int n) @safe nothrow;
public @nogc Box getSlice(int n) @trusted nothrow;
///Writes the displayed portion of the sprite.
///Returns the new slice, if invalid (greater than the bitmap, etc.) returns the old one.
public Box setSlice(int n, Box slice) @safe nothrow;
public Box setSlice(int n, Box slice) @trusted nothrow;
///Returns the selected paletteID of the sprite.
public @nogc ushort getPaletteID(int n) @safe nothrow;
public @nogc ushort getPaletteID(int n) @trusted nothrow;
///Sets the paletteID of the sprite. Returns the new ID, which is truncated to the possible values with a simple binary and operation
///Palette must exist in the parent Raster, otherwise AccessError might happen
public @nogc ushort setPaletteID(int n, ushort paletteID) @safe nothrow;
public @nogc ushort setPaletteID(int n, ushort paletteID) @trusted nothrow;
///Scales bitmap horizontally
public int scaleSpriteHoriz(int n, int hScl) @trusted nothrow;
///Scales bitmap vertically
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,16 +137,16 @@ public class SpriteLayer : Layer, ISpriteLayer {
pixelData = (cast(Bitmap32Bit)(sprite)).getPtr;
}
}
@nogc int opCmp(in DisplayListItem d) const pure @safe nothrow {
@nogc int opCmp(const DisplayListItem d) const pure @safe nothrow {
return priority - d.priority;
}
@nogc bool opEquals(in DisplayListItem d) const pure @safe nothrow {
@nogc bool opEquals(const DisplayListItem d) const pure @safe nothrow {
return priority == d.priority;
}
@nogc int opCmp(in int pri) const pure @safe nothrow {
@nogc int opCmp(const int pri) const pure @safe nothrow {
return priority - pri;
}
@nogc bool opEquals(in int pri) const pure @safe nothrow {
@nogc bool opEquals(const int pri) const pure @safe nothrow {
return priority == pri;
}

Expand All @@ -157,7 +157,8 @@ public class SpriteLayer : Layer, ISpriteLayer {
"; PaletteSel: " ~ to!string(paletteSel) ~ "; bmpType: " ~ to!string(bmpType) ~ "}";
}
}
alias DisplayList = TreeMap!(int, DisplayListItem);
//alias DisplayList = TreeMap!(int, DisplayListItem);
alias DisplayList = SortedList!(DisplayListItem, "a < b", false);
protected DisplayList allSprites; ///All sprites of this layer
//protected OnScreenList displayedSprites; ///Sprites that are being displayed
protected Color[2048] src; ///Local buffer for scaling
Expand Down Expand Up @@ -203,27 +204,27 @@ public class SpriteLayer : Layer, ISpriteLayer {
* Searches the DisplayListItem by priority and returns it.
* Can be used for external use without any safety issues.
*/
public DisplayListItem getDisplayListItem(int n) @nogc pure @safe nothrow {
public DisplayListItem getDisplayListItem(int n) @nogc pure @trusted nothrow {
return allSprites[n];
}
/**
/*
* Searches the DisplayListItem by priority and returns it.
* Intended for internal use, as it returns it as a reference value.
*/
protected final DisplayListItem* getDisplayListItem_internal(int n) @nogc pure @safe nothrow {
return allSprites.ptrOf(n);
}
return allSprites.searchByPtr(n);
}*/
/+override public void setRasterizer(int rX,int rY) {
super.setRasterizer(rX,rY);
}+/
///Returns the displayed portion of the sprite.
public Coordinate getSlice(int n) @nogc pure @safe nothrow {
public Coordinate getSlice(int n) @nogc pure @trusted nothrow {
return getDisplayListItem(n).slice;
}
///Writes the displayed portion of the sprite.
///Returns the new slice, if invalid (greater than the bitmap, etc.) returns Coordinate.init.
public Coordinate setSlice(int n, Coordinate slice) @safe nothrow {
DisplayListItem* sprt = allSprites.ptrOf(n);
public Coordinate setSlice(int n, Coordinate slice) @trusted nothrow {
DisplayListItem* sprt = allSprites.searchByPtr(n);
if(sprt) {
sprt.slice = slice;
checkSprite(*sprt);
Expand All @@ -233,20 +234,22 @@ public class SpriteLayer : Layer, ISpriteLayer {
}
}
///Returns the selected paletteID of the sprite.
public ushort getPaletteID(int n) @nogc pure @safe nothrow {
return allSprites[n].paletteSel;
public ushort getPaletteID(int n) @nogc pure @trusted nothrow {
return allSprites.searchBy(n).paletteSel;
}
///Sets the paletteID of the sprite. Returns the new ID, which is truncated to the possible values with a simple binary and operation
///Palette must exist in the parent Raster, otherwise AccessError might happen
public ushort setPaletteID(int n, ushort paletteID) @nogc pure @safe nothrow {
return getDisplayListItem_internal(n).paletteSel = paletteID;
///Palette must exist in the parent Raster, otherwise AccessError might happen during
public ushort setPaletteID(int n, ushort paletteID) @nogc pure @trusted nothrow {
DisplayListItem* item = allSprites.searchByPtr(n);
if (item is null) return 0;
return item.paletteSel = paletteID;
}
/**
* Returns the sprite rendering function.
* Params:
* n = Sprite priority ID.
*/
public RenderFunc getSpriteRenderingFunc(int n) @nogc @safe pure nothrow {
public RenderFunc getSpriteRenderingFunc(int n) @nogc @trusted pure nothrow {
return allSprites[n].renderFunc;
}
/**
Expand All @@ -256,8 +259,10 @@ public class SpriteLayer : Layer, ISpriteLayer {
* mode = The rendering mode. (init for layer default)
* Returns: The new rendering function.
*/
public RenderFunc setSpriteRenderingMode(int n, RenderingMode mode) @nogc @safe pure nothrow {
return allSprites.ptrOf(n).renderFunc = mode == RenderingMode.init ? mainRenderingFunction : getRenderingFunc(mode);
public RenderFunc setSpriteRenderingMode(int n, RenderingMode mode) @nogc @trusted pure nothrow {
DisplayListItem* item = allSprites.searchByPtr(n);
if (item is null) return null;
return item.renderFunc = mode == RenderingMode.init ? mainRenderingFunction : getRenderingFunc(mode);
}
/**
* Sets the sprite's rendering function. Can be a custom one.
Expand All @@ -266,8 +271,10 @@ public class SpriteLayer : Layer, ISpriteLayer {
* mode = The rendering mode. (init for layer default)
* Returns: The new rendering function.
*/
public RenderFunc setSpriteRenderingFunc(int n, RenderFunc func) @nogc @safe pure nothrow {
return allSprites.ptrOf(n).renderFunc = func;
public RenderFunc setSpriteRenderingFunc(int n, RenderFunc func) @nogc @trusted pure nothrow {
DisplayListItem* item = allSprites.searchByPtr(n);
if (item is null) return null;
return item.renderFunc = func;
}
/**
* Creates a sprite from a bitmap with the given data, then places it to the display list. (New architecture)
Expand All @@ -294,11 +301,11 @@ public class SpriteLayer : Layer, ISpriteLayer {
d.renderFunc = mainRenderingFunction;
else
d.renderFunc = getRenderingFunc(renderMode);
synchronized{
allSprites[n] = d;
//checkSprite(d);
}
return allSprites[n].position;
//synchronized{
allSprites.put(d);
//checkSprite(d);
//}
return d.position;
}
/**
* Adds a sprite to the layer.
Expand All @@ -325,66 +332,66 @@ public class SpriteLayer : Layer, ISpriteLayer {
/**
* Replaces the bitmap of the given sprite.
*/
public void replaceSprite(ABitmap s, int n) @safe nothrow {
DisplayListItem* sprt = getDisplayListItem_internal(n);
sprt.replaceSprite(s);
//checkSprite(*sprt);
public void replaceSprite(ABitmap s, int n) @trusted nothrow {
DisplayListItem* item = allSprites.searchByPtr(n);
if (item is null) return;
item.replaceSprite(s);
}
///Ditto with move
public void replaceSprite(ABitmap s, int n, int x, int y) @safe nothrow {
DisplayListItem* sprt = getDisplayListItem_internal(n);
sprt.replaceSprite(s);
sprt.position.move(x, y);
//checkSprite(*sprt);
public void replaceSprite(ABitmap s, int n, int x, int y) @trusted nothrow {
DisplayListItem* item = allSprites.searchByPtr(n);
if (item is null) return;
item.replaceSprite(s);
item.position.move(x, y);
}
///Ditto with move
public void replaceSprite(ABitmap s, int n, Coordinate c) @safe nothrow {
DisplayListItem* sprt = allSprites.ptrOf(n);
sprt.replaceSprite(s);
sprt.position = c;
checkSprite(*sprt);
public void replaceSprite(ABitmap s, int n, Coordinate c) @trusted nothrow {
DisplayListItem* item = allSprites.searchByPtr(n);
if (item is null) return;
item.replaceSprite(s);
item.position = c;
}
/**
* Removes a sprite from both displaylists by priority.
*/
public void removeSprite(int n) @safe nothrow {
synchronized {
//displayedSprites.removeByElem(n);
allSprites.remove(n);
}
allSprites.removeBy(n);
}
///Clears all sprite from the layer.
public void clear() @safe nothrow {
//displayedSprites = OnScreenList.init;
allSprites = DisplayList.init;
}
/**
* Moves a sprite to the given position.
*/
public void moveSprite(int n, int x, int y) @safe nothrow {
DisplayListItem* sprt = allSprites.ptrOf(n);
sprt.position.move(x, y);
//checkSprite(*sprt);
public void moveSprite(int n, int x, int y) @trusted nothrow {
DisplayListItem* item = allSprites.searchByPtr(n);
if (item is null) return;
item.position.move(x, y);
}
/**
* Moves a sprite by the given amount.
*/
public void relMoveSprite(int n, int x, int y) @safe nothrow {
DisplayListItem* sprt = allSprites.ptrOf(n);
sprt.position.relMove(x, y);
public void relMoveSprite(int n, int x, int y) @trusted nothrow {
DisplayListItem* item = allSprites.searchByPtr(n);
if (item is null) return;
item.position.relMove(x, y);
//checkSprite(*sprt);
}
///Sets the rendering function for the sprite (defaults to the layer's rendering function)
/* ///Sets the rendering function for the sprite (defaults to the layer's rendering function)
public void setSpriteRenderingMode(int n, RenderingMode mode) @safe nothrow {
DisplayListItem* sprt = allSprites.ptrOf(n);
sprt.renderFunc = getRenderingFunc(mode);
}
public @nogc Coordinate getSpriteCoordinate(int n) @safe nothrow {
return allSprites[n].position;
DisplayListItem* item = allSprites.searchByPtr(n);
if (item is null) return 0;
item.renderFunc = getRenderingFunc(mode);
} */
public @nogc Box getSpriteCoordinate(int n) @trusted nothrow {
DisplayListItem* sprt = allSprites.searchByPtr(n);
if(!sprt) return Box.init;
return sprt.position;
}
///Scales sprite horizontally. Returns the new size, or -1 if the scaling value is invalid, or -2 if spriteID not found.
public int scaleSpriteHoriz(int n, int hScl) @trusted nothrow {
DisplayListItem* sprt = allSprites.ptrOf(n);
DisplayListItem* sprt = allSprites.searchByPtr(n);
if(!sprt) return -2;
else if(!hScl) return -1;
else {
Expand All @@ -398,7 +405,7 @@ public class SpriteLayer : Layer, ISpriteLayer {
}
///Scales sprite vertically. Returns the new size, or -1 if the scaling value is invalid, or -2 if spriteID not found.
public int scaleSpriteVert(int n, int vScl) @trusted nothrow {
DisplayListItem* sprt = allSprites.ptrOf(n);
DisplayListItem* sprt = allSprites.searchByPtr(n);
if(!sprt) return -2;
else if(!vScl) return -1;
else {
Expand All @@ -412,22 +419,26 @@ public class SpriteLayer : Layer, ISpriteLayer {
}
///Gets the sprite's current horizontal scale value
public int getScaleSpriteHoriz(int n) @nogc @trusted nothrow {
return allSprites[n].scaleHoriz;
DisplayListItem* item = allSprites.searchByPtr(n);
if (item is null) return 0;
return item.scaleHoriz;
}
///Gets the sprite's current vertical scale value
public int getScaleSpriteVert(int n) @nogc @trusted nothrow {
return allSprites[n].scaleVert;
DisplayListItem* item = allSprites.searchByPtr(n);
if (item is null) return 0;
return item.scaleVert;
}
public override LayerType getLayerType() @nogc @safe pure nothrow const {
return LayerType.TransformableTile;
return LayerType.Sprite;
}
public override @nogc void updateRaster(void* workpad, int pitch, Color* palette) {
/*
* BUG 1: If sprite is wider than 2048 pixels, it'll cause issues (mostly memory leaks) due to a hack. (Fixed!)
* BUG 2: Obscuring the top part of a sprite when scaleVert is not 1024 will cause glitches. (Fixed!!!)
* TO DO: Replace AVL tree with an automatically sorting array with keying abilities.
*/
foreach_reverse (i ; allSprites) {
foreach (i ; allSprites) {
if(!(i.slice.width && i.slice.height
&& (i.position.right > sX && i.position.bottom > sY &&
i.position.left < sX + rasterX && i.position.top < sY + rasterY))) continue;
Expand Down
2 changes: 1 addition & 1 deletion test0/app.d
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class TileLayerTest : SystemEventListener, InputListener {
ocd.objects[65_536] = CollisionShape(Box(0, 0, 31, 31), dlangManCS);
s.addSprite(dlangMan, 0, 0, 0, 1, 0x0, 0x0, -1024, -1024);

for(int i = 1 ; i < 10 ; i++){
for(int i = 1 ; i < 500 ; i++){
const int x = uniform(0,320), y = uniform(0,240);
s.addSprite(dlangMan, i, x, y, 1);
ocd.objects[i] = CollisionShape(Box(x, y, x + 31, y + 31), dlangManCS);
Expand Down

0 comments on commit 0024155

Please sign in to comment.