1 /***************************************************************************
2 debug.c - description
3 -------------------
4 begin : Wed May 15 2002
5 copyright : (C) 2002 by Pete Bernert
6 email : BlackDove@addcom.de
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. See also the license.txt file for *
15 * additional informations. *
16 * *
17 ***************************************************************************/
18
19 //*************************************************************************//
20 // History of changes:
21 //
22 // 2004/09/18 - Pete
23 // - corrected ADSRX value display
24 //
25 // 2003/01/06 - Pete
26 // - added Neil's ADSR timings
27 //
28 // 2002/05/15 - Pete
29 // - generic cleanup for the Peops release
30 //
31 //*************************************************************************//
32
33 #include "stdafx.h"
34
35 #define _IN_DEBUG
36
37 #include "externals.h"
38
39 ////////////////////////////////////////////////////////////////////////
40 // WINDOWS DEBUG DIALOG HANDLING
41 ////////////////////////////////////////////////////////////////////////
42
43 #ifdef _WINDOWS
44
45 #include "resource.h"
46
47 //#define SMALLDEBUG
48 //#include <dbgout.h>
49
50 ////////////////////////////////////////////////////////////////////////
51 // display debug infos
52
53 const COLORREF crStreamCol[]={
54 RGB( 0, 0, 0),
55 RGB(255,255,255),
56 RGB(128, 0,128),
57 RGB( 0,128, 0),
58 RGB( 0, 0,255),
59 RGB(255, 0, 0)
60 };
61
62 const COLORREF crAdsrCol[] ={
63 RGB( 0, 0, 0),
64 RGB(255, 0, 0),
65 RGB( 0,255, 0),
66 RGB(255, 0,255),
67 RGB( 0, 0,255),
68 RGB( 0, 0, 0),
69 };
70
71 HBRUSH hBStream[6]; // brushes for stream lines
72 HPEN hPAdsr[6]; // pens for adsr lines
73 int iSelChannel=0; // user selected channel
74
75 ////////////////////////////////////////////////////////////////////////
76 // display the sound data waves: no subclassing used, so the
77 // area will not be redrawn... but faster that way, and good enuff
78 // for debugging purposes
79
DisplayStreamInfos(HWND hW)80 void DisplayStreamInfos(HWND hW)
81 {
82 HWND hWS=GetDlgItem(hW,IDC_SAREA);
83 HDC hdc;RECT r;HBRUSH hBO;int ch,dy,i,j,id;
84
85 //----------------------------------------------------//
86
87 GetClientRect(hWS,&r); // get size of stream display
88 hdc=GetDC(hWS); // device context
89 r.right--; // leave the right border intact
90 ScrollDC(hdc,-1,0,&r,&r,NULL,NULL); // scroll one pixel to the left
91
92 //----------------------------------------------------//
93
94 hBO=SelectObject(hdc,hBStream[0]); // clean the right border
95 PatBlt(hdc,r.right-1,0,1,r.bottom,PATCOPY);
96
97 //----------------------------------------------------//
98
99 dy=r.bottom/MAXCHAN; // size of one channel area
100
101 for(ch=0;ch<MAXCHAN;ch++) // loop the channels
102 {
103 if(s_chan[ch].bOn) // channel is on?
104 {
105 if(s_chan[ch].iIrqDone)
106 {
107 s_chan[ch].iIrqDone=0;
108 PatBlt(hdc,r.right-1,ch*r.bottom/MAXCHAN,
109 1,dy,BLACKNESS);
110 continue;
111 }
112
113 j=s_chan[ch].sval;if(j<0) j=-j; // -> get one channel data (-32k ... 32k)
114 j=(dy*j)/32768; if(j==0) j=1; // -> adjust to display coords
115 i=(dy/2)+(ch*r.bottom/MAXCHAN)-j/2; // -> position where to paint it
116
117
118
119 if (s_chan[ch].iMute) id=1; // -> get color id
120 else if(s_chan[ch].bNoise) id=2;
121 else if(s_chan[ch].bFMod==2) id=3;
122 else if(s_chan[ch].bFMod==1) id=4;
123 else id=5;
124
125 SelectObject(hdc,hBStream[id]); // -> select the brush
126 PatBlt(hdc,r.right-1,i,1,j,PATCOPY); // -> paint the value line
127 }
128
129 if(ch) SetPixel(hdc,r.right-1, // -> not first line?
130 ch*r.bottom/MAXCHAN,RGB(0,0,0)); // --> draw the line (one dot scrolled to the left)
131 }
132
133 //----------------------------------------------------//
134
135 SelectObject(hdc,hBO); // repair brush
136
137 ReleaseDC(hWS,hdc); // release context
138 }
139
140 ////////////////////////////////////////////////////////////////////////
141 // display adsr lines: also no subclassing for repainting used
142
DisplayADSRInfos(HWND hW)143 void DisplayADSRInfos(HWND hW)
144 {
145 HWND hWS=GetDlgItem(hW,IDC_ADSR);
146 HDC hdc;RECT r;HBRUSH hBO;char szB[16];
147 int ch=iSelChannel,dx,dy,dm,dn,ia,id,is,ir;
148
149 //----------------------------------------------------// get display size
150
151 GetClientRect(hWS,&r);
152 hdc=GetDC(hWS);
153
154 //----------------------------------------------------// clean the area
155
156 hBO=SelectObject(hdc,hBStream[0]);
157 PatBlt(hdc,0,0,r.right,r.bottom,PATCOPY);
158 r.left++;r.right-=2;r.top++;r.bottom-=2; // shrink the display rect for better optics
159
160 //----------------------------------------------------//
161
162 ia=min(s_chan[ch].ADSR.AttackTime,10000); // get adsr, but limit it for drawing
163 id=min(s_chan[ch].ADSR.DecayTime,10000);
164 is=min(s_chan[ch].ADSR.SustainTime,10000);
165 ir=min(s_chan[ch].ADSR.ReleaseTime,10000);
166
167 dx=ia+id+is+ir; // get the dx in (limited) adsr units
168
169 // set the real values to the info statics
170 SetDlgItemInt(hW,IDC_SADSR1,s_chan[ch].ADSRX.AttackRate^0x7f,FALSE);
171 SetDlgItemInt(hW,IDC_SADSR2,(s_chan[ch].ADSRX.DecayRate^0x1f)/4,FALSE);
172 SetDlgItemInt(hW,IDC_SADSR3,s_chan[ch].ADSRX.SustainRate^0x7f,FALSE);
173 SetDlgItemInt(hW,IDC_SADSR4,(s_chan[ch].ADSRX.ReleaseRate^0x1f)/4,FALSE);
174 SetDlgItemInt(hW,IDC_SADSR5,s_chan[ch].ADSRX.SustainLevel>>27,FALSE);
175
176 SetDlgItemInt(hW,IDC_SADSR6,s_chan[ch].ADSRX.SustainIncrease,TRUE);
177 SetDlgItemInt(hW,IDC_SADSR7,s_chan[ch].ADSRX.lVolume,TRUE);
178 wsprintf(szB,"%08lx",s_chan[ch].ADSRX.EnvelopeVol);
179 SetDlgItemText(hW,IDC_SADSR8,szB);
180
181 if(dx) // something to draw?
182 {
183 HPEN hPO=SelectObject(hdc,hPAdsr[1]); // sel A pen
184 dn=r.left;
185 MoveToEx(hdc,dn,r.bottom,NULL); // move to bottom left corner
186
187 dn+=(ia*r.right)/dx; // calc A x line pos
188 LineTo(hdc,dn,r.top); // line to AxPos,top
189
190 SelectObject(hdc,hPAdsr[2]); // sel D pen
191 dn+=(id*r.right)/dx; // calc D x line pos
192 dy=r.top+((1024-s_chan[ch].ADSR.SustainLevel)* // calc the D y pos
193 r.bottom)/1024; // (our S level is ranged from 0 to 1024)
194 LineTo(hdc,dn,dy); // line to DxPos,SLevel
195
196 SelectObject(hdc,hPAdsr[3]); // sel S pen
197 if(s_chan[ch].ADSR.SustainTime>10000) dm=1; // we have to fake the S values... S will
198 else // inc/decrease until channel stop...
199 if(s_chan[ch].ADSR.SustainTime==0) dm=0; // we dunno here when this will happen,
200 else dm=21-(((s_chan[ch].ADSR.SustainTime/500))); // so we do some more ore less angled line,
201 dy=dy-(s_chan[ch].ADSR.SustainModeDec*dm); // roughly depending on the S Time
202 if(dy>r.bottom) dy=r.bottom;
203 if(dy<r.top) dy=r.top;
204 dn+=(is*r.right)/dx;
205 LineTo(hdc,dn,dy); // line to SxPos, fake end volume level
206
207 SelectObject(hdc,hPAdsr[4]); // sel R pen
208 dn+=(ir*r.right)/dx; // calc R x line pos
209 LineTo(hdc,dn,r.bottom); // line to RxPos, bottom right y
210
211 SelectObject(hdc,hPO); // repair pen
212 }
213
214 SelectObject(hdc,hBO); // repair brush
215 ReleaseDC(hWS,hdc); // release context
216 }
217
218 ////////////////////////////////////////////////////////////////////////
219
DisplayChannelInfos(HWND hW)220 void DisplayChannelInfos(HWND hW)
221 {
222 int ch=iSelChannel;char szB[16];
223
224 // channel infos
225 SetDlgItemInt(hW,IDC_CI1,s_chan[ch].bOn,TRUE);
226 SetDlgItemInt(hW,IDC_CI2,s_chan[ch].bStop,TRUE);
227 SetDlgItemInt(hW,IDC_CI3,s_chan[ch].bNoise,TRUE);
228 SetDlgItemInt(hW,IDC_CI4,s_chan[ch].bFMod,TRUE);
229 SetDlgItemInt(hW,IDC_CI5,s_chan[ch].bReverb,TRUE);
230 SetDlgItemInt(hW,IDC_CI6,s_chan[ch].bRVBActive,TRUE);
231 SetDlgItemInt(hW,IDC_CI7,s_chan[ch].iRVBNum,TRUE);
232 SetDlgItemInt(hW,IDC_CI8,s_chan[ch].iRVBOffset,TRUE);
233 SetDlgItemInt(hW,IDC_CI9,s_chan[ch].iRVBRepeat,TRUE);
234 SetDlgItemInt(hW,IDC_CI10,(unsigned long)s_chan[ch].pStart-(unsigned long)spuMemC,FALSE);
235 SetDlgItemInt(hW,IDC_CI11,(unsigned long)s_chan[ch].pCurr-(unsigned long)spuMemC,FALSE);
236 SetDlgItemInt(hW,IDC_CI12,(unsigned long)s_chan[ch].pLoop-(unsigned long)spuMemC,FALSE);
237 SetDlgItemInt(hW,IDC_CI13,s_chan[ch].iRightVolume,TRUE);
238 SetDlgItemInt(hW,IDC_CI14,s_chan[ch].iLeftVolume,TRUE);
239 SetDlgItemInt(hW,IDC_CI15,s_chan[ch].iActFreq,TRUE);
240 SetDlgItemInt(hW,IDC_CI16,s_chan[ch].iUsedFreq,TRUE);
241
242 wsprintf(szB,"%04x",s_chan[ch].iRightVolRaw);
243 SetDlgItemText(hW,IDC_CI17,szB);
244 wsprintf(szB,"%04x",s_chan[ch].iLeftVolRaw);
245 SetDlgItemText(hW,IDC_CI18,szB);
246
247 // generic infos
248 if(pSpuIrq==0)
249 SetDlgItemInt(hW,IDC_STA1,-1,TRUE);
250 else SetDlgItemInt(hW,IDC_STA1,(unsigned long)pSpuIrq-(unsigned long)spuMemC,FALSE);
251 wsprintf(szB,"%04x",spuCtrl);
252 SetDlgItemText(hW,IDC_STA2,szB);
253 wsprintf(szB,"%04x",spuStat);
254 SetDlgItemText(hW,IDC_STA3,szB);
255 SetDlgItemInt(hW,IDC_STA4,spuAddr,TRUE);
256
257 // xa infos
258 if(XAPlay<=XAFeed) ch=XAFeed-XAPlay;
259 else ch=(XAFeed-XAStart)+(XAEnd-XAPlay);
260 SetDlgItemInt(hW,IDC_XA4,ch,FALSE);
261 SetDlgItemInt(hW,IDC_XA5,iLeftXAVol,TRUE);
262 SetDlgItemInt(hW,IDC_XA6,iRightXAVol,TRUE);
263 if(!xapGlobal) return;
264 SetDlgItemInt(hW,IDC_XA1,xapGlobal->freq,TRUE);
265 SetDlgItemInt(hW,IDC_XA2,xapGlobal->stereo,TRUE);
266 SetDlgItemInt(hW,IDC_XA3,xapGlobal->nsamples,TRUE);
267 }
268
269 ////////////////////////////////////////////////////////////////////////
270 // display everything (called in dialog timer for value refreshing)
271
DisplayDebugInfos(HWND hW)272 void DisplayDebugInfos(HWND hW)
273 {
274 DisplayStreamInfos(hW);
275 DisplayADSRInfos(hW);
276 DisplayChannelInfos(hW);
277 }
278
279 ////////////////////////////////////////////////////////////////////////
280 // main debug dlg handler
281
DebugDlgProc(HWND hW,UINT uMsg,WPARAM wParam,LPARAM lParam)282 BOOL CALLBACK DebugDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam)
283 {
284 switch(uMsg)
285 {
286 //--------------------------------------------------// init
287 case WM_INITDIALOG:
288 {
289 int i;
290 ShowCursor(TRUE); // mmm... who is hiding it? main emu? tsts
291 iSelChannel=0; // sel first channel
292 CheckRadioButton(hW,IDC_CHAN1,IDC_CHAN24,IDC_CHAN1);
293 // create brushes/pens
294 hBStream[0]=CreateSolidBrush(GetSysColor(COLOR_3DFACE));
295 hPAdsr[0]=CreatePen(PS_SOLID,0,GetSysColor(COLOR_3DFACE));
296 for(i=1;i<6;i++)
297 {
298 hBStream[i]=CreateSolidBrush(crStreamCol[i]);
299 hPAdsr[i]=CreatePen(PS_SOLID,0,crAdsrCol[i]);
300 }
301 SetTimer(hW,999,50,NULL); // now create update timer
302 return TRUE;
303 }
304 //--------------------------------------------------// destroy
305 case WM_DESTROY:
306 {
307 int i;
308 KillTimer(hW,999); // first kill timer
309 for(i=0;i<6;i++) // then kill brushes/pens
310 {
311 DeleteObject(hBStream[i]);
312 DeleteObject(hPAdsr[i]);
313 }
314 }break;
315 //--------------------------------------------------// timer
316 case WM_TIMER:
317 {
318 if(wParam==999) DisplayDebugInfos(hW); // update all values
319 }break;
320 //--------------------------------------------------// command
321 case WM_COMMAND:
322 {
323 if(wParam==IDCANCEL) iDebugMode=2; // cancel? raise flag for destroying the dialog
324
325 if(wParam>=IDC_MUTE1 && wParam<=IDC_MUTE24) // mute clicked?
326 {
327 if(IsDlgButtonChecked(hW,wParam)) // -> mute/unmute it
328 s_chan[wParam-IDC_MUTE1].iMute=1;
329 else s_chan[wParam-IDC_MUTE1].iMute=0;
330 }
331 // all mute/unmute
332 if(wParam==IDC_MUTEOFF) SendMessage(hW,WM_MUTE,0,0);
333 if(wParam==IDC_MUTEON) SendMessage(hW,WM_MUTE,1,0);
334
335 if(wParam>=IDC_CHAN1 && wParam<=IDC_CHAN24) // sel channel
336 {
337 if(IsDlgButtonChecked(hW,wParam))
338 {
339 iSelChannel=wParam-IDC_CHAN1;
340 SetDlgItemInt(hW,IDC_CHANNUM,iSelChannel+1,FALSE);
341 }
342 }
343 }break;
344 //--------------------------------------------------// mute
345 case WM_MUTE:
346 { // will be called by the mute/unmute all button and on savestate load
347 int i;
348 for(i=IDC_MUTE1;i<=IDC_MUTE24;i++)
349 {
350 CheckDlgButton(hW,i,wParam);
351 if(wParam) s_chan[i-IDC_MUTE1].iMute=1;
352 else s_chan[i-IDC_MUTE1].iMute=0;
353 }
354 }break;
355 //--------------------------------------------------// size
356 case WM_SIZE:
357 if(wParam==SIZE_MINIMIZED) SetFocus(hWMain); // if we get minimized, set the foxus to the main window
358 break;
359 //--------------------------------------------------// setcursor
360 case WM_SETCURSOR:
361 {
362 SetCursor(LoadCursor(NULL,IDC_ARROW)); // force the arrow
363 return TRUE;
364 }
365 //--------------------------------------------------//
366 }
367 return FALSE;
368 }
369
370 ////////////////////////////////////////////////////////////////////////
371
372 #endif