1 //-----------------------------------------------------------------------------
2 //
3 // ImageLib Windows (GDI) Test Source
4 // Copyright (C) 2000 by Denton Woods
5 // Last modified:  08/26/2001 <--Y2K Compliant! =]
6 //
7 // Filename: testil/animtest/animtest.c
8 //
9 // Description:  Animation test application for DevIL.
10 //
11 //-----------------------------------------------------------------------------
12 
13 #include <windows.h>
14 #ifdef _DEBUG
15 #define IL_DEBUG
16 #endif
17 #include <il/il.h>
18 #include <il/ilu.h>
19 #include <il/ilut.h>
20 #include "resource.h"
21 
22 
23 // Evil globals!
24 HINSTANCE hInstance;
25 HDC hDC, hMemDC = NULL;
26 HWND HWnd;
27 
28 #define	BORDER_W	8
29 #define	MENU_H		46
30 #define	MIN_W		205  // Accomodate the menu bar.
31 #define	MAX_W		400
32 #define	MAX_H		400
33 #define	TITLE		"DevIL Animation Test"
34 
35 ILuint	FilterType;
36 ILuint	FilterParamInt;
37 ILfloat	FilterParamFloat;
38 char	FilterEditString[255];
39 char	NewTitle[512];
40 
41 BITMAPINFOHEADER *BmpInfo = NULL;
42 HBITMAP	*Bitmaps = NULL;
43 ILuint	*Durations = NULL;
44 ILuint	NumImages = 0, CurImage = 0;
45 
46 __int64	StartTime, TimerFreq;
47 double	TimerRes;
48 bool	IsPaused = false;
49 
50 
51 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
52 void GenFilterString(char *Out, char **Strings);
53 void DisplayImage(void);
54 void LoadImages(char *FileName);
55 
56 
WinMain(HINSTANCE hInst,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)57 int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
58 {
59 	MSG			msg;
60 	WNDCLASSEX	wcex;
61 	HACCEL		hAccelTable;
62 
63 	hInstance = hInst;
64 
65 	wcex.cbSize = sizeof(WNDCLASSEX);
66 
67 	wcex.style			= CS_HREDRAW | CS_VREDRAW;
68 	wcex.lpfnWndProc	= (WNDPROC)WndProc;
69 	wcex.cbClsExtra		= 0;
70 	wcex.cbWndExtra		= 0;
71 	wcex.hInstance		= hInstance;
72 	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
73 	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
74 	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
75 	wcex.lpszMenuName	= (LPCSTR)IDR_MENU1;
76 	wcex.lpszClassName	= TITLE;
77 	wcex.hIconSm		= LoadIcon(wcex.hInstance, (LPCTSTR)IDI_ICON1);
78 
79 	RegisterClassEx(&wcex);
80 
81 	HWnd = CreateWindow(TITLE, TITLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE,
82 						50, 50, 400, 300, NULL, NULL, hInstance, NULL);
83 	if (HWnd == NULL)
84 		return FALSE;
85 
86 	// Display the window
87 	ShowWindow(HWnd, nCmdShow);
88 	UpdateWindow(HWnd);
89 
90 	ilInit();
91 	ilEnable(IL_ORIGIN_SET);
92 	ilEnable(IL_TYPE_SET);
93 	ilEnable(IL_FORMAT_SET);
94 
95 	ilOriginFunc(IL_ORIGIN_LOWER_LEFT);
96 	ilTypeFunc(IL_UNSIGNED_BYTE);
97 	ilFormatFunc(IL_BGR);
98 
99 	// Is there a file to load from the command-line?
100 	if (__argc > 1) {
101 		LoadImages(__argv[1]);
102 	}
103 
104 	hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDR_MENU1);
105 
106 	while (GetMessage(&msg, NULL, 0, 0)) {
107 		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) {
108 			TranslateMessage(&msg);
109 			DispatchMessage(&msg);
110 		}
111 	}
112 
113 	return msg.wParam;
114 }
115 
116 
LoadImages(char * FileName)117 void LoadImages(char *FileName)
118 {
119 	ILuint Image, i;
120 
121 	hDC = GetDC(HWnd);
122 	hMemDC = CreateCompatibleDC(hDC);
123 
124 	ilGenImages(1, &Image);
125 	ilBindImage(Image);
126 	if (!ilLoadImage(FileName)) {
127 		ilDeleteImages(1, &Image);
128 		return;
129 	}
130 
131 	ilEnable(IL_ORIGIN_SET);
132 	ilEnable(IL_FORMAT_SET);
133 	ilOriginFunc(IL_ORIGIN_LOWER_LEFT);
134 	//ilFormatFunc(IL_BGRA);
135 	ilConvertImage(IL_BGR, IL_UNSIGNED_BYTE);
136 	ilutRenderer(ILUT_WIN32);
137 
138 	CurImage = 0;
139 	NumImages = ilGetInteger(IL_NUM_IMAGES) + 1;
140 	Bitmaps = new HBITMAP[NumImages];
141 	BmpInfo = new BITMAPINFOHEADER[NumImages];
142 	Durations = new ILuint[NumImages];
143 	if (Bitmaps == NULL || BmpInfo == NULL || Durations == NULL) {
144 		ilDeleteImages(1, &Image);
145 		return;
146 	}
147 
148 	for (i = 0; i < NumImages; i++) {
149 		ilActiveImage(0);
150 		ilActiveImage(i);
151 		Durations[i] = ilGetInteger(IL_IMAGE_DURATION);
152 		*(Bitmaps + i) = ilutConvertToHBitmap(hDC);
153 		ilutGetBmpInfo((BITMAPINFO*)(BmpInfo + i));
154 	}
155 
156 	SelectObject(hMemDC, Bitmaps[0]);
157 
158 	ilDeleteImages(1, &Image);
159 
160 	sprintf(NewTitle, "%s - %s", TITLE, FileName);
161 	SetWindowText(HWnd, NewTitle);
162 
163 	QueryPerformanceFrequency((LARGE_INTEGER*)&TimerFreq);
164 	TimerRes = 1.0 / TimerFreq;
165 	QueryPerformanceCounter((LARGE_INTEGER*)&StartTime);
166 
167 	return;
168 }
169 
170 
DestroyGDI()171 void DestroyGDI()
172 {
173 	ILuint i;
174 
175 	if (Bitmaps) {
176 		for (i = 0; i < NumImages; i++) {
177 			DeleteObject(*(Bitmaps + i));
178 		}
179 	}
180 
181 	if (hMemDC)
182 		DeleteDC(hMemDC);
183 
184 	if (Bitmaps)
185 		delete []Bitmaps;
186 	if (BmpInfo)
187 		delete []BmpInfo;
188 
189 	Bitmaps = NULL;
190 	BmpInfo = NULL;
191 	hMemDC = NULL;
192 
193 	return;
194 }
195 
196 
DisplayImage()197 void DisplayImage()
198 {
199 	static PAINTSTRUCT	ps;
200 	static __int64		CurTime;
201 	static double		TimeElapsed;
202 
203 	// Not created yet.
204 	if (Durations == NULL || BmpInfo == NULL || Bitmaps == NULL)
205 		return;
206 
207 	if (!IsPaused) {
208 		QueryPerformanceCounter((LARGE_INTEGER*)&CurTime);
209 		TimeElapsed = (CurTime - StartTime) * TimerRes;
210 		if (TimeElapsed * 1000 > Durations[CurImage]) {
211 			StartTime = CurTime;
212 			CurImage++;
213 			if (CurImage >= NumImages) {
214 				CurImage = 0;
215 			}
216 			SelectObject(hMemDC, Bitmaps[CurImage]);
217 		}
218 	}
219 
220 	hDC = BeginPaint(HWnd, &ps);
221 	BitBlt(hDC, 0, 0, (WORD)BmpInfo[CurImage].biWidth, (WORD)BmpInfo[CurImage].biHeight,
222 		  hMemDC, 0, 0, SRCCOPY);
223 	EndPaint(HWnd, &ps);
224 
225 	return;
226 }
227 
228 
229 // Window procedure, handles all messages for this program
WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)230 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
231 {
232 	static HMENU	hMenu;
233 	static ILuint	Colours;
234 	static RECT		Rect;
235     static HDROP	hDrop;
236 
237 	static char OpenFileName[2048];
238 	static char OpenFilter[2048];
239 	static char *OFilter[] = {
240 		"All Files (*.*)", "*.*",
241 		"Half-Life Model Files (*.mdl)", "*.mdl",
242 		"Homeworld Image Files (*.lif)", "*.lif",
243 		"Image Files (All Supported Types)", "*.jpe;*.jpg;*.jpeg;*.lif;*.bmp;*.ico;*.pbm;*.pgm;*.pnm;*.ppm;*.png;*.bw;*.rgb;*.rgba;*.sgi;*.tga;*.tif;*.tiff;*.pcx",
244 		"Jpeg Files (*.jpe, *.jpg, *.jpeg)", "*.jpe;*.jpg;*.jpeg",
245 		"Microsoft Bitmap Files (*.bmp)", "*.bmp",
246 		"Microsoft Icon Files (*.ico)", "*.ico",
247 		"OpenIL Files (*.oil)", "*.oil",
248 		"Portable AnyMap Files (*.pbm, *.pgm, *.pnm, *.ppm)", "*.pbm;*.pgm;*.pnm;*.ppm",
249 		"Portable Network Graphics Files (*.png)", "*.png",
250 		"Sgi Files (*.sgi)", "*.bw;*.rgb;*.rgba;*.sgi",
251 		"Targa Files (*.tga)", "*.tga",
252 		"Tiff Files (*.tif)", "*.tif;*.tiff",
253 		"Quake Wal Files (*.wal)", "*.wal",
254 		"ZSoft Pcx Files (*.pcx)", "*.pcx",
255 		"\0\0"
256 	};
257 
258 	static OPENFILENAME Ofn = {
259 		sizeof(OPENFILENAME),
260 		hWnd,
261 		NULL,
262 		OpenFilter,
263 		NULL,
264 		0,
265 		0,
266 		OpenFileName,
267 		512,
268 		NULL,
269 		0,
270 		NULL,
271 		NULL,
272 		OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST,
273 		0,
274 		0,
275 		NULL,
276 		NULL,
277 		NULL,
278 		NULL
279 	};
280 
281 	switch (message)
282 	{
283 		case WM_CREATE:
284 			GenFilterString(OpenFilter, OFilter);
285 
286 			hDC = GetDC(hWnd);
287 			DragAcceptFiles(hWnd, TRUE);
288 
289 			break;
290 
291 		case WM_CLOSE:
292 			DestroyGDI();
293 			ReleaseDC(hWnd, hDC);
294 			DestroyWindow(hWnd);
295 			UnregisterClass(TITLE, hInstance);
296 			break;
297 
298 		case WM_DESTROY:
299 			PostQuitMessage(0);
300 			break;
301 
302 		case WM_PAINT:
303 			DisplayImage();
304 			InvalidateRect(hWnd, NULL, FALSE);
305 			break;
306 
307 		case WM_KEYDOWN:
308 			if (wParam == VK_ESCAPE)
309 				PostQuitMessage(0);
310 			InvalidateRect(hWnd, NULL, FALSE);
311 			break;
312 
313 		case WM_DROPFILES:
314 			hDrop = (HDROP)wParam;
315 			DragQueryFile(hDrop, 0, OpenFileName, 512);
316 
317 			DestroyGDI();
318 			LoadImages(OpenFileName);
319 
320 			DragFinish (hDrop);
321 			return 0;
322 
323 		case WM_COMMAND:
324 			FilterType = LOWORD(wParam);
325 
326 			switch (LOWORD(wParam))
327 			{
328 				case ID_FILE_EXIT:
329 					PostMessage(hWnd, WM_CLOSE, 0, 0);
330 					return (0L);
331 
332 				case ID_FILE_LOAD:
333 					sprintf(OpenFileName, "*.*");
334 					Ofn.lpstrFilter = OpenFilter;
335 					Ofn.lpstrFile = OpenFileName;
336 					Ofn.lpstrTitle = "Open File";
337 					Ofn.nFilterIndex = 1;
338 					Ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
339 
340 					if (!GetOpenFileName(&Ofn))
341 						return (0L);
342 
343 					DestroyGDI();
344 					LoadImages(OpenFileName);
345 
346 					return (0L);
347 
348 				case ID_EDIT_PAUSE:
349 					IsPaused = true;
350 					return 0;
351 
352 				case ID_EDIT_RESUME:
353 					IsPaused = false;
354 					QueryPerformanceCounter((LARGE_INTEGER*)&StartTime);
355 					return 0;
356 			}
357 
358 		default:
359 		  return (DefWindowProc(hWnd, message, wParam, lParam));
360 	}
361 
362     return (0L);
363 }
364 
365 
GenFilterString(char * Out,char ** Strings)366 void GenFilterString(char *Out, char **Strings)
367 {
368 	int OutPos = 0, StringPos = 0;
369 
370 	while (Strings[StringPos][0] != 0) {
371 		sprintf(Out + OutPos, Strings[StringPos]);
372 		OutPos += strlen(Strings[StringPos++]) + 1;
373 	}
374 
375 	Out[OutPos++] = 0;
376 	Out[OutPos] = 0;
377 
378 	return;
379 }
380