summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Robertshaw <simon@hardwired.org.uk>2012-03-03 21:38:22 (GMT)
committer Simon Robertshaw <simon@hardwired.org.uk>2012-03-03 21:38:22 (GMT)
commit3bbaa1a111e3770d2ce9b04f4b0f9688948d3e85 (patch)
tree662d315093f4025c2970e7c6264cfe88effd4e7f
parent732b9d6a0d16f94cd1c39f8e023e369c5837bb9c (diff)
downloadpowder-3bbaa1a111e3770d2ce9b04f4b0f9688948d3e85.zip
powder-3bbaa1a111e3770d2ce9b04f4b0f9688948d3e85.tar.gz
Decoration tools - no way to set colour yet
-rw-r--r--src/game/DecorationTool.h34
-rw-r--r--src/game/GameModel.cpp10
-rw-r--r--src/simulation/Simulation.cpp166
-rw-r--r--src/simulation/Simulation.h4
-rw-r--r--src/simulation/SimulationData.cpp1
-rw-r--r--src/simulation/SimulationData.h9
6 files changed, 222 insertions, 2 deletions
diff --git a/src/game/DecorationTool.h b/src/game/DecorationTool.h
new file mode 100644
index 0000000..b6ab7e3
--- /dev/null
+++ b/src/game/DecorationTool.h
@@ -0,0 +1,34 @@
+
+#ifndef DECORATIONTOOL_H_
+#define DECORATIONTOOL_H_
+
+#include "Tool.h"
+
+class DecorationTool: public Tool
+{
+public:
+ enum ToolType { BlendAdd = DECO_ADD, BlendRemove = DECO_SUBTRACT, BlendMultiply = DECO_MULTIPLY, BlendDivide = DECO_DIVIDE, BlendSet = DECO_DRAW };
+
+ ToolType decoMode;
+
+ DecorationTool(ToolType decoMode_, string name, int r, int g, int b):
+ Tool(0, name, r, g, b),
+ decoMode(decoMode_)
+ {
+ }
+ virtual ~DecorationTool() {}
+ virtual void Draw(Simulation * sim, Brush * brush, ui::Point position){
+ sim->ApplyDecorationPoint(position.X, position.Y, 1, 1, 24, 24, 24, 255, decoMode, brush);
+ }
+ virtual void DrawLine(Simulation * sim, Brush * brush, ui::Point position1, ui::Point position2) {
+ sim->ApplyDecorationLine(position1.X, position1.Y, position2.X, position2.Y, 1, 1, 24, 24, 24, 255, decoMode, brush);
+ }
+ virtual void DrawRect(Simulation * sim, Brush * brush, ui::Point position1, ui::Point position2) {
+ sim->ApplyDecorationBox(position1.X, position1.Y, position2.X, position2.Y, 24, 24, 24, 255, decoMode);
+ }
+ virtual void DrawFill(Simulation * sim, Brush * brush, ui::Point position) {
+
+ }
+};
+
+#endif
diff --git a/src/game/GameModel.cpp b/src/game/GameModel.cpp
index 80b56f8..099a501 100644
--- a/src/game/GameModel.cpp
+++ b/src/game/GameModel.cpp
@@ -7,6 +7,7 @@
#include "Brush.h"
#include "EllipseBrush.h"
#include "client/Client.h"
+#include "game/DecorationTool.h"
GameModel::GameModel():
activeTools({NULL, NULL, NULL}),
@@ -58,7 +59,7 @@ GameModel::GameModel():
}
menuList.clear();
- for(int i = 0; i < 12; i++)
+ for(int i = 0; i < SC_TOTAL; i++)
{
menuList.push_back(new Menu((const char)sim->msections[i].icon[0], sim->msections[i].name));
}
@@ -87,6 +88,13 @@ GameModel::GameModel():
//sim->wtypes[i]
}
+ //Add decoration tools to menu
+ menuList[SC_DECO]->AddTool(new DecorationTool(DecorationTool::BlendAdd, "ADD", 0, 0, 0));
+ menuList[SC_DECO]->AddTool(new DecorationTool(DecorationTool::BlendRemove, "SUB", 0, 0, 0));
+ menuList[SC_DECO]->AddTool(new DecorationTool(DecorationTool::BlendMultiply, "MUL", 0, 0, 0));
+ menuList[SC_DECO]->AddTool(new DecorationTool(DecorationTool::BlendDivide, "DIV", 0, 0, 0));
+ menuList[SC_DECO]->AddTool(new DecorationTool(DecorationTool::BlendSet, "SET", 0, 0, 0));
+
//Set default brush palette
brushList.push_back(new Brush(ui::Point(4, 4)));
brushList.push_back(new EllipseBrush(ui::Point(4, 4)));
diff --git a/src/simulation/Simulation.cpp b/src/simulation/Simulation.cpp
index 73757da..0c6c54e 100644
--- a/src/simulation/Simulation.cpp
+++ b/src/simulation/Simulation.cpp
@@ -300,6 +300,172 @@ int Simulation::create_part_add_props(int p, int x, int y, int tv, int rx, int r
return p;
}
+void Simulation::ApplyDecoration(int x, int y, int colR, int colG, int colB, int colA, int mode)
+{
+ int rp, tr, tg, tb, ta;
+ rp = pmap[y][x];
+ if (!rp)
+ return;
+
+ if (mode == DECO_DRAW)
+ {
+ parts[rp>>8].dcolour = ((colA<<24)|(colR<<16)|(colG<<8)|colB);
+ }
+ else
+ {
+ if (parts[rp>>8].dcolour == 0)
+ return;
+
+ ta = (parts[rp>>8].dcolour>>24)&0xFF;
+ tr = (parts[rp>>8].dcolour>>16)&0xFF;
+ tg = (parts[rp>>8].dcolour>>8)&0xFF;
+ tb = (parts[rp>>8].dcolour)&0xFF;
+
+ if (mode == DECO_ADD)
+ {
+ ta += colA;
+ tr += colR;
+ tg += colG;
+ tb += colB;
+ }
+ else if (mode == DECO_SUBTRACT)
+ {
+ ta -= colA;
+ tr -= colR;
+ tg -= colG;
+ tb -= colB;
+ }
+ else if (mode == DECO_MULTIPLY)
+ {
+ ta *= (int)((float)(1.0f+((float)colA)/255.0f));
+ tr *= (int)((float)(1.0f+((float)colR)/255.0f));
+ tg *= (int)((float)(1.0f+((float)colG)/255.0f));
+ tb *= (int)((float)(1.0f+((float)colB)/255.0f));
+ }
+ else if (mode == DECO_DIVIDE)
+ {
+ ta /= (int)((float)(1.0f+((float)colA)/255.0f));
+ tr /= (int)((float)(1.0f+((float)colR)/255.0f));
+ tg /= (int)((float)(1.0f+((float)colG)/255.0f));
+ tb /= (int)((float)(1.0f+((float)colB)/255.0f));
+ }
+ if(ta > 255)
+ ta = 255;
+ else if(ta < 0)
+ ta = 0;
+ if(tr > 255)
+ tr = 255;
+ else if(tr < 0)
+ tr = 0;
+ if(tg > 255)
+ tg = 255;
+ else if(tg < 0)
+ tg = 0;
+ if(tb > 255)
+ tb = 255;
+ else if(tb < 0)
+ tb = 0;
+ parts[rp>>8].dcolour = ((ta<<24)|(tr<<16)|(tg<<8)|tb);
+ }
+}
+
+void Simulation::ApplyDecorationPoint(int x, int y, int rx, int ry, int colR, int colG, int colB, int colA, int mode, Brush * cBrush)
+{
+ int i, j;
+
+ if(cBrush)
+ {
+ rx = cBrush->GetRadius().X;
+ ry = cBrush->GetRadius().Y;
+ }
+
+ if (rx == 0 && ry == 0)
+ {
+ ApplyDecoration(x, y, colR, colG, colB, colA, mode);
+ return;
+ }
+
+ bool *bitmap = cBrush->GetBitmap();
+ for (j=-ry; j<=ry; j++)
+ for (i=-rx; i<=rx; i++)
+ if(bitmap[(j+ry)*(rx*2)+(i+rx)])
+ ApplyDecoration(x+i, y+j, colR, colG, colB, colA, mode);
+}
+
+void Simulation::ApplyDecorationBox(int x1, int y1, int x2, int y2, int colR, int colG, int colB, int colA, int mode)
+{
+ int i, j;
+
+ if (x1>x2)
+ {
+ i = x2;
+ x2 = x1;
+ x1 = i;
+ }
+ if (y1>y2)
+ {
+ j = y2;
+ y2 = y1;
+ y1 = j;
+ }
+ for (j=y1; j<=y2; j++)
+ for (i=x1; i<=x2; i++)
+ ApplyDecorationPoint(i, j, 0, 0, colR, colG, colB, colA, mode);
+}
+
+void Simulation::ApplyDecorationLine(int x1, int y1, int x2, int y2, int rx, int ry, int colR, int colG, int colB, int colA, int mode, Brush * cBrush)
+{
+ int cp=abs(y2-y1)>abs(x2-x1), x, y, dx, dy, sy;
+ float e, de;
+ if (cp)
+ {
+ y = x1;
+ x1 = y1;
+ y1 = y;
+ y = x2;
+ x2 = y2;
+ y2 = y;
+ }
+ if (x1 > x2)
+ {
+ y = x1;
+ x1 = x2;
+ x2 = y;
+ y = y1;
+ y1 = y2;
+ y2 = y;
+ }
+ dx = x2 - x1;
+ dy = abs(y2 - y1);
+ e = 0.0f;
+ if (dx)
+ de = dy/(float)dx;
+ else
+ de = 0.0f;
+ y = y1;
+ sy = (y1<y2) ? 1 : -1;
+ for (x=x1; x<=x2; x++)
+ {
+ if (cp)
+ ApplyDecorationPoint(y, x, rx, ry, colR, colG, colB, colA, mode, cBrush);
+ else
+ ApplyDecorationPoint(x, y, rx, ry, colR, colG, colB, colA, mode, cBrush);
+ e += de;
+ if (e >= 0.5f)
+ {
+ y += sy;
+ if (!(rx+ry))
+ {
+ if (cp)
+ ApplyDecorationPoint(y, x, rx, ry, colR, colG, colB, colA, mode, cBrush);
+ else
+ ApplyDecorationPoint(x, y, rx, ry, colR, colG, colB, colA, mode, cBrush);
+ }
+ e -= 1.0f;
+ }
+ }
+}
+
//this creates particles from a brush, don't use if you want to create one particle
int Simulation::create_parts(int x, int y, int rx, int ry, int c, int flags, Brush * cBrush)
{
diff --git a/src/simulation/Simulation.h b/src/simulation/Simulation.h
index f03b189..007f3c2 100644
--- a/src/simulation/Simulation.h
+++ b/src/simulation/Simulation.h
@@ -245,6 +245,10 @@ public:
int flood_parts(int x, int y, int c, int cm, int bm, int flags);
int create_parts(int x, int y, int rx, int ry, int c, int flags, Brush * cBrush = NULL);
void create_line(int x1, int y1, int x2, int y2, int rx, int ry, int c, int flags, Brush * cBrush = NULL);
+ void ApplyDecoration(int x, int y, int colR, int colG, int colB, int colA, int mode);
+ void ApplyDecorationPoint(int x, int y, int rx, int ry, int colR, int colG, int colB, int colA, int mode, Brush * cBrush = NULL);
+ void ApplyDecorationLine(int x1, int y1, int x2, int y2, int rx, int ry, int colR, int colG, int colB, int colA, int mode, Brush * cBrush = NULL);
+ void ApplyDecorationBox(int x1, int y1, int x2, int y2, int colR, int colG, int colB, int colA, int mode);
void *transform_save(void *odata, int *size, matrix2d transform, vector2d translate);
inline void orbitalparts_get(int block1, int block2, int resblock1[], int resblock2[]);
inline void orbitalparts_set(int *block1, int *block2, int resblock1[], int resblock2[]);
diff --git a/src/simulation/SimulationData.cpp b/src/simulation/SimulationData.cpp
index 9ec5e67..8dd21e0 100644
--- a/src/simulation/SimulationData.cpp
+++ b/src/simulation/SimulationData.cpp
@@ -133,6 +133,7 @@ menu_section * LoadMenus(int & menuCount)
{"\xD2", "Life", 0, 1},
{"\xD7", "Tools", 0, 1},
{"\xD2", "More Life", 0, 1},
+ {"\xC8", "Decoration tools", 0, 1},
{"\xC8", "", 0, 0},
{"\xC8", "Cracker", 0, 0},
{"\xC8", "Cracker!", 0, 0},
diff --git a/src/simulation/SimulationData.h b/src/simulation/SimulationData.h
index ee31aea..c093d5c 100644
--- a/src/simulation/SimulationData.h
+++ b/src/simulation/SimulationData.h
@@ -17,9 +17,10 @@
#define SC_SPECIAL 9
#define SC_LIFE 10
#define SC_TOOL 11
+#define SC_DECO 12
#define SC_CRACKER 13
#define SC_CRACKER2 14
-#define SC_TOTAL 12
+#define SC_TOTAL 13
#define UI_WALLSTART 222
#define UI_ACTUALSTART 122
@@ -54,6 +55,12 @@
#define WL_GRAV 142
#define WL_ALLOWENERGY 145
+#define DECO_DRAW 0
+#define DECO_ADD 1
+#define DECO_SUBTRACT 2
+#define DECO_MULTIPLY 3
+#define DECO_DIVIDE 4
+
#ifndef SIMULATIONDATA_H_
#define SIMULATIONDATA_H_