1 /* 2 * Copyright (C) 2015-2020, by Laszlo Szeremi under the Boost license. 3 * 4 * Pixel Perfect Engine, graphics.layers.base module 5 */ 6 7 module PixelPerfectEngine.graphics.layers.base; 8 9 public import PixelPerfectEngine.graphics.bitmap; 10 public import PixelPerfectEngine.graphics.common; 11 public import PixelPerfectEngine.graphics.layers.interfaces; 12 package import PixelPerfectEngine.graphics.transformFunctions; 13 package import PixelPerfectEngine.system.etc; 14 //package import PixelPerfectEngine.system.platform; 15 16 package import std.bitmanip : bitfields; 17 public import PixelPerfectEngine.system.exc; 18 package import bindbc.sdl; 19 package import core.stdc.stdlib; 20 package import CPUblit.composing; 21 package import CPUblit.composing.specblt : xorBlitter; 22 package import CPUblit.colorlookup; 23 package import CPUblit.transform; 24 25 import inteli.emmintrin; 26 alias RenderFunc = @nogc pure nothrow void function(uint* src, uint* dest, size_t length, ubyte value); 27 /// For generating a blitter function with value modifier 28 @nogc pure nothrow void localBlt(uint* src, uint* dest, size_t length, ubyte value) { 29 blitter!uint(src, dest, length); 30 } 31 /// For generating a copy function with value modifier 32 @nogc pure nothrow void localCpy(uint* src, uint* dest, size_t length, ubyte value) { 33 copy!uint(src, dest, length); 34 } 35 /// For generating a XOR blitter function with value modifier 36 @nogc pure nothrow void localXOR(uint* src, uint* dest, size_t length, ubyte value) { 37 xorBlitter!uint(src, dest, length); 38 } 39 /** 40 * The basis of all layer classes, containing function pointers for rendering. 41 */ 42 abstract class Layer { 43 protected RenderFunc mainRenderingFunction; ///Used to implement changeable renderers for each layers 44 /+protected @nogc pure nothrow void function(ushort* src, uint* dest, uint* palette, size_t length) 45 mainColorLookupFunction;+/ 46 //protected @nogc void function(uint* src, int length) mainHorizontalMirroringFunction; 47 /+protected @nogc pure nothrow void function(ubyte* src, uint* dest, uint* palette, size_t length) 48 main8BitColorLookupFunction;+/ 49 /+protected @nogc pure nothrow void function(ubyte* src, uint* dest, uint* palette, size_t length, int offset) 50 main4BitColorLookupFunction;+/ 51 alias mainColorLookupFunction = colorLookup!(ushort,uint); 52 alias main8BitColorLookupFunction = colorLookup!(ubyte,uint); 53 alias main4BitColorLookupFunction = colorLookup4Bit!uint; 54 protected RenderingMode renderMode; 55 56 // scrolling position 57 //protected int sX, sY, rasterX, rasterY; 58 protected int sX; ///Horizontal scroll position 59 protected int sY; ///Vertical scroll position 60 protected int rasterX;///Raster width (visible) 61 protected int rasterY;///Haster height 62 63 /// Sets the main rasterizer 64 public void setRasterizer(int rX, int rY) @safe pure nothrow { 65 rasterX=rX; 66 rasterY=rY; 67 } 68 ///Sets the rendering mode 69 public void setRenderingMode(RenderingMode mode) @nogc @safe pure nothrow { 70 renderMode = mode; 71 mainRenderingFunction = getRenderingFunc(mode); 72 //mainColorLookupFunction = &colorLookup!(ushort,uint); 73 //mainHorizontalMirroringFunction = &flipHorizontal; 74 //main8BitColorLookupFunction = &colorLookup!(ubyte,uint); 75 //main4BitColorLookupFunction = &colorLookup4Bit!uint; 76 } 77 ///Absolute scrolling. 78 public void scroll(int x, int y) @safe pure nothrow { 79 sX = x; 80 sY = y; 81 } 82 ///Relative scrolling. Positive values scrolls the layer left and up, negative values scrolls the layer down and right. 83 public void relScroll(int x, int y) @safe pure nothrow { 84 sX += x; 85 sY += y; 86 } 87 ///Getter for the X scroll position. 88 public int getSX() @nogc @safe pure nothrow const { 89 return sX; 90 } 91 ///Getter for the Y scroll position. 92 public int getSY() @nogc @safe pure nothrow const { 93 return sY; 94 } 95 /// Override this to enable output to the raster 96 public abstract void updateRaster(void* workpad, int pitch, Color* palette) @nogc ; 97 ///Standard algorithm for horizontal mirroring, used for tile mirroring 98 protected void flipHorizontal(T)(T[] target) @nogc pure nothrow { 99 //sizediff_t j = target.length - 1; 100 for (sizediff_t i, j = target.length - 1 ; i < j ; i++, j--) { 101 const T s = target[i]; 102 target[i] = target[j]; 103 target[j] = s; 104 //j--; 105 } 106 } 107 } 108 /** 109 * Mostly used for internal communication. 110 */ 111 public enum LayerType { 112 init, 113 Tile, 114 TransformableTile, 115 Sprite, 116 Effects, 117 } 118 /** 119 * Defines how the layer or sprite will be rendered. 120 * See each value's documentation individually for more information on each mode. 121 */ 122 public enum RenderingMode : ubyte { 123 init, ///Rendering mode is not set 124 Copy, ///Copies the pixels without any transparencies. The fastest as it only reads once. Best use is either GUI or lowest-layer. 125 Blitter, ///Copies the pixels to the target using simple transparency. No effect from master-alpha values. Can be faster on less memory-bound machines. 126 AlphaBlend, ///Blends the source onto the target, using both per-pixel alpha and master alpha. 127 Multiply, ///Multiplies pixel channel values, then stores it in the destination. 128 MultiplyBl, ///Multiply with alpha used as a blend between the original and target value. 129 Screen, ///Composes the source to the destination using the following formula: 1 - (1 - dest) * (1 - src) 130 ScreenBl, ///Screen with alpha used as a blend between the original and target value. 131 Add, ///Adds with saturation the source to the destination. 132 AddBl, ///Add with alpha used as a blend between the original and target value. 133 Subtract, ///Subtracts with saturation the source from the destination. 134 SubtractBl, ///Subtracts with saturation the source from the destination. Alpha determines how much of the source's other channels is used. 135 Diff, ///Calculates the difference between the source and destination. 136 DiffBl, ///Calculates the difference between the source and destination. Alpha determines how much of the source's other channels is used. 137 AND, ///Logically ANDs the source to the destination. Alpha value is ignored. 138 OR, ///Logically ORs the source to the destination. Alpha value is ignored. 139 XOR, ///Logically XORs the source to the destination. Alpha value is ignored. 140 } 141 /** 142 * Returns the rendering function that belongs to the enumeration value. 143 */ 144 public RenderFunc getRenderingFunc (RenderingMode mode) @nogc @safe pure nothrow { 145 final switch (mode) with (RenderingMode) { 146 case init: 147 return null; 148 case Copy: 149 return &localCpy; 150 case Blitter: 151 return &localBlt; 152 case AlphaBlend: 153 return (uint* src, uint* dest, size_t length, ubyte value) {alphaBlendMV(src, dest, length, value);}; 154 case Multiply: 155 return (uint* src, uint* dest, size_t length, ubyte value) {multMV(src, dest, length, value);}; 156 case MultiplyBl: 157 return (uint* src, uint* dest, size_t length, ubyte value) {multMVBl(src, dest, length, value);}; 158 case Screen: 159 return (uint* src, uint* dest, size_t length, ubyte value) {screenMV(src, dest, length, value);}; 160 case ScreenBl: 161 return (uint* src, uint* dest, size_t length, ubyte value) {screenMVBl(src, dest, length, value);}; 162 case Add: 163 return (uint* src, uint* dest, size_t length, ubyte value) {addMV!(false)(src, dest, length, value);}; 164 case AddBl: 165 return (uint* src, uint* dest, size_t length, ubyte value) {addMV!(true)(src, dest, length, value);}; 166 case Subtract: 167 return (uint* src, uint* dest, size_t length, ubyte value) {subMV!(false)(src, dest, length, value);}; 168 case SubtractBl: 169 return (uint* src, uint* dest, size_t length, ubyte value) {subMV!(true)(src, dest, length, value);}; 170 case Diff: 171 return (uint* src, uint* dest, size_t length, ubyte value) {diffMV(src, dest, length, value);}; 172 case DiffBl: 173 return (uint* src, uint* dest, size_t length, ubyte value) {diffMVBl(src, dest, length, value);}; 174 case AND: 175 return null; 176 case OR: 177 return null; 178 case XOR: 179 return &localXOR; 180 } 181 } 182 /** 183 * Sets the WarpMode for any tile layer. 184 */ 185 public enum WarpMode : ubyte { 186 Off, /// Content shown only once. 187 MapRepeat, /// Tilemap is repeated on the layer. 188 TileRepeat /// Out of bounds areas repeat tile 0x0000. Tile 0xFFFF is still reserved as transparency. 189 } 190 /** 191 * Universal Mapping element, that is stored on 32 bit. 192 */ 193 public struct MappingElement { 194 wchar tileID; ///Determines which tile is being used for the given instance 195 BitmapAttrib attributes; ///General attributes, such as vertical and horizontal mirroring. The extra 6 bits can be used for various purposes 196 ubyte paletteSel; ///Selects the palette for the bitmap if supported 197 ///Default constructor 198 this(wchar tileID, BitmapAttrib attributes = BitmapAttrib(false, false), ubyte paletteSel = 0) @nogc @safe pure nothrow { 199 this.tileID = tileID; 200 this.attributes = attributes; 201 this.paletteSel = paletteSel; 202 } 203 public string toString() const { 204 import std.conv : to; 205 return "[tileID:" ~ to!string(cast(int)tileID) ~ "; attributes:" ~ attributes.toString ~ "; paletteSel:" ~ 206 to!string(paletteSel) ~ "]"; 207 } 208 }