Browse code

Change newlines to LF

find . -type f -exec dos2unix {} + -exec mac2unix {} +

Robert Cranston authored on 27/02/2024 02:27:28
Showing 1 changed files
... ...
@@ -31,7 +31,7 @@
31 31
 // to reduce/remove system dependencies from your code. This means MinGW (DevC++ etc) in, Visual Studio OUT!
32 32
 // Visual Studio's inability to printf is unbearable and MinGW is a lot better.
33 33
 // 210524: Added glutMotionFunc in the header file.
34
-// 210530: Temporary fix for the window size. It is not how I want it to be but it looks OK and will have to do for now.
34
+// 210530: Temporary fix for the window size. It is not how I want it to be but it looks OK and will have to do for now.
35 35
 // 220112: Added support for modifier keys
36 36
 
37 37
 #include <windows.h>
... ...
@@ -106,7 +106,7 @@ void EnableOpenGL(HWND hWnd, HDC * hDC, HGLRC * hRC)
106 106
 		zdepth = 32;
107 107
 	else
108 108
 		zdepth = 0;
109
-
109
+
110 110
 // Not used yet
111 111
 //	if (gContextInitMode & GLUT_STENCIL)
112 112
 //		sdepth = 32;
... ...
@@ -381,16 +381,16 @@ void glutIdleFunc(void (*func)(void))
381 381
 }
382 382
 
383 383
 char glutKeyIsDown(unsigned char c)
384
-{
385
-    if (c == GLUT_KEY_SHIFT)
386
-        return ( ( ( GetKeyState( VK_LSHIFT   ) < 0 ) ||
387
-            ( GetKeyState( VK_RSHIFT   ) < 0 ) ) );
388
-    if (c == GLUT_KEY_CTRL)
389
-         return ( ( ( GetKeyState( VK_LCONTROL   ) < 0 ) ||
390
-            ( GetKeyState( VK_RCONTROL   ) < 0 ) ) );
391
-    if (c == GLUT_KEY_ALT)
392
-         return ( ( ( GetKeyState( VK_LMENU   ) < 0 ) ||
393
-            ( GetKeyState( VK_RMENU   ) < 0 ) ) );
384
+{
385
+    if (c == GLUT_KEY_SHIFT)
386
+        return ( ( ( GetKeyState( VK_LSHIFT   ) < 0 ) ||
387
+            ( GetKeyState( VK_RSHIFT   ) < 0 ) ) );
388
+    if (c == GLUT_KEY_CTRL)
389
+         return ( ( ( GetKeyState( VK_LCONTROL   ) < 0 ) ||
390
+            ( GetKeyState( VK_RCONTROL   ) < 0 ) ) );
391
+    if (c == GLUT_KEY_ALT)
392
+         return ( ( ( GetKeyState( VK_LMENU   ) < 0 ) ||
393
+            ( GetKeyState( VK_RMENU   ) < 0 ) ) );
394 394
 
395 395
 	return gKeymap[c];
396 396
 }
Browse code

Remove executable bit on files

find . -type f -exec chmod -x {} +

Robert Cranston authored on 27/02/2024 02:27:27
Showing 1 changed files
1 1
old mode 100755
2 2
new mode 100644
Browse code

Add cpp-v1

Ingemar Ragnemalm authored on 21/02/2024 20:24:28 • Robert Cranston committed on 21/02/2024 20:24:28
Showing 1 changed files
1 1
new file mode 100755
... ...
@@ -0,0 +1,879 @@
1
+// Micro-GLUT, bare essentials
2
+
3
+// By Ingemar Ragnemalm 2012
4
+// I wrote this since GLUT seems not to have been updated to support
5
+// creation of a 3.2 context on the Mac. You can use FreeGLUT
6
+// which has this support, but I felt I wanted something without the old-style
7
+// material, and that is small enough to include as a single source file.
8
+
9
+// 120309 First Win32 version. Incomplete, lacks timers and more. Also, most settings are not supported.
10
+// 130204 Tried to add GL3 and GLEW. No success.
11
+// Forgotten for too long...
12
+// 1508013 Running with all current utities and GLEW, with the psychedelic teapot demo!
13
+// Timers and rescaling enabled, needs testing.
14
+// 150817: Timers and rescaling runs fine!
15
+// Menus and warp pointer are missing, but this looks good enough for "first beta version"!
16
+// Tested mainly with the Psychedelic Teapot example.
17
+// 150919 Added the very useful glutKeyIsDown plus support for key up events.
18
+// 150920: glutInitWindowPosition and glutInitWindowSize are now working
19
+// 150923: Keyboard events now report ASCII values instead of virtual codes. Also, various special keys like arrow keys should work.
20
+// Finally, I have taken some steps to make special key callbacks obsolete by smarter mapping of special keys.
21
+// 151203: Added a stdio window.
22
+// 160222: Fixed a bug affecting glutKeyIsDown (a very important call which works better now).
23
+// 1602??: Added glutWarpPointer, glutHideCursor, glutShowCursor.
24
+// 160309: Added glutFullScreen, glutExitFullScreen, glutToggleFullScreen.
25
+// 170221: Added glutPositionWindow, glutReshapeWindow. Changed default behavior on resize.
26
+// 170913: Added glutMouseIsDown, corrected support for glutMotionFunc (dragging).
27
+// 200405: Added BeginPaint etc as response to WM_PAINT to make Windows stop sending PAINT repeatedly.
28
+// Also avoided having events blocking timers in the event loop.
29
+// 210524: Important overhaul! After removing WinMain and moving its functionality to glutInit,
30
+// MicroGlut now works with MinGW, and outputs printf's properly! I also moved glewInit into MicroGlut
31
+// to reduce/remove system dependencies from your code. This means MinGW (DevC++ etc) in, Visual Studio OUT!
32
+// Visual Studio's inability to printf is unbearable and MinGW is a lot better.
33
+// 210524: Added glutMotionFunc in the header file.
34
+// 210530: Temporary fix for the window size. It is not how I want it to be but it looks OK and will have to do for now.
35
+// 220112: Added support for modifier keys
36
+
37
+#include <windows.h>
38
+#include "glew.h"
39
+#include <gl/gl.h>
40
+#include "MicroGlut.h"
41
+#include <stdio.h>
42
+#include <io.h>
43
+#include <fcntl.h>
44
+
45
+#ifndef _WIN32
46
+	This line causes an error if you are not using Windows. It means that you are accidentally compiling the Windows version.
47
+	Have a look at your paths.
48
+#endif
49
+
50
+// Vital internal variables
51
+
52
+void (*gDisplay)(void);
53
+void (*gReshape)(int width, int height);
54
+void (*gKey)(unsigned char key, int x, int y);
55
+void (*gKeyUp)(unsigned char key, int x, int y);
56
+void (*gSpecialKey)(unsigned char key, int x, int y); // I consider this obsolete!
57
+void (*gSpecialKeyUp)(unsigned char key, int x, int y); // I consider this obsolete!
58
+void (*gMouseMoved)(int x, int y);
59
+void (*gMouseDragged)(int x, int y);
60
+void (*gMouseFunc)(int button, int state, int x, int y);
61
+unsigned int gContextInitMode = GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH;
62
+void (*gIdle)(void);
63
+char updatePending = 1;
64
+char gRunning = 1;
65
+int gContextVersionMajor = 0;
66
+int gContextVersionMinor = 0;
67
+char gKeymap[256];
68
+char gButtonPressed[10] = {0,0,0,0,0,0,0,0,0,0};
69
+
70
+// Prototype
71
+static void checktimers();
72
+
73
+// -----------
74
+
75
+// Globals (was in GLViewDataPtr)
76
+//NSOpenGLContext	*m_context;
77
+float lastWidth, lastHeight;
78
+//NSView *theView;
79
+
80
+HWND hWnd;
81
+HDC hDC;
82
+HGLRC hRC;
83
+HINSTANCE gInstance;
84
+
85
+// Enable OpenGL
86
+
87
+void EnableOpenGL(HWND hWnd, HDC * hDC, HGLRC * hRC)
88
+{
89
+	PIXELFORMATDESCRIPTOR pfd;
90
+	int format;
91
+	int zdepth; // , sdepth;
92
+#if defined WGL_CONTEXT_MAJOR_VERSION_ARB
93
+// NOT tested because WGL_CONTEXT_MAJOR_VERSION_ARB is undefined on my computer
94
+	int attribs[] =
95
+	{
96
+		WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
97
+		WGL_CONTEXT_MINOR_VERSION_ARB, 2,
98
+		WGL_CONTEXT_FLAGS_ARB, 0,
99
+		0
100
+	};
101
+#endif
102
+	// get the device context (DC)
103
+	*hDC = GetDC( hWnd );
104
+
105
+	if (gContextInitMode & GLUT_DEPTH)
106
+		zdepth = 32;
107
+	else
108
+		zdepth = 0;
109
+
110
+// Not used yet
111
+//	if (gContextInitMode & GLUT_STENCIL)
112
+//		sdepth = 32;
113
+//	else
114
+//		sdepth = 0;
115
+
116
+	// set the pixel format for the DC
117
+	// MUCH OF THIS SHOULD BE OPTIONAL (like depth and stencil above)!
118
+	ZeroMemory( &pfd, sizeof( pfd ) );
119
+	pfd.nSize = sizeof( pfd );
120
+	pfd.nVersion = 1;
121
+	pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
122
+	pfd.iPixelType = PFD_TYPE_RGBA;
123
+	pfd.cColorBits = 24;
124
+	pfd.cDepthBits = zdepth;
125
+	pfd.iLayerType = PFD_MAIN_PLANE;
126
+	format = ChoosePixelFormat( *hDC, &pfd );
127
+	SetPixelFormat( *hDC, format, &pfd );
128
+
129
+#if defined WGL_CONTEXT_MAJOR_VERSION_ARB
130
+// NOT tested because WGL_CONTEXT_MAJOR_VERSION_ARB is undefined on my computer
131
+// Try to support new OpenGL!
132
+	attribs[1] = gContextVersionMajor;
133
+	attribs[3] = gContextVersionMinor;
134
+
135
+    if(wglewIsSupported("WGL_ARB_create_context") == 1)
136
+    {
137
+		*hRC = wglCreateContextAttribsARB(*hDC,0, attribs);
138
+		wglMakeCurrent(*hDC, *hRC);
139
+	}
140
+	else
141
+	{	//It's not possible to make a GL 3.x context. Use the old style context (GL 2.1 and before)
142
+		// create and enable the render context (RC)
143
+		*hRC = wglCreateContext( *hDC );
144
+		wglMakeCurrent( *hDC, *hRC );
145
+	}
146
+#else
147
+		*hRC = wglCreateContext( *hDC );
148
+		wglMakeCurrent( *hDC, *hRC );
149
+#endif
150
+
151
+
152
+	glewInit();
153
+}
154
+
155
+// Disable OpenGL
156
+
157
+void DisableOpenGL(HWND hWnd, HDC hDC, HGLRC hRC)
158
+{
159
+	wglMakeCurrent( NULL, NULL );
160
+	wglDeleteContext( hRC );
161
+	ReleaseDC( hWnd, hDC );
162
+}
163
+
164
+
165
+
166
+
167
+
168
+void glutPostRedisplay()
169
+{
170
+	updatePending = 1;
171
+}
172
+
173
+// ------------------ Main program ---------------------
174
+
175
+//MGApplication *myApp;
176
+//NSView *view;
177
+//NSWindow *window;
178
+//static struct timeval timeStart;
179
+
180
+int gWindowPosX = 10;
181
+int gWindowPosY = 50;
182
+int gWindowWidth = 400;
183
+int gWindowHeight = 400;
184
+
185
+void glutInitWindowPosition (int x, int y)
186
+{
187
+	gWindowPosX = x;
188
+	gWindowPosY = y;
189
+}
190
+void glutInitWindowSize (int width, int height)
191
+{
192
+	gWindowWidth = width;
193
+	gWindowHeight = height;
194
+}
195
+
196
+void glutCreateWindow(const char *title)
197
+{
198
+/*	// Convert title to szTitle!
199
+	#define MAX_LOADSTRING 100
200
+	TCHAR szTitle[MAX_LOADSTRING];					// The title bar text
201
+    int size_needed = MultiByteToWideChar(CP_UTF8, 0, &title[0], strlen(title), NULL, 0);
202
+    MultiByteToWideChar(CP_UTF8, 0, &title[0], strlen(title), &szTitle[0], size_needed);
203
+	szTitle[size_needed] = 0; // Zero terminate
204
+
205
+	// Convert class name to szCn!
206
+	#define MAX_LOADSTRING 100
207
+	char cn[] = "MicroGlutWC";
208
+	TCHAR szCn[MAX_LOADSTRING];					// The title bar text
209
+    size_needed = MultiByteToWideChar(CP_UTF8, 0, &cn[0], strlen(cn), NULL, 0);
210
+    MultiByteToWideChar(CP_UTF8, 0, &cn[0], strlen(cn), &szCn[0], size_needed);
211
+	szCn[size_needed] = 0; // Zero terminate
212
+*/
213
+
214
+/*	RECT r;
215
+	r.left = gWindowPosX;
216
+	r.top = gWindowPosY;
217
+	r.right = gWindowWidth+gWindowPosX;
218
+	r.bottom = gWindowHeight+gWindowPosY;
219
+	r.left = 0;
220
+	r.top = 0;
221
+	r.right = gWindowWidth;
222
+	r.bottom = gWindowHeight;
223
+
224
+	AdjustWindowRect(&r, WS_CAPTION | WS_POPUPWINDOW, 0);
225
+*/
226
+
227
+// Grabbed from FreeGLUT since AdjustWindowRect did not work for me
228
+	// create main window
229
+    int h = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CXDLGFRAME)*2 + gWindowHeight;
230
+    int w = GetSystemMetrics(SM_CXDLGFRAME)*2 + gWindowWidth;
231
+
232
+    // Same window settings as QuakeII
233
+    // WS_BORDER WS_DLGFRAME WS_CLIPSIBLINGS
234
+//    hWnd = CreateWindowEx(WS_EX_APPWINDOW,
235
+//      g_appName, title,
236
+//      WS_BORDER | WS_DLGFRAME | WS_CLIPSIBLINGS,
237
+//      CW_USEDEFAULT, CW_USEDEFAULT, w, h,
238
+//      NULL, NULL, g_hMainInst, NULL);
239
+
240
+// This is with a +10 offset which gives the proper size. I am not happy with this but it will have to do for now since none of
241
+// the "real" methods gave the right result.
242
+    hWnd = CreateWindow("MicroGlutWC", title,
243
+     WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE | WS_OVERLAPPEDWINDOW,
244
+      gWindowPosX, gWindowPosY, w+10, h+10,
245
+      NULL, NULL, gInstance, NULL);
246
+
247
+/*
248
+	hWnd = CreateWindow(
249
+//		szCn, szTitle,
250
+		"MicroGlutWC", title,
251
+		WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE | WS_OVERLAPPEDWINDOW, // WS_OVERLAPPEDWINDOW gives rescalable window
252
+//		0, 0, 256, 256,
253
+//		r.left, r.top, r.right-r.left, r.bottom-r.top,
254
+//		gWindowPosX, gWindowPosY, r.right-r.left, r.bottom-r.top,
255
+		gWindowPosX, gWindowPosY, gWindowWidth + 16, gWindowHeight + 39, // Hard-coded because I get AdjustWindowRect wrong
256
+		NULL, NULL, gInstance, NULL );
257
+	if (hWnd == NULL)
258
+		printf("No window\n");
259
+*/
260
+	// enable OpenGL for the window
261
+	EnableOpenGL( hWnd, &hDC, &hRC );
262
+}
263
+
264
+
265
+void glutMainLoop()
266
+{
267
+	BOOL quit = 0;
268
+	MSG msg;
269
+
270
+	// program main loop
271
+	while ( !quit )
272
+	{
273
+
274
+		// check for messages
275
+		if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE )  )
276
+		{
277
+			// handle or dispatch messages
278
+			if ( msg.message == WM_QUIT )
279
+			{
280
+				quit = TRUE;
281
+			}
282
+			else
283
+			{
284
+				TranslateMessage( &msg );
285
+				DispatchMessage( &msg );
286
+			}
287
+		}
288
+//		else  - SKIPPED in order not to have events blocking timers
289
+		{
290
+			if (updatePending)
291
+			{
292
+				gDisplay();
293
+				updatePending = 0;
294
+			}
295
+			if (gIdle)
296
+				gIdle();
297
+			// TIMERS!
298
+			checktimers();
299
+		}
300
+	}
301
+}
302
+
303
+// This won't work yet
304
+//void glutCheckLoop()
305
+//{
306
+//}
307
+
308
+void glutDisplayFunc(void (*func)(void))
309
+{
310
+	gDisplay = func;
311
+}
312
+
313
+void glutReshapeFunc(void (*func)(int width, int height))
314
+{
315
+	gReshape = func;
316
+	if (func != NULL)
317
+		gReshape(gWindowWidth, gWindowHeight);
318
+}
319
+
320
+void glutKeyboardFunc(void (*func)(unsigned char key, int x, int y))
321
+{
322
+	gKey = func;
323
+}
324
+
325
+void glutKeyboardUpFunc(void (*func)(unsigned char key, int x, int y))
326
+{
327
+	gKeyUp = func;
328
+}
329
+
330
+// I consider this obsolete!
331
+void glutSpecialFunc(void (*func)(unsigned char key, int x, int y))
332
+{
333
+	gSpecialKey = func;
334
+}
335
+
336
+// I consider this obsolete!
337
+void glutSpecialUpFunc(void (*func)(unsigned char key, int x, int y))
338
+{
339
+	gSpecialKeyUp = func;
340
+}
341
+
342
+void glutPassiveMotionFunc(void (*func)(int x, int y))
343
+{
344
+	gMouseMoved = func;
345
+}
346
+
347
+void glutMotionFunc(void (*func)(int x, int y))
348
+{
349
+	gMouseDragged = func;
350
+}
351
+
352
+void glutMouseFunc(void (*func)(int button, int state, int x, int y))
353
+{
354
+	gMouseFunc = func;
355
+}
356
+
357
+// You can safely skip this
358
+void glutSwapBuffers()
359
+{
360
+ 	SwapBuffers(hDC);
361
+}
362
+
363
+int glutGet(int type)
364
+{
365
+//	struct timeval tv;
366
+
367
+//	gettimeofday(&tv, NULL);
368
+//	return (tv.tv_usec - timeStart.tv_usec) / 1000 + (tv.tv_sec - timeStart.tv_sec)*1000;
369
+
370
+	return GetTickCount();
371
+}
372
+
373
+void glutInitDisplayMode(unsigned int mode)
374
+{
375
+	gContextInitMode = mode;
376
+}
377
+
378
+void glutIdleFunc(void (*func)(void))
379
+{
380
+	gIdle = func;
381
+}
382
+
383
+char glutKeyIsDown(unsigned char c)
384
+{
385
+    if (c == GLUT_KEY_SHIFT)
386
+        return ( ( ( GetKeyState( VK_LSHIFT   ) < 0 ) ||
387
+            ( GetKeyState( VK_RSHIFT   ) < 0 ) ) );
388
+    if (c == GLUT_KEY_CTRL)
389
+         return ( ( ( GetKeyState( VK_LCONTROL   ) < 0 ) ||
390
+            ( GetKeyState( VK_RCONTROL   ) < 0 ) ) );
391
+    if (c == GLUT_KEY_ALT)
392
+         return ( ( ( GetKeyState( VK_LMENU   ) < 0 ) ||
393
+            ( GetKeyState( VK_RMENU   ) < 0 ) ) );
394
+
395
+	return gKeymap[c];
396
+}
397
+
398
+static unsigned char scan2ascii(WPARAM vk, LPARAM scancode)
399
+{
400
+   static HKL layout;
401
+   static unsigned char State[256];
402
+   int count;
403
+   static short unsigned int chars1[2];
404
+
405
+   layout = GetKeyboardLayout(0);
406
+   if (GetKeyboardState(State)==FALSE)
407
+      return 0;
408
+   count = ToAsciiEx(vk,scancode,State,&chars1[0],0,layout);
409
+   if (count > 0) return (char)chars1[0];
410
+   else return 0;
411
+}
412
+
413
+static void doKeyboardEvent(WPARAM wParam, LPARAM lParam, void (*keyFunc)(unsigned char key, int x, int y), void (specialKeyFunc)(unsigned char key, int x, int y), char keyMapValue)
414
+{
415
+	unsigned char c;
416
+
417
+		switch(wParam)
418
+		{
419
+			case VK_F1:
420
+				c = GLUT_KEY_F1; break;
421
+			case VK_F2:
422
+				c = GLUT_KEY_F2; break;
423
+			case VK_F3:
424
+				c = GLUT_KEY_F3; break;
425
+			case VK_F4:
426
+				c = GLUT_KEY_F4; break;
427
+			case VK_F5:
428
+				c = GLUT_KEY_F5; break;
429
+			case VK_F6:
430
+				c = GLUT_KEY_F6; break;
431
+			case VK_F7:
432
+				c = GLUT_KEY_F7; break;
433
+// F8 and up ignored since they are not possible on some keyboards - like mine
434
+
435
+			case VK_LEFT:
436
+				c = GLUT_KEY_LEFT; break;
437
+			case VK_UP:
438
+				c = GLUT_KEY_UP; break;
439
+			case VK_RIGHT:
440
+				c = GLUT_KEY_RIGHT; break;
441
+			case VK_DOWN:
442
+				c = GLUT_KEY_DOWN; break;
443
+
444
+			case VK_ESCAPE:
445
+				c = GLUT_KEY_ESC; break;
446
+			case VK_PRIOR:
447
+				c = GLUT_KEY_PAGE_UP; break;
448
+			case VK_NEXT:
449
+				c = GLUT_KEY_PAGE_DOWN; break;
450
+			case VK_HOME:
451
+				c = GLUT_KEY_HOME; break;
452
+			case VK_END:
453
+				c = GLUT_KEY_END; break;
454
+			case VK_INSERT:
455
+				c = GLUT_KEY_INSERT; break;
456
+			default:
457
+				c = scan2ascii(wParam,lParam);
458
+				if (c == 0) return;
459
+		}
460
+		if (keyFunc != NULL)
461
+		{
462
+			keyFunc(c, 0, 0); // TO DO: x and y
463
+		}
464
+		else
465
+		if (specialKeyFunc != NULL && c < 32)
466
+		{
467
+			specialKeyFunc(c, 0, 0); // TO DO: x and y
468
+		}
469
+		gKeymap[c] = keyMapValue;
470
+		//printf("key %i %i\n", c, keyMapValue);
471
+}
472
+
473
+
474
+LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
475
+{
476
+	int x = LOWORD(lParam);
477
+	int y = HIWORD(lParam);
478
+//	static char firstTime = 1;
479
+//
480
+//	if (firstTime)
481
+//	{
482
+//		if (gReshape != NULL)
483
+//			gReshape(gWindowWidth, gWindowHeight);
484
+//		firstTime = 0;
485
+//	}
486
+
487
+	switch (message)
488
+	{
489
+    case WM_LBUTTONUP:
490
+		if (gMouseFunc != NULL)
491
+			gMouseFunc(GLUT_LEFT_BUTTON, GLUT_UP, x, y);
492
+		gButtonPressed[0] = 0;
493
+        break;
494
+
495
+    case WM_LBUTTONDOWN:
496
+		if (gMouseFunc != NULL)
497
+			gMouseFunc(GLUT_LEFT_BUTTON, GLUT_DOWN, x, y);
498
+		gButtonPressed[0] = 1;
499
+     break;
500
+
501
+    case WM_RBUTTONUP:
502
+		if (gMouseFunc != NULL)
503
+			gMouseFunc(GLUT_RIGHT_BUTTON, GLUT_UP, x, y);
504
+		gButtonPressed[1] = 0;
505
+        break;
506
+
507
+    case WM_RBUTTONDOWN:
508
+		if (gMouseFunc != NULL)
509
+			gMouseFunc(GLUT_RIGHT_BUTTON, GLUT_DOWN, x, y);
510
+		gButtonPressed[1] = 1;
511
+     break;
512
+
513
+    case WM_MOUSEMOVE:
514
+		if (gMouseMoved != NULL)
515
+			gMouseMoved(x, y);
516
+		if (gButtonPressed[0] || gButtonPressed[1])
517
+			if (gMouseDragged != NULL)
518
+			gMouseDragged(x, y);
519
+    break;
520
+
521
+	case WM_CREATE:
522
+		return 0;
523
+
524
+	case WM_CLOSE:
525
+		PostQuitMessage( 0 );
526
+		return 0;
527
+
528
+	case WM_DESTROY:
529
+		return 0;
530
+
531
+	case WM_KEYDOWN:
532
+		doKeyboardEvent(wParam, lParam, gKey, gSpecialKey, 1);
533
+		return 0;
534
+	case WM_KEYUP:
535
+		doKeyboardEvent(wParam, lParam, gKeyUp, gSpecialKeyUp, 0);
536
+		return 0;
537
+
538
+	case WM_SIZE:
539
+		if (gReshape != NULL)
540
+			gReshape(LOWORD(lParam), HIWORD(lParam));
541
+		else
542
+		{	glViewport(0,0,LOWORD(lParam), HIWORD(lParam));
543
+			glutPostRedisplay();
544
+		}
545
+		break;
546
+	case WM_PAINT: // Don't have Windows fighting us while resize!
547
+		if (gDisplay)
548
+		{
549
+			PAINTSTRUCT ps;
550
+			BeginPaint(hWnd, &ps); // Added to make Windows stop sending PAINT repeatedly.
551
+			OutputDebugStringA("paint\n");
552
+			gDisplay();
553
+			EndPaint(hWnd, &ps);
554
+			updatePending = 0;
555
+		}
556
+		break;
557
+	case WM_ERASEBKGND:
558
+		return 1;
559
+		break;
560
+	default:
561
+		return DefWindowProc( hWnd, message, wParam, lParam );
562
+	}
563
+
564
+	return 0;
565
+}
566
+
567
+void glutInit(int *argcp, char **argv)
568
+{
569
+	int i;
570
+	int hCrt;
571
+	FILE *hf;
572
+
573
+	for (i = 0; i < 256; i++) gKeymap[i] = 0;
574
+
575
+	WNDCLASS wc;
576
+
577
+	gInstance = GetModuleHandle(NULL);
578
+	// register window class
579
+	wc.style = CS_OWNDC;
580
+	wc.lpfnWndProc = WndProc;
581
+	wc.cbClsExtra = 0;
582
+	wc.cbWndExtra = 0;
583
+	wc.hInstance = gInstance;
584
+	wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
585
+	wc.hCursor = LoadCursor( NULL, IDC_ARROW );
586
+	wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
587
+	wc.lpszMenuName = NULL;
588
+	wc.lpszClassName = "MicroGlutWC";
589
+	if (!RegisterClass( &wc ))
590
+		MessageBox(NULL, "RegisterClass failed", "?", MB_ICONEXCLAMATION | MB_OK);
591
+
592
+	// Make printf work!
593
+	AllocConsole();
594
+	hCrt = _open_osfhandle(
595
+		//(long)
596
+		(long long)GetStdHandle(STD_OUTPUT_HANDLE), // This gives a warning but it works.
597
+		_O_TEXT
598
+		);
599
+	hf = _fdopen( hCrt, "w" );
600
+	*stdout = *hf;
601
+	i = setvbuf( stdout, NULL, _IONBF, 0 );
602
+	*stderr = *hf;
603
+
604
+//	printf("allocated console and window class\n");
605
+}
606
+
607
+void glutClose()
608
+{    /* shutdown OpenGL */
609
+    DisableOpenGL (hWnd, hDC, hRC);
610
+
611
+    /* destroy the window explicitly */
612
+    DestroyWindow (hWnd);
613
+
614
+ //   return 0; // msg.wParam;
615
+}
616
+
617
+
618
+
619
+
620
+
621
+
622
+
623
+// NOTE: The timer is not designed with any multithreading in mind!
624
+typedef struct TimerRec
625
+{
626
+	int arg;
627
+	int time;
628
+	int repeatTime;
629
+	void (*func)(int arg);
630
+	char repeating;
631
+	struct TimerRec *next;
632
+	struct TimerRec *prev;
633
+} TimerRec;
634
+
635
+TimerRec *gTimers = NULL;
636
+
637
+void glutTimerFunc(int millis, void (*func)(int arg), int arg)
638
+{
639
+	TimerRec *t	= (TimerRec *)malloc(sizeof(TimerRec));
640
+	t->arg = arg;
641
+	t->time = millis + glutGet(GLUT_ELAPSED_TIME);
642
+	t->repeatTime = 0;
643
+	t->repeating = 0;
644
+	t->func = func;
645
+	t->next = gTimers;
646
+	t->prev = NULL;
647
+	if (gTimers != NULL)
648
+		gTimers->prev = t;
649
+	gTimers = t;
650
+}
651
+
652
+// Added by Ingemar
653
+void glutRepeatingTimer(int millis)
654
+{
655
+	TimerRec *t	= (TimerRec *)malloc(sizeof(TimerRec));
656
+	t->arg = 0;
657
+	t->time = millis + glutGet(GLUT_ELAPSED_TIME);
658
+	t->repeatTime = millis;
659
+	t->repeating = 1;
660
+	t->func = NULL;
661
+	t->next = gTimers;
662
+	t->prev = NULL;
663
+	if (gTimers != NULL)
664
+		gTimers->prev = t;
665
+	gTimers = t;
666
+}
667
+
668
+// From http://stackoverflow.com/questions/5801813/c-usleep-is-obsolete-workarounds-for-windows-mingw
669
+void usleep(__int64 usec)
670
+{
671
+    HANDLE timer;
672
+    LARGE_INTEGER ft;
673
+
674
+    ft.QuadPart = -(10*usec); // Convert to 100 nanosecond interval, negative value indicates relative time
675
+
676
+    timer = CreateWaitableTimer(NULL, TRUE, NULL);
677
+    SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0);
678
+    WaitForSingleObject(timer, INFINITE);
679
+    CloseHandle(timer);
680
+}
681
+
682
+static void checktimers()
683
+{
684
+	if (gTimers != NULL)
685
+	{
686
+		TimerRec *t, *firethis = NULL;
687
+		int now = glutGet(GLUT_ELAPSED_TIME);
688
+		int nextTime = now + 1000; // Distant future, 1 second
689
+		t = gTimers;
690
+		for (t = gTimers; t != NULL; t = t->next)
691
+		{
692
+			if (t->time < nextTime) nextTime = t->time; // Time for the next one
693
+			if (t->time < now) // See if this is due to fire
694
+			{
695
+				firethis = t;
696
+			}
697
+		}
698
+		if (firethis != NULL)
699
+		{
700
+		// Fire the timer
701
+			if (firethis->func != NULL)
702
+				firethis->func(firethis->arg);
703
+			else
704
+				glutPostRedisplay();
705
+		// Remove the timer if it was one-shot, otherwise update the time
706
+			if (firethis->repeating)
707
+			{
708
+				firethis->time = now + firethis->repeatTime;
709
+			}
710
+			else
711
+			{
712
+				if (firethis->prev != NULL)
713
+					firethis->prev->next = firethis->next;
714
+				else
715
+					gTimers = firethis->next;
716
+                if (firethis->next != NULL)
717
+					firethis->next->prev = firethis->prev;
718
+				free(firethis);
719
+			}
720
+		}
721
+		// Otherwise, sleep until any timer should fire
722
+        if (!updatePending)
723
+			if (nextTime > now)
724
+            {
725
+		usleep((nextTime - now)*1000);
726
+            }
727
+	}
728
+    else
729
+// If no timer and no update, sleep a little to keep CPU load low
730
+        if (!updatePending)
731
+            usleep(10);
732
+}
733
+
734
+void glutInitContextVersion(int major, int minor)
735
+{
736
+	gContextVersionMajor = major;
737
+	gContextVersionMinor = minor;
738
+}
739
+
740
+
741
+void glutHideCursor()
742
+{
743
+	ShowCursor(0);
744
+}
745
+
746
+void glutShowCursor()
747
+{
748
+	ShowCursor(1);
749
+}
750
+
751
+void glutWarpPointer(int x, int y)
752
+{
753
+	POINT coords;
754
+	coords.x = x;
755
+	coords.y = y;
756
+	ClientToScreen(hWnd, &coords);
757
+	SetCursorPos(coords.x, coords.y);
758
+}
759
+
760
+
761
+
762
+// ----------------------------- Full-screen mode support! ---------------------------------
763
+
764
+static int savedWidth;
765
+static int savedHeight;
766
+//static int savedColourBits;
767
+//static int savedRefreshRate;
768
+static int savedXPosition;
769
+static int savedYPosition;
770
+
771
+// This can be useful if you want to change the resolution.
772
+static int enterFullscreenExt(HWND hwnd, int fullscreenWidth, int fullscreenHeight, int colourBits, int refreshRate)
773
+{
774
+    DEVMODE fullscreenSettings;
775
+    int isChangeSuccessful=0;
776
+    RECT windowBoundary;
777
+
778
+	GetWindowRect(hwnd, &windowBoundary);
779
+	savedWidth  = windowBoundary.right - windowBoundary.left;
780
+	savedHeight = windowBoundary.bottom - windowBoundary.top;
781
+	savedXPosition = windowBoundary.left;
782
+	savedYPosition = windowBoundary.top;
783
+
784
+    EnumDisplaySettings(NULL, 0, &fullscreenSettings);
785
+    fullscreenSettings.dmPelsWidth        = fullscreenWidth;
786
+    fullscreenSettings.dmPelsHeight       = fullscreenHeight;
787
+    fullscreenSettings.dmBitsPerPel       = colourBits;
788
+    fullscreenSettings.dmDisplayFrequency = refreshRate;
789
+    fullscreenSettings.dmFields           = DM_PELSWIDTH |
790
+                                            DM_PELSHEIGHT |
791
+                                            DM_BITSPERPEL |
792
+                                            DM_DISPLAYFREQUENCY;
793
+
794
+    SetWindowLongPtr(hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW | WS_EX_TOPMOST);
795
+    SetWindowLongPtr(hwnd, GWL_STYLE, WS_POPUP | WS_VISIBLE);
796
+    SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, fullscreenWidth, fullscreenHeight, SWP_SHOWWINDOW);
797
+//    isChangeSuccessful = ChangeDisplaySettings(&fullscreenSettings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL;
798
+    ShowWindow(hwnd, SW_MAXIMIZE);
799
+
800
+    return isChangeSuccessful;
801
+}
802
+
803
+static int enterFullscreen(HWND hwnd)
804
+{
805
+	int fullscreenWidth;
806
+	int fullscreenHeight;
807
+	int colourBits;
808
+	int refreshRate;
809
+	HDC windowHDC;
810
+
811
+	windowHDC = GetDC(hwnd);
812
+	fullscreenWidth  = GetDeviceCaps(windowHDC, HORZRES);
813
+	fullscreenHeight = GetDeviceCaps(windowHDC, VERTRES);
814
+	colourBits       = GetDeviceCaps(windowHDC, BITSPIXEL);
815
+	refreshRate      = GetDeviceCaps(windowHDC, VREFRESH);
816
+
817
+	return enterFullscreenExt(hwnd, fullscreenWidth, fullscreenHeight, colourBits, refreshRate);
818
+}
819
+
820
+static int exitFullscreen(HWND hwnd)
821
+{
822
+    int isChangeSuccessful;
823
+
824
+    SetWindowLongPtr(hwnd, GWL_EXSTYLE, WS_EX_LEFT);
825
+    SetWindowLongPtr(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE);
826
+    isChangeSuccessful = ChangeDisplaySettings(NULL, CDS_RESET) == DISP_CHANGE_SUCCESSFUL;
827
+    SetWindowPos(hwnd, HWND_NOTOPMOST, savedXPosition, savedYPosition, savedWidth, savedHeight, SWP_SHOWWINDOW);
828
+    ShowWindow(hwnd, SW_RESTORE);
829
+
830
+    return isChangeSuccessful;
831
+}
832
+
833
+int isFullScreen = 0;
834
+
835
+void glutFullScreen()
836
+{
837
+	if (!isFullScreen)
838
+		enterFullscreen(hWnd);
839
+	isFullScreen = 1;
840
+}
841
+
842
+void glutExitFullScreen()
843
+{
844
+	if (isFullScreen)
845
+		exitFullscreen(hWnd);
846
+	isFullScreen = 0;
847
+}
848
+
849
+void glutToggleFullScreen()
850
+{
851
+	if (!isFullScreen)
852
+		enterFullscreen(hWnd);
853
+	else
854
+		exitFullscreen(hWnd);
855
+	isFullScreen = !isFullScreen;
856
+}
857
+
858
+// Added 2017-02-21
859
+void glutPositionWindow(int x, int y)
860
+{
861
+	RECT r;
862
+	GetWindowRect(hWnd, &r);
863
+	MoveWindow(hWnd, x, y, r.right-r.left, r.bottom-r.top, TRUE);
864
+}
865
+
866
+void glutReshapeWindow(int width, int height)
867
+{
868
+	RECT r;
869
+	GetWindowRect(hWnd, &r);
870
+	MoveWindow(hWnd, r.left, r.top, width, height, TRUE);
871
+}
872
+
873
+char glutMouseIsDown(unsigned int c)
874
+{
875
+	return gButtonPressed[c];
876
+}
877
+
878
+
879
+