diff options
Diffstat (limited to 'Magic2/Grid.cpp')
-rw-r--r-- | Magic2/Grid.cpp | 370 |
1 files changed, 370 insertions, 0 deletions
diff --git a/Magic2/Grid.cpp b/Magic2/Grid.cpp new file mode 100644 index 0000000..133f26c --- /dev/null +++ b/Magic2/Grid.cpp @@ -0,0 +1,370 @@ +/* Starshatter OpenSource Distribution + Copyright (c) 1997-2004, Destroyer Studios LLC. + All Rights Reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name "Destroyer Studios" nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + SUBSYSTEM: Magic.exe + FILE: Grid.cpp + AUTHOR: John DiCamillo + + + OVERVIEW + ======== + Implementation of the Grid class +*/ + +#include "stdafx.h" +#include "Magic.h" + +#include "MagicDoc.h" +#include "Grid.h" + +#include "ActiveWindow.h" +#include "Color.h" +#include "Polygon.h" +#include "Scene.h" +#include "Screen.h" +#include "Solid.h" +#include "Video.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +const int MAJOR_COUNT = 64; + +// +--------------------------------------------------------------------+ + +Grid::Grid() + : x_major(0), y_major(0), x_minor(0), y_minor(0), + bmp_plan(0), bmp_front(0), bmp_side(0) +{ + strcpy(name, "Grid"); + + plane = GRID_XZ; // plan + + show = true; + show_ref = true; + snap = true; + minor = true; + + x_size = 4; + y_size = 4; + x_skip = 4; + y_skip = 4; + + x_major = new Vec3[2*MAJOR_COUNT]; + y_major = new Vec3[2*MAJOR_COUNT]; +} + +Grid::~Grid() +{ + delete [] x_major; + delete [] y_major; + delete [] x_minor; + delete [] y_minor; +} + +// +--------------------------------------------------------------------+ + +const char* +Grid::GetReferencePlan() const +{ + if (bmp_plan) + return bmp_plan->GetFilename(); + + return ""; +} + +void +Grid::SetReferencePlan(const char* fname) +{ + bmp_plan = 0; + + if (fname && *fname) + LoadTexture(fname, bmp_plan); +} + +// +--------------------------------------------------------------------+ + +const char* +Grid::GetReferenceFront() const +{ + if (bmp_front) + return bmp_front->GetFilename(); + + return ""; +} + +void +Grid::SetReferenceFront(const char* fname) +{ + bmp_front = 0; + + if (fname && *fname) + LoadTexture(fname, bmp_front); +} + +// +--------------------------------------------------------------------+ + +const char* +Grid::GetReferenceSide() const +{ + if (bmp_side) + return bmp_side->GetFilename(); + + return ""; +} + +void +Grid::SetReferenceSide(const char* fname) +{ + bmp_side = 0; + + if (fname && *fname) + LoadTexture(fname, bmp_side); +} + +// +--------------------------------------------------------------------+ + +void +Grid::Render(Video* video, DWORD flags) +{ + Vec3 origin[4]; + + for (int i = 0; i < 4; i++) + origin[i] = loc; + + const float EXTENT = (float) MAJOR_COUNT * 64.0f; + + switch (plane) { + case GRID_XY: // FRONT + origin[0].x += -EXTENT; + origin[1].x += EXTENT; + origin[2].y += -EXTENT; + origin[3].y += EXTENT; + + for (int i = 0; i < 2*MAJOR_COUNT; i += 2) { + float x = (float) (i-MAJOR_COUNT) * 64.0f; + float y = (float) (i-MAJOR_COUNT) * 64.0f; + + x_major[i ] = loc + Vec3(x, -EXTENT, 0.0f); + x_major[i+1] = loc + Vec3(x, EXTENT, 0.0f); + y_major[i ] = loc + Vec3(-EXTENT, y, 0.0f); + y_major[i+1] = loc + Vec3( EXTENT, y, 0.0f); + } + + break; + + case GRID_XZ: // PLAN + origin[0].x += -EXTENT; + origin[1].x += EXTENT; + origin[2].z += -EXTENT; + origin[3].z += EXTENT; + + for (int i = 0; i < 2*MAJOR_COUNT; i += 2) { + float x = (float) (i-MAJOR_COUNT) * 64.0f; + float z = (float) (i-MAJOR_COUNT) * 64.0f; + + x_major[i ] = loc + Vec3(x, 0.0f, -EXTENT); + x_major[i+1] = loc + Vec3(x, 0.0f, EXTENT); + y_major[i ] = loc + Vec3(-EXTENT, 0.0f, z); + y_major[i+1] = loc + Vec3( EXTENT, 0.0f, z); + } + + break; + + case GRID_YZ: // SIDE + origin[0].y += -EXTENT; + origin[1].y += EXTENT; + origin[2].z += -EXTENT; + origin[3].z += EXTENT; + + for (int i = 0; i < 2*MAJOR_COUNT; i += 2) { + float y = (float) (i-MAJOR_COUNT) * 64.0f; + float z = (float) (i-MAJOR_COUNT) * 64.0f; + + x_major[i ] = loc + Vec3(0.0f, y, -EXTENT); + x_major[i+1] = loc + Vec3(0.0f, y, EXTENT); + y_major[i ] = loc + Vec3(0.0f, -EXTENT, z); + y_major[i+1] = loc + Vec3(0.0f, EXTENT, z); + } + + break; + } + + RenderReference(video); + + video->SetRenderState(Video::FILL_MODE, Video::FILL_SOLID); + video->SetRenderState(Video::LIGHTING_ENABLE, FALSE); + video->SetRenderState(Video::Z_ENABLE, TRUE); + video->SetRenderState(Video::Z_WRITE_ENABLE, TRUE); + + video->DrawLines(MAJOR_COUNT, x_major, Color::Gray, 1); + video->DrawLines(MAJOR_COUNT, y_major, Color::Gray, 1); + video->DrawLines( 2, origin, Color::DarkGray, 1); +} + +// +--------------------------------------------------------------------+ + +void +Grid::RenderReference(Video* video) +{ + if (!show_ref) return; + + Bitmap* bmp = 0; + + switch (plane) { + case GRID_XY: bmp = bmp_front; break; + case GRID_XZ: bmp = bmp_plan; break; + case GRID_YZ: bmp = bmp_side; break; + } + + if (!bmp) return; + + Material mtl; + VertexSet vset(4); + Poly poly; + Vec3 nrm; + + float vx = (float) bmp->Width(); + float vy = (float) bmp->Height(); + float vz = -100.0f; + + if (vx <= 256 || vy <= 256) { + vx *= 2.0f; + vy *= 2.0f; + } + + switch (plane) { + case GRID_XY: // FRONT + nrm = Vec3(0.0f, 0.0f, 1.0f); + vset.loc[0] = loc + Vec3(-vx, -vy, vz); + vset.loc[1] = loc + Vec3( vx, -vy, vz); + vset.loc[2] = loc + Vec3( vx, vy, vz); + vset.loc[3] = loc + Vec3(-vx, vy, vz); + break; + + case GRID_XZ: // PLAN + nrm = Vec3(0.0f, 1.0f, 0.0f); + vset.loc[0] = loc + Vec3(-vx, vz, vy); + vset.loc[1] = loc + Vec3( vx, vz, vy); + vset.loc[2] = loc + Vec3( vx, vz, -vy); + vset.loc[3] = loc + Vec3(-vx, vz, -vy); + break; + + case GRID_YZ: // SIDE + nrm = Vec3(1.0f, 0.0f, 0.0f); + vset.loc[0] = loc + Vec3( vz, -vx, -vy); + vset.loc[1] = loc + Vec3( vz, vx, -vy); + vset.loc[2] = loc + Vec3( vz, vx, vy); + vset.loc[3] = loc + Vec3( vz, -vx, vy); + break; + + default: + return; + } + + mtl.Ka = Color::White; + mtl.Kd = Color::Black; + mtl.tex_diffuse = bmp; + + vset.nrm[0] = nrm; + vset.nrm[1] = nrm; + vset.nrm[2] = nrm; + vset.nrm[3] = nrm; + + vset.tu[0] = 0.0f; + vset.tv[0] = 0.0f; + vset.tu[1] = 1.0f; + vset.tv[1] = 0.0f; + vset.tu[2] = 1.0f; + vset.tv[2] = 1.0f; + vset.tu[3] = 0.0f; + vset.tv[3] = 1.0f; + + poly.nverts = 4; + poly.verts[0] = 0; + poly.verts[1] = 1; + poly.verts[2] = 2; + poly.verts[3] = 3; + poly.material = &mtl; + poly.vertex_set = &vset; + + video->SetRenderState(Video::FILL_MODE, Video::FILL_SOLID); + video->SetRenderState(Video::LIGHTING_ENABLE, TRUE); + video->SetRenderState(Video::Z_ENABLE, FALSE); + video->SetRenderState(Video::Z_WRITE_ENABLE, FALSE); + video->SetAmbient(Color::White); + + video->DrawPolys(1, &poly); +} + +// +----------------------------------------------------------------------+ + +CPoint& +Grid::Snap(CPoint& p) +{ + p.x = snapto(p.x, x_size); + p.y = snapto(p.y, y_size); + + return p; +} + +// +----------------------------------------------------------------------+ + +int +Grid::snapto(int i, int dim) +{ + if (!snap) + return i; + + int n = i + dim/2; + int m = n % dim; + + return (n - m); +} + +// +----------------------------------------------------------------------+ + +void +Grid::SetSize(int x, int y) +{ + x_size = x; + y_size = y ? y : x; +} + +// +----------------------------------------------------------------------+ + +void +Grid::SetSkip(int x, int y) +{ + x_skip = x; + y_skip = y ? y : x; +} + |