1 module caLib.renderers.OneDimBasicRenderer; 2 3 import caLib_abstract.lattice : isBoundedLattice, isAnyBoundedLattice; 4 import caLib_abstract.palette : isColorPalette, isAnyColorPalette; 5 import std.traits : CommonType; 6 import caLib_util.image : Image; 7 import caLib_util.video : Video; 8 import caLib_util.structs : Rect, Color; 9 import caLib_util.graphics; 10 11 public import caLib_util.graphics : Window; 12 13 14 15 template create_OneDimBasicRenderer(Ct, Lt, Pt) 16 if(isBoundedLattice!(Lt, Ct, 1) && isColorPalette!(Pt, Ct)) 17 { 18 OneDimBasicRenderer!(Ct, Lt, Pt)* 19 create_OneDimBasicRenderer(Lt* lattice, Pt* palette, Window window) 20 { 21 return new OneDimBasicRenderer!(Ct, Lt, Pt)(lattice, palette, window); 22 } 23 } 24 25 26 27 28 auto create_OneDimBasicRenderer(Lt, Pt)(Lt* lattice, Pt* palette, Window window) 29 if(isAnyBoundedLattice!Lt && isAnyColorPalette!Pt && Lt.Dimension == 1) 30 { 31 alias Ct = CommonType!(Lt.CellStateType, Pt.CellStateType); 32 static assert(!is(Ct == void)); 33 34 return new OneDimBasicRenderer!(Ct, Lt, Pt)(lattice, palette, window); 35 } 36 37 38 39 struct OneDimBasicRenderer(Ct, Lt, Pt) 40 if(isColorPalette!(Pt, Ct) && isBoundedLattice!(Lt, Ct, 1)) 41 { 42 43 private: 44 45 Lt* lattice; 46 47 Pt* palette; 48 49 Window window; 50 Texture texture; 51 52 uint cellSize; 53 uint n; 54 SDL_Rect sRectBottom; 55 SDL_Rect dRectBottom; 56 SDL_Rect sRectTop; 57 SDL_Rect dRectTop; 58 59 public: 60 61 this(Lt* lattice, Pt* palette, Window window) 62 in 63 { 64 assert(window.getWidth() / lattice.getLatticeBounds()[0] > 0); 65 } 66 body 67 { 68 this.lattice = lattice; 69 this.palette = palette; 70 71 this.window = window; 72 73 cellSize = window.getWidth() / lattice.getLatticeBounds()[0]; 74 n=0; 75 76 texture = new Texture(window, lattice.getLatticeBounds()[0], window.getHeight() / cellSize); 77 78 sRectBottom = SDL_Rect(0, 0, texture.getWidth(), n+1); 79 dRectBottom = SDL_Rect(0, window.getHeight() - (n+1)*cellSize, window.getWidth(), (n+1)*cellSize); 80 sRectTop = SDL_Rect(0, n+1, texture.getWidth(), texture.getHeight() - (n+1)); 81 dRectTop = SDL_Rect(0, 0, window.getWidth(), window.getHeight() - (n+1)*cellSize); 82 } 83 84 void render() 85 { 86 { 87 uint* pixels = texture.lock(); 88 scope(exit) texture.unlock(); 89 90 foreach(col; 0 .. texture.getWidth()) 91 { 92 pixels[n * texture.getWidth() + col] = palette.getDisplayValue(lattice.get(col)); 93 } 94 } 95 96 sRectBottom.h = n+1; 97 dRectBottom.y = window.getHeight() - (n+1) * cellSize; 98 dRectBottom.h = (n+1) * cellSize; 99 SDL_RenderCopy(window.getRenderer(), texture.getTexture(), &sRectBottom, &dRectBottom); 100 101 sRectTop.y = n+1; 102 sRectTop.h = texture.getHeight() - (n+1); 103 dRectTop.h = window.getHeight() - (n+1) * cellSize; 104 SDL_RenderCopy(window.getRenderer(), texture.getTexture(), &sRectTop, &dRectTop); 105 106 SDL_RenderPresent(window.getRenderer()); 107 108 n ++; 109 110 if(n >= texture.getHeight()) 111 n=0; 112 } 113 114 void screenshot(string path) 115 in 116 { assert(path !is(null)); } 117 body 118 { 119 uint* pixels = texture.lock(); 120 scope(exit) texture.unlock(); 121 122 Image image = new Image(texture.getWidth(), texture.getHeight()); 123 foreach(row; 0 .. texture.getHeight()) 124 { 125 foreach(col; 0 .. texture.getWidth()) 126 { 127 image.setPixel(col, row, Color(pixels[(n + row) % texture.getHeight() * texture.getWidth() + col])); 128 } 129 } 130 image.saveToFile(path); 131 } 132 133 void startRecording(string path, uint framerate) 134 { 135 assert(0); 136 } 137 138 void stopRecording() 139 { 140 assert(0); 141 } 142 } 143 144 145 146 version(unittest) 147 { 148 import caLib_abstract.renderer : isRenderer; 149 import caLib_abstract.lattice : BoundedLattice; 150 import caLib_abstract.palette : Palette; 151 } 152 153 154 155 unittest 156 { 157 alias Ct = string; 158 assert(isRenderer!(OneDimBasicRenderer!(Ct, BoundedLattice!(Ct, 1), Palette!(Ct, Color)))); 159 }