Advertisement
r57shell

Dune2GroundEdit

Sep 17th, 2013
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 20.02 KB | None | 0 0
  1. #include <windows.h>
  2. #include <GL/gl.h>
  3. #include <GL/glu.h>
  4. #include <stdio.h>
  5. #include <time.h>
  6.  
  7. #define GET_X_LPARAM(a) ((short)LOWORD(a))
  8. #define GET_Y_LPARAM(a) ((short)HIWORD(a))
  9.  
  10. unsigned short PlaneB[0x1000/2];
  11.  
  12. POINT camera={0,0};
  13. POINT mouse;
  14. double zoom=1;
  15. bool showgray = false;
  16.  
  17. struct Ground
  18. {
  19.     int width;
  20.     int height;
  21.     double *data;
  22.     Ground(int _width, int _height)
  23.     {
  24.         width = _width;
  25.         height = _height;
  26.         data = (double *)malloc(width*height*sizeof(double));
  27.         for (int x=0; x<width; ++x)
  28.             for (int y=0; y<height; ++y)
  29.                 (*this)[x][y] = 0;
  30.     }
  31.    
  32.     double *operator [](int x)
  33.     {
  34.         return data+x*height;
  35.     }
  36.    
  37.     ~Ground()
  38.     {
  39.         if (data)
  40.             free(data);
  41.     }
  42. };
  43.  
  44. struct DuneGround
  45. {
  46.     int width;
  47.     int height;
  48.     BYTE *data;
  49.     DuneGround(int _width, int _height)
  50.     {
  51.         width = _width;
  52.         height = _height;
  53.         data = (BYTE *)malloc(width*height*sizeof(BYTE));
  54.         for (int x=0; x<width; ++x)
  55.             for (int y=0; y<height; ++y)
  56.                 (*this)[x][y] = 0xB0;
  57.     }
  58.    
  59.     BYTE *operator [](int x)
  60.     {
  61.         return data+x*height;
  62.     }
  63.    
  64.     ~DuneGround()
  65.     {
  66.         if (data)
  67.             free(data);
  68.     }
  69.    
  70.     DuneGround(const DuneGround & g)
  71.     {
  72.         width = g.width;
  73.         height = g.height;
  74.         data = (BYTE *)malloc(width*height*sizeof(BYTE));
  75.         memcpy(data,g.data,width*height*sizeof(BYTE));
  76.     }
  77. };
  78.  
  79. /*struct Point
  80. {
  81.     double x,y;
  82. }*/
  83.  
  84. DuneGround duneGround(64,64);
  85. //DuneGround duneGroundPrev(64,64);
  86.  
  87. Ground g(2*64+1,2*64+1);
  88. GLuint GroundTiles;
  89. GLuint GroundGrey;
  90.  
  91. // Declarations //////////////////////////////////////////////////////
  92.  
  93. GLuint LoadTextureRAW( const char * filename, int wrap );
  94. GLuint LoadVRAM( const char * vram, const char * pal);
  95. GLuint GenerateGround();
  96. void RangeGround(double z);
  97. void LocalPick(int x, int y);
  98. void LoadMap( const char * filename );
  99. void SaveMap( const char * filename );
  100. void FreeTexture( GLuint texture );
  101.  
  102. LRESULT CALLBACK WndProc( HWND hWnd, UINT message,
  103.                           WPARAM wParam, LPARAM lParam );
  104.  
  105. VOID EnableOpenGL( HWND hWnd, HDC * hDC, HGLRC * hRC );
  106. VOID DisableOpenGL( HWND hWnd, HDC hDC, HGLRC hRC );
  107. void UpdateViewport(HWND hWnd);
  108. void Render(HWND hWnd, HDC hDC);
  109.  
  110.  
  111.  
  112. // WinMain ///////////////////////////////////////////////////////////
  113.  
  114. int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  115.                     LPSTR lpCmdLine, int iCmdShow )
  116. {
  117.   WNDCLASS wc;
  118.   HWND hWnd;
  119.   HDC hDC;
  120.   HGLRC hRC;
  121.   MSG msg;
  122.   BOOL bQuit = FALSE;
  123.  
  124.   // register window class
  125.   wc.style = CS_OWNDC;
  126.   wc.lpfnWndProc = WndProc;
  127.   wc.cbClsExtra = 0;
  128.   wc.cbWndExtra = 0;
  129.   wc.hInstance = hInstance;
  130.   wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
  131.   wc.hCursor = LoadCursor( NULL, IDC_ARROW );
  132.   wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
  133.   wc.lpszMenuName = NULL;
  134.   wc.lpszClassName = "GLSample";
  135.   RegisterClass( &wc );
  136.  
  137.   // create main window
  138.   hWnd = CreateWindow(
  139.     "GLSample", "OpenGL Texture Sample",
  140.     WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE | WS_MAXIMIZEBOX | WS_THICKFRAME,
  141.     0, 0, 800, 600,
  142.     NULL, NULL, hInstance, NULL );
  143.  
  144.   // enable OpenGL for the window
  145.   EnableOpenGL( hWnd, &hDC, &hRC );
  146.   UpdateViewport( hWnd);
  147.  
  148.   // load our texture
  149.   GroundTiles = LoadTextureRAW( "tex1.bmp", TRUE );
  150.   LoadMap("map_18.bin");
  151.  
  152.   srand(time(0));
  153.   GroundGrey = GenerateGround();
  154.   //texture = LoadVRAM( "vram.bin", "pal.bin" );
  155.  
  156.   int startTime = GetTickCount();
  157.   int prevTime = startTime;
  158.  
  159.   // program main loop
  160.   while ( !bQuit ) {
  161.  
  162.     // check for messages
  163.     if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) {
  164.  
  165.       // handle or dispatch messages
  166.       if ( msg.message == WM_QUIT ) {
  167.         bQuit = TRUE;
  168.       } else {
  169.         TranslateMessage( &msg );
  170.         DispatchMessage( &msg );
  171.       }
  172.  
  173.     } else {
  174.         int n = GetTickCount();
  175.         if (n - prevTime > 1000/40)
  176.         {
  177.             Render(hWnd, hDC);
  178.             prevTime = n;
  179.         }
  180.         else
  181.             Sleep(1);
  182.     }
  183.  
  184.   }
  185.  
  186.   // free the texture
  187.   FreeTexture( GroundTiles );
  188.   FreeTexture( GroundGrey );
  189.  
  190.   // shutdown OpenGL
  191.   DisableOpenGL( hWnd, hDC, hRC );
  192.  
  193.   // destroy the window explicitly
  194.   DestroyWindow( hWnd );
  195.  
  196.   return msg.wParam;
  197.  
  198. }
  199.  
  200. void Render(HWND hWnd, HDC hDC)
  201. {
  202.     // OpenGL animation code goes here
  203.     RECT rc;
  204.     GetClientRect(hWnd,&rc);
  205.     double cx = int((camera.x+mouse.x-(rc.right/2))/32.0/zoom);
  206.     double cy = int((camera.y+mouse.y-(rc.bottom/2))/32.0/zoom);
  207.     if ((int)(cx*2) <64*2+1 && (int)(cx*2)>=0
  208.      && (int)(cy*2) <64*2+1 && (int)(cy*2)>=0)
  209.         LocalPick(cx*2,cy*2);//RangeGround(g[(int)(cx*2)][(int)(cy*2)]);
  210.  
  211.     glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
  212.     glClear( GL_COLOR_BUFFER_BIT );
  213.  
  214.     // setup texture mapping
  215.     glEnable( GL_TEXTURE_2D );
  216.     glBindTexture( GL_TEXTURE_2D, GroundTiles );
  217.  
  218.     glPushMatrix();
  219.     glBegin( GL_QUADS );
  220.  
  221.     // tiles
  222.     /*double tw = 1.0/64;
  223.     for (int i=0; i<32; ++i)
  224.     {
  225.         for (int j=0; j<64; ++j)
  226.         {
  227.             int id = PlaneB[i*64+j]&0x7FF;
  228.             int idx = id&63;
  229.             int idy = id>>6;
  230.             glTexCoord2d(tw*(idx+0),tw*(idy+0)); glVertex2d(-1.0+tw*j,+1.0-tw*i);
  231.             glTexCoord2d(tw*(idx+1),tw*(idy+0)); glVertex2d(-1.0+tw*(j+1),+1.0-tw*i);
  232.             glTexCoord2d(tw*(idx+1),tw*(idy+1)); glVertex2d(-1.0+tw*(j+1),+1.0-tw*(i+1));
  233.             glTexCoord2d(tw*(idx+0),tw*(idy+1)); glVertex2d(-1.0+tw*j,+1.0-tw*(i+1));
  234.         }
  235.     }
  236.     glTexCoord2d(0.0,0.0); glVertex2d(-8.0,+8.0);
  237.     glTexCoord2d(1.0,0.0); glVertex2d(+8.0,+8.0);
  238.     glTexCoord2d(1.0,1.0); glVertex2d(+8.0,-8.0);
  239.     glTexCoord2d(0.0,1.0); glVertex2d(-8.0,-8.0);*/
  240.     GetClientRect(hWnd, &rc);
  241.     double tw = 1.0/16;
  242.     for (int i=0; i<64; ++i)
  243.     {
  244.         for (int j=0; j<64; ++j)
  245.         {
  246.             int id = duneGround[j][i];
  247.             int idx = id&15;
  248.             int idy = (id>>4);
  249.             glTexCoord2d(tw*(idx+0),1-tw*(idy+0)); glVertex2d(j,-i);
  250.             glTexCoord2d(tw*(idx+1),1-tw*(idy+0)); glVertex2d(j+1,-i);
  251.             glTexCoord2d(tw*(idx+1),1-tw*(idy+1)); glVertex2d(j+1,-(i+1));
  252.             glTexCoord2d(tw*(idx+0),1-tw*(idy+1)); glVertex2d(j,-(i+1));
  253.            
  254.         }
  255.     }
  256.     glEnd();
  257.  
  258.     if (showgray)
  259.     {
  260.     glBindTexture( GL_TEXTURE_2D, GroundGrey );
  261.     glBegin( GL_QUADS );
  262.           glTexCoord2d(0,0); glVertex2d(0,-0);
  263.           glTexCoord2d(1,0); glVertex2d(64,-0);
  264.           glTexCoord2d(1,1); glVertex2d(64,-64);
  265.           glTexCoord2d(0,1); glVertex2d(0,-64);
  266.     glEnd();
  267.     }
  268.  
  269.     /*glBindTexture( GL_TEXTURE_2D, texture );
  270.     glBegin( GL_QUADS );
  271.        
  272.         glTexCoord2d(tw*(3+0),1-tw*(0+0)); glVertex2d(cx,-cy);
  273.         glTexCoord2d(tw*(3+1),1-tw*(0+0)); glVertex2d(cx+1,-cy);
  274.         glTexCoord2d(tw*(3+1),1-tw*(0+1)); glVertex2d(cx+1,-cy-1);
  275.         glTexCoord2d(tw*(3+0),1-tw*(0+1)); glVertex2d(cx,-cy-1);
  276.     glEnd();*/
  277.     glPopMatrix();
  278.  
  279.     SwapBuffers( hDC );
  280. }
  281.  
  282.  
  283. // Texture ///////////////////////////////////////////////////////////
  284.  
  285. // load a 256x256 RGB .RAW file as a texture
  286. GLuint LoadTextureRAW( const char * filename, int wrap )
  287. {
  288.   GLuint texture;
  289.   int width, height;
  290.   BYTE * data;
  291.   FILE * file;
  292.   FILE *f;
  293.   BYTE tmp;
  294.   int i;
  295.  
  296.   // open texture data
  297.   file = fopen( filename, "rb" );
  298.   if ( file == NULL ) return 0;
  299.  
  300.   // allocate buffer
  301.   width = 512;
  302.   height = 512;
  303.   data = (BYTE*)malloc( width * height * 3 );
  304.  
  305.   // read texture data
  306.  
  307.   fseek( file, 0x36, SEEK_SET);
  308.   fread( data, width * height * 3, 1, file );
  309.   fclose( file );
  310.  
  311.   for (i=0; i<width*height; ++i)
  312.   {
  313.         tmp = data[i*3];
  314.         data[i*3] = data[i*3+2];
  315.         data[i*3+2] = tmp;
  316.   }
  317.  
  318.   // allocate a texture name
  319.   glGenTextures( 1, &texture );
  320.  
  321.   // select our current texture
  322.   glBindTexture( GL_TEXTURE_2D, texture );
  323.  
  324.   // select modulate to mix texture with color for shading
  325.   glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
  326.  
  327.   // when texture area is small, bilinear filter the closest MIP map
  328.   glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  329.  
  330.   // when texture area is large, bilinear filter the first MIP map
  331.   glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  332.  
  333.   // if wrap is true, the texture wraps over at the edges (repeat)
  334.   //       ... false, the texture ends at the edges (clamp)
  335.   glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
  336.                    wrap ? GL_REPEAT : GL_CLAMP );
  337.   glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
  338.                    wrap ? GL_REPEAT : GL_CLAMP );
  339.  
  340.   // build our texture MIP maps
  341.   //gluBuild2DMipmaps( GL_TEXTURE_2D, 3, width,
  342.   //  height, GL_RGB, GL_UNSIGNED_BYTE, data );
  343.   glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, width,
  344.     height, 0, GL_RGB, GL_UNSIGNED_BYTE, data );
  345.  
  346.   // free buffer
  347.   free( data );
  348.  
  349.   return texture;
  350.  
  351. }
  352.  
  353. double randf()
  354. {
  355.     return rand()/double(RAND_MAX);
  356. }
  357.  
  358. void GenerateGroundRecursive(Ground &g, int x, int y, int width, int height)
  359. {
  360.     if (width <= 1 || height <= 1)
  361.         return;
  362.     double a,b,c,d;
  363.     a = g[x      ][y      ];
  364.     b = g[x+width][y      ];
  365.     c = g[x      ][y+height];
  366.     d = g[x+width][y+height];
  367.  
  368.     g[(x + (x + width))/2][ y                  ] = (a + b)/2;
  369.     g[ x                 ][(y + (y + height))/2] = (a + c)/2;
  370.     g[(x + (x + width))/2][ y + height         ] = (c + d)/2;
  371.     g[ x + width         ][(y + (y + height))/2] = (b + d)/2;
  372.    
  373.     double z = (a+b+c+d)/4+((-1+randf()*2)*width/64/2);
  374.     if (z > 1)
  375.         z = 1;
  376.     if (z < 0)
  377.         z = 0;
  378.     g[(x + (x + width))/2][(y + (y + height))/2] = z;
  379.    
  380.     GenerateGroundRecursive(g, x          , y           , width/2, height/2);
  381.     GenerateGroundRecursive(g, x + width/2, y           , width/2, height/2);
  382.     GenerateGroundRecursive(g, x          , y + height/2, width/2, height/2);
  383.     GenerateGroundRecursive(g, x + width/2, y + height/2, width/2, height/2);
  384. }
  385.  
  386. void LocalPick(int x, int y)
  387. {
  388.     static bool was[2*64+1][2*64+1];
  389.  
  390.     for (int i=0; i<2*64+1; ++i)
  391.         for (int j=0; j<2*64+1; ++j)
  392.             was[i][j] = false;
  393.  
  394.     static int X[(2*64+1)*(2*64+1)];
  395.     static int Y[(2*64+1)*(2*64+1)];
  396.     double z = g[x][y];
  397.     int s = 0,e = 0;
  398.     X[e] = x;
  399.     Y[e] = y;
  400.     was[x][y] = true;
  401.     ++e;
  402.     while (s < e)
  403.     {
  404.         for (int i=-1; i<2; ++i)
  405.             for (int j=-1; j<2; ++j)
  406.                 if (X[s]+i>=0 && X[s]+i<2*64+1
  407.                  && Y[s]+j>=0 && Y[s]+j<2*64+1
  408.                  && !was[X[s]+i][Y[s]+j]
  409.                  && g[X[s]+i][Y[s]+j]>=z)
  410.                 {
  411.                     X[e] = X[s]+i;
  412.                     Y[e] = Y[s]+j;
  413.                     was[X[e]][Y[e]] = true;
  414.                     ++e;
  415.                 }
  416.         ++s;
  417.     }
  418.    
  419.     for (int x=0; x<64; ++x)
  420.     {
  421.         for (int y=0; y<64; ++y)
  422.         {
  423.             int mask = 0;
  424.             for (int i=0; i<3; ++i)
  425.                 for (int j=0; j<3; ++j)
  426.                     if (was[i+x*2][j+y*2])
  427.                         mask |= 1<<(i+j*3);
  428.  
  429.             int k = 0;
  430.             //1    2   4
  431.             //8   16  32
  432.             //64 128 256
  433.             if ( (mask&(1+2+4)) == (1+2+4))
  434.                 k++;
  435.             if ( (mask&(4+32+256)) == (4+32+256))
  436.                 k |= 2;
  437.             if ( (mask&(64+128+256)) == (64+128+256))
  438.                 k |= 4;
  439.             if ( (mask&(1+8+64)) == (1+8+64))
  440.                 k |= 8;
  441.             int id = 0x80+k;
  442.             if ( k == 0)
  443.                 id = 0xB0;
  444.             if ( k == 0 && (mask & 16))
  445.                 id = 0x80;
  446.             if ( k == 3 && !(mask & 16))
  447.                 id = 0x3C;
  448.             if ( k == 6 && !(mask & 16))
  449.                 id = 0x3D;
  450.             if ( k == 12 && !(mask & 16))
  451.                 id = 0x3F;
  452.             if ( k == 9 && !(mask & 16))
  453.                 id = 0x3E;
  454.  
  455.             duneGround[x][y] = id;
  456.         }
  457.     }
  458. }
  459.  
  460. void RangeGround(double z)
  461. {
  462.     for (int x=0; x<64; ++x)
  463.     {
  464.         for (int y=0; y<64; ++y)
  465.         {
  466.             int mask = 0;
  467.             for (int i=0; i<3; ++i)
  468.                 for (int j=0; j<3; ++j)
  469.                     if (g[i+x*2][j+y*2]>z)
  470.                         mask |= 1<<(i+j*3);
  471.             int k = 0;
  472.             //1    2   4
  473.             //8   16  32
  474.             //64 128 256
  475.             if ( (mask&(1+2+4)) == (1+2+4))
  476.                 k++;
  477.             if ( (mask&(4+32+256)) == (4+32+256))
  478.                 k |= 2;
  479.             if ( (mask&(64+128+256)) == (64+128+256))
  480.                 k |= 4;
  481.             if ( (mask&(1+8+64)) == (1+8+64))
  482.                 k |= 8;
  483.             int id = 0x80+k;
  484.             if ( k == 0)
  485.                 id = 0xB0;
  486.             if ( k == 0 && (mask & 16))
  487.                 id = 0x80;
  488.             if ( k == 3 && !(mask & 16))
  489.                 id = 0x3C;
  490.             if ( k == 6 && !(mask & 16))
  491.                 id = 0x3D;
  492.             if ( k == 12 && !(mask & 16))
  493.                 id = 0x3F;
  494.             if ( k == 9 && !(mask & 16))
  495.                 id = 0x3E;
  496.  
  497.             duneGround[x][y] = id;
  498.         }
  499.     }
  500. }
  501.  
  502. GLuint GenerateGround()
  503. {
  504.     g[        0][         0] = randf();
  505.     g[g.width-1][         0] = randf();
  506.     g[        0][g.height-1] = randf();
  507.     g[g.width-1][g.height-1] = randf();
  508.  
  509.     GenerateGroundRecursive(g, 0, 0, g.width-1, g.height-1);
  510.    
  511.     BYTE *data = (BYTE*)malloc( (g.width-1) * (g.height-1) * 3 );
  512.  
  513.     for (int x=0; x<g.width-1; ++x)
  514.     {
  515.         for (int y=0; y<g.height-1; ++y)
  516.         {
  517.             for (int i=0; i<3; ++i)
  518.                 data[(x + y*(g.width-1))*3 + i] = g[x][y]*255;
  519.         }
  520.     }
  521.    
  522.     GLuint texture;
  523.     glGenTextures( 1, &texture );
  524.  
  525.     glBindTexture( GL_TEXTURE_2D, texture );
  526.    
  527.     glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
  528.  
  529.     // when texture area is small, bilinear filter the closest MIP map
  530.     glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  531.    
  532.     // when texture area is large, bilinear filter the first MIP map
  533.     glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  534.  
  535.     // if wrap is true, the texture wraps over at the edges (repeat)
  536.     //       ... false, the texture ends at the edges (clamp)
  537.     glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
  538.     glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
  539.                  
  540.     glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, g.width-1, g.height-1, 0, GL_RGB, GL_UNSIGNED_BYTE, data );
  541.  
  542.     free(data);
  543.  
  544.    
  545.     /*for (int x=0; x<64; ++x)
  546.     {
  547.         for (int y=0; y<64; ++y)
  548.         {
  549.             int t;
  550.             if (g[x*2][y*2]>0.5)
  551.                 t = 0x8F;
  552.             else
  553.                 t = 0xB0;
  554.             Map[x+y*64]=t;
  555.         }
  556.     }
  557.    
  558.     for (int x=0; x<64; ++x)
  559.     {
  560.         for (int y=0; y<64; ++y)
  561.         {
  562.             int t;
  563.             if (g[x*2][y*2]>0.5)
  564.                 t = 0x8F;
  565.             else
  566.                 t = 0xB0;
  567.             Map[x+y*64]=t;
  568.         }
  569.     }
  570.     for (int x=0; x<64; ++x)
  571.     {
  572.         for (int y=0; y<64; ++y)
  573.         {
  574.             int k = 0;
  575.             if ( y > 0  && Map[x+(y-1)*64] == 0x8F)
  576.                 k++;
  577.             if ( x < 63 && Map[x+1+y*64] == 0x8F)
  578.                 k |= 2;
  579.             if ( y < 63 && Map[x+(y+1)*64] == 0x8F)
  580.                 k |= 4;
  581.             if ( x > 0 && Map[x-1+y*64] == 0x8F)
  582.                 k |= 8;
  583.             if (k != 0 && Map[x+y*64] != 0x8F)
  584.                 Map[x+y*64] = 0x80 + k;
  585.         }
  586.     }*/
  587.     return texture;
  588. }
  589.  
  590. // load a 256x256 RGB .RAW file as a texture
  591. GLuint LoadVRAM( const char * vram, const char * pal)
  592. {
  593.     GLuint texture;
  594.     int width, height;
  595.     BYTE palette[16*4][3];
  596.     BYTE * data;
  597.     BYTE * vdata;
  598.     FILE * file;
  599.     FILE *f;
  600.     int x;
  601.     int y;
  602.  
  603.     file = fopen( pal, "rb" );
  604.     if ( file == NULL ) return 0;
  605.  
  606.     for (int i=0; i<16*4; ++i)
  607.     {
  608.         BYTE tmp = 0;
  609.         short color;
  610.         fread(&tmp, 1, 1, file);
  611.         color = tmp << 8;
  612.         fread(&tmp, 1, 1, file);
  613.         color |= tmp;
  614.    
  615.         for (int j=0; j<3; ++j)
  616.         {
  617.             palette[i][j] = (((color >> (j*4))&0xE)/double(0xE))*0xFF;
  618.         }
  619.     }
  620.     fclose( file );
  621.      
  622.     // open texture data
  623.     file = fopen( vram, "rb" );
  624.     if ( file == NULL ) return 0;
  625.  
  626.     // allocate buffer
  627.     width = 512;
  628.     height = 512;
  629.     data = (BYTE*)malloc( width * height * 3 );
  630.     vdata = (BYTE*)malloc( 0x800 * 32 );
  631.  
  632.     // read texture data
  633.  
  634.     fread( vdata,  0x800 * 32, 1, file );
  635.     fclose( file );
  636.  
  637.     x = 0;
  638.     y = 0;
  639.     for (int i=0; i < 0x800; ++i)
  640.     {
  641.         for (int v = 0; v < 8; ++v)
  642.             for (int u = 0; u < 4; ++u)
  643.             {
  644.                 BYTE tmp = vdata[i*32+v*4+u];
  645.                 BYTE *ptr = data+((y+v)*512+x+u*2)*3;
  646.                 for (int j=0; j<3; ++j)
  647.                 {
  648.                     ptr[j] = palette[tmp>>4][j];
  649.                     ptr[j+3] = palette[tmp&0xF][j];
  650.                 }
  651.                 /*for (int j=0; j<3; ++j)
  652.                 {
  653.                     ptr[j] = palette[i%17][j];
  654.                     ptr[j+3] = palette[i%17][j];
  655.                 }*/
  656.             }
  657.         x += 8;
  658.         if (x == 512)
  659.         {
  660.             x = 0;
  661.             y += 8;
  662.         }
  663.     }
  664.  
  665.     for (int i=0; i<0x1000/2; ++i)
  666.     {
  667.         PlaneB[i]=(vdata[0xC000+i*2]<<8)|vdata[0xC000+i*2+1];
  668.     }
  669.  
  670.   // allocate a texture name
  671.   glGenTextures( 1, &texture );
  672.  
  673.   // select our current texture
  674.   glBindTexture( GL_TEXTURE_2D, texture );
  675.  
  676.   // select modulate to mix texture with color for shading
  677.   glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
  678.  
  679.   // when texture area is small, bilinear filter the closest MIP map
  680.   glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  681.   // when texture area is large, bilinear filter the first MIP map
  682.   glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  683.  
  684.   // if wrap is true, the texture wraps over at the edges (repeat)
  685.   //       ... false, the texture ends at the edges (clamp)
  686.   glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  687.   glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  688.  
  689.   // build our texture MIP maps
  690.   gluBuild2DMipmaps( GL_TEXTURE_2D, 3, width,
  691.     height, GL_RGB, GL_UNSIGNED_BYTE, data );
  692.  
  693.   // free buffer
  694.   free( data );
  695.  
  696.   // free vram data
  697.   free ( vdata );
  698.  
  699.   return texture;
  700.  
  701. }
  702.  
  703. void LoadMap( const char * filename )
  704. {
  705.     FILE *f = fopen(filename, "rb");
  706.     if (!f)
  707.         return;
  708.     BYTE tmp;
  709.     for (int y=0; y<64; ++y)
  710.         for (int x=0; x<64; ++x)
  711.         {
  712.             fread(&tmp,1,1,f);
  713.             duneGround[x][y]=tmp;
  714.         }
  715.     fclose(f);
  716. }
  717.  
  718. void SaveMap( const char * filename )
  719. {
  720.     FILE *f = fopen(filename,"wb");
  721.     if (!f)
  722.         return;
  723.     for (int y=0; y<64; ++y)
  724.         for (int x=0; x<64; ++x)
  725.             fwrite(&duneGround[x][y],1,1,f);
  726.     fclose(f);
  727. }
  728.  
  729. void FreeTexture( GLuint texture )
  730. {
  731.     glDeleteTextures( 1, &texture );
  732. }
  733.  
  734. bool mousedown = false;
  735.  
  736. void UpdateViewport(HWND hWnd)
  737. {
  738.     RECT rc;
  739.     GetClientRect(hWnd, &rc);
  740.     glViewport( 0, 0, rc.right, rc.bottom);
  741.     glMatrixMode( GL_PROJECTION );
  742.     glLoadIdentity();
  743.     //gluOrtho2D( 0,0,500,500);//camera.x, camera.y, camera.x+rc.right, camera.y+rc.bottom);
  744.     double scale = 1/32.0/zoom;
  745.     glScalef(64.0/rc.right*zoom,64.0/rc.bottom*zoom,1);
  746.     glTranslatef( -camera.x*scale, camera.y*scale, 0);
  747.     glMatrixMode( GL_MODELVIEW );
  748. }
  749.  
  750. // Window Proc ///////////////////////////////////////////////////////
  751.  
  752. LRESULT CALLBACK WndProc( HWND hWnd, UINT message,
  753.                           WPARAM wParam, LPARAM lParam )
  754. {
  755.     switch ( message ) {
  756.  
  757.     case WM_CREATE:
  758.         return 0;
  759.  
  760.     case WM_CLOSE:
  761.         PostQuitMessage( 0 );
  762.         return 0;
  763.  
  764.     case WM_SIZE:
  765.         UpdateViewport(hWnd);
  766.         break;
  767.  
  768.     case WM_DESTROY:
  769.         return 0;
  770.  
  771.     case WM_KEYDOWN:
  772.     switch ( wParam ) {
  773.  
  774.     case VK_ESCAPE:
  775.         PostQuitMessage( 0 );
  776.         return 0;
  777.  
  778.     case 'S':
  779.         SaveMap("map.bin");
  780.         return 0;
  781.  
  782.     case 'R':
  783.         FreeTexture(GroundGrey);
  784.         GroundGrey = GenerateGround();
  785.         return 0;
  786.      
  787.     case VK_SPACE:
  788.         showgray = !showgray;
  789.         return 0;
  790.     }
  791.     return 0;
  792.  
  793.   case WM_MOUSEWHEEL:
  794.     {
  795.     RECT rc;
  796.     GetClientRect(hWnd,&rc);
  797.     mouse.x = GET_X_LPARAM(lParam);
  798.     mouse.y = GET_Y_LPARAM(lParam);
  799.     short zDelta = HIWORD(wParam);
  800.     if (zDelta > 0)
  801.     {
  802.         zoom *= 1.2;
  803.         camera.x *= 1.2;//(camera.x + mouse.x) * (zoom/(zoom-0.1)) - mouse.x;
  804.         camera.y *= 1.2;//(camera.y + mouse.y) * (zoom/(zoom-0.1)) - mouse.y;
  805.     }
  806.     else
  807.     {
  808.         zoom /= 1.2;
  809.         camera.x /= 1.2;
  810.         camera.y /= 1.2;
  811.     }
  812.    
  813.     UpdateViewport(hWnd);
  814.     }
  815.     break;
  816.   case WM_LBUTTONDOWN:
  817.     {
  818.     SetCapture(hWnd);
  819.     mouse.x = GET_X_LPARAM(lParam);
  820.     mouse.y = GET_Y_LPARAM(lParam);
  821.     RECT rc;
  822.     GetClientRect(hWnd,&rc);
  823.     int cx = int((camera.x+mouse.x-(rc.right/2))/32.0/zoom);
  824.     int cy = int((camera.y+mouse.y-(rc.bottom/2))/32.0/zoom);
  825.     //Map[cx+cy*64] = 3;
  826.     mousedown = true;
  827.     }
  828.     break;
  829.   case WM_MOUSEMOVE:
  830.     if (mousedown)
  831.     {
  832.         int xPos = mouse.x; mouse.x = GET_X_LPARAM(lParam);
  833.         int yPos = mouse.y; mouse.y = GET_Y_LPARAM(lParam);
  834.         camera.x -= mouse.x-xPos;
  835.         camera.y -= mouse.y-yPos;
  836.         UpdateViewport(hWnd);
  837.     }
  838.     mouse.x = GET_X_LPARAM(lParam);
  839.     mouse.y = GET_Y_LPARAM(lParam);
  840.     break;
  841.   case WM_LBUTTONUP:
  842.     ReleaseCapture();
  843.     mousedown = false;
  844.     break;
  845.   }
  846.   return DefWindowProc( hWnd, message, wParam, lParam );
  847. }
  848.  
  849.  
  850. // OpenGL ////////////////////////////////////////////////////////////
  851.  
  852. // Enable OpenGL
  853.  
  854. VOID EnableOpenGL( HWND hWnd, HDC * hDC, HGLRC * hRC )
  855. {
  856.   PIXELFORMATDESCRIPTOR pfd;
  857.   int iFormat;
  858.  
  859.   // get the device context (DC)
  860.   *hDC = GetDC( hWnd );
  861.  
  862.   // set the pixel format for the DC
  863.   ZeroMemory( &pfd, sizeof( pfd ) );
  864.   pfd.nSize = sizeof( pfd );
  865.   pfd.nVersion = 1;
  866.   pfd.dwFlags = PFD_DRAW_TO_WINDOW |
  867.     PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
  868.   pfd.iPixelType = PFD_TYPE_RGBA;
  869.   pfd.cColorBits = 24;
  870.   pfd.cDepthBits = 16;
  871.   pfd.iLayerType = PFD_MAIN_PLANE;
  872.   iFormat = ChoosePixelFormat( *hDC, &pfd );
  873.   SetPixelFormat( *hDC, iFormat, &pfd );
  874.  
  875.   // create and enable the render context (RC)
  876.   *hRC = wglCreateContext( *hDC );
  877.   wglMakeCurrent( *hDC, *hRC );
  878.  
  879. }
  880.  
  881. // Disable OpenGL
  882.  
  883. VOID DisableOpenGL( HWND hWnd, HDC hDC, HGLRC hRC )
  884. {
  885.   wglMakeCurrent( NULL, NULL );
  886.   wglDeleteContext( hRC );
  887.   ReleaseDC( hWnd, hDC );
  888. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement