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