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