diff --git a/src/game/GameModel.cpp b/src/game/GameModel.cpp index e4ee15ba8..29d13ce0c 100644 --- a/src/game/GameModel.cpp +++ b/src/game/GameModel.cpp @@ -84,7 +84,7 @@ GameModel::GameModel(): //Build other menus from wall data for(int i = 0; i < UI_WALLCOUNT; i++) { - Tool * tempTool = new WallTool(i, "", std::string(sim->wtypes[i].descs), PIXR(sim->wtypes[i].colour), PIXG(sim->wtypes[i].colour), PIXB(sim->wtypes[i].colour)); + Tool * tempTool = new WallTool(i, "", std::string(sim->wtypes[i].descs), PIXR(sim->wtypes[i].colour), PIXG(sim->wtypes[i].colour), PIXB(sim->wtypes[i].colour), sim->wtypes[i].textureGen); menuList[SC_WALL]->AddTool(tempTool); //sim->wtypes[i] } diff --git a/src/game/GameView.cpp b/src/game/GameView.cpp index 69beb7594..6b4a953ac 100644 --- a/src/game/GameView.cpp +++ b/src/game/GameView.cpp @@ -441,6 +441,11 @@ void GameView::NotifyToolListChanged(GameModel * sender) currentX -= 31; tempButton->SetActionCallback(new ToolAction(this, toolList[i])); + VideoBuffer * tempTexture = toolList[i]->GetTexture(30, 18); + tempButton->Appearance.SetTexture(tempTexture); + if(tempTexture) + delete tempTexture; + tempButton->Appearance.BackgroundInactive = ui::Colour(toolList[i]->colRed, toolList[i]->colGreen, toolList[i]->colBlue); if(sender->GetActiveTool(0) == toolList[i]) diff --git a/src/game/SignTool.cpp b/src/game/SignTool.cpp index 35f802d53..5b3bb8b66 100644 --- a/src/game/SignTool.cpp +++ b/src/game/SignTool.cpp @@ -118,6 +118,11 @@ void SignWindow::OnDraw() g->drawrect(Position.X, Position.Y, Size.X, Size.Y, 200, 200, 200, 255); } +VideoBuffer * SignTool::GetIcon(int toolID, int width, int height) +{ + +} + void SignTool::Click(Simulation * sim, Brush * brush, ui::Point position) { int signX, signY, signW, signH, signIndex = -1; diff --git a/src/game/Tool.cpp b/src/game/Tool.cpp index efe483112..977896b5d 100644 --- a/src/game/Tool.cpp +++ b/src/game/Tool.cpp @@ -12,15 +12,24 @@ using namespace std; -Tool::Tool(int id, string name, string description, int r, int g, int b): +Tool::Tool(int id, string name, string description, int r, int g, int b, VideoBuffer * (*textureGen)(int, int, int)): toolID(id), toolName(name), toolDescription(description), colRed(r), colGreen(g), - colBlue(b) + colBlue(b), + textureGen(textureGen) { } +VideoBuffer * Tool::GetTexture(int width, int height) +{ + if(textureGen) + { + return textureGen(toolID, width, height); + } + return NULL; +} string Tool::GetName() { return toolName; } string Tool::GetDescription() { return toolDescription; } Tool::~Tool() {} @@ -36,8 +45,8 @@ void Tool::DrawRect(Simulation * sim, Brush * brush, ui::Point position1, ui::Po } void Tool::DrawFill(Simulation * sim, Brush * brush, ui::Point position) {}; -ElementTool::ElementTool(int id, string name, string description, int r, int g, int b): - Tool(id, name, description, r, g, b) +ElementTool::ElementTool(int id, string name, string description, int r, int g, int b, VideoBuffer * (*textureGen)(int, int, int)): + Tool(id, name, description, r, g, b, textureGen) { } ElementTool::~ElementTool() {} @@ -55,8 +64,8 @@ void ElementTool::DrawFill(Simulation * sim, Brush * brush, ui::Point position) } -WallTool::WallTool(int id, string name, string description, int r, int g, int b): -Tool(id, name, description, r, g, b) +WallTool::WallTool(int id, string name, string description, int r, int g, int b, VideoBuffer * (*textureGen)(int, int, int)): +Tool(id, name, description, r, g, b, textureGen) { } WallTool::~WallTool() {} @@ -74,8 +83,8 @@ void WallTool::DrawFill(Simulation * sim, Brush * brush, ui::Point position) { } -GolTool::GolTool(int id, string name, string description, int r, int g, int b): - Tool(id, name, description, r, g, b) +GolTool::GolTool(int id, string name, string description, int r, int g, int b, VideoBuffer * (*textureGen)(int, int, int)): + Tool(id, name, description, r, g, b, textureGen) { } GolTool::~GolTool() {} diff --git a/src/game/Tool.h b/src/game/Tool.h index 2cc33be9b..c7b7f587b 100644 --- a/src/game/Tool.h +++ b/src/game/Tool.h @@ -16,17 +16,20 @@ using namespace std; class Simulation; class Brush; +class VideoBuffer; class Tool { protected: + VideoBuffer * (*textureGen)(int, int, int); int toolID; string toolName; string toolDescription; public: - Tool(int id, string name, string description, int r, int g, int b); + Tool(int id, string name, string description, int r, int g, int b, VideoBuffer * (*textureGen)(int, int, int) = NULL); string GetName(); string GetDescription(); + VideoBuffer * GetTexture(int width, int height); virtual ~Tool(); virtual void Click(Simulation * sim, Brush * brush, ui::Point position); virtual void Draw(Simulation * sim, Brush * brush, ui::Point position); @@ -40,9 +43,10 @@ class SignTool: public Tool { public: SignTool(): - Tool(0, "SIGN", "Sign. Click a sign to edit or anywhere else to create a new one", 0, 0, 0) + Tool(0, "SIGN", "Sign. Click a sign to edit or anywhere else to create a new one", 0, 0, 0, SignTool::GetIcon) { } + static VideoBuffer * GetIcon(int toolID, int width, int height); virtual ~SignTool() {} virtual void Click(Simulation * sim, Brush * brush, ui::Point position); virtual void Draw(Simulation * sim, Brush * brush, ui::Point position) { } @@ -55,7 +59,7 @@ class PropertyTool: public Tool { public: PropertyTool(): - Tool(0, "PROP", "Property Edit. Click to alter the properties of elements in the field", 0, 0, 0) + Tool(0, "PROP", "Property Edit. Click to alter the properties of elements in the field", 0, 0, 0, NULL) { } virtual ~PropertyTool() {} @@ -69,7 +73,7 @@ public: class Element_LIGH_Tool: public Tool { public: - Element_LIGH_Tool(int id, string name, string description, int r, int g, int b): + Element_LIGH_Tool(int id, string name, string description, int r, int g, int b, VideoBuffer * (*textureGen)(int, int, int) = NULL): Tool(id, name, description, r, g, b) { } @@ -84,7 +88,7 @@ public: class ElementTool: public Tool { public: - ElementTool(int id, string name, string description, int r, int g, int b); + ElementTool(int id, string name, string description, int r, int g, int b, VideoBuffer * (*textureGen)(int, int, int) = NULL); virtual ~ElementTool(); virtual void Draw(Simulation * sim, Brush * brush, ui::Point position); virtual void DrawLine(Simulation * sim, Brush * brush, ui::Point position1, ui::Point position2); @@ -95,7 +99,7 @@ public: class WallTool: public Tool { public: - WallTool(int id, string name, string description, int r, int g, int b); + WallTool(int id, string name, string description, int r, int g, int b, VideoBuffer * (*textureGen)(int, int, int) = NULL); virtual ~WallTool(); virtual void Draw(Simulation * sim, Brush * brush, ui::Point position); virtual void DrawLine(Simulation * sim, Brush * brush, ui::Point position1, ui::Point position2); @@ -106,7 +110,7 @@ public: class GolTool: public Tool { public: - GolTool(int id, string name, string description, int r, int g, int b); + GolTool(int id, string name, string description, int r, int g, int b, VideoBuffer * (*textureGen)(int, int, int) = NULL); virtual ~GolTool(); virtual void Draw(Simulation * sim, Brush * brush, ui::Point position); virtual void DrawLine(Simulation * sim, Brush * brush, ui::Point position1, ui::Point position2); diff --git a/src/game/ToolButton.cpp b/src/game/ToolButton.cpp index 729530993..21e19be28 100644 --- a/src/game/ToolButton.cpp +++ b/src/game/ToolButton.cpp @@ -40,7 +40,14 @@ void ToolButton::Draw(const ui::Point& screenPos) Graphics * g = ui::Engine::Ref().g; int totalColour = Appearance.BackgroundInactive.Blue + (3*Appearance.BackgroundInactive.Green) + (2*Appearance.BackgroundInactive.Red); - g->fillrect(screenPos.X+2, screenPos.Y+2, Size.X-4, Size.Y-4, Appearance.BackgroundInactive.Red, Appearance.BackgroundInactive.Green, Appearance.BackgroundInactive.Blue, Appearance.BackgroundInactive.Alpha); + if(Appearance.GetTexture()) + { + g->draw_image(Appearance.GetTexture(), screenPos.X, screenPos.Y, 255); + } + else + { + g->fillrect(screenPos.X+2, screenPos.Y+2, Size.X-4, Size.Y-4, Appearance.BackgroundInactive.Red, Appearance.BackgroundInactive.Green, Appearance.BackgroundInactive.Blue, Appearance.BackgroundInactive.Alpha); + } if(isMouseInside && currentSelection == -1) { diff --git a/src/graphics/Graphics.cpp b/src/graphics/Graphics.cpp index 5f84088e0..23ee09217 100644 --- a/src/graphics/Graphics.cpp +++ b/src/graphics/Graphics.cpp @@ -7,6 +7,36 @@ #define INCLUDE_FONTDATA #include "font.h" +VideoBuffer::VideoBuffer(int width, int height): + Width(width), + Height(height) +{ + Buffer = new pixel[width*height]; + std::fill(Buffer, Buffer+(width*height), 0); +}; + +VideoBuffer::VideoBuffer(const VideoBuffer & old): + Width(old.Width), + Height(old.Height) +{ + Buffer = new pixel[old.Width*old.Height]; + std::copy(old.Buffer, old.Buffer+(old.Width*old.Height), Buffer); +}; + +VideoBuffer::VideoBuffer(VideoBuffer * old): + Width(old->Width), + Height(old->Height) +{ + Buffer = new pixel[old->Width*old->Height]; + std::copy(old->Buffer, old->Buffer+(old->Width*old->Height), Buffer); +}; + + +VideoBuffer::~VideoBuffer() +{ + delete[] Buffer; +}; + TPT_INLINE void VideoBuffer::BlendPixel(int x, int y, int r, int g, int b, int a) { #ifdef PIX32OGL @@ -786,4 +816,13 @@ pixel *Graphics::render_packed_rgb(void *image, int width, int height, int cmp_s return res; } +void Graphics::draw_image(const VideoBuffer & vidBuf, int x, int y, int a) +{ + draw_image(vidBuf.Buffer, x, y, vidBuf.Width, vidBuf.Height, a); +} + +void Graphics::draw_image(VideoBuffer * vidBuf, int x, int y, int a) +{ + draw_image(vidBuf->Buffer, x, y, vidBuf->Width, vidBuf->Height, a); +} diff --git a/src/graphics/Graphics.h b/src/graphics/Graphics.h index 1209b8667..41c521aaf 100644 --- a/src/graphics/Graphics.h +++ b/src/graphics/Graphics.h @@ -90,14 +90,16 @@ public: pixel * Buffer; int Width, Height; - VideoBuffer(int width, int height): Width(width), Height(height), Buffer((pixel*)calloc(width*height, PIXELSIZE)) { }; + VideoBuffer(const VideoBuffer & old); + VideoBuffer(VideoBuffer * old); + VideoBuffer(int width, int height); void BlendPixel(int x, int y, int r, int g, int b, int a); void AddPixel(int x, int y, int r, int g, int b, int a); void SetPixel(int x, int y, int r, int g, int b, int a); int BlendCharacter(int x, int y, int c, int r, int g, int b, int a); int AddCharacter(int x, int y, int c, int r, int g, int b, int a); int SetCharacter(int x, int y, int c, int r, int g, int b, int a); - ~VideoBuffer() { free(Buffer); }; + ~VideoBuffer(); }; class Graphics @@ -158,6 +160,8 @@ public: void gradientrect(int x, int y, int width, int height, int r, int g, int b, int a, int r2, int g2, int b2, int a2); void draw_image(pixel *img, int x, int y, int w, int h, int a); + void draw_image(const VideoBuffer & vidBuf, int w, int h, int a); + void draw_image(VideoBuffer * vidBuf, int w, int h, int a); Graphics(); ~Graphics(); diff --git a/src/graphics/Renderer.cpp b/src/graphics/Renderer.cpp index 30f1bfdec..d91d30f86 100644 --- a/src/graphics/Renderer.cpp +++ b/src/graphics/Renderer.cpp @@ -394,6 +394,95 @@ void Renderer::RenderZoom() #endif } +int Renderer_wtypesCount; +wall_type * Renderer_wtypes = LoadWalls(Renderer_wtypesCount); + + +VideoBuffer * Renderer::WallIcon(int wallID, int width, int height) +{ + int x, y, i, j, cr, cg, cb; + int wt = wallID; + if (wt<0 || wt>=Renderer_wtypesCount) + return 0; + wall_type *wtypes = Renderer_wtypes; + pixel pc = wtypes[wt].colour; + pixel gc = wtypes[wt].eglow; + VideoBuffer * newTexture = new VideoBuffer(width, height); + if (wtypes[wt].drawstyle==1) + { + for (j=0; j>1)&1; iSetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255); + } + else if (wtypes[wt].drawstyle==2) + { + for (j=0; jSetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255); + } + else if (wtypes[wt].drawstyle==3) + { + for (j=0; jSetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255); + } + else if (wtypes[wt].drawstyle==4) + { + for (j=0; jSetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255); + else if (i%CELL == (j%CELL)+1 || (i%CELL == 0 && j%CELL == CELL-1)) + newTexture->SetPixel(i, j, PIXR(gc), PIXG(gc), PIXB(gc), 255); + else + newTexture->SetPixel(i, j, 0x20, 0x20, 0x20, 255); + } + + // special rendering for some walls + if (wt==WL_EWALL) + { + for (j=0; j width/2) + { + if (i&j&1) + newTexture->SetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255); + } + else + { + if (!(i&j&1)) + newTexture->SetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255); + } + } + else if (wt==WL_WALLELEC) + { + for (j=0; jSetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255); + else + newTexture->SetPixel(i, j, 0x80, 0x80, 0x80, 255); + } + } + else if (wt==WL_EHOLE) + { + for (j=0; jSetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255); + } + else + { + if (!(i&j&1)) + newTexture->SetPixel(i, j, PIXR(pc), PIXG(pc), PIXB(pc), 255); + } + } + return newTexture; +} + void Renderer::DrawWalls() { #ifndef OGLR diff --git a/src/graphics/Renderer.h b/src/graphics/Renderer.h index b2ae64011..c292b80b3 100644 --- a/src/graphics/Renderer.h +++ b/src/graphics/Renderer.h @@ -122,6 +122,8 @@ public: void SetColourMode(unsigned int mode); unsigned int GetColourMode(); + static VideoBuffer * WallIcon(int wallID, int width, int height); + Renderer(Graphics * g, Simulation * sim); ~Renderer(); diff --git a/src/interface/Appearance.cpp b/src/interface/Appearance.cpp index 29227227f..b504d02b7 100644 --- a/src/interface/Appearance.cpp +++ b/src/interface/Appearance.cpp @@ -28,6 +28,30 @@ namespace ui BorderActive(255, 255, 255), Margin(1, 4), - icon(NoIcon) + icon(NoIcon), + + texture(NULL) {}; + + VideoBuffer * Appearance::GetTexture() + { + return texture; + } + + void Appearance::SetTexture(VideoBuffer * texture) + { + if(this->texture) + delete this->texture; + if(texture) + this->texture = new VideoBuffer(texture); + else + this->texture = NULL; + } + + Appearance::~Appearance() + { + if(texture) + delete texture; + } + } diff --git a/src/interface/Appearance.h b/src/interface/Appearance.h index 174973174..4767edbee 100644 --- a/src/interface/Appearance.h +++ b/src/interface/Appearance.h @@ -16,6 +16,8 @@ namespace ui { class Appearance { + private: + VideoBuffer * texture; public: enum HorizontalAlignment { @@ -46,8 +48,12 @@ namespace ui ui::Border Margin; Icon icon; + + VideoBuffer * GetTexture(); + void SetTexture(VideoBuffer * texture); Appearance(); + ~Appearance(); }; } diff --git a/src/simulation/SimulationData.cpp b/src/simulation/SimulationData.cpp index 66e39a43f..877474b08 100644 --- a/src/simulation/SimulationData.cpp +++ b/src/simulation/SimulationData.cpp @@ -119,22 +119,22 @@ wall_type * LoadWalls(int & wallCount) { wall_type wtypes[] = { - {PIXPACK(0x808080), PIXPACK(0x000000), 0, "Erases walls."}, - {PIXPACK(0xC0C0C0), PIXPACK(0x101010), 0, "Wall. Indestructible. Blocks everything. Conductive."}, - {PIXPACK(0x808080), PIXPACK(0x808080), 0, "E-Wall. Becomes transparent when electricity is connected."}, - {PIXPACK(0xFF8080), PIXPACK(0xFF2008), 1, "Detector. Generates electricity when a particle is inside."}, - {PIXPACK(0x808080), PIXPACK(0x000000), 0, "Streamline. Set start point of a streamline."}, - {PIXPACK(0x8080FF), PIXPACK(0x000000), 1, "Fan. Accelerates air. Use line tool to set direction and strength."}, - {PIXPACK(0xC0C0C0), PIXPACK(0x101010), 2, "Wall. Blocks most particles but lets liquids through. Conductive."}, - {PIXPACK(0x808080), PIXPACK(0x000000), 1, "Wall. Absorbs particles but lets air currents through."}, - {PIXPACK(0x808080), PIXPACK(0x000000), 3, "Wall. Indestructible. Blocks everything."}, - {PIXPACK(0x3C3C3C), PIXPACK(0x000000), 1, "Wall. Indestructible. Blocks particles, allows air"}, - {PIXPACK(0x575757), PIXPACK(0x000000), 1, "Wall. Indestructible. Blocks liquids and gasses, allows powders"}, - {PIXPACK(0xFFFF22), PIXPACK(0x101010), 2, "Conductor, allows particles, conducts electricity"}, - {PIXPACK(0x242424), PIXPACK(0x101010), 0, "E-Hole, absorbs particles, release them when powered"}, - {PIXPACK(0x579777), PIXPACK(0x000000), 1, "Wall. Indestructible. Blocks liquids and solids, allows gasses"}, - {PIXPACK(0xFFEE00), PIXPACK(0xAA9900), 4, "Gravity wall"}, - {PIXPACK(0xFFAA00), PIXPACK(0xAA5500), 4, "Energy wall, allows only energy type particles to pass"}, + {PIXPACK(0x808080), PIXPACK(0x000000), 0, Renderer::WallIcon, "Erases walls."}, + {PIXPACK(0xC0C0C0), PIXPACK(0x101010), 0, Renderer::WallIcon, "Wall. Indestructible. Blocks everything. Conductive."}, + {PIXPACK(0x808080), PIXPACK(0x808080), 0, Renderer::WallIcon, "E-Wall. Becomes transparent when electricity is connected."}, + {PIXPACK(0xFF8080), PIXPACK(0xFF2008), 1, Renderer::WallIcon, "Detector. Generates electricity when a particle is inside."}, + {PIXPACK(0x808080), PIXPACK(0x000000), 0, Renderer::WallIcon, "Streamline. Set start point of a streamline."}, + {PIXPACK(0x8080FF), PIXPACK(0x000000), 1, Renderer::WallIcon, "Fan. Accelerates air. Use line tool to set direction and strength."}, + {PIXPACK(0xC0C0C0), PIXPACK(0x101010), 2, Renderer::WallIcon, "Wall. Blocks most particles but lets liquids through. Conductive."}, + {PIXPACK(0x808080), PIXPACK(0x000000), 1, Renderer::WallIcon, "Wall. Absorbs particles but lets air currents through."}, + {PIXPACK(0x808080), PIXPACK(0x000000), 3, Renderer::WallIcon, "Wall. Indestructible. Blocks everything."}, + {PIXPACK(0x3C3C3C), PIXPACK(0x000000), 1, Renderer::WallIcon, "Wall. Indestructible. Blocks particles, allows air"}, + {PIXPACK(0x575757), PIXPACK(0x000000), 1, Renderer::WallIcon, "Wall. Indestructible. Blocks liquids and gasses, allows powders"}, + {PIXPACK(0xFFFF22), PIXPACK(0x101010), 2, Renderer::WallIcon, "Conductor, allows particles, conducts electricity"}, + {PIXPACK(0x242424), PIXPACK(0x101010), 0, Renderer::WallIcon, "E-Hole, absorbs particles, release them when powered"}, + {PIXPACK(0x579777), PIXPACK(0x000000), 1, Renderer::WallIcon, "Wall. Indestructible. Blocks liquids and solids, allows gasses"}, + {PIXPACK(0xFFEE00), PIXPACK(0xAA9900), 4, Renderer::WallIcon, "Gravity wall"}, + {PIXPACK(0xFFAA00), PIXPACK(0xAA5500), 4, Renderer::WallIcon, "Energy wall, allows only energy type particles to pass"}, }; wallCount = UI_WALLCOUNT; wall_type * wtypesT = (wall_type*)malloc(UI_WALLCOUNT*sizeof(wall_type)); diff --git a/src/simulation/WallType.h b/src/simulation/WallType.h index bd453d8c5..06d71cebf 100644 --- a/src/simulation/WallType.h +++ b/src/simulation/WallType.h @@ -14,6 +14,7 @@ struct wall_type pixel colour; pixel eglow; // if emap set, add this to fire glow int drawstyle; + VideoBuffer * (*textureGen)(int, int, int); const char *descs; };