1 /*
2     TiMidity++ -- MIDI to WAVE converter and player
3     Copyright (C) 1999-2002 Masanao Izumo <mo@goice.co.jp>
4     Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>
5 
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 
20     w32g_subwin3.c: Written by Daisuke Aoki <dai@y7.net>
21 */
22 
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif /* HAVE_CONFIG_H */
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <process.h>
29 #include <stddef.h>
30 #ifndef NO_STRING_H
31 #include <string.h>
32 #else
33 #include <strings.h>
34 #endif
35 
36 #include "timidity.h"
37 #include "common.h"
38 #include "instrum.h"
39 #include "playmidi.h"
40 #include "readmidi.h"
41 #include "output.h"
42 #include "controls.h"
43 #include "tables.h"
44 #include "miditrace.h"
45 #include "reverb.h"
46 #ifdef SUPPORT_SOUNDSPEC
47 #include "soundspec.h"
48 #endif /* SUPPORT_SOUNDSPEC */
49 #include "recache.h"
50 #include "arc.h"
51 #include "strtab.h"
52 #include "mid.defs"
53 
54 #include "w32g.h"
55 #include <shlobj.h>
56 #include <commctrl.h>
57 #include <windowsx.h>
58 #include "w32g_res.h"
59 #include "w32g_utl.h"
60 #include "w32g_pref.h"
61 #include "w32g_subwin.h"
62 #include "w32g_ut2.h"
63 
64 #include "w32g_tracer.h"
65 
66 extern int gdi_lock_ex ( DWORD timeout );
67 #if 0
68 static int gdi_lock_result;
69 #define GDI_LOCK_EX(timeout) ( \
70 	ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "GDI_LOCK_EX(%s: %d)", __FILE__, __LINE__ ), \
71 	gdi_lock_result = gdi_lock_ex(timeout), \
72 	ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "GDI_LOCK_EX_RESULT(%d)", gdi_lock_result ), \
73 	gdi_lock_result \
74 )
75 #define GDI_LOCK() { \
76 	ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "GDI_LOCK(%s: %d)", __FILE__, __LINE__ ); \
77 	gdi_lock(); \
78 }
79 #define GDI_UNLOCK() { \
80 	ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "GDI_UNLOCK(%s: %d)", __FILE__, __LINE__ ); \
81 	gdi_unlock(); \
82 }
83 #else
84 #define GDI_LOCK() { gdi_lock(); }
85 #define GDI_LOCK_EX(timeout) gdi_lock_ex(timeout)
86 #define GDI_UNLOCK() { gdi_unlock(); }
87 #endif
88 
89 #if defined(__CYGWIN32__) || defined(__MINGW32__)
90 #ifndef TPM_TOPALIGN
91 #define TPM_TOPALIGN	0x0000L
92 #endif
93 #endif
94 
95 extern void VprintfEditCtlWnd(HWND hwnd, char *fmt, va_list argList);
96 extern void PrintfEditCtlWnd(HWND hwnd, char *fmt, ...);
97 extern void PutsEditCtlWnd(HWND hwnd, char *str);
98 extern void ClearEditCtlWnd(HWND hwnd);
99 
100 #define C_BACK RGB(0x00,0x00,0x00)
101 // #define C_BAR_FORE RGB(0xFF,0xFF,0x00)
102 #define C_BAR_FORE RGB(0xD0,0xD0,0x00)
103 #define C_BAR_FORE2 RGB(0xD0,0xB0,0x00)
104 #define C_BAR_BACK RGB(0xA0,0xA0,0xA0)
105 #define C_BAR_LEFT RGB(0xD0,0xD0,0x00)
106 #define C_BAR_RIGHT RGB(0x80,0xD0,0x40)
107 #define C_TEXT_FORE RGB(0x00,0x00,0x00)
108 #define C_TEXT_BACK RGB(0xC0,0xC0,0xC0)
109 #define C_TEXT_BACK_DARK RGB(0x80,0x80,0x80)
110 #define C_TEXT_BACK_VERY_DARK RGB(0x40,0x40,0x40)
111 
112 #define CVV_TYPE_NONE 0
113 #define CVV_TYPE_LEFT 1		// ������E
114 #define CVV_TYPE_RIGHT 2	// �E���獶
115 #define CVV_TYPE_TOP 3		// �ォ�牺
116 #define CVV_TYPE_BOTTOM 4	// �������
117 
118 #define VEL_MAX 128*4
119 
120 #define TWI_MODE_1_32CH		1
121 #define TWI_MODE_1_16CH		2
122 #define TWI_MODE_17_32CH	3
123 
124 #define CTL_STATUS_UPDATE -98
125 
126 extern ControlMode *ctl;
127 
128 #define CSV_LEFT	0
129 #define CSV_RIGHT	1
130 #define CSV_CENTER 2
131 
132 static struct tracer_bmp_ {
133 	HBITMAP hbmp;
134 	HDC hmdc;
135 	RECT rc_volume;
136 	RECT rc_expression;
137 	RECT rc_pan;
138 	RECT rc_sustain;
139 	RECT rc_pitch_bend;
140 	RECT rc_mod_wheel;
141 	RECT rc_chorus_effect;
142 	RECT rc_reverb_effect;
143 	RECT rc_velocity[2];
144 	RECT rc_notes;
145 	RECT rc_notes_sustain;
146 	RECT rc_notes_on;
147 	RECT rc_notes_mask[12];
148 	RECT rc_note[12];
149 	RECT rc_note_sustain[12];
150 	RECT rc_note_on[12];
151 	RECT rc_gm_on;
152 	RECT rc_gm_off;
153 	RECT rc_gs_on;
154 	RECT rc_gs_off;
155 	RECT rc_xg_on;
156 	RECT rc_xg_off;
157 	RECT rc_temper_keysig[32];
158 	RECT rc_temper_type[8];
159 } tracer_bmp;
160 
161 static int get_head_rc ( RECT *rc, RECT *rc_base );
162 static int get_ch_rc ( int ch, RECT *rc, RECT *rc_base );
163 static int notes_view_draw ( RECT *lprc, int note, int vel, int back_draw, int lockflag );
164 #if 0
165 static int cheap_volume_view_draw ( RECT *lprc, int vol, int max, COLORREF fore, COLORREF back, int type, int lockflag );
166 #endif
167 static int cheap_string_view_draw ( RECT *lprc, char *str, COLORREF fore, COLORREF back, int mode, int lockflag );
168 static int cheap_half_string_view_draw ( RECT *lprc, char *str, COLORREF fore, COLORREF back, int mode, int lockflag );
169 
170 static int change_tracer_wnd_mode ( int mode );
171 
172 static int init_tracer_bmp ( HDC hdc );
173 
174 static int tracer_ch_number_draw(int ch, int mute, int lockflag);
175 static int tracer_ch_program_draw ( int ch, int bank, int program, char *instrument, int mapID, int lockflag );
176 static int tracer_velocity_draw ( RECT *lprc, int vol, int max, int lockflag );
177 static int tracer_velocity_draw_ex ( RECT *lprc, int vol, int vol_old, int max, int lockflag );
178 static int tracer_volume_draw ( RECT *lprc, int vol, int max, int lockflag );
179 static int tracer_expression_draw ( RECT *lprc, int vol, int max, int lockflag );
180 static int tracer_pan_draw ( RECT *lprc, int vol, int max, int lockflag );
181 static int tracer_sustain_draw ( RECT *lprc, int vol, int lockflag );
182 static int tracer_pitch_bend_draw ( RECT *lprc, int vol, int max, int lockflag );
183 static int tracer_mod_wheel_draw ( RECT *lprc, int vol, int max, int lockflag );
184 static int tracer_chorus_effect_draw ( RECT *lprc, int vol, int max, int lockflag );
185 static int tracer_reverb_effect_draw ( RECT *lprc, int vol, int max, int lockflag );
186 static int tracer_temper_keysig_draw(RECT *lprc, int8 tk, int ko, int lockflag);
187 static int tracer_temper_type_draw(RECT *lprc, int ch, int8 tt, int lockflag);
188 static int tracer_gm_draw ( RECT *lprc, int flag, int lockflag );
189 static int tracer_gs_draw ( RECT *lprc, int flag, int lockflag );
190 static int tracer_xg_draw ( RECT *lprc, int flag, int lockflag );
191 
192 static int notes_view_generate ( int lockflag );
193 
194 // ****************************************************************************
195 // lock
196 
197 #if 0
198 static int tracer_lock_result;
199 #define TRACER_LOCK_EX(timeout) ( \
200 	ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "TRACER_LOCK_EX(%s: %d)", __FILE__, __LINE__ ), \
201 	tracer_lock_result = tracer_lock_ex(timeout), \
202 	ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "TRACER_LOCK_EX_RESULT(%d)", tracer_lock_result ), \
203 	tracer_wnd_lock_result \
204 )
205 #define TRACER_LOCK() { \
206 	ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "TRACER_LOCK(%s: %d)", __FILE__, __LINE__ ); \
207 	tracer_wnd_lock(); \
208 }
209 #define TRACER_UNLOCK() { \
210 	ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "TRACER_UNLOCK(%s: %d)", __FILE__, __LINE__ ); \
211 	tracer_wnd_unlock(); \
212 }
213 #else
214 #define TRACER_LOCK() { tracer_wnd_lock(); }
215 #define TRACER_LOCK_EX(timeout) tracer_wnd_lock_ex(timeout)
216 #define TRACER_UNLOCK() { tracer_wnd_unlock(); }
217 #endif
218 
219 static HANDLE volatile hMutexWrd = NULL;
tracer_wnd_lock_ex(DWORD timeout)220 static BOOL tracer_wnd_lock_ex ( DWORD timeout )
221 {
222 	if ( hMutexWrd == NULL ) {
223 		hMutexWrd = CreateMutex ( NULL, FALSE, NULL );
224 		if ( hMutexWrd == NULL )
225 			return FALSE;
226 	}
227 	if ( WaitForSingleObject ( hMutexWrd, timeout )== WAIT_FAILED ) {
228 		return FALSE;
229 	}
230 	return TRUE;
231 }
tracer_wnd_lock(void)232 static BOOL tracer_wnd_lock (void)
233 {
234 	return tracer_wnd_lock_ex ( INFINITE );
235 }
tracer_wnd_unlock(void)236 static void tracer_wnd_unlock (void)
237 {
238 	ReleaseMutex ( hMutexWrd );
239 }
240 
241 // ****************************************************************************
242 // Tracer Window
243 
244 TRACERWNDINFO TracerWndInfo;
245 
246 static int TracerWndInfoReset(HWND hwnd);
247 static int TracerWndInfoApply(void);
248 
249 w32g_tracer_wnd_t w32g_tracer_wnd;
250 
SetTracerWndActive(void)251 BOOL SetTracerWndActive(void)
252 {
253 	if ( IsWindowVisible(hTracerWnd) ) {
254 		w32g_tracer_wnd.active = TRUE;
255 	} else {
256 		w32g_tracer_wnd.active = FALSE;
257 	}
258 	return w32g_tracer_wnd.active;
259 }
260 
261 BOOL CALLBACK TracerWndProc(HWND hwnd, UINT uMess, WPARAM wParam, LPARAM lParam);
262 BOOL CALLBACK TracerCanvasWndProc(HWND hwnd, UINT uMess, WPARAM wParam, LPARAM lParam);
InitTracerWnd(HWND hParentWnd)263 void InitTracerWnd(HWND hParentWnd)
264 {
265 	WNDCLASS wndclass ;
266 	int height, space;
267 	RECT rc, rc2;
268 	HICON hIcon;
269 	static int init = 1;
270 
271 	if ( init ) {
272 		w32g_tracer_wnd.hNullBrush = GetStockObject ( NULL_BRUSH );
273 		w32g_tracer_wnd.hNullPen = GetStockObject ( NULL_PEN );
274 		init = 0;
275 	}
276 
277 	if (hTracerWnd != NULL) {
278 		TRACER_LOCK();
279 		DestroyWindow(hTracerWnd);
280 		hTracerWnd = NULL;
281 		DeleteObject ( (HGDIOBJ)w32g_tracer_wnd.hFontCommon );
282 		DeleteObject ( (HGDIOBJ)w32g_tracer_wnd.hFontHalf );
283 		DeleteDC ( w32g_tracer_wnd.hmdc );
284 		TRACER_UNLOCK();
285 	}
286 
287 	w32g_tracer_wnd.active = FALSE;
288 	INILoadTracerWnd();
289 	hTracerWnd = CreateDialog
290 		(hInst,MAKEINTRESOURCE(IDD_DIALOG_TRACER),hParentWnd,TracerWndProc);
291 	TracerWndInfoReset(hTracerWnd);
292 	ShowWindow(hTracerWnd,SW_HIDE);
293 	hIcon = LoadImage(hInst, MAKEINTRESOURCE(IDI_ICON_TIMIDITY), IMAGE_ICON, 16, 16, 0);
294 	if (hIcon!=NULL) SendMessage(hTracerWnd,WM_SETICON,FALSE,(LPARAM)hIcon);
295 	INILoadTracerWnd();
296 
297 	w32g_tracer_wnd.font_common_height = 14;
298 	w32g_tracer_wnd.font_common_width = 0;
299 	SetRect ( &w32g_tracer_wnd.rc_head, 1, 2,  0, 0 );
300 	SetRect ( &w32g_tracer_wnd.rc_all_channels, 1,  20 + 2,  0, 0 );
301 	w32g_tracer_wnd.width = 2 + 880 + 2;
302 	w32g_tracer_wnd.height = 1 + 19 + 1 + (19 + 1) * 32 + 1;
303 
304 	w32g_tracer_wnd.ch_height = 19;
305 	w32g_tracer_wnd.ch_space = 1;
306 	height = w32g_tracer_wnd.ch_height;
307 	space = w32g_tracer_wnd.ch_space;
308 
309 #if 0
310 	SetRect ( &w32g_tracer_wnd.rc_current_time, 2, 1, 80, height );
311 	SetRect ( &w32g_tracer_wnd.rc_tempo, 82, 1, 160, height );
312 	SetRect ( &w32g_tracer_wnd.rc_master_volume, 162, 1, 200, height / 2 - 1 );
313 	SetRect ( &w32g_tracer_wnd.rc_maxvoices, 162, height / 2 + 1, 200, height );
314 #endif
315 
316 	wndclass.style         = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_CLASSDC;
317 	wndclass.lpfnWndProc   = TracerCanvasWndProc ;
318 	wndclass.cbClsExtra    = 0 ;
319 	wndclass.cbWndExtra    = 0 ;
320 	wndclass.hInstance     = hInst ;
321 	wndclass.hIcon         = NULL;
322 	wndclass.hCursor       = LoadCursor(0,IDC_ARROW) ;
323 	wndclass.hbrBackground = w32g_tracer_wnd.hNullBrush;
324 	wndclass.lpszMenuName  = NULL;
325 	wndclass.lpszClassName = "tracer canvas wnd";
326 	RegisterClass(&wndclass);
327 	w32g_tracer_wnd.hwnd = CreateWindowEx(0,"tracer canvas wnd",0,WS_CHILD,
328 		CW_USEDEFAULT,0,w32g_tracer_wnd.width,w32g_tracer_wnd.height,
329 		hTracerWnd,0,hInst,0);
330 
331 	w32g_tracer_wnd.hdc = GetDC(w32g_tracer_wnd.hwnd);
332 
333 	TRACER_LOCK();
334 	SelectObject ( w32g_tracer_wnd.hdc, w32g_tracer_wnd.hNullBrush );
335 	SelectObject ( w32g_tracer_wnd.hdc, w32g_tracer_wnd.hNullPen );
336 
337 	w32g_tracer_wnd.hbitmap = CreateCompatibleBitmap(w32g_tracer_wnd.hdc,w32g_tracer_wnd.width,w32g_tracer_wnd.height);
338 	w32g_tracer_wnd.hmdc = CreateCompatibleDC(w32g_tracer_wnd.hdc);
339 	w32g_tracer_wnd.hgdiobj_hmdcprev = SelectObject(w32g_tracer_wnd.hmdc,w32g_tracer_wnd.hbitmap);
340 	SelectObject ( w32g_tracer_wnd.hmdc, w32g_tracer_wnd.hNullBrush );
341 	SelectObject ( w32g_tracer_wnd.hmdc, w32g_tracer_wnd.hNullPen );
342 	TRACER_UNLOCK();
343 	init_tracer_bmp ( w32g_tracer_wnd.hdc );
344 
345 	ReleaseDC(w32g_tracer_wnd.hwnd,w32g_tracer_wnd.hdc);
346 
347 	{
348 		char fontname[128];
349 		if ( PlayerLanguage == LANGUAGE_JAPANESE )
350 			strcpy(fontname,"�l�r �o����");
351 		else {
352 			strcpy(fontname,"Arial");
353 			w32g_tracer_wnd.font_common_height = 16;
354 		}
355 		w32g_tracer_wnd.hFontCommon = CreateFont(w32g_tracer_wnd.font_common_height,w32g_tracer_wnd.font_common_width,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,
356 			DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,ANTIALIASED_QUALITY,
357 			DEFAULT_PITCH | FF_MODERN ,fontname);
358 		w32g_tracer_wnd.hFontHalf = CreateFont(-10,0,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,
359 			DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,ANTIALIASED_QUALITY,
360 			DEFAULT_PITCH | FF_MODERN ,"Courier");
361 	}
362 	TracerWndReset();
363 
364 	SetRect(&w32g_tracer_wnd.rc_channel_top, 1, 0, 20, height);
365 	SetRect(&w32g_tracer_wnd.rc_instrument, 21, 0, 179, height);
366 	SetRect(&w32g_tracer_wnd.rc_inst_map, 180, 0, 233, height);
367 	SetRect(&w32g_tracer_wnd.rc_bank, 234, 0, 264, height);
368 	SetRect(&w32g_tracer_wnd.rc_program, 265, 0, 295, height);
369 	SetRect(&w32g_tracer_wnd.rc_velocity, 296, 0, 326, height);
370 	SetRect(&w32g_tracer_wnd.rc_volume, 327, 0, 347, height / 2);
371 	SetRect(&w32g_tracer_wnd.rc_expression, 327, height / 2 + 1, 347, height);
372 	SetRect(&w32g_tracer_wnd.rc_panning, 348, 0, 368, height / 2);
373 	SetRect(&w32g_tracer_wnd.rc_sustain, 348, height / 2 + 1, 368, height);
374 	SetRect(&w32g_tracer_wnd.rc_pitch_bend, 369, 0, 389, height / 2);
375 	SetRect(&w32g_tracer_wnd.rc_mod_wheel, 369, height / 2 + 1, 389, height);
376 	SetRect(&w32g_tracer_wnd.rc_chorus_effect, 390, 0, 410, height / 2);
377 	SetRect(&w32g_tracer_wnd.rc_reverb_effect, 390, height / 2 + 1, 410, height);
378 	SetRect(&w32g_tracer_wnd.rc_temper_keysig, 411, 0, 444, height);
379 	SetRect(&w32g_tracer_wnd.rc_gm, 445, 0, 469, height);
380 	SetRect(&w32g_tracer_wnd.rc_gs, 470, 0, 494, height);
381 	SetRect(&w32g_tracer_wnd.rc_xg, 495, 0, 519, height);
382 	SetRect(&w32g_tracer_wnd.rc_head_rest, 520, 0, 890, height);
383 	SetRect(&w32g_tracer_wnd.rc_temper_type, 411, 0, 430, height);
384 	SetRect(&w32g_tracer_wnd.rc_notes, 431, 0, 890, height);
385 
386 	GetWindowRect ( hTracerWnd, &rc );
387 	GetClientRect ( hTracerWnd, &rc2 );
388 	rc.left = rc.left;
389 	rc.top = rc.top;
390 	rc.right = (rc.right - rc.left) - (rc2.right - rc2.left) + w32g_tracer_wnd.width;
391 	rc.bottom = (rc.bottom - rc.top) - (rc2.bottom - rc2.top) + w32g_tracer_wnd.height;
392 	MoveWindow ( hTracerWnd, rc.left, rc.top, rc.right, rc.bottom, TRUE);
393 	MoveWindow(w32g_tracer_wnd.hwnd,0,0,w32g_tracer_wnd.width,w32g_tracer_wnd.height,TRUE);
394 	ShowWindow(w32g_tracer_wnd.hwnd,SW_SHOW);
395 	UpdateWindow(w32g_tracer_wnd.hwnd);
396 	UpdateWindow(hTracerWnd);
397 
398 	INILoadTracerWnd();
399 	TracerWndInfoApply();
400 }
401 
notes_view_generate(int lockflag)402 static int notes_view_generate ( int lockflag )
403 {
404 	int i;
405 
406 	if ( lockflag ) TRACER_LOCK ();
407 	for(i=0;i<12;i++) {
408 		BitBlt ( tracer_bmp.hmdc, tracer_bmp.rc_note[i].left, tracer_bmp.rc_note[i].top, tracer_bmp.rc_note[i].right - tracer_bmp.rc_note[i].left, tracer_bmp.rc_note[i].bottom - tracer_bmp.rc_note[i].top,
409 			tracer_bmp.hmdc, tracer_bmp.rc_notes_mask[i].left, tracer_bmp.rc_notes_mask[i].top, SRCINVERT );
410 		BitBlt ( tracer_bmp.hmdc, tracer_bmp.rc_note[i].left, tracer_bmp.rc_note[i].top, tracer_bmp.rc_note[i].right - tracer_bmp.rc_note[i].left, tracer_bmp.rc_note[i].bottom - tracer_bmp.rc_note[i].top,
411 			tracer_bmp.hmdc, tracer_bmp.rc_notes.left, tracer_bmp.rc_notes.top, SRCPAINT );
412 		BitBlt ( tracer_bmp.hmdc, tracer_bmp.rc_note_on[i].left, tracer_bmp.rc_note_on[i].top, tracer_bmp.rc_note_on[i].right - tracer_bmp.rc_note_on[i].left, tracer_bmp.rc_note_on[i].bottom - tracer_bmp.rc_note_on[i].top,
413 			tracer_bmp.hmdc, tracer_bmp.rc_notes_mask[i].left, tracer_bmp.rc_notes_mask[i].top, SRCINVERT );
414 		BitBlt ( tracer_bmp.hmdc, tracer_bmp.rc_note_on[i].left, tracer_bmp.rc_note_on[i].top, tracer_bmp.rc_note_on[i].right - tracer_bmp.rc_note_on[i].left, tracer_bmp.rc_note_on[i].bottom - tracer_bmp.rc_note_on[i].top,
415 			tracer_bmp.hmdc, tracer_bmp.rc_notes_on.left, tracer_bmp.rc_notes_on.top, SRCPAINT );
416 		BitBlt ( tracer_bmp.hmdc, tracer_bmp.rc_note_sustain[i].left, tracer_bmp.rc_note_sustain[i].top, tracer_bmp.rc_note_sustain[i].right - tracer_bmp.rc_note_sustain[i].left, tracer_bmp.rc_note_sustain[i].bottom - tracer_bmp.rc_note_sustain[i].top,
417 			tracer_bmp.hmdc, tracer_bmp.rc_notes_mask[i].left, tracer_bmp.rc_notes_mask[i].top, SRCINVERT );
418 		BitBlt ( tracer_bmp.hmdc, tracer_bmp.rc_note_sustain[i].left, tracer_bmp.rc_note_sustain[i].top, tracer_bmp.rc_note_sustain[i].right - tracer_bmp.rc_note_sustain[i].left, tracer_bmp.rc_note_sustain[i].bottom - tracer_bmp.rc_note_sustain[i].top,
419 			tracer_bmp.hmdc, tracer_bmp.rc_notes_sustain.left, tracer_bmp.rc_notes_sustain.top, SRCPAINT );
420 	}
421 	if ( lockflag ) TRACER_UNLOCK ();
422 
423 	return 0;
424 }
425 
426 #define TRACER_BMP_SIZE_X 316
427 #define TRACER_BMP_SIZE_Y 269
428 #define TRACER_CANVAS_SIZE_X 316
429 #define TRACER_CANVAS_SIZE_Y 451
430 
init_tracer_bmp(HDC hdc)431 static int init_tracer_bmp ( HDC hdc )
432 {
433 	int i, j;
434 	static int init = 1;
435 	HBITMAP hbmp;
436 	HDC hmdc;
437 
438 	if ( init ) {
439 		tracer_bmp.hbmp = NULL;
440 		tracer_bmp.hmdc = NULL;
441 		init = 0;
442 	}
443 	TRACER_LOCK ();
444 	if ( tracer_bmp.hmdc != NULL )
445 		DeleteDC ( tracer_bmp.hmdc );
446 	if ( tracer_bmp.hbmp != NULL )
447 		DeleteObject ( (HGDIOBJ) tracer_bmp.hbmp );
448 	tracer_bmp.hbmp = CreateCompatibleBitmap ( hdc, TRACER_CANVAS_SIZE_X, TRACER_CANVAS_SIZE_Y );
449 	tracer_bmp.hmdc = CreateCompatibleDC ( hdc );
450 	SelectObject ( tracer_bmp.hmdc, w32g_tracer_wnd.hNullBrush ); /* �K�v�Ȃ���������Ȃ��� */
451 	SelectObject ( tracer_bmp.hmdc, w32g_tracer_wnd.hNullPen ); /* �K�v�Ȃ���������Ȃ��� */
452 	SelectObject ( tracer_bmp.hmdc, tracer_bmp.hbmp );
453 
454 	hbmp = LoadBitmap ( hInst, MAKEINTRESOURCE(IDB_BITMAP_TRACER) );
455 	hmdc = CreateCompatibleDC ( hdc );
456 	SelectObject ( hmdc, hbmp );
457 	BitBlt ( tracer_bmp.hmdc, 0, 0, TRACER_CANVAS_SIZE_X, TRACER_CANVAS_SIZE_Y, hmdc, 0, 0, WHITENESS );
458 	BitBlt ( tracer_bmp.hmdc, 0, 0, TRACER_BMP_SIZE_X, TRACER_BMP_SIZE_Y, hmdc, 0, 0, SRCCOPY );
459 	DeleteDC(hmdc);
460 	DeleteObject(hbmp);
461 
462 	TRACER_UNLOCK ();
463 
464 	SetRect ( &tracer_bmp.rc_volume, 8, 16, 28, 195 );
465 	SetRect ( &tracer_bmp.rc_expression, 32, 16, 52, 195 );
466 	SetRect ( &tracer_bmp.rc_pan, 56, 16, 76, 195 );
467 	SetRect ( &tracer_bmp.rc_sustain, 80, 16, 100, 195 );
468 	SetRect ( &tracer_bmp.rc_pitch_bend, 104, 16, 124, 195 );
469 	SetRect ( &tracer_bmp.rc_mod_wheel, 128, 16, 148, 195 );
470 	SetRect ( &tracer_bmp.rc_chorus_effect, 152, 16, 172, 195 );
471 	SetRect ( &tracer_bmp.rc_reverb_effect, 176, 16, 196, 195 );
472 	SetRect ( &tracer_bmp.rc_velocity[0], 200, 16, 230, 215 );
473 	SetRect ( &tracer_bmp.rc_velocity[1], 231, 16, 261, 215 );
474 	SetRect ( &tracer_bmp.rc_notes, 16, 59, 58, 78 );
475 	SetRect ( &tracer_bmp.rc_notes_sustain, 202, 59, 244, 78 );
476 	SetRect ( &tracer_bmp.rc_notes_on, 156, 59, 198, 78 );
477 	for(i=0;i<6;i++) {
478 		SetRect ( &tracer_bmp.rc_notes_mask[i], 16 + i * 46, 107, 58 + i * 46, 126);
479 		SetRect ( &tracer_bmp.rc_note[i], 16 + i * 46, 271, 58 + i * 46, 290);
480 		SetRect ( &tracer_bmp.rc_note_on[i], 16 + i * 46, 319, 58 + i * 46, 338);
481 		SetRect ( &tracer_bmp.rc_note_sustain[i], 16 + i * 46, 367, 58 + i * 46, 386);
482 	}
483 	for(i=0;i<6;i++) {
484 		SetRect ( &tracer_bmp.rc_notes_mask[i + 6], 16 + i * 46, 131, 58 + i * 46, 150);
485 		SetRect ( &tracer_bmp.rc_note[i + 6], 16 + i * 46, 295, 58 + i * 46, 314);
486 		SetRect ( &tracer_bmp.rc_note_on[i + 6], 16 + i * 46, 343, 58 + i * 46, 362);
487 		SetRect ( &tracer_bmp.rc_note_sustain[i + 6], 16 + i * 46, 391, 58 + i * 46, 410);
488 	}
489 	notes_view_generate(TRUE);
490 	SetRect ( &tracer_bmp.rc_gm_on, 64, 59, 88, 78 );
491 	SetRect ( &tracer_bmp.rc_gm_off, 64, 83, 88, 102 );
492 	SetRect ( &tracer_bmp.rc_gs_on, 96, 59, 120, 78 );
493 	SetRect ( &tracer_bmp.rc_gs_off, 96, 83, 120, 102 );
494 	SetRect ( &tracer_bmp.rc_xg_on, 128, 59, 152, 78 );
495 	SetRect ( &tracer_bmp.rc_xg_off, 128, 83, 152, 102 );
496 	for (i = 0; i < 4; i++)
497 		for (j = 0; j < 8; j++)
498 			SetRect(&tracer_bmp.rc_temper_keysig[i * 8 + j],
499 					16 + j * 37, 155 + i * 23, 49 + j * 37, 174 + i * 23);
500 	for (i = 0; i < 8; i++)
501 		SetRect(&tracer_bmp.rc_temper_type[i],
502 				16 + i * 23, 247, 35 + i * 23, 266);
503 
504 	return 0;
505 }
506 
TracerWndReset(void)507 void TracerWndReset(void)
508 {
509 	int i, j;
510 	strcpy ( w32g_tracer_wnd.titlename, "" );
511 	strcpy ( w32g_tracer_wnd.filename, "" );
512 #if 0
513 	sprintf ( w32g_tracer_wnd.current_time, "00:00:00" );
514 	w32g_tracer_wnd.current_time_sec = 0;
515 	w32g_tracer_wnd.tempo = 0;
516 	w32g_tracer_wnd.master_volume = 0;
517 	w32g_tracer_wnd.maxvoices = 0;
518 #endif
519 	for ( i = 0; i < TRACER_CHANNELS; i ++ ) {
520 		strcpy ( w32g_tracer_wnd.instrument[i],"  ----" );
521 		w32g_tracer_wnd.mapID[i] = INST_NO_MAP;
522 		w32g_tracer_wnd.bank[i] = 0;
523 		w32g_tracer_wnd.program[i] = 0;
524 		w32g_tracer_wnd.velocity[i] = 0;
525 		w32g_tracer_wnd.volume[i] = 0;
526 		w32g_tracer_wnd.expression[i] = 0;
527 		w32g_tracer_wnd.panning[i] = 64;
528 		w32g_tracer_wnd.sustain[i] = 0;
529 		w32g_tracer_wnd.pitch_bend[i] = 0x2000;
530 		w32g_tracer_wnd.mod_wheel[i] = 0;
531 		w32g_tracer_wnd.chorus_effect[i] = 0;
532 		w32g_tracer_wnd.reverb_effect[i] = 0;
533 		w32g_tracer_wnd.tt[i] = 0;
534 		for ( j = 0; j < 256; j ++ ) {
535 			w32g_tracer_wnd.notes[i][j] = -1;
536 		}
537 	}
538 	w32g_tracer_wnd.play_system_mode = play_system_mode;
539 	w32g_tracer_wnd.quietchannels = quietchannels;
540 	w32g_tracer_wnd.channel_mute = channel_mute;
541 
542 	InvalidateRect(w32g_tracer_wnd.hwnd,NULL, FALSE);
543 }
544 
TracerWndReset2(void)545 void TracerWndReset2(void)
546 {
547 	int i, j;
548 	for ( i = 0; i < TRACER_CHANNELS; i ++ ) {
549 		w32g_tracer_wnd.velocity[i] = 0;
550 		for ( j = 0; j < 128; j ++ ) {
551 			w32g_tracer_wnd.notes[i][j] = -1;
552 		}
553 	}
554 	TRACER_LOCK();
555 	for ( i = 0; i < TRACER_CHANNELS; i ++ ) {
556 		for ( j = 0; j < 128; j ++ ) {
557 			RECT rc;
558 			if ( get_ch_rc ( i, &rc, &w32g_tracer_wnd.rc_notes ) == 0 )
559 				notes_view_draw ( &rc, j, w32g_tracer_wnd.notes[i][j], TRUE, FALSE );
560 		}
561 	}
562 	TRACER_UNLOCK();
563 }
564 
565 
566 // ��ʏ���
TracerWndClear(int lockflag)567 void TracerWndClear(int lockflag)
568 {
569 	HPEN hPen;
570 	HBRUSH hBrush;
571 	HGDIOBJ hgdiobj_hpen, hgdiobj_hbrush;
572 	RECT rc;
573 
574 	if ( lockflag ) TRACER_LOCK();
575 	hPen = CreatePen(PS_SOLID,1,C_BACK);
576 	hBrush = CreateSolidBrush(C_BACK);
577 	hgdiobj_hpen = SelectObject(w32g_tracer_wnd.hmdc, hPen);
578 	hgdiobj_hbrush = SelectObject(w32g_tracer_wnd.hmdc, hBrush);
579 	GetClientRect(w32g_tracer_wnd.hwnd,&rc);
580 	Rectangle(w32g_tracer_wnd.hmdc,rc.left,rc.top,rc.right,rc.bottom);
581 	InvalidateRect( w32g_tracer_wnd.hwnd, NULL, FALSE );
582 	SelectObject(w32g_tracer_wnd.hmdc, hgdiobj_hpen);
583 	DeleteObject(hPen);
584 	SelectObject(w32g_tracer_wnd.hmdc, hgdiobj_hbrush);
585 	DeleteObject(hBrush);
586 	if ( lockflag ) TRACER_UNLOCK();
587 
588 }
589 
590 #define TRACER_VOICE_OFF -1
591 #define TRACER_VOICE_SUSTAINED -2
592 
w32_tracer_ctl_event(CtlEvent * e)593 void w32_tracer_ctl_event(CtlEvent *e)
594 {
595 	RECT rc;
596 	int v1, v2;
597     switch ( e->type ) {
598 	case CTLE_NOW_LOADING:
599 	{
600 		char * title;
601 		TracerWndReset ();
602 		TracerWndPaintAll (TRUE);
603 		strncpy ( w32g_tracer_wnd.filename, (char *)e->v1, 1000 );
604 		w32g_tracer_wnd.filename[1000] = '\0';
605 		title = get_midi_title(w32g_tracer_wnd.filename);
606 		if ( title == NULL ) title = w32g_tracer_wnd.filename;
607 		strcpy ( w32g_tracer_wnd.titlename, "  " );
608 		strncat ( w32g_tracer_wnd.titlename, title, 1000 );
609 		w32g_tracer_wnd.titlename[1000] = '\0';
610 		get_head_rc ( &rc, &w32g_tracer_wnd.rc_head_rest );
611 		cheap_string_view_draw ( &rc, w32g_tracer_wnd.titlename, C_TEXT_FORE, C_TEXT_BACK, CSV_LEFT, TRUE );
612 	}
613 		break;
614 	case CTLE_LOADING_DONE:
615 		break;
616 	case CTLE_PLAY_START:
617 #if 0
618 		{
619 		int i;
620 		for ( i = 0; i < TRACER_CHANNELS; i++ ) {
621 //			tracer_ch_program_draw ( i, -1, -1, (char *)-1, -1 );
622 			w32g_tracer_wnd.volume[i] = channel[i].volume;
623 			w32g_tracer_wnd.expression[i] = channel[i].expression;
624 			w32g_tracer_wnd.panning[i] = channel[i].panning;
625 			w32g_tracer_wnd.sustain[i] = channel[i].sustain;
626 			w32g_tracer_wnd.pitch_bend[i] = channel[i].pitchbend;
627 			w32g_tracer_wnd.mod_wheel[i] = channel[i].mod.val;
628 			w32g_tracer_wnd.chorus_effect[i] = channel[i].chorus_level;
629 			w32g_tracer_wnd.reverb_effect[i] = channel[i].reverb_level;
630 		}
631 #endif
632 		break;
633 	case CTLE_PLAY_END:
634 		break;
635 	case CTLE_CUEPOINT:
636 		break;
637 	case CTLE_TEMPO:
638 #if 0
639 		{
640 		char buff[64];
641 		w32g_tracer_wnd.tempo = (int)e->v1;
642 		sprintf ( buff, "%08ld", w32g_tracer_wnd.current_time);
643 		cheap_string_view_draw ( &w32g_tracer_wnd.rc_tempo, buff, C_TEXT_FORE, C_TEXT_BACK, CSV_CENTER, TRUE );
644 		}
645 #endif
646 		break;
647 	case CTLE_METRONOME:
648 		break;
649 	case CTLE_CURRENT_TIME:
650 #if 0
651 		{
652 		int sec, min, hour;
653 		if(midi_trace.flush_flag)
654 			return;
655 		if(ctl->trace_playing)
656 			sec = (int)e->v1;
657 		else {
658 			sec = current_trace_samples();
659 			if(sec < 0)
660 				sec = (int)e->v1;
661 			else
662 				sec = sec / play_mode->rate;
663 		}
664 		min = sec / 60; sec %= 60;
665 		hour = min / 60; min %= 60;
666 		sprintf ( w32g_tracer_wnd.current_time, "%02d:%02d:%02d", hour, min, sec );
667 		w32g_tracer_wnd.current_time_sec = sec;
668 		cheap_string_view_draw ( &w32g_tracer_wnd.rc_current_time, w32g_tracer_wnd.current_time, C_TEXT_FORE, C_TEXT_BACK, CSV_CENTER, TRUE );
669 		cheap_volume_view_draw ( &w32g_tracer_wnd.rc_maxvoices, (int)e->v2, voices, C_BAR_FORE, C_BAR_BACK, CVV_TYPE_LEFT, TRUE );
670 	}
671 #endif
672 		break;
673 	case CTLE_NOTE:
674 		{
675 		int vel = 0, vel_old = w32g_tracer_wnd.velocity[(int)e->v2];
676 		switch ( (int)e->v1 ) {
677 		case VOICE_ON:
678 			w32g_tracer_wnd.velocity[(int)e->v2] += (int)e->v4;
679 			break;
680 		case VOICE_SUSTAINED:
681 			vel = TRACER_VOICE_SUSTAINED;
682 			break;
683 		case VOICE_DIE:
684 		case VOICE_FREE:
685 		case VOICE_OFF:
686 			w32g_tracer_wnd.velocity[(int)e->v2] -= (int)e->v4;
687 			vel = TRACER_VOICE_OFF;
688 			break;
689 		}
690 		if ( w32g_tracer_wnd.velocity[(int)e->v2]  < 0 )
691 			w32g_tracer_wnd.velocity[(int)e->v2]  = 0;
692 		if ( get_ch_rc ( (int)e->v2, &rc, &w32g_tracer_wnd.rc_notes ) == 0 )
693 			notes_view_draw ( &rc, (int)e->v3, vel, FALSE, TRUE );
694 		w32g_tracer_wnd.notes[(int)e->v2][(int)e->v3] = vel;
695 
696 		if ( get_ch_rc ( (int)e->v2, &rc, &w32g_tracer_wnd.rc_velocity ) == 0 )
697 			tracer_velocity_draw_ex ( &rc, w32g_tracer_wnd.velocity[(int)e->v2], vel_old, VEL_MAX, TRUE );
698 		}
699 		break;
700 	case CTLE_MASTER_VOLUME:
701 //		ctl_master_volume((int)e->v1);
702 #if 0
703 		w32g_tracer_wnd.master_volume = (int)e->v1;
704 		cheap_volume_view_draw ( &w32g_tracer_wnd.rc_master_volume, w32g_tracer_wnd.master_volume, 256, C_BAR_FORE, C_BAR_BACK, CVV_TYPE_LEFT, TRUE );
705 #endif
706 		break;
707 	case CTLE_MUTE:
708 		tracer_ch_number_draw((int) e->v1, (int) e->v2, TRUE);
709 		break;
710 	case CTLE_PROGRAM:
711 		v1 = (int)e->v1; v2 = (int)e->v2;
712 		tracer_ch_program_draw ( v1, -1, v2, (char *)e->v3, -1, TRUE );
713 		break;
714 	case CTLE_DRUMPART:
715 		break;
716 	case CTLE_VOLUME:
717 		v1 = (int)e->v1; v2 = (int)e->v2;
718 		if ( w32g_tracer_wnd.volume[v1] != v2 )
719 			if ( get_ch_rc ( v1, &rc, &w32g_tracer_wnd.rc_volume ) == 0 )
720 				tracer_volume_draw ( &rc, v2, 128, TRUE );
721 		w32g_tracer_wnd.volume[v1] = v2;
722 		break;
723 	case CTLE_EXPRESSION:
724 		v1 = (int)e->v1; v2 = (int)e->v2;
725 		if ( w32g_tracer_wnd.expression[v1] != v2 )
726 			if ( get_ch_rc ( v1, &rc, &w32g_tracer_wnd.rc_expression ) == 0 )
727 				tracer_expression_draw ( &rc, v2, 128, TRUE );
728 		w32g_tracer_wnd.expression[v1] = v2;
729 		break;
730 	case CTLE_PANNING:
731 		v1 = (int)e->v1; v2 = (int)e->v2;
732 		if ( w32g_tracer_wnd.panning[v1] != v2 )
733 			if ( get_ch_rc ( v1, &rc, &w32g_tracer_wnd.rc_panning ) == 0 )
734 				tracer_pan_draw ( &rc, v2, 128, TRUE );
735 		w32g_tracer_wnd.panning[v1] = v2;
736 		break;
737 	case CTLE_SUSTAIN:
738 		v1 = (int)e->v1; v2 = (int)e->v2;
739 		if ( w32g_tracer_wnd.sustain[v1] != v2 )
740 			if ( get_ch_rc ( v1, &rc, &w32g_tracer_wnd.rc_sustain ) == 0 )
741 				tracer_sustain_draw ( &rc, v2, TRUE );
742 		w32g_tracer_wnd.sustain[v1] = v2;
743 		break;
744 	case CTLE_PITCH_BEND:
745 		v1 = (int)e->v1; v2 = (int)e->v2;
746 		if ( w32g_tracer_wnd.pitch_bend[v1] != v2 )
747 			if ( get_ch_rc ( v1, &rc, &w32g_tracer_wnd.rc_pitch_bend ) == 0 )
748 				tracer_pitch_bend_draw ( &rc, v2, 0x4000, TRUE );
749 		w32g_tracer_wnd.pitch_bend[v1] = v2;
750 		break;
751 	case CTLE_MOD_WHEEL:
752 		v1 = (int)e->v1; v2 = (int)e->v2;
753 		if ( w32g_tracer_wnd.mod_wheel[v1] != v2 )
754 			if ( get_ch_rc ( v1, &rc, &w32g_tracer_wnd.rc_mod_wheel ) == 0 )
755 				tracer_mod_wheel_draw ( &rc, v2, 32, TRUE );
756 		w32g_tracer_wnd.mod_wheel[v1] = v2;
757 		break;
758 	case CTLE_CHORUS_EFFECT:
759 		v1 = (int)e->v1; v2 = (int)e->v2;
760 		if ( w32g_tracer_wnd.chorus_effect[v1] != v2 )
761 			if ( get_ch_rc ( v1, &rc, &w32g_tracer_wnd.rc_chorus_effect ) == 0 )
762 				tracer_chorus_effect_draw ( &rc, v2, 128, TRUE );
763 		w32g_tracer_wnd.chorus_effect[v1] = v2;
764 		break;
765 	case CTLE_REVERB_EFFECT:
766 		v1 = (int)e->v1; v2 = (int)e->v2;
767 		if ( w32g_tracer_wnd.reverb_effect[v1] != v2 )
768 			if ( get_ch_rc ( v1, &rc, &w32g_tracer_wnd.rc_reverb_effect ) == 0 )
769 				tracer_reverb_effect_draw ( &rc, v2, 128, TRUE );
770 		w32g_tracer_wnd.reverb_effect[v1] = v2;
771 		break;
772 	case CTLE_KEY_OFFSET:
773 		get_head_rc(&rc, &w32g_tracer_wnd.rc_temper_keysig);
774 		tracer_temper_keysig_draw(&rc, CTL_STATUS_UPDATE, (int) e->v1, TRUE);
775 		break;
776 	case CTLE_TEMPER_KEYSIG:
777 		get_head_rc(&rc, &w32g_tracer_wnd.rc_temper_keysig);
778 		tracer_temper_keysig_draw(&rc, (int8) e->v1, CTL_STATUS_UPDATE, TRUE);
779 		break;
780 	case CTLE_TEMPER_TYPE:
781 		if (! get_ch_rc((int) e->v1, &rc, &w32g_tracer_wnd.rc_temper_type))
782 			tracer_temper_type_draw(&rc, (int) e->v1, (int8) e->v2, TRUE);
783 		break;
784 	case CTLE_LYRIC:
785 		break;
786 	case CTLE_REFRESH:
787 		break;
788 	case CTLE_RESET:
789 		TracerWndReset2();
790 #if 0
791 		if ( w32g_tracer_wnd.play_system_mode != play_system_mode ) {
792 #endif
793 			get_head_rc ( &rc, &w32g_tracer_wnd.rc_gm );
794 			tracer_gm_draw ( &rc, play_system_mode == GM_SYSTEM_MODE ? 1 : 0, TRUE );
795 			get_head_rc ( &rc, &w32g_tracer_wnd.rc_gs );
796 			tracer_gs_draw ( &rc, play_system_mode == GS_SYSTEM_MODE ? 1 : 0, TRUE );
797 			get_head_rc ( &rc, &w32g_tracer_wnd.rc_xg );
798 			tracer_xg_draw ( &rc, play_system_mode == XG_SYSTEM_MODE ? 1 : 0, TRUE );
799 #if 0
800 		}
801 #endif
802 		w32g_tracer_wnd.play_system_mode = play_system_mode;
803 		break;
804 	case CTLE_SPEANA:
805 		break;
806 	case CTLE_PAUSE:
807 		break;
808 	case CTLE_MAXVOICES:
809 #if 0
810 		w32g_tracer_wnd.maxvoices = (int)e->v1;
811 #endif
812 		break;
813 	case CTLE_GSLCD:
814 		break;
815     }
816 }
817 
818 static int get_head_rc ( RECT *rc, RECT *rc_base )
819 {
820 	rc->top = w32g_tracer_wnd.rc_head.top + rc_base->top;
821 	rc->bottom = w32g_tracer_wnd.rc_head.top + rc_base->bottom;
822 	rc->left = w32g_tracer_wnd.rc_head.left + rc_base->left;
823 	rc->right = w32g_tracer_wnd.rc_head.left + rc_base->right;
824 	return 0;
825 }
826 
827 static int get_ch_rc ( int ch, RECT *rc, RECT *rc_base )
828 {
829 	switch (TracerWndInfo.mode) {
830 	default:
831 	case TWI_MODE_1_32CH:
832 		break;
833 	case TWI_MODE_1_16CH:
834 		if ( ch >= 16 )
835 			return -1;
836 		break;
837 	case TWI_MODE_17_32CH:
838 		if ( ch < 16 )
839 			return -1;
840 		ch = ch - 16;
841 		break;
842 	}
843 	rc->top = w32g_tracer_wnd.rc_all_channels.top +
844 		rc_base->top + ( w32g_tracer_wnd.ch_height + w32g_tracer_wnd.ch_space ) * ( ch - 0 );
845 	rc->bottom = w32g_tracer_wnd.rc_all_channels.top +
846 		rc_base->bottom + ( w32g_tracer_wnd.ch_height + w32g_tracer_wnd.ch_space ) * ( ch - 0 );
847 	rc->left = w32g_tracer_wnd.rc_all_channels.left + rc_base->left;
848 	rc->right = w32g_tracer_wnd.rc_all_channels.left + rc_base->right;
849 	return 0;
850 }
851 
852 static int notes_view_draw ( RECT *lprc, int note, int vel, int back_draw, int lockflag )
853 {
854 	HDC hdc = w32g_tracer_wnd.hmdc;
855 	RECT rc1;
856 	int note1, left, top;
857 
858 	if (!w32g_tracer_wnd.active)
859 		return 0;
860 	note1 = note / 12;
861 	left = rc1.left = lprc->left + 6 * 7 * note1 + 0;
862 	top = rc1.top = lprc->top + 0;
863 	rc1.right = lprc->left + 6 * 7 * (note1 + 1) - 0;
864 	rc1.bottom = lprc->top + 19 + 1;
865 
866 	if ( back_draw ) {
867   	if ( lockflag ) TRACER_LOCK ();
868 		BitBlt ( hdc, rc1.left, rc1.top, rc1.right - rc1.left, rc1.bottom - rc1.top,
869 			tracer_bmp.hmdc, tracer_bmp.rc_notes.left, tracer_bmp.rc_notes.top, SRCCOPY );
870 		if ( lockflag ) TRACER_UNLOCK ();
871 		InvalidateRect ( w32g_tracer_wnd.hwnd, &rc1, FALSE );
872 	}
873 
874 	note = note % 12;
875 
876 	switch(note) {
877 		// white keys
878 		case 0: left = 0;
879 			rc1.right = rc1.left + 7;
880 			break;
881 		case 2: rc1.left += left = 6;
882 			rc1.right = rc1.left + 7;
883 			break;
884 		case 4: rc1.left += left = 12;
885 			rc1.right = rc1.left + 7;
886 			break;
887 		case 5: rc1.left += left = 18;
888 			rc1.right = rc1.left + 7;
889 			break;
890 		case 7: rc1.left += left = 24;
891 			rc1.right = rc1.left + 7;
892 			break;
893 		case 9: rc1.left += left = 30;
894 			rc1.right = rc1.left + 7;
895 			break;
896 		case 11: rc1.left += left = 36;
897 			rc1.right = rc1.left + 6;
898 			break;
899 		// black keys
900 		case 1: rc1.left += left = 4;
901 			rc1.right = rc1.left + 5;
902 			break;
903 		case 3: rc1.left += left = 10;
904 			rc1.right = rc1.left + 5;
905 			break;
906 		case 6: rc1.left += left = 22;
907 			rc1.right = rc1.left + 5;
908 			break;
909 		case 8: rc1.left += left = 28;
910 			rc1.right = rc1.left + 5;
911 			break;
912 		case 10: rc1.left += left = 34;
913 			rc1.right = rc1.left + 5;
914 			break;
915 		default: break;
916 	}
917 
918 	if ( lockflag ) TRACER_LOCK ();
919 	if ( vel >= 0 ) {
920 		BitBlt ( hdc, rc1.left, rc1.top, rc1.right - rc1.left, rc1.bottom - rc1.top,
921 			tracer_bmp.hmdc, tracer_bmp.rc_notes_mask[note].left + left, tracer_bmp.rc_notes_mask[note].top, SRCPAINT );
922 		BitBlt ( hdc, rc1.left, rc1.top, rc1.right - rc1.left, rc1.bottom - rc1.top,
923 			tracer_bmp.hmdc, tracer_bmp.rc_note_on[note].left + left, tracer_bmp.rc_note_on[note].top, SRCAND );
924 	} else if ( vel  == TRACER_VOICE_SUSTAINED ) {
925 		BitBlt ( hdc, rc1.left, rc1.top, rc1.right - rc1.left, rc1.bottom - rc1.top,
926 			tracer_bmp.hmdc, tracer_bmp.rc_notes_mask[note].left + left, tracer_bmp.rc_notes_mask[note].top, SRCPAINT );
927 		BitBlt ( hdc, rc1.left, rc1.top, rc1.right - rc1.left, rc1.bottom - rc1.top,
928 			tracer_bmp.hmdc, tracer_bmp.rc_note_sustain[note].left + left, tracer_bmp.rc_note_sustain[note].top, SRCAND );
929 	} else {
930 		BitBlt ( hdc, rc1.left, rc1.top, rc1.right - rc1.left, rc1.bottom - rc1.top,
931 			tracer_bmp.hmdc, tracer_bmp.rc_notes_mask[note].left + left, tracer_bmp.rc_notes_mask[note].top, SRCPAINT );
932 		BitBlt ( hdc, rc1.left, rc1.top, rc1.right - rc1.left, rc1.bottom - rc1.top,
933 			tracer_bmp.hmdc, tracer_bmp.rc_note[note].left + left, tracer_bmp.rc_note[note].top, SRCAND );
934 
935 	}
936 	if ( lockflag ) TRACER_UNLOCK ();
937 
938 	InvalidateRect ( w32g_tracer_wnd.hwnd, &rc1, FALSE );
939 
940 	return 0;
941 }
942 
943 static int tracer_ch_number_draw(int ch, int mute, int lockflag)
944 {
945 	RECT rc;
946 	char buff[3];
947 
948 	if (mute != CTL_STATUS_UPDATE) {
949 		if (((IS_SET_CHANNELMASK(
950 				w32g_tracer_wnd.channel_mute, ch)) ? 1 : 0) == mute)
951 			return 0;
952 		if (mute)
953 			SET_CHANNELMASK(w32g_tracer_wnd.channel_mute, ch);
954 		else
955 			UNSET_CHANNELMASK(w32g_tracer_wnd.channel_mute, ch);
956 	} else
957 		mute = (IS_SET_CHANNELMASK(
958 				w32g_tracer_wnd.channel_mute, ch)) ? 1 : 0;
959 	if (IS_SET_CHANNELMASK(w32g_tracer_wnd.quietchannels, ch))
960 		return 0;
961 	if (get_ch_rc(ch, &rc, &w32g_tracer_wnd.rc_channel_top) == 0) {
962 		sprintf(buff, "%02d", ch + 1);
963 		cheap_string_view_draw(&rc, buff, C_TEXT_FORE,
964 				(mute) ? C_TEXT_BACK_DARK : C_TEXT_BACK,
965 				CSV_CENTER, lockflag);
966 	}
967 	return 0;
968 }
969 
970 static int tracer_ch_program_draw ( int ch, int bank, int program, char *instrument, int mapID, int lockflag )
971 {
972 	RECT rc;
973 	char buff[64];
974 	char *p_buff;
975 	if ( bank >= 0 ) {
976 		w32g_tracer_wnd.bank[ch] = bank;
977 	} else {
978 		if ( ISDRUMCHANNEL(ch) )
979 			bank = w32g_tracer_wnd.bank[ch] = 128;
980 		else
981 			bank = w32g_tracer_wnd.bank[ch] = channel[ch].bank;
982 	}
983 	if ( bank == 128 ) {
984 		if ( get_ch_rc ( ch, &rc, &w32g_tracer_wnd.rc_bank ) == 0 ) {
985 			sprintf ( buff, "drum");
986 			cheap_string_view_draw ( &rc, buff, C_TEXT_FORE, C_TEXT_BACK, CSV_CENTER, lockflag );
987 		}
988 	} else {
989 		if ( get_ch_rc ( ch, &rc, &w32g_tracer_wnd.rc_bank ) == 0 ) {
990 			sprintf ( buff, "%03d", bank );
991 			cheap_string_view_draw ( &rc, buff, C_TEXT_FORE, C_TEXT_BACK, CSV_CENTER, lockflag );
992 		}
993 	}
994 	if ( program >= 0 ) {
995 		w32g_tracer_wnd.program[ch] = program;
996 	} else {
997 		program = w32g_tracer_wnd.program[ch] = channel[ch].program;
998 	}
999 	if ( get_ch_rc ( ch, &rc, &w32g_tracer_wnd.rc_program ) == 0 ) {
1000 		sprintf ( buff, "%03d", program );
1001 		cheap_string_view_draw ( &rc, buff, C_TEXT_FORE, C_TEXT_BACK, CSV_CENTER, lockflag );
1002 	}
1003 
1004 	if ( instrument == NULL ) {instrument = " ----";}
1005 	strncpy ( w32g_tracer_wnd.instrument[ch], (char *)instrument, 250 );
1006 	w32g_tracer_wnd.instrument[ch][250] = '\0';
1007 	if ( w32g_tracer_wnd.instrument[ch][0] != ' ' ) {
1008 		char buff[255];
1009 		strncpy ( buff, w32g_tracer_wnd.instrument[ch], 250 );
1010 		buff[250] = '\0';
1011 		w32g_tracer_wnd.instrument[ch][0] = ' ';
1012 		w32g_tracer_wnd.instrument[ch][1] = '\0';
1013 		strcat ( w32g_tracer_wnd.instrument[ch], buff );
1014 	}
1015 	if ( get_ch_rc ( ch, &rc, &w32g_tracer_wnd.rc_instrument ) == 0 )
1016 		cheap_string_view_draw ( &rc, w32g_tracer_wnd.instrument[ch], C_TEXT_FORE, C_TEXT_BACK, CSV_LEFT, lockflag );
1017 
1018 	if ( mapID >= 0 ) {
1019 		w32g_tracer_wnd.mapID[ch] = mapID;
1020 	} else {
1021 		mapID = w32g_tracer_wnd.mapID[ch] = channel[ch].mapID;
1022 	}
1023 	switch ( mapID ) {
1024 	default:
1025     case INST_NO_MAP:
1026     case NUM_INST_MAP:
1027 		p_buff = "----";
1028 		break;
1029     case SC_55_TONE_MAP:
1030 		p_buff = "55 T";
1031 		break;
1032     case SC_55_DRUM_MAP:
1033 		p_buff = "55 D";
1034 		break;
1035     case SC_88_TONE_MAP:
1036 		p_buff = "88 T";
1037 		break;
1038     case SC_88_DRUM_MAP:
1039 		p_buff = "88 D";
1040 		break;
1041     case SC_88PRO_TONE_MAP:
1042 		p_buff = "88Pro T";
1043 		break;
1044     case SC_88PRO_DRUM_MAP:
1045 		p_buff = "88Pro D";
1046 		break;
1047     case SC_8850_TONE_MAP:
1048 		p_buff = "8850 T";
1049 		break;
1050     case SC_8850_DRUM_MAP:
1051 		p_buff = "8850 D";
1052 		break;
1053     case XG_NORMAL_MAP:
1054 		p_buff = "XG";
1055 		break;
1056     case XG_SFX64_MAP:
1057 		p_buff = "XG SFX64";
1058 		break;
1059     case XG_SFX126_MAP:
1060 		p_buff = "XG SFX126";
1061 		break;
1062     case XG_DRUM_MAP:
1063 		p_buff = "XG D";
1064 		break;
1065     case GM2_TONE_MAP:
1066 		p_buff = "GM2 T";
1067 		break;
1068     case GM2_DRUM_MAP:
1069 		p_buff = "GM2 D";
1070 	}
1071 	if ( get_ch_rc ( ch, &rc, &w32g_tracer_wnd.rc_inst_map ) == 0 )
1072 		cheap_string_view_draw ( &rc, p_buff, C_TEXT_FORE, C_TEXT_BACK, CSV_CENTER, lockflag );
1073 
1074 	return 0;
1075 }
1076 
1077 static int effect_view_border_draw ( RECT *lprc, int lockflag)
1078 {
1079 	HDC hdc;
1080 	COLORREF base = RGB(128, 128, 128);
1081 	HPEN hPen1 = NULL;
1082 	HPEN hPen3 = NULL;
1083 	HPEN hOldPen = NULL;
1084 
1085 	if ( !w32g_tracer_wnd.active )
1086 		return 0;
1087 	hdc = w32g_tracer_wnd.hmdc;
1088 
1089 	hPen1 = CreatePen(PS_SOLID, 1, base);
1090 	hPen3 = CreatePen(PS_SOLID, 1, base);
1091 	if ( lockflag ) TRACER_LOCK ();
1092 	hOldPen= (HPEN)SelectObject(hdc,GetStockObject(NULL_PEN));
1093 
1094 	// �E��
1095 	SelectObject(hdc, hPen3);
1096 	MoveToEx(hdc, lprc->right, lprc->top - 1, NULL);
1097 	LineTo(hdc, lprc->right, lprc->bottom + 1);
1098 
1099 	// ����
1100 	SelectObject(hdc, hPen1);
1101 	MoveToEx(hdc, lprc->left - 1, lprc->bottom, NULL);
1102 	LineTo(hdc, lprc->right + 1, lprc->bottom);
1103 
1104 	SelectObject(hdc, hOldPen);
1105 
1106 	if ( lockflag ) TRACER_UNLOCK ();
1107 
1108 	DeleteObject (hPen1);
1109 	DeleteObject (hPen3);
1110 
1111 	return 0;
1112 }
1113 
1114 static int tracer_velocity_draw ( RECT *lprc, int vol, int max, int lockflag )
1115 {
1116 	return tracer_velocity_draw_ex ( lprc, vol, -1, max, lockflag );
1117 }
1118 
1119 static int tracer_velocity_draw_ex ( RECT *lprc, int vol, int vol_old, int max, int lockflag )
1120 {
1121 	HDC hdc;
1122 	const int view_max = 30, div = 17;
1123 	RECT rc;
1124 	if ( !w32g_tracer_wnd.active )
1125 		return 0;
1126 	hdc = w32g_tracer_wnd.hmdc;
1127 
1128 	vol /= div;
1129 	if ( vol_old < 0 ) vol_old = max;
1130 	vol_old /= div;
1131 	if(vol >= view_max) {vol = view_max;}
1132 	if(vol_old >= view_max) {vol_old = view_max;}
1133 
1134 	if ( lockflag ) TRACER_LOCK ();
1135 	// �K�v�Ȃ����x���V�e�B�o�[�̔w�i��`��
1136 //	BitBlt ( hdc, lprc->left +  vol, lprc->top, lprc->right - lprc->left -  vol, lprc->bottom - lprc->top,
1137 	BitBlt ( hdc, lprc->left +  vol, lprc->top, vol_old - vol, lprc->bottom - lprc->top,
1138 		tracer_bmp.hmdc, tracer_bmp.rc_velocity[0].left + vol, tracer_bmp.rc_velocity[0].top, SRCCOPY );
1139 
1140 	// �K�v�Ȃ����x���V�e�B�o�[��`��
1141 	BitBlt ( hdc, lprc->left, lprc->top, vol, lprc->bottom - lprc->top,
1142 		tracer_bmp.hmdc, tracer_bmp.rc_velocity[0].left, tracer_bmp.rc_velocity[0].top + 19 + 1, SRCCOPY );
1143 
1144 	SetRect ( &rc, lprc->left, lprc->top, lprc->left + (( vol_old > vol ) ? vol_old : vol), lprc->bottom);
1145 	effect_view_border_draw (lprc, lockflag);
1146 	InvalidateRect ( w32g_tracer_wnd.hwnd, &rc, FALSE );
1147 
1148 	if ( lockflag ) TRACER_UNLOCK ();
1149 	return 0;
1150 }
1151 
1152 static int tracer_volume_draw ( RECT *lprc, int vol, int max, int lockflag )
1153 {
1154 	HDC hdc;
1155  	const int view_max = 20, div = 7;
1156 	if ( !w32g_tracer_wnd.active )
1157 		return 0;
1158 	hdc = w32g_tracer_wnd.hmdc;
1159 
1160 	vol /= div;
1161 	if(vol >= view_max) {vol = view_max;}
1162 
1163 	if ( lockflag ) TRACER_LOCK ();
1164 	// �K�v�Ȃ����w�i��`��
1165 	BitBlt ( hdc, lprc->left +  vol, lprc->top, lprc->right - lprc->left -  vol, lprc->bottom - lprc->top,
1166 		tracer_bmp.hmdc, tracer_bmp.rc_volume.left, tracer_bmp.rc_volume.top, SRCCOPY );
1167 	// �K�v�Ȃ����`��
1168 	BitBlt ( hdc, lprc->left, lprc->top, vol, lprc->bottom - lprc->top,
1169 		tracer_bmp.hmdc, tracer_bmp.rc_volume.left, tracer_bmp.rc_volume.top + 9 + 1, SRCCOPY );
1170 	if ( lockflag ) TRACER_UNLOCK ();
1171 	effect_view_border_draw (lprc, lockflag);
1172 	InvalidateRect ( w32g_tracer_wnd.hwnd, lprc, FALSE );
1173 
1174 	return 0;
1175 }
1176 
1177 static int tracer_expression_draw ( RECT *lprc, int vol, int max, int lockflag )
1178 {
1179 	HDC hdc;
1180 	const int view_max = 20, div = 7;
1181 	if ( !w32g_tracer_wnd.active )
1182 		return 0;
1183 	hdc = w32g_tracer_wnd.hmdc;
1184 
1185 	vol /= div;
1186 	if(vol >= view_max) {vol = view_max;}
1187 
1188 	if ( lockflag ) TRACER_LOCK ();
1189 	// �K�v�Ȃ����w�i��`��
1190 	BitBlt ( hdc, lprc->left +  vol, lprc->top, lprc->right - lprc->left -  vol, lprc->bottom - lprc->top,
1191 		tracer_bmp.hmdc, tracer_bmp.rc_expression.left, tracer_bmp.rc_expression.top, SRCCOPY );
1192 	// �K�v�Ȃ����`��
1193 	BitBlt ( hdc, lprc->left, lprc->top, vol, lprc->bottom - lprc->top,
1194 		tracer_bmp.hmdc, tracer_bmp.rc_expression.left, tracer_bmp.rc_expression.top + 9 + 1, SRCCOPY );
1195 	if ( lockflag ) TRACER_UNLOCK ();
1196 	effect_view_border_draw (lprc, lockflag);
1197 	InvalidateRect ( w32g_tracer_wnd.hwnd, lprc, FALSE );
1198 
1199 	return 0;
1200 }
1201 
1202 static int tracer_pan_draw ( RECT *lprc, int vol, int max, int lockflag )
1203 {
1204 	HDC hdc;
1205 	const int view_max = 10, div = 7;
1206 	if ( !w32g_tracer_wnd.active )
1207 		return 0;
1208 	hdc = w32g_tracer_wnd.hmdc;
1209 
1210 	vol = (vol - 64) / div;
1211 	if(vol > view_max) {vol = view_max;}
1212 	else if(vol < -view_max) {vol = -view_max;}
1213 
1214 	if ( lockflag ) TRACER_LOCK ();
1215 	// �w�i��`��
1216 	BitBlt ( hdc, lprc->left, lprc->top, lprc->right - lprc->left, lprc->bottom - lprc->top,
1217 		tracer_bmp.hmdc, tracer_bmp.rc_pan.left, tracer_bmp.rc_pan.top, SRCCOPY );
1218 	// ���ȉ���2�‚̓]�������ł͖��ʂȕ������]�����Ă���̂ŁA���܂����ΏȂ���B
1219 	// �}�X�N��`��
1220 	BitBlt ( hdc, lprc->left + vol, lprc->top, lprc->right - lprc->left, lprc->bottom - lprc->top,
1221 		tracer_bmp.hmdc, tracer_bmp.rc_pan.left, tracer_bmp.rc_pan.top + (9 + 1) * 2, SRCPAINT );
1222 	// �‚܂݂�`��
1223 	BitBlt ( hdc, lprc->left + vol, lprc->top, lprc->right - lprc->left, lprc->bottom - lprc->top,
1224 		tracer_bmp.hmdc, tracer_bmp.rc_pan.left, tracer_bmp.rc_pan.top + 9 + 1, SRCAND );
1225 	if ( lockflag ) TRACER_UNLOCK ();
1226 	effect_view_border_draw (lprc, lockflag);
1227 	InvalidateRect ( w32g_tracer_wnd.hwnd, lprc, FALSE );
1228 
1229 	return 0;
1230 }
1231 
1232 static int tracer_sustain_draw ( RECT *lprc, int vol, int lockflag )
1233 {
1234 	HDC hdc;
1235 	const int view_max = 20, div = 6;
1236 	if ( !w32g_tracer_wnd.active )
1237 		return 0;
1238 	hdc = w32g_tracer_wnd.hmdc;
1239 
1240 	vol /= div;
1241 	if(vol >= view_max) {vol = view_max;}
1242 
1243 	if ( lockflag ) TRACER_LOCK ();
1244 	// �K�v�Ȃ����w�i��`��
1245 	BitBlt ( hdc, lprc->left +  vol, lprc->top, lprc->right - lprc->left -  vol, lprc->bottom - lprc->top,
1246 		tracer_bmp.hmdc, tracer_bmp.rc_sustain.left, tracer_bmp.rc_sustain.top, SRCCOPY );
1247 	// �K�v�Ȃ����`��
1248 	BitBlt ( hdc, lprc->left, lprc->top, vol, lprc->bottom - lprc->top,
1249 		tracer_bmp.hmdc, tracer_bmp.rc_sustain.left, tracer_bmp.rc_sustain.top + 9 + 1, SRCCOPY );
1250 	if ( lockflag ) TRACER_UNLOCK ();
1251 	effect_view_border_draw (lprc, lockflag);
1252 	InvalidateRect ( w32g_tracer_wnd.hwnd, lprc, FALSE );
1253 
1254 	return 0;
1255 /*
1256 	HDC hdc;
1257 	if ( !w32g_tracer_wnd.active )
1258 		return 0;
1259 	hdc = w32g_tracer_wnd.hmdc;
1260 	if ( vol <= 0 ) vol = 0;
1261 	if ( vol >= 1 ) vol = 1;
1262 	if ( lockflag ) TRACER_LOCK ();
1263 	BitBlt ( hdc, lprc->left, lprc->top, lprc->right - lprc->left, lprc->bottom - lprc->top,
1264 		tracer_bmp.hmdc, tracer_bmp.rc_sustain.left, tracer_bmp.rc_sustain.top + vol * ( 9 + 1 ), SRCCOPY );
1265 	if ( lockflag ) TRACER_UNLOCK ();
1266 
1267 	effect_view_border_draw (lprc, lockflag);
1268 	InvalidateRect ( w32g_tracer_wnd.hwnd, lprc, FALSE );
1269 	return 0;*/
1270 }
1271 
1272 static int tracer_pitch_bend_draw ( RECT *lprc, int vol, int max, int lockflag )
1273 {
1274 	HDC hdc;
1275 	const int view_max = 10;
1276 	if ( !w32g_tracer_wnd.active )
1277 		return 0;
1278 	hdc = w32g_tracer_wnd.hmdc;
1279 
1280 	vol = (vol - max / 2) * view_max * 2 / max;
1281 	if(vol > view_max) {vol = view_max;}
1282 	else if(vol < -view_max) {vol = -view_max;}
1283 
1284 	if ( lockflag ) TRACER_LOCK ();
1285 	// �w�i��`��
1286 	BitBlt ( hdc, lprc->left, lprc->top, lprc->right - lprc->left, lprc->bottom - lprc->top,
1287 		tracer_bmp.hmdc, tracer_bmp.rc_pitch_bend.left, tracer_bmp.rc_pitch_bend.top, SRCCOPY );
1288 	if(vol > 0) {	// �K�v�Ȃ����`��
1289 	BitBlt ( hdc, lprc->left + view_max, lprc->top, vol, lprc->bottom - lprc->top,
1290 		tracer_bmp.hmdc, tracer_bmp.rc_pitch_bend.left + view_max, tracer_bmp.rc_pitch_bend.top + 9 + 1, SRCCOPY );
1291 	} else if(vol < 0) {
1292 	BitBlt ( hdc, lprc->left + view_max + vol, lprc->top, -vol, lprc->bottom - lprc->top,
1293 		tracer_bmp.hmdc, tracer_bmp.rc_pitch_bend.left + view_max + vol, tracer_bmp.rc_pitch_bend.top + 9 + 1, SRCCOPY );
1294 	}
1295 	if ( lockflag ) TRACER_UNLOCK ();
1296 	effect_view_border_draw (lprc, lockflag);
1297 	InvalidateRect ( w32g_tracer_wnd.hwnd, lprc, FALSE );
1298 
1299 	return 0;
1300 }
1301 
1302 static int tracer_mod_wheel_draw ( RECT *lprc, int vol, int max, int lockflag )
1303 {
1304 	HDC hdc;
1305 	const int view_max = 20, div = 7;
1306 	if ( !w32g_tracer_wnd.active )
1307 		return 0;
1308 	hdc = w32g_tracer_wnd.hmdc;
1309 
1310 	vol /= div;
1311  	if(vol >= view_max) {vol = view_max;}
1312 
1313 	if ( lockflag ) TRACER_LOCK ();
1314 	// �K�v�Ȃ����w�i��`��
1315 	BitBlt ( hdc, lprc->left +  vol, lprc->top, lprc->right - lprc->left -  vol, lprc->bottom - lprc->top,
1316 		tracer_bmp.hmdc, tracer_bmp.rc_mod_wheel.left, tracer_bmp.rc_mod_wheel.top, SRCCOPY );
1317 	// �K�v�Ȃ����`��
1318 	BitBlt ( hdc, lprc->left, lprc->top, vol, lprc->bottom - lprc->top,
1319 		tracer_bmp.hmdc, tracer_bmp.rc_mod_wheel.left, tracer_bmp.rc_mod_wheel.top + 9 + 1, SRCCOPY );
1320 	if ( lockflag ) TRACER_UNLOCK ();
1321 	effect_view_border_draw (lprc, lockflag);
1322 	InvalidateRect ( w32g_tracer_wnd.hwnd, lprc, FALSE );
1323 
1324 	return 0;
1325 }
1326 
1327 static int tracer_chorus_effect_draw ( RECT *lprc, int vol, int max, int lockflag )
1328 {
1329 	HDC hdc;
1330 	const int view_max = 20, div = 7;
1331 	if ( !w32g_tracer_wnd.active )
1332 		return 0;
1333 	hdc = w32g_tracer_wnd.hmdc;
1334 
1335 	vol /= div;
1336 	if(vol >= view_max) {vol = view_max;}
1337 
1338 	if ( lockflag ) TRACER_LOCK ();
1339 	// �K�v�Ȃ����w�i��`��
1340 	BitBlt ( hdc, lprc->left +  vol, lprc->top, lprc->right - lprc->left -  vol, lprc->bottom - lprc->top,
1341 		tracer_bmp.hmdc, tracer_bmp.rc_chorus_effect.left, tracer_bmp.rc_chorus_effect.top, SRCCOPY );
1342 	// �K�v�Ȃ����`��
1343 	BitBlt ( hdc, lprc->left, lprc->top, vol, lprc->bottom - lprc->top,
1344 		tracer_bmp.hmdc, tracer_bmp.rc_chorus_effect.left, tracer_bmp.rc_chorus_effect.top + 9 + 1, SRCCOPY );
1345 	if ( lockflag ) TRACER_UNLOCK ();
1346 	effect_view_border_draw (lprc, lockflag);
1347 	InvalidateRect ( w32g_tracer_wnd.hwnd, lprc, FALSE );
1348 
1349 	return 0;
1350 }
1351 
1352 static int tracer_reverb_effect_draw ( RECT *lprc, int vol, int max, int lockflag )
1353 {
1354 	HDC hdc;
1355 	const int view_max = 20, div = 7;
1356 	if ( !w32g_tracer_wnd.active )
1357 		return 0;
1358 	hdc = w32g_tracer_wnd.hmdc;
1359 
1360 	vol /= div;
1361 	if(vol >= view_max) {vol = view_max;}
1362 
1363 	if ( lockflag ) TRACER_LOCK ();
1364 	// �K�v�Ȃ����w�i��`��
1365 	BitBlt ( hdc, lprc->left +  vol, lprc->top, lprc->right - lprc->left -  vol, lprc->bottom - lprc->top,
1366 		tracer_bmp.hmdc, tracer_bmp.rc_reverb_effect.left, tracer_bmp.rc_reverb_effect.top, SRCCOPY );
1367 	// �K�v�Ȃ����`��
1368 	BitBlt ( hdc, lprc->left, lprc->top, vol, lprc->bottom - lprc->top,
1369 		tracer_bmp.hmdc, tracer_bmp.rc_reverb_effect.left, tracer_bmp.rc_reverb_effect.top + 9 + 1, SRCCOPY );
1370 	if ( lockflag ) TRACER_UNLOCK ();
1371 	effect_view_border_draw (lprc, lockflag);
1372 	InvalidateRect ( w32g_tracer_wnd.hwnd, lprc, FALSE );
1373 
1374 	return 0;
1375 }
1376 
1377 static int tracer_temper_keysig_draw(RECT *lprc, int8 tk, int ko, int lockflag)
1378 {
1379 	static int8 lastkeysig = CTL_STATUS_UPDATE;
1380 	static int lastoffset = CTL_STATUS_UPDATE;
1381 	int adj, i, j;
1382 	HDC hdc;
1383 
1384 	if (tk == CTL_STATUS_UPDATE)
1385 		tk = lastkeysig;
1386 	else
1387 		lastkeysig = tk;
1388 	if (ko == CTL_STATUS_UPDATE)
1389 		ko = lastoffset;
1390 	else
1391 		lastoffset = ko;
1392 	adj = tk + 8 & 0x20, tk = (tk + 8) % 32 - 8;
1393 	i = tk + ((tk < 8) ? 7 : -9);
1394 	if (ko > 0)
1395 		for (j = 0; j < ko; j++)
1396 			i += (i > 7) ? -5 : 7;
1397 	else
1398 		for (j = 0; j < abs(ko); j++)
1399 			i += (i < 7) ? 5 : -7;
1400 	i += (tk < 8) ? 1 : 17;
1401 	if (! w32g_tracer_wnd.active)
1402 		return 0;
1403 	hdc = w32g_tracer_wnd.hmdc;
1404 	if (lockflag)
1405 		TRACER_LOCK();
1406 	BitBlt(hdc, lprc->left, lprc->top,
1407 			lprc->right - lprc->left, lprc->bottom - lprc->top,
1408 			tracer_bmp.hmdc, tracer_bmp.rc_temper_keysig[i].left,
1409 			tracer_bmp.rc_temper_keysig[i].top, (adj) ? NOTSRCCOPY : SRCCOPY);
1410 	if (lockflag)
1411 		TRACER_UNLOCK();
1412 	InvalidateRect(w32g_tracer_wnd.hwnd, lprc, FALSE);
1413 	return 0;
1414 }
1415 
1416 static int tracer_temper_type_draw(RECT *lprc, int ch, int8 tt, int lockflag)
1417 {
1418 	HDC hdc;
1419 
1420 	if (tt != CTL_STATUS_UPDATE) {
1421 		if (w32g_tracer_wnd.tt[ch] == tt)
1422 			return 0;
1423 		w32g_tracer_wnd.tt[ch] = tt;
1424 	} else
1425 		tt = w32g_tracer_wnd.tt[ch];
1426 	if (! w32g_tracer_wnd.active)
1427 		return 0;
1428 	hdc = w32g_tracer_wnd.hmdc;
1429 	if (lockflag)
1430 		TRACER_LOCK();
1431 	BitBlt(hdc, lprc->left, lprc->top,
1432 			lprc->right - lprc->left, lprc->bottom - lprc->top,
1433 			tracer_bmp.hmdc,
1434 			tracer_bmp.rc_temper_type[(tt < 0x40) ? tt : tt - 0x3c].left,
1435 			tracer_bmp.rc_temper_type[(tt < 0x40) ? tt : tt - 0x3c].top,
1436 			SRCCOPY);
1437 	if (lockflag)
1438 		TRACER_UNLOCK();
1439 	effect_view_border_draw (lprc, lockflag);
1440 	InvalidateRect(w32g_tracer_wnd.hwnd, lprc, FALSE);
1441 	return 0;
1442 }
1443 
1444 static int tracer_gm_draw ( RECT *lprc, int flag, int lockflag )
1445 {
1446 	HDC hdc;
1447 	if ( !w32g_tracer_wnd.active )
1448 		return 0;
1449 	hdc = w32g_tracer_wnd.hmdc;
1450 	if ( lockflag ) TRACER_LOCK ();
1451 	switch ( flag ) {
1452 	default:
1453 	case 0:
1454 		BitBlt ( hdc, lprc->left, lprc->top, lprc->right - lprc->left, lprc->bottom - lprc->top,
1455 			tracer_bmp.hmdc, tracer_bmp.rc_gm_off.left, tracer_bmp.rc_gm_off.top, SRCCOPY );
1456 		break;
1457 	case 1:
1458 		BitBlt ( hdc, lprc->left, lprc->top, lprc->right - lprc->left, lprc->bottom - lprc->top,
1459 			tracer_bmp.hmdc, tracer_bmp.rc_gm_on.left, tracer_bmp.rc_gm_on.top, SRCCOPY );
1460 		break;
1461 	}
1462 	if ( lockflag ) TRACER_UNLOCK ();
1463 	InvalidateRect ( w32g_tracer_wnd.hwnd, lprc, FALSE );
1464 	return 0;
1465 }
1466 
1467 static int tracer_gs_draw ( RECT *lprc, int flag, int lockflag )
1468 {
1469 	HDC hdc;
1470 	if ( !w32g_tracer_wnd.active )
1471 		return 0;
1472 	hdc = w32g_tracer_wnd.hmdc;
1473 	if ( lockflag ) TRACER_LOCK ();
1474 	switch ( flag ) {
1475 	default:
1476 	case 0:
1477 		BitBlt ( hdc, lprc->left, lprc->top, lprc->right - lprc->left, lprc->bottom - lprc->top,
1478 			tracer_bmp.hmdc, tracer_bmp.rc_gs_off.left, tracer_bmp.rc_gs_off.top, SRCCOPY );
1479 		break;
1480 	case 1:
1481 		BitBlt ( hdc, lprc->left, lprc->top, lprc->right - lprc->left, lprc->bottom - lprc->top,
1482 			tracer_bmp.hmdc, tracer_bmp.rc_gs_on.left, tracer_bmp.rc_gs_on.top, SRCCOPY );
1483 		break;
1484 	}
1485 	if ( lockflag ) TRACER_UNLOCK ();
1486 	InvalidateRect ( w32g_tracer_wnd.hwnd, lprc, FALSE );
1487 	return 0;
1488 }
1489 
1490 static int tracer_xg_draw ( RECT *lprc, int flag, int lockflag )
1491 {
1492 	HDC hdc;
1493 	if ( !w32g_tracer_wnd.active )
1494 		return 0;
1495 	hdc = w32g_tracer_wnd.hmdc;
1496 	if ( lockflag ) TRACER_LOCK ();
1497 	switch ( flag ) {
1498 	default:
1499 	case 0:
1500 		BitBlt ( hdc, lprc->left, lprc->top, lprc->right - lprc->left, lprc->bottom - lprc->top,
1501 			tracer_bmp.hmdc, tracer_bmp.rc_xg_off.left, tracer_bmp.rc_xg_off.top, SRCCOPY );
1502 		break;
1503 	case 1:
1504 		BitBlt ( hdc, lprc->left, lprc->top, lprc->right - lprc->left, lprc->bottom - lprc->top,
1505 			tracer_bmp.hmdc, tracer_bmp.rc_xg_on.left, tracer_bmp.rc_xg_on.top, SRCCOPY );
1506 	break;
1507 	}
1508 	if ( lockflag ) TRACER_UNLOCK ();
1509 	InvalidateRect ( w32g_tracer_wnd.hwnd, lprc, FALSE );
1510 	return 0;
1511 }
1512 
1513 #if 0
1514 static int cheap_volume_view_draw ( RECT *lprc, int vol, int max, COLORREF fore, COLORREF back, int type, int lockflag )
1515 {
1516 	RECT rc1;
1517 	HDC hdc;
1518 	HBRUSH hFore, hBack;
1519 
1520 	if ( !w32g_tracer_wnd.active )
1521 		return 0;
1522 	rc1;
1523 	hdc = w32g_tracer_wnd.hmdc;
1524 	hFore = CreateSolidBrush ( fore );
1525 	hBack = CreateSolidBrush ( back );
1526 	if ( vol > max ) vol = max;
1527 	if ( vol < 0 ) vol = 0;
1528 	switch (type) {
1529 	default:
1530 	case CVV_TYPE_LEFT:
1531 		rc1.left = lprc->left;
1532 		rc1.right = lprc->left + (lprc->right - lprc->left) * vol / max;
1533 		rc1.top = lprc->top;
1534 		rc1.bottom = lprc->bottom;
1535 		break;
1536 	case CVV_TYPE_RIGHT:
1537 		rc1.left = lprc->left + (lprc->right - lprc->left) * (max - vol) / max;
1538 		rc1.right = lprc->right;
1539 		rc1.top = lprc->top;
1540 		rc1.bottom = lprc->bottom;
1541 		break;
1542 	case CVV_TYPE_TOP:
1543 		rc1.left = lprc->left;
1544 		rc1.right = lprc->right;
1545 		rc1.top = lprc->top;
1546 		rc1.bottom = lprc->top + (lprc->bottom - lprc->top) * vol / max;
1547 		break;
1548 	case CVV_TYPE_BOTTOM:
1549 		rc1.left = lprc->left;
1550 		rc1.right = lprc->right;
1551 		rc1.top = lprc->top + (lprc->bottom - lprc->top) * (max - vol) / max;
1552 		rc1.bottom = lprc->bottom;
1553 		break;
1554 	}
1555 	if ( lockflag ) TRACER_LOCK ();
1556 	FillRect(hdc, &rc1, hFore);
1557 	if ( lockflag ) TRACER_UNLOCK ();
1558 	InvalidateRect ( w32g_tracer_wnd.hwnd, &rc1, FALSE );
1559 
1560 	switch (type) {
1561 	default:
1562 	case CVV_TYPE_LEFT:
1563 		rc1.left = rc1.right;
1564 		rc1.right = lprc->right;
1565 		break;
1566 	case CVV_TYPE_RIGHT:
1567 		rc1.left = lprc->left;
1568 		rc1.right = rc1.left;
1569 		break;
1570 	case CVV_TYPE_TOP:
1571 		rc1.top = rc1.bottom;
1572 		rc1.bottom = lprc->bottom;
1573 		break;
1574 	case CVV_TYPE_BOTTOM:
1575 		rc1.top = lprc->top;
1576 		rc1.bottom = rc1.top;
1577 		break;
1578 	}
1579 	if ( lockflag ) TRACER_LOCK ();
1580 	FillRect(hdc, &rc1, hBack);
1581 	if ( lockflag ) TRACER_UNLOCK ();
1582 	InvalidateRect ( w32g_tracer_wnd.hwnd, &rc1, FALSE );
1583 
1584 	DeleteObject ( (HGDIOBJ) hFore );
1585 	DeleteObject ( (HGDIOBJ) hBack );
1586 
1587 	return 0;
1588 }
1589 #endif
1590 
1591 static int string_view_border_draw ( RECT *lprc, COLORREF back, int lockflag)
1592 {
1593 	HDC hdc;
1594 	HPEN hPen1 = NULL;
1595 	HPEN hPen2 = NULL;
1596 	HPEN hPen3 = NULL;
1597 	HPEN hPen4 = NULL;
1598 	HPEN hOldPen = NULL;
1599 
1600 	if ( !w32g_tracer_wnd.active )
1601 		return 0;
1602 	hdc = w32g_tracer_wnd.hmdc;
1603 
1604 	hPen1 = CreatePen(PS_SOLID, 1, RGB(GetRValue(back) + 32, GetGValue(back) + 32, GetBValue(back) + 32));
1605 	hPen2 = CreatePen(PS_SOLID, 1, RGB(GetRValue(back) - 16, GetGValue(back) - 16, GetBValue(back) - 16));
1606 	hPen3 = CreatePen(PS_SOLID, 1, RGB(GetRValue(back) + 16, GetGValue(back) + 16, GetBValue(back) + 16));
1607 	hPen4 = CreatePen(PS_SOLID, 1, RGB(GetRValue(back) - 32, GetGValue(back) - 32, GetBValue(back) - 32));
1608 	if ( lockflag ) TRACER_LOCK ();
1609 	hOldPen= (HPEN)SelectObject(hdc,GetStockObject(NULL_PEN));
1610 
1611 	// ���
1612 	SelectObject(hdc, hPen1);
1613 	MoveToEx(hdc, lprc->left, lprc->top, NULL);
1614 	LineTo(hdc, lprc->right, lprc->top);
1615 
1616 	// ����
1617 	SelectObject(hdc, hPen3);
1618 	MoveToEx(hdc, lprc->left, lprc->top, NULL);
1619 	LineTo(hdc, lprc->left, lprc->bottom);
1620 
1621 	// ����
1622 	SelectObject(hdc, hPen2);
1623 	MoveToEx(hdc, lprc->left, lprc->bottom - 1, NULL);
1624 	LineTo(hdc, lprc->right, lprc->bottom - 1);
1625 
1626 	// �E��
1627 	SelectObject(hdc, hPen4);
1628 	MoveToEx(hdc, lprc->right - 1, lprc->top, NULL);
1629 	LineTo(hdc, lprc->right - 1, lprc->bottom);
1630 
1631 	SelectObject(hdc, hOldPen);
1632 
1633 	if ( lockflag ) TRACER_UNLOCK ();
1634 
1635 	DeleteObject (hPen1);
1636 	DeleteObject (hPen2);
1637 	DeleteObject (hPen3);
1638 	DeleteObject (hPen4);
1639 
1640 	return 0;
1641 }
1642 
1643 static int cheap_string_view_draw_font ( RECT *lprc, char *str, COLORREF fore, COLORREF back, int mode, HFONT hFont, int lockflag )
1644 {
1645 	HDC hdc;
1646 	COLORREF old_fore, old_back;
1647 	HGDIOBJ hgdiobj;
1648 	UINT old_mode;
1649 	int left, top, bottom;
1650 	if ( !w32g_tracer_wnd.active )
1651 		return 0;
1652 	hdc = w32g_tracer_wnd.hmdc;
1653 	if ( lockflag ) TRACER_LOCK ();
1654 	if ( mode == CSV_CENTER ) {
1655 		old_mode = SetTextAlign(hdc, TA_CENTER | TA_BOTTOM );
1656 		left = ( lprc->left + lprc->right ) / 2;
1657 		top = lprc->top;
1658 		bottom = lprc->bottom;
1659 	} else if ( mode == CSV_LEFT ) {
1660 		old_mode = SetTextAlign(hdc, TA_LEFT | TA_BOTTOM );
1661 		left = lprc->left;
1662 		top = lprc->top;
1663 		bottom = lprc->bottom;
1664 	} else if ( mode == CSV_RIGHT ) {
1665 		old_mode = SetTextAlign(hdc, TA_RIGHT | TA_BOTTOM );
1666 		left = lprc->right;
1667 		top = lprc->top;
1668 		bottom = lprc->bottom;
1669 	}
1670 	old_fore = SetTextColor ( hdc, fore );
1671 	old_back = SetBkColor ( hdc, back );
1672 	hgdiobj = SelectObject( hdc, hFont );
1673 //	ExtTextOut ( hdc, left, top, ETO_CLIPPED | ETO_OPAQUE, lprc, str, strlen(str), NULL);
1674 	ExtTextOut ( hdc, left, bottom - 2, ETO_CLIPPED | ETO_OPAQUE, lprc, str, strlen(str), NULL);
1675 	SetTextColor ( hdc, old_fore );
1676 	SetBkColor ( hdc, old_back );
1677 	SelectObject( hdc, hgdiobj );
1678 	SetTextAlign(hdc, old_mode );
1679 
1680 	string_view_border_draw(lprc, back, FALSE);
1681 	if ( lockflag ) TRACER_UNLOCK ();
1682 
1683 	InvalidateRect ( w32g_tracer_wnd.hwnd, lprc, FALSE );
1684 
1685 	return 0;
1686 }
1687 
1688 static int cheap_string_view_draw ( RECT *lprc, char *str, COLORREF fore, COLORREF back, int mode, int lockflag )
1689 {
1690 	return cheap_string_view_draw_font ( lprc, str, fore, back, mode, w32g_tracer_wnd.hFontCommon, lockflag );
1691 }
1692 
1693 static int cheap_half_string_view_draw ( RECT *lprc, char *str, COLORREF fore, COLORREF back, int mode, int lockflag )
1694 {
1695 	HDC hdc;
1696 	COLORREF old_fore, old_back;
1697 	HGDIOBJ hgdiobj;
1698 	UINT old_mode;
1699 	HFONT hFont = w32g_tracer_wnd.hFontHalf;
1700 	int left, top;
1701 	if ( !w32g_tracer_wnd.active )
1702 		return 0;
1703 	hdc = w32g_tracer_wnd.hmdc;
1704 	if ( lockflag ) TRACER_LOCK ();
1705 	if ( mode == CSV_CENTER ) {
1706 		old_mode = SetTextAlign(hdc, TA_CENTER );
1707 		left = ( lprc->left + lprc->right ) / 2;
1708 		top = lprc->top;
1709 	} else if ( mode == CSV_LEFT ) {
1710 		old_mode = SetTextAlign(hdc, TA_LEFT );
1711 		left = lprc->left;
1712 		top = lprc->top;
1713 	} else if ( mode == CSV_RIGHT ) {
1714 		old_mode = SetTextAlign(hdc, TA_RIGHT );
1715 		left = lprc->right;
1716 		top = lprc->top;
1717 	}
1718 	old_fore = SetTextColor ( hdc, fore );
1719 	old_back = SetBkColor ( hdc, back );
1720 	hgdiobj = SelectObject( hdc, hFont );
1721 	ExtTextOut ( hdc, left, top-3, ETO_CLIPPED | ETO_OPAQUE, lprc, str, strlen(str), NULL);
1722 	SetTextColor ( hdc, old_fore );
1723 	SetBkColor ( hdc, old_back );
1724 	SelectObject( hdc, hgdiobj );
1725 	SetTextAlign(hdc, old_mode );
1726 
1727 	string_view_border_draw(lprc, back, FALSE);
1728 	if ( lockflag ) TRACER_UNLOCK ();
1729 
1730 	InvalidateRect ( w32g_tracer_wnd.hwnd, lprc, FALSE );
1731 
1732 	return 0;
1733 }
1734 
1735 
1736 
1737 void TracerWndPaintAll(int lockflag)
1738 {
1739 	int i, j;
1740 	char buff[1024];
1741 	RECT rc;
1742 	if ( !w32g_tracer_wnd.active )
1743 		return;
1744 	if ( lockflag ) TRACER_LOCK();
1745 	// �^�C�g��
1746 	strcpy ( buff, "ch" );
1747 	get_head_rc ( &rc, &w32g_tracer_wnd.rc_channel_top );
1748 	cheap_string_view_draw ( &rc, buff, C_TEXT_FORE, C_TEXT_BACK, CSV_CENTER, FALSE );
1749 	strcpy ( buff, "  instrument  " );
1750 	get_head_rc ( &rc, &w32g_tracer_wnd.rc_instrument );
1751 	cheap_string_view_draw ( &rc, buff, C_TEXT_FORE, C_TEXT_BACK, CSV_CENTER, FALSE );
1752 	strcpy ( buff, "  map  " );
1753 	get_head_rc ( &rc, &w32g_tracer_wnd.rc_inst_map );
1754 	cheap_string_view_draw ( &rc, buff, C_TEXT_FORE, C_TEXT_BACK, CSV_CENTER, FALSE );
1755 	strcpy ( buff, "bank" );
1756 	get_head_rc ( &rc, &w32g_tracer_wnd.rc_bank );
1757 	cheap_string_view_draw ( &rc, buff, C_TEXT_FORE, C_TEXT_BACK, CSV_CENTER, FALSE );
1758 	strcpy ( buff, "prog" );
1759 	get_head_rc ( &rc, &w32g_tracer_wnd.rc_program );
1760 	cheap_string_view_draw ( &rc, buff, C_TEXT_FORE, C_TEXT_BACK, CSV_CENTER, FALSE );
1761 	strcpy ( buff, "vel" );
1762 	get_head_rc ( &rc, &w32g_tracer_wnd.rc_velocity );
1763 	cheap_string_view_draw ( &rc, buff, C_TEXT_FORE, C_TEXT_BACK, CSV_CENTER, FALSE );
1764 	strcpy ( buff, "vo" );
1765 	get_head_rc ( &rc, &w32g_tracer_wnd.rc_volume );
1766 	cheap_half_string_view_draw ( &rc, buff, C_TEXT_FORE, C_TEXT_BACK, CSV_CENTER, FALSE );
1767 	strcpy ( buff, "ex" );
1768 	get_head_rc ( &rc, &w32g_tracer_wnd.rc_expression );
1769 	cheap_half_string_view_draw ( &rc, buff, C_TEXT_FORE, C_TEXT_BACK, CSV_CENTER, FALSE );
1770 	strcpy ( buff, "pa" );
1771 	get_head_rc ( &rc, &w32g_tracer_wnd.rc_panning );
1772 	cheap_half_string_view_draw ( &rc, buff, C_TEXT_FORE, C_TEXT_BACK, CSV_CENTER, FALSE );
1773 	strcpy ( buff, "su" );
1774 	get_head_rc ( &rc, &w32g_tracer_wnd.rc_sustain );
1775 	cheap_half_string_view_draw ( &rc, buff, C_TEXT_FORE, C_TEXT_BACK, CSV_CENTER, FALSE );
1776 	strcpy ( buff, "pb" );
1777 	get_head_rc ( &rc, &w32g_tracer_wnd.rc_pitch_bend );
1778 	cheap_half_string_view_draw ( &rc, buff, C_TEXT_FORE, C_TEXT_BACK, CSV_CENTER, FALSE );
1779 	strcpy ( buff, "mw" );
1780 	get_head_rc ( &rc, &w32g_tracer_wnd.rc_mod_wheel );
1781 	cheap_half_string_view_draw ( &rc, buff, C_TEXT_FORE, C_TEXT_BACK, CSV_CENTER, FALSE );
1782 	strcpy ( buff, "ch" );
1783 	get_head_rc ( &rc, &w32g_tracer_wnd.rc_chorus_effect );
1784 	cheap_half_string_view_draw ( &rc, buff, C_TEXT_FORE, C_TEXT_BACK, CSV_CENTER, FALSE );
1785 	strcpy ( buff, "re" );
1786 	get_head_rc ( &rc, &w32g_tracer_wnd.rc_reverb_effect );
1787 	cheap_half_string_view_draw ( &rc, buff, C_TEXT_FORE, C_TEXT_BACK, CSV_CENTER, FALSE );
1788 	get_head_rc(&rc, &w32g_tracer_wnd.rc_temper_keysig);
1789 	tracer_temper_keysig_draw(&rc, CTL_STATUS_UPDATE, CTL_STATUS_UPDATE, FALSE);
1790 	get_head_rc ( &rc, &w32g_tracer_wnd.rc_gm );
1791 	tracer_gm_draw ( &rc, w32g_tracer_wnd.play_system_mode == GM_SYSTEM_MODE ? 1 : 0, FALSE );
1792 	get_head_rc ( &rc, &w32g_tracer_wnd.rc_gs );
1793 	tracer_gs_draw ( &rc, w32g_tracer_wnd.play_system_mode == GS_SYSTEM_MODE ? 1 : 0, FALSE );
1794 	get_head_rc ( &rc, &w32g_tracer_wnd.rc_xg );
1795 	tracer_xg_draw ( &rc, w32g_tracer_wnd.play_system_mode == XG_SYSTEM_MODE ? 1 : 0, FALSE );
1796 	strcpy ( buff, w32g_tracer_wnd.titlename );
1797 	get_head_rc ( &rc, &w32g_tracer_wnd.rc_head_rest );
1798 	cheap_string_view_draw ( &rc, buff, C_TEXT_FORE, C_TEXT_BACK, CSV_LEFT, FALSE );
1799 
1800 	// �e�`�����l��
1801 	for ( i = 0; i < TRACER_CHANNELS ; i ++ ) {
1802 		if ( get_ch_rc ( i, &rc, &w32g_tracer_wnd.rc_channel_top ) == 0 ) {
1803 			sprintf ( buff, "%02d", i + 1);
1804 			if ( IS_SET_CHANNELMASK ( w32g_tracer_wnd.quietchannels, i ) )
1805 				cheap_string_view_draw ( &rc, buff, C_TEXT_FORE, C_TEXT_BACK_VERY_DARK, CSV_CENTER, FALSE );
1806 			else {
1807 				if ( IS_SET_CHANNELMASK ( w32g_tracer_wnd.channel_mute, i ) )
1808 					cheap_string_view_draw ( &rc, buff, C_TEXT_FORE, C_TEXT_BACK_DARK, CSV_CENTER, FALSE );
1809 				else
1810 					cheap_string_view_draw ( &rc, buff, C_TEXT_FORE, C_TEXT_BACK, CSV_CENTER, FALSE );
1811 			}
1812 		}
1813 
1814 		tracer_ch_program_draw ( i, w32g_tracer_wnd.bank[i], w32g_tracer_wnd.program[i], w32g_tracer_wnd.instrument[i], w32g_tracer_wnd.mapID[i], FALSE );
1815 
1816 		if ( get_ch_rc ( i, &rc, &w32g_tracer_wnd.rc_velocity ) == 0 )
1817 			tracer_velocity_draw ( &rc, w32g_tracer_wnd.velocity[i], VEL_MAX, FALSE );
1818 
1819 		if ( get_ch_rc ( i, &rc, &w32g_tracer_wnd.rc_volume ) == 0 )
1820 			tracer_volume_draw ( &rc, w32g_tracer_wnd.volume[i], 128, FALSE );
1821 
1822 		if ( get_ch_rc ( i, &rc, &w32g_tracer_wnd.rc_expression ) == 0 )
1823 			tracer_expression_draw ( &rc, w32g_tracer_wnd.expression[i], 128, FALSE );
1824 
1825 		if ( get_ch_rc ( i, &rc, &w32g_tracer_wnd.rc_panning ) == 0 )
1826 			tracer_pan_draw ( &rc, w32g_tracer_wnd.panning[i], 128, FALSE );
1827 
1828 		if ( get_ch_rc ( i, &rc, &w32g_tracer_wnd.rc_sustain ) == 0 )
1829 			tracer_sustain_draw ( &rc, w32g_tracer_wnd.sustain[i], FALSE );
1830 
1831 		if ( get_ch_rc ( i, &rc, &w32g_tracer_wnd.rc_pitch_bend ) == 0 )
1832 			tracer_pitch_bend_draw ( &rc, w32g_tracer_wnd.pitch_bend[i], 0x4000, FALSE );
1833 
1834 		if ( get_ch_rc ( i, &rc, &w32g_tracer_wnd.rc_mod_wheel ) == 0 )
1835 			tracer_mod_wheel_draw ( &rc, w32g_tracer_wnd.mod_wheel[i], 32, FALSE );
1836 
1837 		if ( get_ch_rc ( i, &rc, &w32g_tracer_wnd.rc_chorus_effect ) == 0 )
1838 			tracer_chorus_effect_draw ( &rc, w32g_tracer_wnd.chorus_effect[i], 128, FALSE );
1839 
1840 		if ( get_ch_rc ( i, &rc, &w32g_tracer_wnd.rc_reverb_effect ) == 0 )
1841 			tracer_reverb_effect_draw ( &rc, w32g_tracer_wnd.reverb_effect[i], 128, FALSE );
1842 
1843 		if (! get_ch_rc(i, &rc, &w32g_tracer_wnd.rc_temper_type))
1844 			tracer_temper_type_draw(&rc, i, CTL_STATUS_UPDATE, FALSE);
1845 
1846 		for ( j = 0; j < 128; j ++ ) {
1847 			if ( get_ch_rc ( i, &rc, &w32g_tracer_wnd.rc_notes ) == 0 )
1848 				notes_view_draw ( &rc, j, w32g_tracer_wnd.notes[i][j], TRUE, FALSE );
1849 		}
1850 
1851 	}
1852 
1853 	// ...
1854 	if ( lockflag ) TRACER_UNLOCK();
1855 	InvalidateRect( w32g_tracer_wnd.hwnd,NULL, FALSE );
1856 }
1857 
1858 // GUI �X���b�h����̂݌Ăׂ�
1859 void TracerWndPaintDo(int flag)
1860 {
1861 	RECT rc;
1862 	if ( !w32g_tracer_wnd.active )
1863 		return;
1864 	if ( flag ) InvalidateRect( w32g_tracer_wnd.hwnd,NULL, FALSE );
1865 	if ( GetUpdateRect(w32g_tracer_wnd.hwnd, &rc, FALSE) ) {
1866 		PAINTSTRUCT ps;
1867 		if ( GDI_LOCK_EX(0) == 0 ) {
1868 			TRACER_LOCK();
1869 			w32g_tracer_wnd.hdc = BeginPaint(w32g_tracer_wnd.hwnd, &ps);
1870 			BitBlt(w32g_tracer_wnd.hdc,rc.left,rc.top,rc.right,rc.bottom,w32g_tracer_wnd.hmdc,rc.left,rc.top,SRCCOPY);
1871 			EndPaint(w32g_tracer_wnd.hwnd, &ps);
1872 			GDI_UNLOCK();
1873 			TRACER_UNLOCK();
1874 		} else {
1875 			InvalidateRect ( w32g_tracer_wnd.hwnd, &rc, FALSE );
1876 		}
1877 	}
1878 }
1879 
1880 BOOL CALLBACK
1881 TracerCanvasWndProc(HWND hwnd, UINT uMess, WPARAM wParam, LPARAM lParam)
1882 {
1883 	switch (uMess)
1884 	{
1885 		case WM_CREATE:
1886 			break;
1887 		case WM_PAINT:
1888 	      	TracerWndPaintDo(FALSE);
1889 	    	return 0;
1890 		case WM_DROPFILES:
1891 			SendMessage(hMainWnd,WM_DROPFILES,wParam,lParam);
1892 			return 0;
1893 		case WM_RBUTTONDBLCLK:
1894 		case WM_LBUTTONDBLCLK:
1895 			{
1896 			int i, mode;
1897 			int xPos = LOWORD(lParam);
1898 			int yPos = HIWORD(lParam);
1899 			RECT rc;
1900 			int flag = FALSE;
1901 			get_head_rc ( &rc, &w32g_tracer_wnd.rc_channel_top );
1902 			if ( rc.left <= xPos && xPos <= rc.right && rc.top <= yPos && yPos <= rc.bottom ) {
1903 				char buff[64];
1904 				for ( i = 0; i < TRACER_CHANNELS; i ++ ) {
1905 					if ( get_ch_rc ( i, &rc, &w32g_tracer_wnd.rc_channel_top ) == 0 ) {
1906 						sprintf ( buff, "%02d", i + 1 );
1907 						if ( uMess == WM_RBUTTONDBLCLK )
1908 							UNSET_CHANNELMASK ( channel_mute, i );
1909 						else
1910 							TOGGLE_CHANNELMASK ( channel_mute, i );
1911 						if ( IS_SET_CHANNELMASK ( quietchannels, i ) )
1912 							cheap_string_view_draw ( &rc, buff, C_TEXT_FORE, C_TEXT_BACK_VERY_DARK, CSV_CENTER, TRUE );
1913 						else {
1914 							flag = TRUE;
1915 							if ( IS_SET_CHANNELMASK ( channel_mute, i ) )
1916 								cheap_string_view_draw ( &rc, buff, C_TEXT_FORE, C_TEXT_BACK_DARK, CSV_CENTER, TRUE );
1917 							else
1918 								cheap_string_view_draw ( &rc, buff, C_TEXT_FORE, C_TEXT_BACK, CSV_CENTER, TRUE );
1919 						}
1920 					}
1921 				}
1922 				if ( flag )
1923 					w32g_send_rc ( RC_SYNC_RESTART, 0 );
1924 				w32g_tracer_wnd.channel_mute = channel_mute;
1925 				w32g_tracer_wnd.quietchannels = quietchannels;
1926 				flag = TRUE;
1927 			}
1928 			if ( uMess == WM_RBUTTONDBLCLK )
1929 				break;
1930 			if ( flag )
1931 				break;
1932 			for ( i = 0; i < TRACER_CHANNELS; i ++ ) {
1933 				if ( get_ch_rc ( i, &rc, &w32g_tracer_wnd.rc_channel_top ) == 0 ) {
1934 					if ( rc.left <= xPos && xPos <= rc.right && rc.top <= yPos && yPos <= rc.bottom ) {
1935 						char buff[64];
1936 						sprintf ( buff, "%02d", i + 1 );
1937 						TOGGLE_CHANNELMASK ( channel_mute, i );
1938 						if ( IS_SET_CHANNELMASK ( quietchannels, i ) )
1939 							cheap_string_view_draw ( &rc, buff, C_TEXT_FORE, C_TEXT_BACK_VERY_DARK, CSV_CENTER, TRUE );
1940 						else {
1941 							flag = TRUE;
1942 							if ( IS_SET_CHANNELMASK ( channel_mute, i ) )
1943 								cheap_string_view_draw ( &rc, buff, C_TEXT_FORE, C_TEXT_BACK_DARK, CSV_CENTER, TRUE );
1944 							else
1945 								cheap_string_view_draw ( &rc, buff, C_TEXT_FORE, C_TEXT_BACK, CSV_CENTER, TRUE );
1946 						}
1947 						w32g_tracer_wnd.channel_mute = channel_mute;
1948 						w32g_tracer_wnd.quietchannels = quietchannels;
1949 						if ( flag )
1950 							w32g_send_rc ( RC_SYNC_RESTART, 0 );
1951 						flag = TRUE;
1952 						break;
1953 					}
1954 				}
1955 			}
1956 			if ( flag )
1957 				break;
1958 			switch ( TracerWndInfo.mode ) {
1959 			case TWI_MODE_1_32CH:
1960 				mode = TWI_MODE_1_16CH;
1961 				break;
1962 			case TWI_MODE_1_16CH:
1963 				mode = TWI_MODE_17_32CH;
1964 				break;
1965 			default:
1966 			case TWI_MODE_17_32CH:
1967 				mode = TWI_MODE_1_32CH;
1968 				break;
1969 			}
1970 			change_tracer_wnd_mode ( mode );
1971 			}
1972 			break;
1973 		case WM_CHAR:
1974 //		case WM_KEYDOWN:
1975 //			ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
1976 //				 "%x", wParam );
1977 			switch ( wParam ) {
1978 			case 0x50:	// P
1979 			case 0x70:	// p
1980 				SendMessage(hMainWnd,WM_COMMAND,MAKEWPARAM(IDM_PREV,0),0);
1981 				return 0;
1982 			case 0x4e:	// N
1983 			case 0x6e:	// n
1984 				SendMessage(hMainWnd,WM_COMMAND,MAKEWPARAM(IDM_NEXT,0),0);
1985 				return 0;
1986 			case 0x45:	// E
1987 			case 0x65:	// e
1988 				w32g_send_rc ( RC_RESTART, 0);
1989 				SendMessage(hMainWnd,WM_COMMAND,MAKEWPARAM(IDM_STOP,0),0);
1990 				return 0;
1991 			case 0x48:	// H
1992 			case 0x68:	// h
1993 				if ( PlayerLanguage == LANGUAGE_JAPANESE ){
1994 				MessageBox(hTracerWnd,
1995 					"�L�[�R�}���h\n"
1996 					"�g���[�T�E�C���h�E�R�}���h\n"
1997 					"  ESC: �w���v��‚���      H: �w���v���o��\n"
1998 					"  +: �L�[�A�b�v    -: �L�[�_�E��\n"
1999 					"  >: �X�s�[�h�A�b�v    <: �X�s�[�h�_�E��\n"
2000 					"�v���C���[�R�}���h\n"
2001 					"  SPACE/ENTER: ���t�J�n    E: ��~    S: �ꎞ��~\n"
2002 					"  P: �O�̋�    N: ���̋�\n"
2003 					"TiMidity �R�}���h\n"
2004 					"  Q: �I��\n"
2005 					,"�w���v", MB_OK);
2006 				} else {
2007 				MessageBox(hTracerWnd,
2008 					"Usage of key.\n"
2009 					"Tracer window command.\n"
2010 					"  ESC: Close Help      H: Help\n"
2011 					"  +: Key up    -: Key down\n"
2012 					"  >: Speed up    <: Speed down\n"
2013 					"Player command.\n"
2014 					"  SPACE/ENTER: PLAY    E: Stop    S: Pause\n"
2015 					"  P: Prev    N: Next\n"
2016 					"TiMidity command.\n"
2017 					"  Q: Quit\n"
2018 					,"Help", MB_OK);
2019 				}
2020 				return 0;
2021 			case 0x52:	// R
2022 			case 0x72:	// r
2023 				return 0;
2024 			case 0x53:	// S
2025 			case 0x73:	// s
2026 				SendMessage(hMainWnd,WM_COMMAND,MAKEWPARAM(IDM_PAUSE,0),0);
2027 				return 0;
2028 			case VK_ESCAPE:
2029 				SendMessage(hTracerWnd,WM_COMMAND,MAKEWPARAM(0,IDCLOSE),0);
2030 				return 0;
2031 			case 0x51:	// Q
2032 			case 0x71:	// q
2033 				if(MessageBox(hTracerWnd,"Quit TiMidity?","TiMidity",MB_ICONQUESTION|MB_YESNO)==IDYES)
2034 					SendMessage(hMainWnd,WM_CLOSE,0,0);
2035 				return 0;
2036 			case VK_SPACE:
2037 			case VK_RETURN:
2038 				SendMessage(hMainWnd,WM_COMMAND,MAKEWPARAM(IDM_PLAY,0),0);
2039 				return 0;
2040 			case 0x3E:		// <
2041 				w32g_send_rc ( RC_SPEEDUP, 1);
2042 				return 0;
2043 			case 0x3C:		// <
2044 				w32g_send_rc ( RC_SPEEDDOWN, 1);
2045 				return 0;
2046 			case 0x2B:		// +
2047 				w32g_send_rc ( RC_KEYUP, 1);
2048 				return 0;
2049 			case 0x2D:		// -
2050 //				w32g_send_rc ( RC_KEYDOWN, 1);
2051 				w32g_send_rc ( RC_KEYDOWN, -1);
2052 				return 0;
2053 #if 0
2054 			case 0x4F:		// O
2055 				w32g_send_rc ( RC_VOICEINCR, 1);
2056 				return 0;
2057 			case 0x6F:		// o
2058 				w32g_send_rc ( RC_VOICEDECR, 1);
2059 				return 0;
2060 #endif
2061 			}
2062 		default:
2063 			return DefWindowProc(hwnd,uMess,wParam,lParam) ;
2064 	}
2065 	return 0L;
2066 }
2067 
2068 extern void MainWndUpdateTracerButton(void);
2069 
2070 BOOL CALLBACK
2071 TracerWndProc(HWND hwnd, UINT uMess, WPARAM wParam, LPARAM lParam)
2072 {
2073 	switch (uMess){
2074 	case WM_INITDIALOG:
2075 		SetWindowPosSize(GetDesktopWindow(),hwnd,TracerWndInfo.PosX, TracerWndInfo.PosY );
2076 		return FALSE;
2077 	case WM_DESTROY:
2078 		{
2079 			RECT rc;
2080 			GetWindowRect(hwnd,&rc);
2081 			TracerWndInfo.PosX = rc.left;
2082 			TracerWndInfo.PosY = rc.top;
2083 		}
2084 		INISaveTracerWnd();
2085 		break;
2086 	case WM_COMMAND:
2087 		switch (LOWORD(wParam)) {
2088 		case IDCLOSE:
2089 			ShowWindow(hwnd, SW_HIDE);
2090 			MainWndUpdateTracerButton();
2091 			break;
2092 		default:
2093 			return FALSE;
2094 		}
2095 	case WM_MOVE:
2096 		// TracerWndInfo.PosX = (int) LOWORD(lParam);
2097 		// TracerWndInfo.PosY = (int) HIWORD(lParam);
2098 		{
2099 			RECT rc;
2100 			GetWindowRect(hwnd,&rc);
2101 			TracerWndInfo.PosX = rc.left;
2102 			TracerWndInfo.PosY = rc.top;
2103 		}
2104 		break;
2105 	case WM_SHOWWINDOW:
2106 		if ( wParam ) {
2107 			w32g_tracer_wnd.active = TRUE;
2108 			TracerWndClear( TRUE );
2109 			TracerWndPaintAll ( TRUE );
2110 		} else {
2111 			w32g_tracer_wnd.active = FALSE;
2112 		}
2113 		break;
2114 	case WM_CLOSE:
2115 		ShowWindow(hTracerWnd, SW_HIDE);
2116 		MainWndUpdateTracerButton();
2117 		break;
2118 	case WM_DROPFILES:
2119 		SendMessage(hMainWnd,WM_DROPFILES,wParam,lParam);
2120 		return 0;
2121 	case WM_LBUTTONDBLCLK:
2122 		{
2123 		int mode;
2124 		switch ( TracerWndInfo.mode ) {
2125 		case TWI_MODE_1_32CH:
2126 			mode = TWI_MODE_1_16CH;
2127 			break;
2128 		case TWI_MODE_1_16CH:
2129 			mode = TWI_MODE_17_32CH;
2130 			break;
2131 		default:
2132 		case TWI_MODE_17_32CH:
2133 			mode = TWI_MODE_1_32CH;
2134 			break;
2135 		}
2136 		change_tracer_wnd_mode ( mode );
2137 		}
2138 		break;
2139 	default:
2140 		return FALSE;
2141 	}
2142 	return FALSE;
2143 }
2144 
2145 
2146 extern int PosSizeSave;
2147 
2148 #define SEC_TRACERWND "TracerWnd"
2149 int INISaveTracerWnd(void)
2150 {
2151 	char *section = SEC_TRACERWND;
2152 	char *inifile = TIMIDITY_WINDOW_INI_FILE;
2153 	char buffer[256];
2154 	if ( PosSizeSave ) {
2155 		if ( TracerWndInfo.PosX >= 0 || TracerWndInfo.PosY >= 0 ) {
2156 			if ( TracerWndInfo.PosX < 0 )
2157 				TracerWndInfo.PosX = 0;
2158 			if ( TracerWndInfo.PosY < 0 )
2159 				TracerWndInfo.PosY = 0;
2160 		}
2161 		sprintf(buffer,"%d",TracerWndInfo.PosX);
2162 		if ( TracerWndInfo.PosX >= 0 )
2163 		WritePrivateProfileString(section,"PosX",buffer,inifile);
2164 		sprintf(buffer,"%d",TracerWndInfo.PosY);
2165 		if ( TracerWndInfo.PosY >= 0 )
2166 		WritePrivateProfileString(section,"PosY",buffer,inifile);
2167 	}
2168 	sprintf(buffer,"%d",TracerWndInfo.mode);
2169 	WritePrivateProfileString(section,"mode",buffer,inifile);
2170 	WritePrivateProfileString(NULL,NULL,NULL,inifile);		// Write Flush
2171 	return 0;
2172 }
2173 
2174 int INILoadTracerWnd(void)
2175 {
2176 	char *section = SEC_TRACERWND;
2177 	char *inifile = TIMIDITY_WINDOW_INI_FILE;
2178 	int num;
2179 	num = GetPrivateProfileInt(section,"PosX",-1,inifile);
2180 	TracerWndInfo.PosX = num;
2181 	num = GetPrivateProfileInt(section,"PosY",-1,inifile);
2182 	TracerWndInfo.PosY = num;
2183 	num = GetPrivateProfileInt(section,"mode",TWI_MODE_1_32CH,inifile);
2184 	TracerWndInfo.mode = num;
2185 	return 0;
2186 }
2187 
2188 static int TracerWndInfoReset(HWND hwnd)
2189 {
2190 	memset(&TracerWndInfo,0,sizeof(TRACERWNDINFO));
2191 	TracerWndInfo.PosX = - 1;
2192 	TracerWndInfo.PosY = - 1;
2193 	TracerWndInfo.mode = TWI_MODE_1_32CH;
2194 	return 0;
2195 }
2196 
2197 static int TracerWndInfoApply(void)
2198 {
2199 	change_tracer_wnd_mode ( TracerWndInfo.mode );
2200 	return 0;
2201 }
2202 
2203 static int change_tracer_wnd_mode ( int mode )
2204 {
2205 	RECT rc, rc2;
2206 	switch (mode) {
2207 	default:
2208 	case TWI_MODE_1_32CH:
2209 		w32g_tracer_wnd.height = 1 + 19 + 1 + (19 + 1) * 32 + 1;
2210 		break;
2211 	case TWI_MODE_1_16CH:
2212 	case TWI_MODE_17_32CH:
2213 		w32g_tracer_wnd.height = 1 + 19 + 1 + (19 + 1) * 16 + 1;
2214 		break;
2215 	}
2216 	GetWindowRect ( hTracerWnd, &rc );
2217 	GetClientRect ( hTracerWnd, &rc2 );
2218 	rc.left = rc.left;
2219 	rc.top = rc.top;
2220 	rc.right = (rc.right - rc.left) - (rc2.right - rc2.left) + w32g_tracer_wnd.width;
2221 	rc.bottom = (rc.bottom - rc.top) - (rc2.bottom - rc2.top) + w32g_tracer_wnd.height;
2222 	MoveWindow ( hTracerWnd, rc.left, rc.top, rc.right, rc.bottom, TRUE);
2223 	MoveWindow (w32g_tracer_wnd.hwnd,0,0,w32g_tracer_wnd.width,w32g_tracer_wnd.height,TRUE);
2224 	TracerWndInfo.mode = mode;
2225 	TracerWndClear(TRUE);
2226 	TracerWndPaintAll ( TRUE );
2227 	return 0;
2228 }
2229 
2230 void TracerWndApplyQuietChannel( ChannelBitMask quietchannels_ )
2231 {
2232 	w32g_tracer_wnd.quietchannels = quietchannels_;
2233 	TracerWndPaintAll(TRUE);
2234 }
2235 
2236 
2237