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