- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# ShaderEditorDlg.cpp

    00001 // ShaderEditorDlg.cpp : implementation file
    00002 //
    00003
    00004 #include "stdafx.h"
    00005 #include "mplayerc.h"
    00006 #include "PixelShaderCompiler.h"
    00007 #include "ShaderEditorDlg.h"
    00008
    00009 #undef SubclassWindow
    00010
    00011
    00012 // CShaderLabelComboBox
    00013
    00014 BEGIN_MESSAGE_MAP(CShaderLabelComboBox, CComboBox)
    00015         ON_WM_CTLCOLOR()
    00016         ON_WM_DESTROY()
    00017 END_MESSAGE_MAP()
    00018
    00019 HBRUSH CShaderLabelComboBox::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
    00020 {
    00021         if(nCtlColor == CTLCOLOR_EDIT)
    00022         {
    00023                 if(m_edit.GetSafeHwnd() == NULL)
    00024             m_edit.SubclassWindow(pWnd->GetSafeHwnd());
    00025         }
    00026
    00027         return __super::OnCtlColor(pDC, pWnd, nCtlColor);
    00028 }
    00029
    00030 void CShaderLabelComboBox::OnDestroy()
    00031 {
    00032         if(m_edit.GetSafeHwnd() != NULL)
    00033                 m_edit.UnsubclassWindow();
    00034
    00035         __super::OnDestroy();
    00036 }
    00037
    00038 // CShaderEdit
    00039
    00040 CShaderEdit::CShaderEdit()
    00041 {
    00042         m_acdlg.Create(CShaderAutoCompleteDlg::IDD, NULL);
    00043
    00044         m_nEndChar = -1;
    00045         m_nIDEvent = -1;
    00046 }
    00047
    00048 CShaderEdit::~CShaderEdit()
    00049 {
    00050         m_acdlg.DestroyWindow();
    00051 }
    00052
    00053 BOOL CShaderEdit::PreTranslateMessage(MSG* pMsg)
    00054 {
    00055         if(m_acdlg.IsWindowVisible()
    00056                 && pMsg->message == WM_KEYDOWN
    00057                 && (pMsg->wParam == VK_UP || pMsg->wParam == VK_DOWN
    00058                 || pMsg->wParam == VK_PRIOR || pMsg->wParam == VK_NEXT
    00059                 || pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE))
    00060         {
    00061                 int i = m_acdlg.m_list.GetCurSel();
    00062
    00063                 if(pMsg->wParam == VK_RETURN && i >= 0)
    00064                 {
    00065                         CString str;
    00066                         m_acdlg.m_list.GetText(i, str);
    00067                         i = str.Find('(')+1;
    00068                         if(i > 0) str = str.Left(i);
    00069
    00070                         int nStartChar = 0, nEndChar = -1;
    00071                         GetSel(nStartChar, nEndChar);
    00072
    00073                         CString text;
    00074                         GetWindowText(text);
    00075                         while(nStartChar > 0 && _istalnum(text.GetAt(nStartChar-1)))
    00076                                 nStartChar--;
    00077
    00078                         SetSel(nStartChar, nEndChar);
    00079                         ReplaceSel(str, TRUE);
    00080                 }
    00081                 else if(pMsg->wParam == VK_ESCAPE)
    00082                 {
    00083                         m_acdlg.ShowWindow(SW_HIDE);
    00084                 }
    00085                 else
    00086                 {
    00087                         m_acdlg.m_list.SendMessage(pMsg->message, pMsg->wParam, pMsg->lParam);
    00088                 }
    00089
    00090                 return TRUE;
    00091         }
    00092
    00093         return __super::PreTranslateMessage(pMsg);
    00094 }
    00095
    00096 BEGIN_MESSAGE_MAP(CShaderEdit, CLineNumberEdit)
    00097         ON_CONTROL_REFLECT(EN_UPDATE, OnUpdate)
    00098         ON_WM_KILLFOCUS()
    00099         ON_WM_TIMER()
    00100 END_MESSAGE_MAP()
    00101
    00102 void CShaderEdit::OnUpdate()
    00103 {
    00104         if(m_nIDEvent == -1)
    00105         {
    00106                 m_nIDEvent = SetTimer(1, 100, NULL);
    00107         }
    00108
    00109         CString text;
    00110         int nStartChar = 0, nEndChar = -1;
    00111         GetSel(nStartChar, nEndChar);
    00112
    00113         if(nStartChar == nEndChar)
    00114         {
    00115                 GetWindowText(text);
    00116                 while(nStartChar > 0 && _istalnum(text.GetAt(nStartChar-1)))
    00117                         nStartChar--;
    00118         }
    00119
    00120         if(nStartChar < nEndChar)
    00121         {
    00122                 text = text.Mid(nStartChar, nEndChar - nStartChar);
    00123                 text.TrimRight('(');
    00124                 text.MakeLower();
    00125
    00126                 m_acdlg.m_list.ResetContent();
    00127
    00128                 CString key, value;
    00129                 POSITION pos = m_acdlg.m_inst.GetStartPosition();
    00130                 while(pos)
    00131                 {
    00132                         POSITION cur = pos;
    00133                         m_acdlg.m_inst.GetNextAssoc(pos, key, value);
    00134
    00135                         if(key.Find(text) == 0)
    00136                         {
    00137                                 CList<CString> sl;
    00138                                 Explode(value, sl, '|', 2);
    00139                                 if(sl.GetCount() != 2) continue;
    00140                                 CString name = sl.RemoveHead();
    00141                                 CString description = sl.RemoveHead();
    00142                                 int i = m_acdlg.m_list.AddString(name);
    00143                                 m_acdlg.m_list.SetItemDataPtr(i, cur);
    00144                         }
    00145                 }
    00146
    00147                 if(m_acdlg.m_list.GetCount() > 0)
    00148                 {
    00149                         int lineheight = GetLineHeight();
    00150
    00151                         CPoint p = PosFromChar(nStartChar);
    00152                         p.y += lineheight;
    00153                         ClientToScreen(&p);
    00154                         CRect r(p, CSize(100, 100));
    00155
    00156                         m_acdlg.MoveWindow(r);
    00157                         m_acdlg.SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
    00158                         m_acdlg.ShowWindow(SW_SHOWNOACTIVATE);
    00159
    00160                         m_nEndChar = nEndChar;
    00161
    00162                         return;
    00163                 }
    00164         }
    00165
    00166         m_acdlg.ShowWindow(SW_HIDE);
    00167 }
    00168
    00169 void CShaderEdit::OnKillFocus(CWnd* pNewWnd)
    00170 {
    00171         CString text;
    00172         GetWindowText(text);
    00173         __super::OnKillFocus(pNewWnd);
    00174         GetWindowText(text);
    00175
    00176         m_acdlg.ShowWindow(SW_HIDE);
    00177 }
    00178
    00179 void CShaderEdit::OnTimer(UINT nIDEvent)
    00180 {
    00181         if(m_nIDEvent == nIDEvent)
    00182         {
    00183                 int nStartChar = 0, nEndChar = -1;
    00184                 GetSel(nStartChar, nEndChar);
    00185                 if(nStartChar != nEndChar || m_nEndChar != nEndChar)
    00186                         m_acdlg.ShowWindow(SW_HIDE);
    00187         }
    00188
    00189         __super::OnTimer(nIDEvent);
    00190 }
    00191
    00192 // CShaderEditorDlg dialog
    00193
    00194 CShaderEditorDlg::CShaderEditorDlg(CString label, ISubPicAllocatorPresenter* pCAP, CWnd* pParent /*=NULL*/)
    00195         : CResizableDialog(CShaderEditorDlg::IDD, pParent)
    00196         , m_label(label)
    00197         , m_pCAP(pCAP)
    00198         , m_fSplitterGrabbed(false)
    00199 {
    00200         m_pPSC = new CPixelShaderCompiler(NULL);
    00201 }
    00202
    00203 CShaderEditorDlg::~CShaderEditorDlg()
    00204 {
    00205         delete m_pPSC;
    00206 }
    00207
    00208 void CShaderEditorDlg::DoDataExchange(CDataExchange* pDX)
    00209 {
    00210         __super::DoDataExchange(pDX);
    00211         DDX_Control(pDX, IDC_COMBO1, m_labels);
    00212         DDX_Control(pDX, IDC_COMBO2, m_targets);
    00213         DDX_Control(pDX, IDC_EDIT1, m_srcdata);
    00214         DDX_Control(pDX, IDC_EDIT2, m_output);
    00215 }
    00216
    00217 bool CShaderEditorDlg::HitTestSplitter(CPoint p)
    00218 {
    00219         CRect r, rs, ro;
    00220         m_srcdata.GetWindowRect(&rs);
    00221         m_output.GetWindowRect(&ro);
    00222         ScreenToClient(&rs);
    00223         ScreenToClient(&ro);
    00224         GetClientRect(&r);
    00225         r.left = ro.left;
    00226         r.right = ro.right;
    00227         r.top = rs.bottom;
    00228         r.bottom = ro.top;
    00229         return !!r.PtInRect(p);
    00230 }
    00231
    00232 BEGIN_MESSAGE_MAP(CShaderEditorDlg, CResizableDialog)
    00233         ON_CBN_SELCHANGE(IDC_COMBO1, OnCbnSelchangeCombo1)
    00234         ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
    00235         ON_BN_CLICKED(IDC_BUTTON2, OnBnClickedButton2)
    00236         ON_WM_TIMER()
    00237         ON_WM_CLOSE()
    00238         ON_WM_LBUTTONDOWN()
    00239         ON_WM_LBUTTONUP()
    00240         ON_WM_MOUSEMOVE()
    00241         ON_WM_SETCURSOR()
    00242 END_MESSAGE_MAP()
    00243
    00244
    00245 // CShaderEditorDlg message handlers
    00246
    00247 BOOL CShaderEditorDlg::OnInitDialog()
    00248 {
    00249         __super::OnInitDialog();
    00250
    00251         AddAnchor(IDC_COMBO1, TOP_LEFT, TOP_RIGHT);
    00252         AddAnchor(IDC_COMBO2, TOP_RIGHT);
    00253         AddAnchor(IDC_BUTTON1, TOP_RIGHT);
    00254         AddAnchor(IDC_BUTTON2, TOP_RIGHT);
    00255         AddAnchor(IDC_EDIT1, TOP_LEFT, BOTTOM_RIGHT);
    00256         AddAnchor(IDC_EDIT2, BOTTOM_LEFT, BOTTOM_RIGHT);
    00257
    00258         m_srcdata.SetTabStops(16);
    00259
    00260         CRect r;
    00261         GetWindowRect(r);
    00262         CSize s = r.Size();
    00263         s.cx = 400;
    00264         s.cy = 150;
    00265         SetMinTrackSize(s);
    00266
    00267         CMap<CString, LPCTSTR, bool, bool> targetmap;
    00268         targetmap[_T("ps_1_1")] = true;
    00269         targetmap[_T("ps_1_2")] = true;
    00270         targetmap[_T("ps_1_3")] = true;
    00271         targetmap[_T("ps_1_4")] = true;
    00272         targetmap[_T("ps_2_0")] = true;
    00273         targetmap[_T("ps_2_a")] = true;
    00274         targetmap[_T("ps_2_sw")] = true;
    00275         targetmap[_T("ps_3_0")] = true;
    00276         targetmap[_T("ps_3_sw")] = true;
    00277
    00278         int nSelIndex = -1;
    00279
    00280         for(int i = 0; ; i++)
    00281         {
    00282                 CString str;
    00283                 str.Format(_T("%d"), i);
    00284                 str = AfxGetApp()->GetProfileString(_T("Shaders"), str);
    00285
    00286                 CList<CString> sl;
    00287                 Explode(str, sl, '|', 3);
    00288                 if(sl.GetCount() != 3) break;
    00289
    00290                 CString label = sl.RemoveHead();
    00291                 CString target = sl.RemoveHead();
    00292                 CString srcdata = sl.RemoveHead();
    00293                 srcdata.Replace(_T("\\n"), _T("\r\n"));
    00294                 srcdata.Replace(_T("\\t"), _T("\t"));
    00295
    00296                 targetmap[target] = false;
    00297
    00298                 shader_t s = {target, srcdata};
    00299                 m_shaders[label] = s;
    00300
    00301                 int nIndex = m_labels.AddString(label);
    00302
    00303                 if(m_label == label)
    00304                         nSelIndex = nIndex;
    00305         }
    00306
    00307         m_labels.SetCurSel(nSelIndex);
    00308
    00309         POSITION pos = targetmap.GetStartPosition();
    00310         while(pos)
    00311         {
    00312                 CString target;
    00313                 bool b;
    00314                 targetmap.GetNextAssoc(pos, target, b);
    00315                 m_targets.AddString(target);
    00316         }
    00317
    00318         OnCbnSelchangeCombo1();
    00319
    00320         m_nIDEventShader = SetTimer(1, 1000, NULL);
    00321
    00322         return TRUE;  // return TRUE unless you set the focus to a control
    00323         // EXCEPTION: OCX Property Pages should return FALSE
    00324 }
    00325
    00326 BOOL CShaderEditorDlg::PreTranslateMessage(MSG* pMsg)
    00327 {
    00328         if(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN
    00329                 && pMsg->hwnd == m_labels.m_edit.GetSafeHwnd())
    00330         {
    00331                 CString label;
    00332                 m_labels.GetWindowText(label);
    00333
    00334                 shader_t s;
    00335                 m_labels.SetCurSel(!m_shaders.Lookup(label, s)
    00336                         ? m_labels.AddString(label)
    00337                         : m_labels.FindStringExact(0, label));
    00338
    00339                 OnCbnSelchangeCombo1();
    00340
    00341                 return TRUE;
    00342         }
    00343         else if(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_TAB
    00344                 && pMsg->hwnd == m_srcdata.GetSafeHwnd())
    00345         {
    00346                 int nStartChar, nEndChar;
    00347                 m_srcdata.GetSel(nStartChar, nEndChar);
    00348
    00349                 if(nStartChar == nEndChar)
    00350             m_srcdata.ReplaceSel(_T("\t"));
    00351
    00352                 return TRUE;
    00353         }
    00354         else if(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE)
    00355         {
    00356                 return TRUE;
    00357         }
    00358
    00359         return __super::PreTranslateMessage(pMsg);
    00360 }
    00361
    00362 void CShaderEditorDlg::OnCbnSelchangeCombo1()
    00363 {
    00364         int i = m_labels.GetCurSel();
    00365         if(i < 0) return;
    00366         CString label;
    00367         m_labels.GetLBText(i, label);
    00368         if(label.IsEmpty()) return;
    00369
    00370         shader_t s;
    00371
    00372         if(!m_shaders.Lookup(label, s))
    00373         {
    00374                 s.target = _T("ps_2_0");
    00375                 s.srcdata =
    00376             "sampler s0 : register(s0);\r\n"
    00377                         "float4 p0 : register(c0);\r\n"
    00378             "\r\n"
    00379                         "#define width (p0[0])\r\n"
    00380                         "#define height (p0[1])\r\n"
    00381                         "#define counter (p0[2])\r\n"
    00382             "#define clock (p0[3])\r\n"
    00383                         "\r\n"
    00384                         "float4 main(float2 tex : TEXCOORD0) : COLOR\r\n"
    00385                         "{\r\n"
    00386                         "\tfloat4 c0 = tex2D(s0, tex);\r\n"
    00387                         "\t// TODO\r\n"
    00388                         "\treturn c0;\r\n"
    00389                         "}\r\n";
    00390                 m_shaders[label] = s;
    00391         }
    00392
    00393         if(m_shaders.Lookup(label, s))
    00394         {
    00395                 m_targets.SetWindowText(s.target);
    00396                 m_srcdata.SetWindowText(s.srcdata);
    00397         }
    00398 }
    00399
    00400 void CShaderEditorDlg::OnBnClickedButton1()
    00401 {
    00402         CString label;
    00403         m_labels.GetWindowText(label);
    00404         int nIndex = m_labels.FindStringExact(0, label);
    00405         if(nIndex >= 0) m_labels.DeleteString(nIndex);
    00406         m_labels.SetWindowText(_T(""));
    00407         m_targets.SetWindowText(_T(""));
    00408         m_srcdata.SetWindowText(_T(""));
    00409         m_shaders.RemoveKey(label);
    00410 }
    00411
    00412 void CShaderEditorDlg::OnBnClickedButton2()
    00413 {
    00414         CString label;
    00415         m_labels.GetWindowText(label);
    00416         m_targets.GetWindowText(m_shaders[label].target);
    00417         m_srcdata.GetWindowText(m_shaders[label].srcdata);
    00418         if(m_labels.FindStringExact(0, label) < 0)
    00419                 m_labels.SetCurSel(m_labels.AddString(label));
    00420 }
    00421
    00422 void CShaderEditorDlg::OnTimer(UINT nIDEvent)
    00423 {
    00424         if(nIDEvent == m_nIDEventShader)
    00425         {
    00426                 static CString s_srcdata, s_target;
    00427
    00428                 CString srcdata;
    00429                 m_srcdata.GetWindowText(srcdata);
    00430                 srcdata.Trim();
    00431
    00432                 CString target;
    00433                 m_targets.GetWindowText(target);
    00434                 target.Trim();
    00435
    00436                 if(!srcdata.IsEmpty() && !target.IsEmpty() && (s_srcdata != srcdata || s_target != target))
    00437                 {
    00438                         CString disasm, errmsg(_T("Unknown Error"));
    00439
    00440                         HRESULT hr = m_pPSC->CompileShader(CStringA(srcdata), "main", CStringA(target), D3DXSHADER_DEBUG, NULL, &disasm, &errmsg);
    00441
    00442                         if(SUCCEEDED(hr))
    00443                         {
    00444                                 errmsg = _T("D3DXCompileShader succeeded\n");
    00445                                 if(m_pCAP && FAILED(m_pCAP->SetPixelShader(CStringA(srcdata), CStringA(target))))
    00446                                         errmsg += _T("SetPixelShader failed\n");
    00447                                 errmsg += _T("\n");
    00448                                 errmsg += disasm;
    00449                         }
    00450
    00451                         errmsg.Replace(_T("\n"), _T("\r\n"));
    00452
    00453                         m_output.SetWindowText(errmsg);
    00454                 }
    00455
    00456                 s_srcdata = srcdata;
    00457                 s_target = target;
    00458         }
    00459
    00460         __super::OnTimer(nIDEvent);
    00461 }
    00462
    00463 void CShaderEditorDlg::OnClose()
    00464 {
    00465         if(IDYES == AfxMessageBox(_T("Save changes?"), MB_YESNO))
    00466         {
    00467                 OnBnClickedButton2();
    00468
    00469                 CWinApp* pApp = AfxGetApp();
    00470
    00471                 pApp->WriteProfileString(_T("Shaders"), NULL, NULL);
    00472                 pApp->WriteProfileInt(_T("Shaders"), _T("Initialized"), 1);
    00473
    00474                 for(int i = 0, id = 0; i < m_labels.GetCount(); i++)
    00475                 {
    00476                         CString label;
    00477                         m_labels.GetLBText(i, label);
    00478
    00479                         shader_t s;
    00480                         if(!label.IsEmpty() && m_shaders.Lookup(label, s))
    00481                         {
    00482                                 CString str;
    00483                                 str.Format(_T("%d"), id++);
    00484                                 s.srcdata.Replace(_T("\r"), _T(""));
    00485                                 s.srcdata.Replace(_T("\n"), _T("\\n"));
    00486                                 s.srcdata.Replace(_T("\t"), _T("\\t"));
    00487                                 AfxGetApp()->WriteProfileString(_T("Shaders"), str, label + _T("|") + s.target + _T("|") + s.srcdata);
    00488                         }
    00489                 }
    00490         }
    00491
    00492         __super::OnClose();
    00493 }
    00494
    00495 void CShaderEditorDlg::OnLButtonDown(UINT nFlags, CPoint point)
    00496 {
    00497         if(HitTestSplitter(point))
    00498         {
    00499                 m_fSplitterGrabbed = true;
    00500                 SetCapture();
    00501         }
    00502
    00503         __super::OnLButtonDown(nFlags, point);
    00504 }
    00505
    00506 void CShaderEditorDlg::OnLButtonUp(UINT nFlags, CPoint point)
    00507 {
    00508         if(m_fSplitterGrabbed)
    00509         {
    00510                 ReleaseCapture();
    00511                 m_fSplitterGrabbed = false;
    00512         }
    00513
    00514         __super::OnLButtonUp(nFlags, point);
    00515 }
    00516
    00517 void CShaderEditorDlg::OnMouseMove(UINT nFlags, CPoint point)
    00518 {
    00519         if(m_fSplitterGrabbed)
    00520         {
    00521                 CRect r, rs, ro;
    00522                 GetClientRect(&r);
    00523                 m_srcdata.GetWindowRect(&rs);
    00524                 m_output.GetWindowRect(&ro);
    00525                 ScreenToClient(&rs);
    00526                 ScreenToClient(&ro);
    00527
    00528                 int dist = ro.top - rs.bottom;
    00529                 int avgdist = dist / 2;
    00530
    00531                 rs.bottom = min(max(point.y, rs.top + 40), ro.bottom - 40) - avgdist;
    00532                 ro.top = rs.bottom + dist;
    00533                 m_srcdata.MoveWindow(&rs);
    00534                 m_output.MoveWindow(&ro);
    00535
    00536                 int div = 100 * ((rs.bottom + ro.top) / 2) / (ro.bottom - rs.top);
    00537
    00538                 RemoveAnchor(IDC_EDIT1);
    00539                 RemoveAnchor(IDC_EDIT2);
    00540                 AddAnchor(IDC_EDIT1, TOP_LEFT, CSize(100, div)/*BOTTOM_RIGHT*/);
    00541                 AddAnchor(IDC_EDIT2, CSize(0, div)/*BOTTOM_LEFT*/, BOTTOM_RIGHT);
    00542         }
    00543
    00544         __super::OnMouseMove(nFlags, point);
    00545 }
    00546
    00547 BOOL CShaderEditorDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
    00548 {
    00549         CPoint p;
    00550         GetCursorPos(&p);
    00551         ScreenToClient(&p);
    00552         if(HitTestSplitter(p))
    00553         {
    00554                 ::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZENS));
    00555                 return TRUE;
    00556         }
    00557
    00558         return __super::OnSetCursor(pWnd, nHitTest, message);
    00559 }
    00560