Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //cl /EHsc /O2 DuneGroundEdit.cpp gdi32.lib user32.lib opengl32.lib comdlg32.lib
- #include <windows.h>
- #include <GL/gl.h>
- #include <GL/glu.h>
- #include <stdio.h>
- #include <time.h>
- #include "dunes.h"
- #include "dunestructures.h"
- #include <vector>
- #define GET_X_LPARAM(a) ((short)LOWORD(a))
- #define GET_Y_LPARAM(a) ((short)HIWORD(a))
- unsigned short PlaneB[0x1000/2];
- POINT camera = {0,0};
- POINT mouse;
- double zoom = 1;
- bool showgrey = false;
- bool showunits = true;
- int state = 0;
- int drawtype = 0;
- int drawsize = 1;
- bool drawinverse = false;
- struct Ground
- {
- int width;
- int height;
- double *data;
- Ground(int _width, int _height)
- {
- width = _width;
- height = _height;
- data = (double *)malloc(width*height*sizeof(double));
- for (int x=0; x<width; ++x)
- for (int y=0; y<height; ++y)
- (*this)[x][y] = 0;
- }
- bool in(int x, int y)
- {
- if (x<0
- || y<0
- || x>=width
- || y>=height)
- return false;
- return true;
- }
- double *operator [](int x)
- {
- return data+x*height;
- }
- ~Ground()
- {
- if (data)
- free(data);
- }
- };
- struct DuneGround
- {
- enum Types {Dust, Ground, SpiceLow, SpiceHigh, Dune};
- int width;
- int height;
- BYTE *data;
- BYTE *types;
- DuneGround(int _width, int _height)
- {
- width = _width;
- height = _height;
- data = (BYTE *)malloc(width*height*sizeof(BYTE));
- types = (BYTE *)malloc(twidth()*theight()*sizeof(BYTE));
- Clear();
- }
- ~DuneGround()
- {
- if (data)
- free(data);
- if (types)
- free(types);
- }
- DuneGround(const DuneGround & g)
- {
- data = 0;
- types = 0;
- width = 0;
- height = 0;
- (*this) = g;
- }
- const DuneGround & operator = (const DuneGround &g)
- {
- if (width != g.width
- || height != g.height)
- {
- if (data)
- free(data);
- if (types)
- free(types);
- data = (BYTE *)malloc(g.width*g.height*sizeof(BYTE));
- types = (BYTE *)malloc(g.twidth()*g.theight()*sizeof(BYTE));
- }
- width = g.width;
- height = g.height;
- memcpy(data,g.data,width*height*sizeof(BYTE));
- memcpy(types,g.types,twidth()*theight()*sizeof(BYTE));
- return (*this);
- }
- void Clear()
- {
- for (int x=0; x<width; ++x)
- for (int y=0; y<height; ++y)
- (*this)[x][y] = 0xB0;
- for (int x=0; x<twidth(); ++x)
- for (int y=0; y<theight(); ++y)
- this->t(x,y) = Dust;
- }
- inline int twidth() const
- {
- return width*2+1;
- }
- inline int theight() const
- {
- return height*2+1;
- }
- inline bool tin(int x, int y) const
- {
- return (x>=0 && y>=0 && x<twidth() && y<theight());
- }
- inline bool in(int x, int y) const
- {
- return (x>=0 && y>=0 && x<width && y<height);
- }
- void Draw(int x, int y, BYTE type)
- {
- // 0 1 2
- // 0 1 2 3 4 5 6
- this->t(x,y) = type;
- if (in(x/2, y/2))
- Correct(x/2, y/2, type);
- if (in(x/2-1, y/2))
- Correct(x/2-1,y/2,type);
- if (in(x/2, y/2-1))
- Correct(x/2,y/2-1,type);
- if (in(x/2-1, y/2-1))
- Correct(x/2-1-1,y/2-1,type);
- }
- void Correct(int x, int y, BYTE type_draw)
- {
- if (type_draw == Ground)
- {
- for (int i=0; i<3; ++i)
- for (int j=0; j<3; ++j)
- if (t(i+x*2,j+y*2) != Ground
- && t(i+x*2,j+y*2) != Dust)
- Draw(i+x*2,j+y*2,Dust);
- }
- if (type_draw == SpiceLow)
- {
- for (int i=0; i<3; ++i)
- for (int j=0; j<3; ++j)
- if (t(i+x*2,j+y*2) != SpiceLow
- && t(i+x*2,j+y*2) != SpiceHigh
- && t(i+x*2,j+y*2) != Dust)
- Draw(i+x*2,j+y*2,Dust);
- }
- if (type_draw == SpiceHigh)
- {
- for (int i=0; i<3; ++i)
- for (int j=0; j<3; ++j)
- if (t(i+x*2,j+y*2) != SpiceHigh
- && t(i+x*2,j+y*2) != SpiceLow)
- Draw(i+x*2,j+y*2,SpiceLow);
- }
- if (type_draw == SpiceHigh)
- {
- for (int i=0; i<3; ++i)
- for (int j=0; j<3; ++j)
- if (t(i+x*2,j+y*2) != SpiceHigh
- && t(i+x*2,j+y*2) != SpiceLow)
- Draw(i+x*2,j+y*2,SpiceLow);
- }
- if (type_draw == Dune)
- {
- for (int i=0; i<3; ++i)
- for (int j=0; j<3; ++j)
- if (t(i+x*2,j+y*2) != Dune
- && t(i+x*2,j+y*2) != Dust)
- Draw(i+x*2,j+y*2,Dust);
- /*int k = GetK(x,y,Dune);
- int mask = dunemask[k];
- for (int i=0; i<3; ++i)
- for (int j=0; j<3; ++j)
- {
- if ((mask & (1<<(i+j*3)))
- && t(i+x*2,j+y*2) != Dune)
- Draw(i+x*2,j+y*2,Dune);
- if (!(mask & (1<<(i+j*3)))
- && t(i+x*2,j+y*2) == Dune)
- Draw(i+x*2,j+y*2,Dust);
- }*/
- }
- for (int i=-1; i<2; ++i)
- for (int j=-1; j<2; ++j)
- if (in(x+i,y+j))
- Update(x+i, y+j);
- }
- int GetK(int x, int y, BYTE type)
- {
- int mask = 0;
- int k = 0;
- for (int i=0; i<3; ++i)
- for (int j=0; j<3; ++j)
- if (t(i+x*2,j+y*2) == type)
- mask |= 1<<(i+j*3);
- //1 2 4
- //8 16 32
- //64 128 256
- if ( type == Dune )
- {
- k = 0;
- int min = 10;
- for (int i=0; i<256; ++i)
- if (dunemask[i] != -1)
- {
- int d = DunemaskDist((dunemask[i] & DUNE_MASK), (mask & DUNE_MASK));
- if (((dunemask[i] & DUNE_MASK) & (mask & DUNE_MASK)) == (mask & DUNE_MASK)
- && d < min)
- {
- k = i;
- min = d;
- }
- }
- for (int i=0; i<256; ++i)
- if (dunemask[i] != -1)
- {
- if (((dunemask[k] & DUNE_MASK)|(mask&16)) == (dunemask[i] & DUNE_MASKMID))
- k = i;
- }
- if (k == 0x9C && (mask & 2))
- k = 0x60;
- if (dunemask[k] == 0)
- k = 0;
- }
- else
- {
- if ( (mask&(1+2+4)) == (1+2+4))
- k++;
- if ( (mask&(4+32+256)) == (4+32+256))
- k |= 2;
- if ( (mask&(64+128+256)) == (64+128+256))
- k |= 4;
- if ( (mask&(1+8+64)) == (1+8+64))
- k |= 8;
- if ( type == Ground && k == 0 && (mask & 16)) // point
- k = 16;
- if ( k == 3 && !(mask & 16))
- k = 17;
- if ( k == 6 && !(mask & 16))
- k = 18;
- if ( k == 12 && !(mask & 16))
- k = 20;
- if ( k == 9 && !(mask & 16))
- k = 19;
- }
- return k;
- }
- void Update(int x, int y)
- {
- int types_mask = 0;
- for (int type = 0; type < 5; ++type)
- {
- bool was = false;
- for (int i=0; i<3; ++i)
- for (int j=0; j<3; ++j)
- if (t(i+x*2,j+y*2) == type)
- was = true;
- if (was)
- types_mask |= 1<<type;
- }
- int k = 0;
- int mask = 0;
- int id = 0xB0;
- if (types_mask & (1<<Ground))
- {
- k = GetK(x,y,Ground);
- id = 0x80+k;
- if (k == 0)
- id = 0xB0;
- if ( k == 16) // point
- id = 0x80;
- if ( k == 17)
- id = 0x3C;
- if ( k == 18)
- id = 0x3D;
- if ( k == 20)
- id = 0x3F;
- if ( k == 19)
- id = 0x3E;
- }
- if (types_mask & (1<<SpiceLow))
- {
- k = GetK(x,y,SpiceLow);
- id = 0xB0+k;
- if ( k == 17)
- id = 0x40;
- if ( k == 18)
- id = 0x41;
- if ( k == 20)
- id = 0x43;
- if ( k == 19)
- id = 0x42;
- }
- if (types_mask & (1<<SpiceHigh))
- {
- k = GetK(x,y,SpiceHigh);
- id = 0xC0+k;
- if ( k == 17 )
- id = 0x44;
- if ( k == 18 )
- id = 0x45;
- if ( k == 20 )
- id = 0x47;
- if ( k == 19 )
- id = 0x46;
- }
- if (types_mask & (1<<Dune))
- {
- k = GetK(x,y,Dune);
- if (k)
- id = k;
- //id = 0x9F;
- }
- (*this)[x][y] = id;
- }
- void SetTileMask(int x, int y)
- {
- int id = (*this)[x][y];
- int type = Dust;
- int mask = 0;
- int k = 0;
- if (id > 0x80 && id <= 0x8F)
- {
- type = Ground; k = id-0x80;
- }
- if (id == 0x80)
- {
- type = Ground; k = 16;
- }
- if (id == 0x3C)
- {
- type = Ground; k = 17;
- }
- if (id == 0x3D)
- {
- type = Ground; k = 18;
- }
- if (id == 0x3F)
- {
- type = Ground; k = 20;
- }
- if (id == 0x3E)
- {
- type = Ground; k = 19;
- }
- if (id == 0x80)
- {
- type = Ground; k = 16;
- }
- if (id > 0xB0 && id <= 0xBF)
- {
- type = SpiceLow; k = id-0xB0;
- }
- if (id == 0x40)
- {
- type = SpiceLow; k = 17;
- }
- if (id == 0x41)
- {
- type = SpiceLow; k = 18;
- }
- if (id == 0x43)
- {
- type = SpiceLow; k = 20;
- }
- if (id == 0x42)
- {
- type = SpiceLow; k = 19;
- }
- if (id > 0xC0 && id <= 0xCF)
- {
- type = SpiceHigh; k = id-0xC0;
- }
- if (id == 0x44)
- {
- type = SpiceHigh; k = 17;
- }
- if (id == 0x45)
- {
- type = SpiceHigh; k = 18;
- }
- if (id == 0x47)
- {
- type = SpiceHigh; k = 20;
- }
- if (id == 0x46)
- {
- type = SpiceHigh; k = 19;
- }
- if (type != Dust)
- {
- if (k<16)
- {
- mask = 0;
- if (k & 1)
- mask |= (1+2+4);
- if (k & 2)
- mask |= (4+32+256);
- if (k & 4)
- mask |= (64+128+256);
- if (k & 8)
- mask |= (1+8+64);
- if (k != 1
- && k != 2
- && k != 4
- && k != 8)
- mask |= 16;
- }
- else
- {
- if (k == 16)
- mask = 16;
- if (k == 17)
- mask = make_dunemask(1,1,1,0,0,1,0,0,1);
- if (k == 18)
- mask = make_dunemask(0,0,1,0,0,1,1,1,1);
- if (k == 20)
- mask = make_dunemask(1,0,0,1,0,0,1,1,1);
- if (k == 19)
- mask = make_dunemask(1,1,1,1,0,0,1,0,0);
- }
- }
- for (int i=0; i<256; ++i)
- if (dunemask[i] != -1 && i == id)
- {
- mask = dunemask[i];
- type = Dune;
- }
- int a = type;
- int b = Dust;
- if (type == SpiceHigh)
- b = SpiceLow;
- for (int i=0; i<3; ++i)
- for (int j=0; j<3; ++j)
- if (mask & (1<<(i+j*3)))
- t(i+x*2,j+y*2) = a;
- else
- {
- if (b == SpiceLow && t(i+x*2,j+y*2) != SpiceLow)
- t(i+x*2,j+y*2) = b;
- }
- }
- BYTE *operator [](int x)
- {
- return data+x*height;
- }
- BYTE & t(int x,int y)
- {
- return types[y*twidth()+x];
- }
- };
- struct DuneUnit
- {
- short house;
- short id;
- short life;
- short pos;
- short angle;
- short ai;
- };
- struct DuneStructure
- {
- short flag;
- short house;
- short id;
- short life;
- short pos;
- };
- DuneGround duneGround(64,64);
- DuneGround duneGroundNew(64,64);
- std::vector<DuneUnit> Units;
- std::vector<DuneStructure> Structures;
- Ground g(2*64+1,2*64+1);
- GLuint GroundTiles;
- GLuint GroundGrey;
- GLuint StructuresTexture;
- // Declarations //////////////////////////////////////////////////////
- LPCSTR OpenFile(HWND hWnd, LPCSTR title);
- LPCSTR SaveFile(HWND hWnd, LPCSTR title);
- GLuint LoadTextureRAW( const char * filename, int wrap );
- GLuint LoadGreyTexture( const char * filename);
- GLuint LoadVRAM( const char * vram, const char * pal);
- GLuint GenerateGround();
- GLuint MakeGreyTexture();
- void ChangeState(int _state);
- void RangeGround(double z);
- void LocalPick(int x, int y, int type, double z, bool inverse);
- void LoadMap( const char * filename );
- void LoadMission( const char * filename );
- void SaveMap( const char * filename );
- void FreeTexture( GLuint texture );
- LRESULT CALLBACK WndProc( HWND hWnd, UINT message,
- WPARAM wParam, LPARAM lParam );
- VOID EnableOpenGL( HWND hWnd, HDC * hDC, HGLRC * hRC );
- VOID DisableOpenGL( HWND hWnd, HDC hDC, HGLRC hRC );
- void UpdateViewport(HWND hWnd);
- void Render(HWND hWnd, HDC hDC);
- // WinMain ///////////////////////////////////////////////////////////
- int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
- LPSTR lpCmdLine, int iCmdShow )
- {
- WNDCLASS wc;
- HWND hWnd;
- HDC hDC;
- HGLRC hRC;
- MSG msg;
- BOOL bQuit = FALSE;
- // register window class
- wc.style = CS_OWNDC;
- wc.lpfnWndProc = WndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = hInstance;
- wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
- wc.hCursor = LoadCursor( NULL, IDC_ARROW );
- wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
- wc.lpszMenuName = NULL;
- wc.lpszClassName = "DuneGroundEditor";
- RegisterClass( &wc );
- DunemaskInit();
- // create main window
- hWnd = CreateWindow(
- "DuneGroundEditor", "DuneGroundEditor",
- WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_THICKFRAME,
- 0, 0, 800, 600,
- NULL, NULL, hInstance, NULL );
- // enable OpenGL for the window
- EnableOpenGL( hWnd, &hDC, &hRC );
- UpdateViewport( hWnd);
- // load our texture
- GroundTiles = LoadTextureRAW( "tex1.bmp", TRUE );
- StructuresTexture = LoadTextureRAW( "structures.bmp", TRUE);
- srand(time(0));
- GroundGrey = GenerateGround();
- int startTime = GetTickCount();
- int prevTime = startTime;
- // program main loop
- while ( !bQuit )
- {
- // check for messages
- if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
- {
- // handle or dispatch messages
- if ( msg.message == WM_QUIT )
- {
- bQuit = TRUE;
- }
- else
- {
- TranslateMessage( &msg );
- DispatchMessage( &msg );
- }
- }
- else
- {
- int n = GetTickCount();
- if (n - prevTime > 1000/40)
- {
- Render(hWnd, hDC);
- prevTime = n;
- }
- else
- Sleep(1);
- }
- }
- // free the texture
- FreeTexture( GroundTiles );
- FreeTexture( GroundGrey );
- // shutdown OpenGL
- DisableOpenGL( hWnd, hDC, hRC );
- // destroy the window explicitly
- DestroyWindow( hWnd );
- return msg.wParam;
- }
- void Render(HWND hWnd, HDC hDC)
- {
- // OpenGL animation code goes here
- RECT rc;
- GetClientRect(hWnd,&rc);
- double cx = (camera.x+mouse.x-(rc.right/2))/32.0/zoom*2+0.5;
- double cy = (camera.y+mouse.y-(rc.bottom/2))/32.0/zoom*2+0.5;
- if (state == 2 && duneGround.tin(cx,cy))
- {
- int x = cx;
- int y = cy;
- double n = 0;
- double z = 0;
- for (int i=0; i<2; ++i)
- for (int j=0; j<2; ++j)
- if ( duneGround.tin(x+i,y+j) )
- {
- double w = (1-(cx-x-i))*(1-(cy-y-j));
- n += w;
- z += w*g[x+i][y+j];
- }
- z /= n;
- LocalPick(cx,cy,drawtype,z,drawinverse);//RangeGround(g[(int)(cx*2)][(int)(cy*2)]);*/
- }
- glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
- glClear( GL_COLOR_BUFFER_BIT );
- // setup texture mapping
- glEnable( GL_TEXTURE_2D );
- glBindTexture( GL_TEXTURE_2D, GroundTiles );
- glPushMatrix();
- glBegin( GL_QUADS );
- GetClientRect(hWnd, &rc);
- double tw = 1.0/16;
- //else
- {
- for (int i=0; i<duneGround.width; ++i)
- {
- for (int j=0; j<duneGround.height; ++j)
- {
- int id;
- if (state == 2)
- id = duneGroundNew[j][i];
- else
- id = duneGround[j][i];
- int idx = id&15;
- int idy = (id>>4);
- glTexCoord2d(tw*(idx+0),1-tw*(idy+0)); glVertex2d(j,-i);
- glTexCoord2d(tw*(idx+1),1-tw*(idy+0)); glVertex2d(j+1,-i);
- glTexCoord2d(tw*(idx+1),1-tw*(idy+1)); glVertex2d(j+1,-(i+1));
- glTexCoord2d(tw*(idx+0),1-tw*(idy+1)); glVertex2d(j,-(i+1));
- }
- }
- }
- glEnd();
- if (state == 1)
- {
- glEnable( GL_BLEND );
- glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
- glColor4f(1.f,1.f,1.f,0.5f);
- glBegin( GL_QUADS );
- for (int y=0; y<duneGround.theight(); ++y)
- {
- for (int x=0; x<duneGround.twidth(); ++x)
- {
- static int tid[]={0xB0,0x8F,0xC0,0xCF,0x9F};
- int id = duneGround.t(x,y);
- id = tid[id];
- int idx = id&15;
- int idy = (id>>4);
- glTexCoord2d(tw*(idx+0),1-tw*(idy+0)); glVertex2d(x*0.5-0.25,-(y*0.5-0.25));
- glTexCoord2d(tw*(idx+1),1-tw*(idy+0)); glVertex2d(x*0.5+0.5-0.25,-(y*0.5-0.25));
- glTexCoord2d(tw*(idx+1),1-tw*(idy+1)); glVertex2d(x*0.5+0.5-0.25,-(y*0.5+0.5-0.25));
- glTexCoord2d(tw*(idx+0),1-tw*(idy+1)); glVertex2d(x*0.5-0.25,-(y*0.5+0.5-0.25));
- }
- }
- glEnd();
- glDisable( GL_BLEND );
- }
- if (showunits)
- {
- glBindTexture( GL_TEXTURE_2D, StructuresTexture );
- glBegin( GL_QUADS );
- for (int i = 0; i < Structures.size(); ++i)
- {
- int x = (Structures[i].pos&0x3F);
- int y = (Structures[i].pos/0x40);
- int id = Structures[i].id;
- auto si = StructureDrawInfos[id];
- glTexCoord2d((si.x+ 0)/512.0,1-(si.y+ 0)/512.0); glVertex2d(x, -y);
- glTexCoord2d((si.x+si.width)/512.0,1-(si.y+ 0)/512.0); glVertex2d(x+si.width/32,-y);
- glTexCoord2d((si.x+si.width)/512.0,1-(si.y+si.height)/512.0); glVertex2d(x+si.width/32,-(y+si.height/32));
- glTexCoord2d((si.x+ 0)/512.0,1-(si.y+si.height)/512.0); glVertex2d(x, -(y+si.height/32));
- }
- glEnd();
- glBindTexture( GL_TEXTURE_2D, GroundGrey );
- glBegin( GL_QUADS );
- for (int i = 0; i < Units.size(); ++i)
- {
- int x = (Units[i].pos&0x3F);
- int y = (Units[i].pos/0x40);
- int id = Units[i].id;
- int idx = id&15;
- int idy = (id>>4);
- glTexCoord2d(tw*(idx+0),1-tw*(idy+0)); glVertex2d(x,-y);
- glTexCoord2d(tw*(idx+1),1-tw*(idy+0)); glVertex2d(x+1,-y);
- glTexCoord2d(tw*(idx+1),1-tw*(idy+1)); glVertex2d(x+1,-(y+1));
- glTexCoord2d(tw*(idx+0),1-tw*(idy+1)); glVertex2d(x,-(y+1));
- }
- glEnd();
- }
- if (showgrey)
- {
- glBindTexture( GL_TEXTURE_2D, GroundGrey );
- glBegin( GL_QUADS );
- glTexCoord2d(0,0); glVertex2d(0,-0);
- glTexCoord2d(1,0); glVertex2d(64,-0);
- glTexCoord2d(1,1); glVertex2d(64,-64);
- glTexCoord2d(0,1); glVertex2d(0,-64);
- glEnd();
- }
- glPopMatrix();
- SwapBuffers( hDC );
- }
- // Texture ///////////////////////////////////////////////////////////
- // load a 512x512 24 bit RGB .BMP file as a texture
- GLuint LoadTextureRAW( const char * filename, int wrap )
- {
- GLuint texture;
- int width, height;
- BYTE * data;
- FILE * file;
- FILE *f;
- BYTE tmp;
- int i;
- // open texture data
- file = fopen( filename, "rb" );
- if ( file == NULL ) return 0;
- // allocate buffer
- width = 512;
- height = 512;
- data = (BYTE*)malloc( width * height * 3 );
- // read texture data
- fseek( file, 0x36, SEEK_SET);
- fread( data, width * height * 3, 1, file );
- fclose( file );
- for (i=0; i<width*height; ++i)
- {
- tmp = data[i*3];
- data[i*3] = data[i*3+2];
- data[i*3+2] = tmp;
- }
- // allocate a texture name
- glGenTextures( 1, &texture );
- // select our current texture
- glBindTexture( GL_TEXTURE_2D, texture );
- // select modulate to mix texture with color for shading
- glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
- // when texture area is small, bilinear filter the closest MIP map
- glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
- // when texture area is large, bilinear filter the first MIP map
- glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
- // if wrap is true, the texture wraps over at the edges (repeat)
- // ... false, the texture ends at the edges (clamp)
- glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
- wrap ? GL_REPEAT : GL_CLAMP );
- glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
- wrap ? GL_REPEAT : GL_CLAMP );
- glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, width,
- height, 0, GL_RGB, GL_UNSIGNED_BYTE, data );
- // free buffer
- free( data );
- return texture;
- }
- GLuint LoadGreyTexture( const char * filename )
- {
- GLuint texture;
- int width, height;
- BYTE * data;
- FILE * file;
- FILE *f;
- BYTE tmp;
- int i;
- // open texture data
- file = fopen( filename, "rb" );
- if ( file == NULL ) return 0;
- // allocate buffer
- width = 128;
- height = 128;
- data = (BYTE*)malloc( width * height * 4 );
- // read texture data
- fseek( file, 0x36, SEEK_SET);
- fread( data, width * height * 3, 1, file );
- fclose( file );
- for (i=0; i<width*height; ++i)
- {
- int all = 0;
- for (int j=0; j<3; ++j)
- all += data[i*3+j];
- all /= 3;
- g[i%width][width - 1 - i/width] = all/255.0;
- }
- free(data);
- return MakeGreyTexture();
- }
- double randf()
- {
- return rand()/double(RAND_MAX);
- }
- // Midpoint displacement
- void GenerateGroundRecursive(Ground &g, int x, int y, int width, int height)
- {
- if (width <= 1 || height <= 1)
- return;
- double a,b,c,d;
- a = g[x ][y ];
- b = g[x+width][y ];
- c = g[x ][y+height];
- d = g[x+width][y+height];
- g[(x + (x + width))/2][ y ] = (a + b)/2;
- g[ x ][(y + (y + height))/2] = (a + c)/2;
- g[(x + (x + width))/2][ y + height ] = (c + d)/2;
- g[ x + width ][(y + (y + height))/2] = (b + d)/2;
- double z = (a+b+c+d)/4+((-1+randf()*2)*width/64/2);
- if (z > 1)
- z = 1;
- if (z < 0)
- z = 0;
- g[(x + (x + width))/2][(y + (y + height))/2] = z;
- GenerateGroundRecursive(g, x , y , width/2, height/2);
- GenerateGroundRecursive(g, x + width/2, y , width/2, height/2);
- GenerateGroundRecursive(g, x , y + height/2, width/2, height/2);
- GenerateGroundRecursive(g, x + width/2, y + height/2, width/2, height/2);
- }
- void LocalPick(int x, int y, int type, double z, bool inverse)
- {
- /*static std::vector<bool> was(129*129);
- if (was.size() != duneGround.width * duneGround.height)
- was.resize(duneGround.width * duneGround.height);
- was.assign(was.size(), false);*/
- static bool was[129][129];
- memset(was,0,sizeof(was));
- duneGroundNew = duneGround;
- static int X[(2*64+1)*(2*64+1)];
- static int Y[(2*64+1)*(2*64+1)];
- int s = 0,e = 0;
- X[e] = x;
- Y[e] = y;
- was[x][y] = true;
- ++e;
- while (s < e)
- {
- for (int i=-1; i<2; ++i)
- for (int j=-1; j<2; ++j)
- if (duneGround.tin(X[s]+i, Y[s]+j)
- && !was[X[s]+i][Y[s]+j]
- && ((!inverse && g[X[s]+i][Y[s]+j]>=z) || (inverse && g[X[s]+i][Y[s]+j]<=z) ))
- {
- X[e] = X[s]+i;
- Y[e] = Y[s]+j;
- was[X[e]][Y[e]] = true;
- duneGroundNew.Draw(X[e],Y[e],type);
- ++e;
- }
- ++s;
- }
- //char str[50];
- //sprintf(str,"%d %d < %d", s, e, (2*64+1)*(2*64+1));
- //MessageBox(NULL,"Oo",str,MB_OK);
- }
- void RangeGround(double z)
- {
- for (int x=0; x<64; ++x)
- {
- for (int y=0; y<64; ++y)
- {
- int mask = 0;
- for (int i=0; i<3; ++i)
- for (int j=0; j<3; ++j)
- if (g[i+x*2][j+y*2]>z)
- mask |= 1<<(i+j*3);
- int k = 0;
- //1 2 4
- //8 16 32
- //64 128 256
- if ( (mask&(1+2+4)) == (1+2+4))
- k++;
- if ( (mask&(4+32+256)) == (4+32+256))
- k |= 2;
- if ( (mask&(64+128+256)) == (64+128+256))
- k |= 4;
- if ( (mask&(1+8+64)) == (1+8+64))
- k |= 8;
- int id = 0x80+k;
- if ( k == 0)
- id = 0xB0;
- if ( k == 0 && (mask & 16))
- id = 0x80;
- if ( k == 3 && !(mask & 16))
- id = 0x3C;
- if ( k == 6 && !(mask & 16))
- id = 0x3D;
- if ( k == 12 && !(mask & 16))
- id = 0x3F;
- if ( k == 9 && !(mask & 16))
- id = 0x3E;
- duneGround[x][y] = id;
- }
- }
- }
- // Diamond Square algorithm
- void GenerateGroundCycle(Ground &g, int width)
- {
- for (int step = width; step >= 1; step/=2)
- {
- int step2 = step/2;
- for (int y=step2; y<width; y+=step)
- {
- for (int x=step2; x<width; x+=step)
- {
- g[x][y] = (g[x-step2][y-step2]
- + g[x+step2][y-step2]
- + g[x-step2][y+step2]
- + g[x+step2][y+step2])/4 + ((-1+randf()*2)*step2/64);
- if (g[x][y]>1)
- g[x][y]=1;
- if (g[x][y]<0)
- g[x][y]=0;
- }
- }
- for (int z=0; z<2; ++z)
- {
- for (int y=z*step2; y<width; y+=step)
- {
- for (int x=(1-z)*step2; x<width; x+=step)
- {
- double h = 0;
- int n = 0;
- if (g.in(x-step2,y))
- {
- h += g[x-step2][y];
- ++n;
- }
- if (g.in(x+step2,y))
- {
- h += g[x+step2][y];
- ++n;
- }
- if (g.in(x,y-step2))
- {
- h += g[x][y-step2];
- ++n;
- }
- if (g.in(x,y+step2))
- {
- h += g[x][y+step2];
- ++n;
- }
- h /= n;
- h += ((-1+randf()*2)*step2/64);
- if (h>1)
- h=1;
- if (h<0)
- h=0;
- g[x][y] = h;
- }
- }
- }
- }
- }
- GLuint GenerateGround()
- {
- g[ 0][ 0] = randf();
- g[g.width-1][ 0] = randf();
- g[ 0][g.height-1] = randf();
- g[g.width-1][g.height-1] = randf();
- //GenerateGroundRecursive(g, 0, 0, g.width-1, g.height-1);
- GenerateGroundCycle(g, g.width-1);
- return MakeGreyTexture();
- }
- GLuint MakeGreyTexture()
- {
- BYTE *data = (BYTE*)malloc( (g.width-1) * (g.height-1) * 3 );
- for (int x=0; x<g.width-1; ++x)
- {
- for (int y=0; y<g.height-1; ++y)
- {
- for (int i=0; i<3; ++i)
- data[(x + y*(g.width-1))*3 + i] = g[x][y]*255;
- }
- }
- GLuint texture;
- glGenTextures( 1, &texture );
- glBindTexture( GL_TEXTURE_2D, texture );
- glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
- // when texture area is small, bilinear filter the closest MIP map
- glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
- // when texture area is large, bilinear filter the first MIP map
- glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
- // if wrap is true, the texture wraps over at the edges (repeat)
- // ... false, the texture ends at the edges (clamp)
- glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
- glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
- glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, g.width-1, g.height-1, 0, GL_RGB, GL_UNSIGNED_BYTE, data );
- free(data);
- return texture;
- }
- void LoadMap( const char * filename )
- {
- FILE *f = fopen(filename, "rb");
- if (!f)
- return;
- BYTE tmp;
- duneGround.Clear();
- for (int y=0; y<duneGround.height; ++y)
- for (int x=0; x<duneGround.width; ++x)
- {
- fread(&tmp,1,1,f);
- duneGround[x][y]=tmp;
- duneGround.SetTileMask(x,y);
- }
- fclose(f);
- }
- void SaveMap( const char * filename )
- {
- FILE *f = fopen(filename,"wb");
- if (!f)
- return;
- for (int y=0; y<duneGround.height; ++y)
- for (int x=0; x<duneGround.width; ++x)
- fwrite(&duneGround[x][y],1,1,f);
- fclose(f);
- }
- void LoadMission( const char * filename )
- {
- FILE *f = fopen(filename, "rb");
- if (!f)
- return;
- //FILE *log = fopen("log.txt","w");
- BYTE buff[20];
- Units.clear();
- Structures.clear();
- DuneUnit unit;
- DuneStructure structure;
- for (;;)
- {
- BYTE cmd;
- BYTE subcmd;
- if (!fread(&cmd,1,1,f))
- break;
- fread(&subcmd,1,1,f);
- //fprintf(log,"cmd = %d, subcmd = %d, offset = %X\n",cmd,subcmd,ftell(f)-2);
- if (cmd & 0x80)
- break;
- switch(cmd)
- {
- // Settings
- case 0:
- switch(subcmd)
- {
- // LosePicture
- case 0:
- // WinPicture
- case 1:
- // BriefPicture
- case 2:
- fread(buff,1,2,f);
- fseek(f,(buff[0]<<8)|buff[1],SEEK_CUR);
- break;
- // TimeOut
- case 3:
- // MapScale
- case 4:
- // CursorPos
- case 5:
- // TacticalPos
- case 6:
- // LoseFlags
- case 7:
- // WinFlags
- case 8:
- fread(buff,1,2,f);
- break;
- }
- break;
- // MAP
- case 1:
- switch(subcmd)
- {
- // Bloom
- case 'B':
- // Field
- case 'F':
- fread(buff,1,2,f);
- fseek(f,((buff[0]<<8)|buff[1])*2,SEEK_CUR);
- break;
- case 'S':
- fread(buff,1,2,f);
- //sprintf(buff,"%d",((buff[0]<<8)|buff[1]));
- //MessageBox(NULL,buff,"Seed",MB_OK);
- break;
- }
- break;
- // Harkonnen
- case 2:
- // Atreides
- case 3:
- // Ordos
- case 4:
- // Fremen
- case 5:
- switch(subcmd)
- {
- // Quota
- case 'Q':
- // Credits
- case 'C':
- // Brain
- case 'B':
- // MaxUnits
- case 'M':
- fread(buff,1,2,f);
- //sprintf(buff,"%d(%X)%c",cmd,ftell(f),subcmd);
- //MessageBox(NULL,buff,"House",MB_OK);
- break;
- }
- break;
- // Starport (subcmd = unit)
- case 6:
- fread(buff,1,2,f);
- break;
- // Teams ( subcmd = team id )
- case 7:
- fseek(f,5*2,SEEK_CUR);
- break;
- // Units ( subcmd = unk )
- case 8:
- fread(buff,1,6*2,f);
- unit.house = (buff[ 0]<<8) | buff[ 1];
- unit.id = (buff[ 2]<<8) | buff[ 3];
- unit.life = (buff[ 4]<<8) | buff[ 5];
- unit.pos = (buff[ 6]<<8) | buff[ 7];
- unit.angle = (buff[ 8]<<8) | buff[ 9];
- unit.ai = (buff[10]<<8) | buff[12];
- Units.push_back(unit);
- break;
- // Structures ( subcmd = unk )
- case 9:
- if (subcmd == 'G')
- {
- fread(buff,1,3*2,f);
- structure.pos = (buff[ 0]<<8) | buff[ 1];
- structure.house = (buff[ 2]<<8) | buff[ 3];
- structure.id = (buff[ 4]<<8) | buff[ 5];
- }
- else
- {
- fread(buff,1,5*2,f);
- structure.flag = (buff[ 0]<<8) | buff[ 1];
- structure.house = (buff[ 2]<<8) | buff[ 3];
- structure.id = (buff[ 4]<<8) | buff[ 5];
- structure.life = (buff[ 6]<<8) | buff[ 7];
- structure.pos = (buff[ 8]<<8) | buff[ 9];
- }
- Structures.push_back(structure);
- break;
- // Reinforcements
- case 10:
- fread(buff,1,4*2,f);
- break;
- }
- }
- fclose(f);
- //fclose(log);
- //sprintf((char*)buff,"%d",Units.size());
- //MessageBox(NULL,(char*)buff,"Units.size()",MB_OK);
- }
- void FreeTexture( GLuint texture )
- {
- glDeleteTextures( 1, &texture );
- }
- bool mousedown = false;
- void UpdateViewport(HWND hWnd)
- {
- RECT rc;
- GetClientRect(hWnd, &rc);
- glViewport( 0, 0, rc.right, rc.bottom);
- glMatrixMode( GL_PROJECTION );
- glLoadIdentity();
- //gluOrtho2D( 0,0,500,500);//camera.x, camera.y, camera.x+rc.right, camera.y+rc.bottom);
- double scale = 1/32.0/zoom;
- glScalef(64.0/rc.right*zoom,64.0/rc.bottom*zoom,1);
- glTranslatef( -camera.x*scale, camera.y*scale, 0);
- glMatrixMode( GL_MODELVIEW );
- }
- void ChangeState(int _state)
- {
- if (state == _state)
- return;
- state = _state;
- }
- int CurrentMap = 0;
- void TryQuit(HWND hWnd)
- {
- int ret = MessageBox(hWnd,"Do you want to save map?","DuneGroundEditor",MB_YESNOCANCEL);
- if (ret == IDYES)
- {
- LPCSTR filename = SaveFile(hWnd, NULL);
- if (filename)
- {
- SaveMap(filename);
- PostQuitMessage( 0 );
- }
- }
- if (ret == IDNO)
- PostQuitMessage( 0 );
- }
- // Window Proc ///////////////////////////////////////////////////////
- LRESULT CALLBACK WndProc( HWND hWnd, UINT message,
- WPARAM wParam, LPARAM lParam )
- {
- switch ( message ) {
- case WM_CREATE:
- return 0;
- case WM_CLOSE:
- TryQuit(hWnd);
- return 0;
- case WM_SIZE:
- UpdateViewport(hWnd);
- break;
- case WM_DESTROY:
- return 0;
- case WM_KEYDOWN:
- switch ( wParam ) {
- case VK_ESCAPE:
- if (state == 0)
- TryQuit(hWnd);
- else
- ChangeState(0);
- return 0;
- case 'O':
- {
- LPCSTR filename = OpenFile(hWnd, "Choose Map");
- if (filename)
- LoadMap(filename);
- }
- return 0;
- case 'M':
- {
- LPCSTR filename = OpenFile(hWnd, "Choose Mission");
- if (filename)
- LoadMission(filename);
- }
- return 0;
- case 'S':
- {
- LPCSTR filename = SaveFile(hWnd, NULL);
- if (filename)
- SaveMap(filename);
- }
- return 0;
- case 'G':
- {
- LPCSTR filename = OpenFile(hWnd, "Choose Grey Bitmap");
- if (filename)
- {
- FreeTexture(GroundGrey);
- GroundGrey = LoadGreyTexture(filename);
- }
- }
- return 0;
- case 'R':
- FreeTexture(GroundGrey);
- GroundGrey = GenerateGround();
- return 0;
- case 'E':
- if (state == 2)
- ChangeState(1);
- else
- ChangeState(state^1);
- return 0;
- case 'F':
- if (state == 2)
- ChangeState(0);
- else
- ChangeState(2);
- return 0;
- case 'I':
- drawinverse = !drawinverse;
- return 0;
- case '0':
- drawtype = 0;
- return 0;
- case '1':
- drawtype = 1;
- return 0;
- case '2':
- drawtype = 2;
- return 0;
- case '3':
- drawtype = 3;
- return 0;
- case '4':
- drawtype = 4;
- return 0;
- case 'Q':
- --drawsize;
- if (drawsize == 0)
- drawsize = 1;
- return 0;
- case 'W':
- ++drawsize;
- return 0;
- case 'C':
- if (MessageBox(hWnd,"Do you really want to clear map?","DuneGroundEditor",MB_YESNO) == IDYES)
- duneGround.Clear();
- return 0;
- case VK_SPACE:
- showgrey = !showgrey;
- return 0;
- case 'U':
- showunits = !showunits;
- return 0;
- }
- return 0;
- case WM_MOUSEWHEEL:
- {
- RECT rc;
- GetClientRect(hWnd,&rc);
- mouse.x = GET_X_LPARAM(lParam);
- mouse.y = GET_Y_LPARAM(lParam);
- short zDelta = HIWORD(wParam);
- if (zDelta > 0)
- {
- zoom *= 1.2;
- camera.x *= 1.2;//(camera.x + mouse.x) * (zoom/(zoom-0.1)) - mouse.x;
- camera.y *= 1.2;//(camera.y + mouse.y) * (zoom/(zoom-0.1)) - mouse.y;
- }
- else
- {
- zoom /= 1.2;
- camera.x /= 1.2;
- camera.y /= 1.2;
- }
- UpdateViewport(hWnd);
- }
- break;
- case WM_LBUTTONDOWN:
- {
- SetCapture(hWnd);
- mouse.x = GET_X_LPARAM(lParam);
- mouse.y = GET_Y_LPARAM(lParam);
- //RECT rc;
- //GetClientRect(hWnd,&rc);
- //double cx = ((camera.x+mouse.x-(rc.right/2))/32.0/zoom);
- //double cy = ((camera.y+mouse.y-(rc.bottom/2))/32.0/zoom);
- if (state == 2)
- {
- duneGround = duneGroundNew;
- ChangeState(0);
- }
- }
- break;
- case WM_MOUSEMOVE:
- {
- POINT pos = mouse;
- mouse.x = GET_X_LPARAM(lParam);
- mouse.y = GET_Y_LPARAM(lParam);
- RECT rc;
- GetClientRect(hWnd,&rc);
- if (mousedown)
- {
- camera.x -= mouse.x-pos.x;
- camera.y -= mouse.y-pos.y;
- UpdateViewport(hWnd);
- }
- double cx = ((camera.x+mouse.x-(rc.right/2))/32.0/zoom)*2+0.5;
- double cy = ((camera.y+mouse.y-(rc.bottom/2))/32.0/zoom)*2+0.5;
- if (state == 1 && duneGround.tin(cx,cy) && (GetKeyState(VK_LBUTTON) & 0x80))
- {
- for (int x=0; x<drawsize; ++x)
- for (int y=0; y<drawsize; ++y)
- if (duneGround.tin(cx+x,cx+y))
- duneGround.Draw(cx+x,cy+y,drawtype);
- }
- }
- break;
- case WM_LBUTTONUP:
- ReleaseCapture();
- break;
- case WM_RBUTTONDOWN:
- SetCapture(hWnd);
- mouse.x = GET_X_LPARAM(lParam);
- mouse.y = GET_Y_LPARAM(lParam);
- mousedown = true;
- break;
- case WM_RBUTTONUP:
- ReleaseCapture();
- mousedown = false;
- break;
- }
- return DefWindowProc( hWnd, message, wParam, lParam );
- }
- // Dialogs
- LPCSTR OpenFile(HWND hWnd, LPCSTR title)
- {
- OPENFILENAME opn;
- memset(&opn, 0, sizeof(opn));
- opn.lStructSize = sizeof(opn);
- opn.hwndOwner = hWnd;
- opn.lpstrFilter = "All Files\0*.*\0\0";
- opn.nFilterIndex = 1;
- static char filename[MAX_PATH];
- filename[0] = 0;
- opn.lpstrFile = filename;
- opn.nMaxFile = MAX_PATH;
- opn.lpstrTitle = title;
- opn.Flags = OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR;
- if (GetOpenFileName(&opn))
- return filename;
- return NULL;
- }
- LPCSTR SaveFile(HWND hWnd, LPCSTR title)
- {
- OPENFILENAME opn;
- memset(&opn, 0, sizeof(opn));
- opn.lStructSize = sizeof(opn);
- opn.hwndOwner = hWnd;
- opn.lpstrFilter = "All Files\0*.*\0\0";
- opn.nFilterIndex = 1;
- static char filename[MAX_PATH];
- filename[0] = 0;
- opn.lpstrFile = filename;
- opn.nMaxFile = MAX_PATH;
- opn.lpstrTitle = title;
- opn.Flags = OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR;
- if (GetSaveFileName(&opn))
- return filename;
- return NULL;
- }
- // Enable OpenGL
- VOID EnableOpenGL( HWND hWnd, HDC * hDC, HGLRC * hRC )
- {
- PIXELFORMATDESCRIPTOR pfd;
- int iFormat;
- // get the device context (DC)
- *hDC = GetDC( hWnd );
- // set the pixel format for the DC
- ZeroMemory( &pfd, sizeof( pfd ) );
- pfd.nSize = sizeof( pfd );
- pfd.nVersion = 1;
- pfd.dwFlags = PFD_DRAW_TO_WINDOW |
- PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
- pfd.iPixelType = PFD_TYPE_RGBA;
- pfd.cColorBits = 24;
- pfd.cDepthBits = 16;
- pfd.iLayerType = PFD_MAIN_PLANE;
- iFormat = ChoosePixelFormat( *hDC, &pfd );
- SetPixelFormat( *hDC, iFormat, &pfd );
- // create and enable the render context (RC)
- *hRC = wglCreateContext( *hDC );
- wglMakeCurrent( *hDC, *hRC );
- }
- // Disable OpenGL
- VOID DisableOpenGL( HWND hWnd, HDC hDC, HGLRC hRC )
- {
- wglMakeCurrent( NULL, NULL );
- wglDeleteContext( hRC );
- ReleaseDC( hWnd, hDC );
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement