1 /* ______ ___ ___
2 * /\ _ \ /\_ \ /\_ \
3 * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
4 * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
5 * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
6 * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7 * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
8 * /\____/
9 * \_/__/
10 *
11 * Example program showing how to use Allegro as a sound
12 * library under Windows.
13 *
14 * By Eric Botcazou.
15 *
16 * Original idea and improvements by Javier Gonzalez.
17 *
18 * See readme.txt for copyright information.
19 */
20
21 #include "allegro.h"
22 #include "winalleg.h"
23 #include "dibsound.rh"
24
25
26 HINSTANCE hInst = NULL;
27 PALETTE pal;
28 BITMAP *bmp = NULL;
29
30
31
AboutDlgProc(HWND hwnd,UINT Message,WPARAM wParam,LPARAM lParam)32 BOOL CALLBACK AboutDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
33 {
34 switch(Message) {
35
36 case WM_INITDIALOG:
37 return TRUE;
38
39 case WM_COMMAND:
40 switch(LOWORD(wParam)) {
41
42 case IDOK:
43 EndDialog(hwnd, IDOK);
44 return TRUE;
45
46 case IDCANCEL:
47 EndDialog(hwnd, IDCANCEL);
48 return TRUE;
49 }
50 break;
51 }
52
53 return FALSE;
54 }
55
56
57
OpenNewSample(SAMPLE ** sample,HWND hwnd)58 int OpenNewSample(SAMPLE **sample, HWND hwnd)
59 {
60 OPENFILENAME openfilename;
61 SAMPLE *new_sample;
62 char filename[512];
63
64 memset(&openfilename, 0, sizeof(OPENFILENAME));
65 openfilename.lStructSize = sizeof(OPENFILENAME);
66 openfilename.hwndOwner = hwnd;
67 openfilename.lpstrFilter = "Sounds (*.wav;*.voc)\0*.wav;*.voc\0";
68 openfilename.lpstrFile = filename;
69 openfilename.nMaxFile = sizeof(filename);
70 openfilename.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
71
72 filename[0] = 0;
73
74 if (GetOpenFileName(&openfilename)) {
75 new_sample = load_sample(openfilename.lpstrFile);
76
77 if (!new_sample) {
78 MessageBox(hwnd, "This is not a standard sound file.", "Error!",
79 MB_ICONERROR | MB_OK);
80 return -1;
81 }
82
83 /* make room for next samples */
84 if (*sample)
85 destroy_sample(*sample);
86
87 *sample = new_sample;
88 return 0;
89 }
90
91 return -1;
92 }
93
94
95
WndProc(HWND hwnd,UINT Message,WPARAM wParam,LPARAM lParam)96 LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
97 {
98 static SAMPLE *sample = NULL;
99 static int volume = 128;
100 static int pan = 128;
101 static int speed = 1000;
102 static int loop = FALSE;
103 HDC hdc;
104 RECT updaterect;
105 PAINTSTRUCT ps;
106
107 switch(Message) {
108
109 case WM_COMMAND:
110 switch(LOWORD(wParam)) {
111
112 case CMD_FILE_OPEN:
113 OpenNewSample(&sample, hwnd);
114 break;
115
116 case CMD_FILE_PLAY:
117 if (!sample) {
118 if (OpenNewSample(&sample, hwnd) != 0)
119 break;
120 }
121
122 /* play it !! */
123 play_sample(sample, volume, pan, speed, loop);
124 break;
125
126 case CMD_FILE_STOP:
127 if (sample)
128 stop_sample(sample);
129 break;
130
131 case CMD_FILE_EXIT:
132 PostMessage(hwnd, WM_CLOSE, 0, 0);
133 break;
134
135 case CMD_SET_VOLUME_UP:
136 volume = MIN(volume+32, 255);
137 if (sample)
138 adjust_sample(sample, volume, pan, speed, loop);
139 break;
140
141 case CMD_SET_VOLUME_DOWN:
142 volume = MAX(volume-32, 0);
143 if (sample)
144 adjust_sample(sample, volume, pan, speed, loop);
145 break;
146
147 case CMD_SET_VOLUME_DEFAULT:
148 volume = 128;
149 if (sample)
150 adjust_sample(sample, volume, pan, speed, loop);
151 break;
152
153 case CMD_SET_PAN_LEFT:
154 pan = MAX(pan-32, 0);
155 if (sample)
156 adjust_sample(sample, volume, pan, speed, loop);
157 break;
158
159 case CMD_SET_PAN_RIGHT:
160 pan = MIN(pan+32, 255);
161 if (sample)
162 adjust_sample(sample, volume, pan, speed, loop);
163 break;
164
165 case CMD_SET_PAN_CENTER:
166 pan = 128;
167 if (sample)
168 adjust_sample(sample, volume, pan, speed, loop);
169 break;
170
171 case CMD_SET_SPEED_UP:
172 speed = MIN(speed*2, 8000);
173 if (sample)
174 adjust_sample(sample, volume, pan, speed, loop);
175 break;
176
177 case CMD_SET_SPEED_DOWN:
178 speed = MAX(speed/2, 125);
179 if (sample)
180 adjust_sample(sample, volume, pan, speed, loop);
181 break;
182
183 case CMD_SET_SPEED_NORMAL:
184 speed = 1000;
185 if (sample)
186 adjust_sample(sample, volume, pan, speed, loop);
187 break;
188
189 case CMD_SET_LOOP_MODE:
190 loop = !loop;
191 CheckMenuItem(GetMenu(hwnd), CMD_SET_LOOP_MODE, loop ? MF_CHECKED : MF_UNCHECKED);
192 if (sample)
193 adjust_sample(sample, volume, pan, speed, loop);
194 break;
195
196 case CMD_HELP_ABOUT:
197 DialogBox(hInst, "ABOUTDLG", hwnd, AboutDlgProc);
198 break;
199 }
200 return 0;
201
202 case WM_QUERYNEWPALETTE:
203 InvalidateRect(hwnd, NULL, TRUE);
204 return TRUE;
205
206 case WM_PALETTECHANGED:
207 if ((HWND)wParam != hwnd) {
208 hdc = GetDC(hwnd);
209 InvalidateRect(hwnd, NULL, TRUE);
210 ReleaseDC(hwnd, hdc);
211 }
212 return TRUE;
213
214 case WM_PAINT:
215 if (GetUpdateRect(hwnd, &updaterect, FALSE)) {
216 hdc = BeginPaint(hwnd, &ps);
217 set_palette_to_hdc(hdc, pal);
218 draw_to_hdc(hdc, bmp, 0, 0);
219 EndPaint(hwnd, &ps);
220 }
221 return 0;
222
223 case WM_CLOSE:
224 destroy_sample(sample);
225 DestroyWindow(hwnd);
226 return 0;
227
228 case WM_DESTROY:
229 PostQuitMessage(0);
230 return 0;
231 }
232
233 return DefWindowProc(hwnd, Message, wParam, lParam);
234 }
235
236
237
WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)238 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
239 {
240 static char szAppName[] = "Sound Player";
241 WNDCLASS wndClass;
242 HWND hwnd;
243 HACCEL haccel;
244 MSG msg;
245
246 hInst = hInstance;
247
248 if (!hPrevInstance) {
249 wndClass.style = CS_HREDRAW | CS_VREDRAW;
250 wndClass.lpfnWndProc = WndProc;
251 wndClass.cbClsExtra = 0;
252 wndClass.cbWndExtra = 0;
253 wndClass.hInstance = hInst;
254 wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
255 wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
256 wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
257 wndClass.lpszMenuName = "MYMENU";
258 wndClass.lpszClassName = szAppName;
259
260 RegisterClass(&wndClass);
261 }
262
263 hwnd = CreateWindow(szAppName, szAppName,
264 WS_OVERLAPPEDWINDOW,
265 CW_USEDEFAULT, CW_USEDEFAULT,
266 320, 240,
267 NULL, NULL,
268 hInst, NULL);
269
270 if (!hwnd) {
271 MessageBox(0, "Window Creation Failed.", "Error!",
272 MB_ICONERROR | MB_OK | MB_SYSTEMMODAL);
273 return 0;
274 }
275
276 /* register our window BEFORE calling allegro_init() */
277 win_set_window(hwnd);
278
279 /* initialize the library */
280 if (allegro_init() != 0)
281 return 0;
282
283 /* install the digital sound module */
284 install_sound(DIGI_AUTODETECT, MIDI_NONE, NULL);
285
286 /* allow Allegro to keep playing samples in the background */
287 set_display_switch_mode(SWITCH_BACKGROUND);
288
289 /* load some 8 bit bitmap */
290 set_color_conversion(COLORCONV_NONE);
291 bmp = load_bitmap("..\\..\\examples\\allegro.pcx", pal);
292 if (!bmp) {
293 /* the CMake MSVC workspace puts the executable one directory deeper */
294 bmp = load_bitmap("..\\..\\..\\examples\\allegro.pcx", pal);
295 if (!bmp) {
296 MessageBox(hwnd, "Can't load ..\\..\\examples\\allegro.pcx", "Error!",
297 MB_ICONERROR | MB_OK);
298 return 0;
299 }
300 }
301
302 /* display the window */
303 haccel = LoadAccelerators(hInst, "MYACCEL");
304 ShowWindow(hwnd, nCmdShow);
305 UpdateWindow(hwnd);
306
307 /* process messages */
308 while(GetMessage(&msg, NULL, 0, 0)) {
309 if (!TranslateAccelerator(hwnd, haccel, &msg)) {
310 TranslateMessage(&msg);
311 DispatchMessage(&msg);
312 }
313 }
314
315 return msg.wParam;
316 }
317