void CMagneticView::ClearAll(void) { CMagneticApp* pApp = (CMagneticApp*)AfxGetApp(); m_strOutput.Empty(); m_strStatLocation.Empty(); m_strStatScore.Empty(); m_strStatCurrent.Empty(); m_Scrollback.GetScrollback().Empty(); m_PageTable.RemoveAll(); m_Input.RemoveAll(); m_History.RemoveAll(); m_iLines = 0; m_iMaxLines = 0; m_bStatusBar = false; m_bAnimate = false; pApp->SetGameLoaded(0); m_Recording = Recording::RecordingOff; if (m_pFileRecord) fclose(m_pFileRecord); m_pFileRecord = NULL; m_Scripting = Scripting::ScriptingOff; if (m_pFileScript) fclose(m_pFileScript); m_pFileScript = NULL; m_strScript.Empty(); if (m_PicWnd.GetSafeHwnd()) m_PicWnd.SendMessage(WM_CLOSE,0,0); m_Picture.ClearAll(); SetAnimate(FALSE); ClearAnims(); }
void CMagneticView::OnRecord() { CMagneticApp* pApp = (CMagneticApp*)AfxGetApp(); SimpleFileDialog RecordDlg(FALSE,NULL,m_strRecName,OFN_HIDEREADONLY|OFN_ENABLESIZING, "Record Files (*.rec)|*.rec|All Files (*.*)|*.*||",this); RecordDlg.m_ofn.lpstrTitle = "Record Input File"; switch (m_Recording) { case Recording::RecordingOff: if (ms_is_running()) pApp->SetRedrawStatus(CMagneticApp::Redraw::ThisLine); if (RecordDlg.DoModal() == IDOK) { m_strRecName = RecordDlg.GetPathName(); if ((m_pFileRecord = fopen(m_strRecName,"wt")) != NULL) m_Recording = Recording::RecordingOn; } break; case Recording::RecordingOn: if (m_pFileRecord) fclose(m_pFileRecord); m_pFileRecord = NULL; m_Recording = Recording::RecordingOff; break; case Recording::PlaybackOn: break; } }
void CMagneticView::OnScrollback() { CMagneticApp* pApp = (CMagneticApp*)AfxGetApp(); pApp->SetRedrawStatus(CMagneticApp::Redraw::ThisLine); m_Scrollback.DoModal(); }
void CMagneticView::OnPlayback() { CMagneticApp* pApp = (CMagneticApp*)AfxGetApp(); SimpleFileDialog PlayDlg(TRUE,NULL,m_strRecName, OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_ENABLESIZING, "Record Files (*.rec)|*.rec|All Files (*.*)|*.*||",this); PlayDlg.m_ofn.lpstrTitle = "Play Back a File"; switch (m_Recording) { case Recording::RecordingOff: if (ms_is_running()) pApp->SetRedrawStatus(CMagneticApp::Redraw::ThisLine); if (PlayDlg.DoModal() == IDOK) { m_strRecName = PlayDlg.GetPathName(); if ((m_pFileRecord = fopen(m_strRecName,"rt")) != NULL) { m_Recording = Recording::PlaybackOn; if (pApp->GetGameLoaded() && ms_is_running()) pApp->SetRedrawStatus(CMagneticApp::Redraw::EndPlayback); } } break; case Recording::RecordingOn: break; case Recording::PlaybackOn: if (m_pFileRecord) fclose(m_pFileRecord); m_pFileRecord = NULL; m_Recording = Recording::RecordingOff; break; } }
void CMagneticView::OnScript() { CMagneticApp* pApp = (CMagneticApp*)AfxGetApp(); SimpleFileDialog ScriptDlg(FALSE,NULL,m_strScrName,OFN_HIDEREADONLY|OFN_ENABLESIZING, "Script Files (*.scr)|*.scr|All Files (*.*)|*.*||",this); ScriptDlg.m_ofn.lpstrTitle = "Scripting"; switch (m_Scripting) { case Scripting::ScriptingOff: if (ms_is_running()) pApp->SetRedrawStatus(CMagneticApp::Redraw::ThisLine); if (ScriptDlg.DoModal() == IDOK) { m_strScrName = ScriptDlg.GetPathName(); if ((m_pFileScript = fopen(m_strScrName,"wt")) != NULL) m_Scripting = Scripting::ScriptingOn; } break; case Scripting::ScriptingOn: if (m_pFileScript) fclose(m_pFileScript); m_pFileScript = NULL; m_Scripting = Scripting::ScriptingOff; break; } }
void CMagneticView::OnScrollback() { CMagneticApp* pApp = (CMagneticApp*)AfxGetApp(); pApp->SetRedrawStatus(CMagneticApp::Redraw::ThisLine); AfxGetMainWnd()->GetWindowRect(m_Scrollback.GetRect()); m_Scrollback.DoModal(); }
type8 ms_getchar(type8 trans) { bool done = false; char c = 0; do { CMagneticView* pView = CMagneticView::GetView(); if (pView == NULL) return 1; if (pView->GetRecording() == CMagneticView::Recording::PlaybackOn) { if (pView->GetRecordFile()) { CMagneticApp* pApp = (CMagneticApp*)AfxGetApp(); if (pApp->GetAnimWait()) { while (pView->GetAnimate() && (ms_anim_is_repeating() == 0)) { if (pApp->PumpMessage() == FALSE) { ::PostQuitMessage(0); return 1; } pApp->CWinApp::OnIdle(0); } } char cInput = CMagneticView::GetPlaybackChar(pView->GetRecordFile()); if (feof(pView->GetRecordFile()) != 0) { pView->SetRecording(CMagneticView::Recording::RecordingOff); fclose(pView->GetRecordFile()); pView->SetRecordFile(NULL); pView->ClearPagination(); } else { if (cInput == '\n') { cInput = 10; pView->TrimOutput(); pView->GetPageTable().RemoveAll(); pView->Invalidate(); } else pView->AddOutChar(cInput); return cInput; } } } c = CMagneticView::GetInput(done,trans != 0); } while (done == false); return c; }
BOOL CMagneticView::LineFull(CDC* pDC, LPCSTR lpszText, int iLength) { CMagneticApp* pApp = (CMagneticApp*)AfxGetApp(); CSize TextLen = pDC->GetTextExtent(lpszText,iLength); CRect Client; GetClientRect(Client); return (TextLen.cx >= (Client.Width()-(2*pApp->GetMargins().cx))) ? 1 : 0; }
int CMagneticPic::GetScaledWidth(void) const { int iWidth = 0; if (m_pBitmap && m_pBitmapInfo) { CMagneticApp* pApp = (CMagneticApp*)AfxGetApp(); double dScale = pApp->GetScaleFactor(); iWidth = (int)(m_Size.cx * dScale); } return iWidth; }
int CMagneticPic::GetScaledHeight(void) const { int iHeight = 0; if (m_pBitmap && m_pBitmapInfo) { CMagneticApp* pApp = (CMagneticApp*)AfxGetApp(); double dScale = pApp->GetScaleFactor(); iHeight = (int)(m_Size.cy * dScale); } return iHeight; }
BOOL CMagneticView::OnEraseBkgnd(CDC* pDC) { CMagneticApp* pApp = (CMagneticApp*)AfxGetApp(); CRect Background; GetClientRect(Background); if (pApp->GetGameLoaded() == 0) pDC->FillSolidRect(Background,pApp->GetBackColour()); return 1; }
void CPictureWnd::OnDestroy() { CMagneticApp* pApp = (CMagneticApp*)AfxGetApp(); // Store the position of the top-left corner of the window. CRect rWnd; CPoint& TopLeft = pApp->GetPicTopLeft(); GetWindowRect(rWnd); TopLeft = rWnd.TopLeft(); CWnd::OnDestroy(); }
type8 ms_showhints(struct ms_hint * hints) { CMagneticView* pView = CMagneticView::GetView(); if (pView == NULL) return 0; CMagneticApp* pApp = (CMagneticApp*)AfxGetApp(); if (pApp->GetUseHintWindow() == FALSE) return 0; if (ms_is_running()) pApp->SetRedrawStatus(CMagneticApp::Redraw::ThisLine); pView->m_hintDlg.SetHints(hints); pView->m_hintDlg.DoModal(); return 1; }
void CMagneticView::TextSetup(void) { CMagneticApp* pApp = (CMagneticApp*)AfxGetApp(); if (m_pTextDC) return; // Set up a device context for font information m_pTextDC = new CPaintDC(this); // Create the font m_pTextFont = new CFont(); m_pTextFont->CreateFontIndirect(pApp->GetLogFont()); m_pOldFont = m_pTextDC->SelectObject(m_pTextFont); }
void CMagneticView::SetCursorPos(CDC* pDC, int iRight) { CMagneticApp* pApp = (CMagneticApp*)AfxGetApp(); int i = m_PageTable.GetSize()-2; // Start of the last visible line int offset = m_iLines-m_iMaxLines-1; if (offset > 0) i -= offset; if (i >= 0) { CSize TextLen = pDC->GetTextExtent((LPCTSTR)m_strOutput+m_PageTable[i], m_PageTable[i+1]-m_PageTable[i]-1-iRight); // Set the caret position SetCaretPos(CPoint(TextLen.cx+pApp->GetMargins().cx,m_LastLineRect.top)); } }
void ms_fatal(type8s *txt) { static bool InProgress = false; if (InProgress == false) { InProgress = true; CString Error; Error.Format("Magnetic has encountered an internal error:\n%s",txt ? (char*)txt : ""); AfxGetMainWnd()->MessageBox(Error,"Internal Error",MB_ICONERROR|MB_OK); ms_stop(); CMagneticApp* pApp = (CMagneticApp*)AfxGetApp(); pApp->SetRedrawStatus(CMagneticApp::Redraw::EndOpcode); InProgress = false; } }
void ms_showpic(type32 c, type8 mode) { CMagneticApp* pApp = (CMagneticApp*)AfxGetApp(); if (pApp->GetShowGraphics() != CMagneticApp::ShowGraphics::NoGraphics) { CMagneticView* pView = CMagneticView::GetView(); if (pView == NULL) return; type8 *pPictureData = NULL; type16 Width, Height; type8 IsAnim = 0; switch (mode) { case 0: // Graphics off if (pView->GetPictureWindow().GetSafeHwnd()) pView->GetPictureWindow().SendMessage(WM_CLOSE,0,0); pView->GetPicture().ClearAll(); pView->SetAnimate(FALSE); pView->ClearAnims(); break; case 1: // Graphics on (thumbnails) case 2: // Graphics on (normal) pView->SetAnimate(FALSE); pView->ClearAnims(); pPictureData = ms_extract(c,&Width,&Height,pView->GetPalette(),&IsAnim); if (pPictureData) { pView->GetPicture().NewPicture(Width,Height,pPictureData,pView->GetPalette()); pView->SetAnimate(IsAnim != 0); if (IsAnim != 0) pView->Animate(); pView->Invalidate(); pView->SetPictureWindowState(); } break; } } }
void CMagneticView::SetPictureWindowState(void) { CMagneticApp* pApp = (CMagneticApp*)AfxGetApp(); if (pApp->GetShowGraphics() == CMagneticApp::ShowGraphics::SeparateWindow) { if ((m_PicWnd.GetSafeHwnd() == NULL) && (m_Picture.IsValid())) { if (m_PicWnd.CreatePicWnd(this)) SetFocus(); } m_PicWnd.Update(); } else { if (m_PicWnd.GetSafeHwnd()) m_PicWnd.SendMessage(WM_CLOSE,0,0); } }
void CMagneticView::Animate(void) { CMagneticApp* pApp = (CMagneticApp*)AfxGetApp(); if (m_bAnimate && (pApp->GetShowGraphics() != CMagneticApp::ShowGraphics::NoGraphics)) { struct ms_position * Positions; type16 Count, Width, Height; type8 * pMask; if (ms_animate(&Positions,&Count) == 0) { m_bAnimate = false; return; } ClearAnims(); for (int i = 0; i < Count; i++) { type8* pPictureData = ms_get_anim_frame(Positions[i].number,&Width,&Height,&pMask); if (pPictureData) { CMagneticPic* pFrame = new CMagneticPic(); pFrame->NewPicture(Width,Height,pPictureData,m_Palette); pFrame->SetOrigin(CPoint(Positions[i].x,Positions[i].y)); pFrame->SetMask(pMask); m_AnimFrames.Add(pFrame); } } switch (pApp->GetShowGraphics()) { case CMagneticApp::ShowGraphics::SeparateWindow: if (m_PicWnd.GetSafeHwnd()) m_PicWnd.Invalidate(); break; case CMagneticApp::ShowGraphics::MainWindow: Invalidate(); break; } } }
BOOL CPictureWnd::CreatePicWnd(CWnd* pParent, const RECT& rect) { CMagneticApp* pApp = (CMagneticApp*)AfxGetApp(); m_pMagneticWnd = pParent; BOOL bCreate = CreateEx(0,AfxRegisterWndClass(0),"Magnetic", WS_CAPTION|WS_VISIBLE|WS_SYSMENU,rect,pParent,0,NULL); if (bCreate == FALSE) return FALSE; SetIcon(pApp->LoadIcon(IDR_MAINFRAME),TRUE); // Get the horizontal and vertical border sizes CRect r1, r2; GetWindowRect(r1); GetClientRect(r2); m_Borders.cx = r1.Width() - r2.Width(); m_Borders.cy = r1.Height() - r2.Height(); return TRUE; }
void CMagneticView::OnToggleGfx() { CMagneticApp* pApp = (CMagneticApp*)AfxGetApp(); if (GetFocus() == this) { if (m_bMorePrompt == false) { switch (pApp->GetShowGraphics()) { case CMagneticApp::ShowGraphics::NoGraphics: pApp->SetShowGraphics(CMagneticApp::ShowGraphics::SeparateWindow); break; case CMagneticApp::ShowGraphics::SeparateWindow: pApp->SetShowGraphics(CMagneticApp::ShowGraphics::MainWindow); break; case CMagneticApp::ShowGraphics::MainWindow: pApp->SetShowGraphics(CMagneticApp::ShowGraphics::NoGraphics); break; } pApp->SetRedrawStatus(CMagneticApp::Redraw::ThisLine); SetPictureWindowState(); } } }
type8 ms_load_file(type8s *name, type8 *ptr, type16 size) { CMagneticApp* pApp = (CMagneticApp*)AfxGetApp(); CString strLoadName; FILE *fh; if (name == NULL) { CMagneticView* pView = CMagneticView::GetView(); if (pView == NULL) return 0; SimpleFileDialog LoadDlg(TRUE,NULL,pView->GetFileName(), OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_ENABLESIZING, "Saved Game Files (*.sav)|*.sav|All Files (*.*)|*.*||",pView); LoadDlg.m_ofn.lpstrTitle = "Load a Saved Game"; if (ms_is_running()) pApp->SetRedrawStatus(CMagneticApp::Redraw::ThisLine); if (LoadDlg.DoModal() == IDOK) { strLoadName = LoadDlg.GetPathName(); pView->GetFileName() = strLoadName; } else return 0; } else strLoadName = (char*)name; if ((fh = fopen(strLoadName,"rb")) == NULL) return 1; if (fread(ptr,1,size,fh) != size) return 1; fclose(fh); return 0; }
BOOL CScrollBackDlg::OnInitDialog() { BaseDialog::OnInitDialog(); CMagneticApp* pApp = (CMagneticApp*)AfxGetApp(); // Subclass the text control if (m_RichEdit.SubclassDlgItem(IDC_TEXT,this) == FALSE) return FALSE; // Get the relative position of the top of the text control CRect size; m_RichEdit.GetWindowRect(size); ScreenToClient(size); m_TextTop = size.top; // Change the window icon SetIcon(pApp->LoadIcon(IDR_MAINFRAME),TRUE); // Resize the dialog BaseDialog::MoveWindow(m_DialogRect); // Set the control to format the text so that it fits // into the window m_RichEdit.SetTargetDevice(NULL,0); // Set the background colour m_RichEdit.SetBackgroundColor(FALSE,GetSysColor(COLOR_3DFACE)); // Put the text into the control m_RichEdit.SetWindowText(m_strScrollback); // Put the cursor at the end of the buffer m_RichEdit.SetSel(-1,-1); m_RichEdit.SendMessage(EM_SCROLLCARET); return TRUE; }
char CMagneticView::GetInput(bool& done, bool trans) { static const int MAX_HISTORY = 20; done = true; CMagneticApp* pApp = (CMagneticApp*)AfxGetApp(); CMagneticView* pView = CMagneticView::GetView(); if (pView == NULL) return 0; int cInput = 0; // Input character int iPosition = 0; // Current cursor position int iHistory = -1; // Current history position static CString strFullLine; // Input line already obtained? if (strFullLine.GetLength() > 0) { cInput = strFullLine[0]; strFullLine = strFullLine.Right(strFullLine.GetLength()-1); if (cInput == (signed char)(CMagneticView::SPECIAL_KEYS + VK_SPACE)) cInput = ' '; return (char)cInput; } if (pView->m_bMorePrompt) pView->m_PageTable.RemoveAt(pView->m_PageTable.GetSize()-1); else pView->m_PageTable.RemoveAll(); // Refresh the view pView->Invalidate(); pView->CaretOn(); pView->m_bInputActive = true; while (cInput != 10 && cInput != 1) { pView = CMagneticView::GetView(); if (pView == NULL) break; // Wait for a character CArray<int, int>& Input = pView->m_Input; if (Input.GetSize() == 0) { pApp->PumpMessage(); pApp->CWinApp::OnIdle(0); // Call base class OnIdle(); pView = CMagneticView::GetView(); if (pView) { CMagneticApp::Redraw Status = pApp->GetRedrawStatus(); switch (Status) { case CMagneticApp::Redraw::EndPlayback: done = false; // intentional fall-through case CMagneticApp::Redraw::EndLine: case CMagneticApp::Redraw::EndOpcode: Input.RemoveAll(); strFullLine.Empty(); if (Status == CMagneticApp::Redraw::EndOpcode) cInput = 1; else cInput = 10; // intentional fall-through case CMagneticApp::Redraw::ThisLine: pView->CaretOff(); pView->CaretOn(); pView->Invalidate(); break; } pView->SetCursorPos(pView->m_pTextDC,strFullLine.GetLength()-iPosition); } } else { cInput = (pView->m_bMorePrompt) ? 10 : Input[0]; Input.RemoveAt(0); int iInsertPos, iRemovePos; switch (cInput) { case 10: // Return strFullLine += (char)cInput; break; case CMagneticView::SPECIAL_KEYS + VK_LEFT: // Cursor left if (iPosition > 0) iPosition--; break; case CMagneticView::SPECIAL_KEYS + VK_RIGHT: // Cursor right if (iPosition < strFullLine.GetLength()) iPosition++; break; case CMagneticView::SPECIAL_KEYS + VK_HOME: // Home iPosition = 0; break; case CMagneticView::SPECIAL_KEYS + VK_END: // End iPosition = strFullLine.GetLength(); break; case CMagneticView::SPECIAL_KEYS + VK_DELETE: // Delete if (iPosition < strFullLine.GetLength()) { iRemovePos = strFullLine.GetLength() - iPosition; pView->RemoveChar(strFullLine,iRemovePos); pView->RemoveChar(pView->m_strOutput,iRemovePos,TRUE); } break; case 8: // Backspace if (iPosition > 0) { iRemovePos = strFullLine.GetLength() - iPosition + 1; pView->RemoveChar(strFullLine,iRemovePos); pView->RemoveChar(pView->m_strOutput,iRemovePos,TRUE); iPosition--; } break; case CMagneticView::SPECIAL_KEYS + VK_UP: // Cursor up if (iHistory < pView->m_History.GetSize()-1) iHistory++; if ((iHistory >= 0) && (pView->m_History.GetSize() > 0)) { int iOldLength = strFullLine.GetLength(); strFullLine = pView->m_History[iHistory]; pView->UseHistory(strFullLine,iOldLength); iPosition = strFullLine.GetLength(); } break; case CMagneticView::SPECIAL_KEYS + VK_DOWN: // Cursor down if (iHistory > 0) iHistory--; if ((iHistory >= 0) && (pView->m_History.GetSize() > 0)) { int iOldLength = strFullLine.GetLength(); strFullLine = pView->m_History[iHistory]; pView->UseHistory(strFullLine,iOldLength); iPosition = strFullLine.GetLength(); } break; case CMagneticView::SPECIAL_KEYS + VK_SPACE: // Space iInsertPos = strFullLine.GetLength() - iPosition; pView->InsertChar(pView->m_strOutput,(char)cInput,iInsertPos,TRUE); pView->InsertChar(strFullLine,(char)cInput,iInsertPos); iPosition++; break; default: if (isprint(cInput) && (cInput < CMagneticView::SPECIAL_KEYS)) { // Insert the character into the input string iInsertPos = strFullLine.GetLength() - iPosition; pView->InsertChar(pView->m_strOutput,(char)cInput,iInsertPos,TRUE); pView->InsertChar(strFullLine,(char)cInput,iInsertPos); iPosition++; } break; } // Update the input line pView->InvalidateRect(pView->m_LastLineRect,FALSE); } } if (pView && (strFullLine.GetLength() > 0)) { if (pView->m_bMorePrompt == false) { // Store in input history CString strHistory = strFullLine.Left(strFullLine.GetLength()-1); if (strHistory.GetLength() > 0) { pView->m_History.InsertAt(0,strHistory); if (pView->m_History.GetSize() > MAX_HISTORY) pView->m_History.RemoveAt(pView->m_History.GetSize()-1); } int i; while ((i = strHistory.Find((char)(CMagneticView::SPECIAL_KEYS + VK_SPACE))) >= 0) strHistory.SetAt(i,' '); // Input recording if ((pView->m_Recording == Recording::RecordingOn) && (pView->m_pFileRecord)) fprintf(pView->m_pFileRecord,"%s\n",strHistory); // Scrollback buffer pView->m_Scrollback.GetScrollback() += strHistory; // Scripting if (pView->m_Scripting == Scripting::ScriptingOn) pView->m_strScript += strHistory; } if (trans && (strFullLine.CompareNoCase("#undo\n") == 0)) { cInput = 0; strFullLine.Empty(); } else { cInput = strFullLine[0]; strFullLine = strFullLine.Right(strFullLine.GetLength()-1); } } if (pView) { pView->m_iLines = 0; pView->m_bInputActive = false; pView->CaretOff(); } if (cInput == (signed char)(CMagneticView::SPECIAL_KEYS + VK_SPACE)) cInput = ' '; return (char)cInput; }
BOOL CMagneticView::OpenGame(LPCTSTR lpszPathName) { CMagneticApp* pApp = (CMagneticApp*)AfxGetApp(); CMagneticView* pView = CMagneticView::GetView(); if (pApp->GetGameLoaded() && ms_is_running()) pApp->SetRedrawStatus(CMagneticApp::Redraw::EndOpcode); if (pView) pView->ClearAll(); CString strGfxName, strHntName, strSndName; MakeFilePath(strGfxName,lpszPathName,".gfx"); MakeFilePath(strHntName,lpszPathName,".hnt"); MakeFilePath(strSndName,lpszPathName,".snd"); // Free previous game ms_freemem(); // Initialize new game pApp->SetGameLoaded(ms_init((type8s*)lpszPathName, (type8s*)((LPCTSTR)strGfxName), (type8s*)((LPCTSTR)strHntName), (type8s*)((LPCTSTR)strSndName))); // If required, make the random number generator predictable if (pApp->GetPredictable()) ms_seed(pApp->GetRandomSeed()); // Check status of loaded game if (pApp->GetGameLoaded() == 0) { CString strMessage; strMessage.Format("Failed to load game \"%s\"",lpszPathName); AfxMessageBox(strMessage,MB_ICONEXCLAMATION); } else { if (pView) { pView->m_bStatusBar = false; pView->Invalidate(); } // Show the title picture, if possible CMagneticTitleDlg Title; Title.ShowTitle(lpszPathName); if (pView) { // Set up default file names MakeFilePath(pView->m_strRecName,lpszPathName,".rec"); MakeFilePath(pView->m_strScrName,lpszPathName,".scr"); MakeFilePath(pView->m_strFileName,lpszPathName,".sav"); pView->m_bStatusBar = ms_is_magwin() ? false : true; } } if (pView) pView->Invalidate(); return (pApp->GetGameLoaded() != 0) ? TRUE : FALSE; }
void CMagneticPic::NewPicture(int iWidth, int iHeight, const unsigned char* pBuffer, const unsigned short* pPalette) { CMagneticApp* pApp = (CMagneticApp*)AfxGetApp(); ClearAll(); m_pBitmapInfo = (BITMAPINFO*) (new unsigned char[sizeof(BITMAPINFOHEADER)+(16*sizeof(RGBQUAD))]); // The bitmap data must be long-word aligned int iModulo = iWidth % 4; int iDibWidth = iWidth + ((iModulo > 0) ? (4-iModulo) : iModulo); m_pBitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); m_pBitmapInfo->bmiHeader.biWidth = iWidth; m_pBitmapInfo->bmiHeader.biHeight = iHeight * -1; // top-down bitmap m_pBitmapInfo->bmiHeader.biPlanes = 1; m_pBitmapInfo->bmiHeader.biBitCount = 8; m_pBitmapInfo->bmiHeader.biCompression = BI_RGB; m_pBitmapInfo->bmiHeader.biSizeImage = 0; m_pBitmapInfo->bmiHeader.biXPelsPerMeter = 0; m_pBitmapInfo->bmiHeader.biYPelsPerMeter = 0; m_pBitmapInfo->bmiHeader.biClrUsed = 16; m_pBitmapInfo->bmiHeader.biClrImportant = 0; LOGPALETTE* pLogPalette = (LPLOGPALETTE) new unsigned char[sizeof(LOGPALETTE)+(16*sizeof(PALETTEENTRY))]; pLogPalette->palVersion = 0x300; pLogPalette->palNumEntries = 16; for (int i = 0; i < 16; i++) { int red = (pPalette[i]&0x0F00)>>3; int green = (pPalette[i]&0x00F0)<<1; int blue = (pPalette[i]&0x000F)<<5; // Gamma correction double dGamma = pApp->GetGamma(); if (dGamma > 0.0) { red = (int)sqrt((double)red*(double)red*dGamma); green = (int)sqrt((double)green*(double)green*dGamma); blue = (int)sqrt((double)blue*(double)blue*dGamma); } m_pBitmapInfo->bmiColors[i].rgbRed = (unsigned char)(red > 0xFF ? 0xFF : red); m_pBitmapInfo->bmiColors[i].rgbGreen = (unsigned char)(green > 0xFF ? 0xFF : green); m_pBitmapInfo->bmiColors[i].rgbBlue = (unsigned char)(blue > 0xFF ? 0xFF : blue); m_pBitmapInfo->bmiColors[i].rgbReserved = 0; pLogPalette->palPalEntry[i].peRed = m_pBitmapInfo->bmiColors[i].rgbRed; pLogPalette->palPalEntry[i].peGreen = m_pBitmapInfo->bmiColors[i].rgbGreen; pLogPalette->palPalEntry[i].peBlue = m_pBitmapInfo->bmiColors[i].rgbBlue; pLogPalette->palPalEntry[i].peFlags = 0; } m_pBitmap = new unsigned char[iDibWidth*iHeight]; for (i = 0; i < iHeight; i++) { for (int j = 0; j < iDibWidth; j++) { if (j < iWidth) m_pBitmap[(i*iDibWidth)+j] = pBuffer[(i*iWidth)+j]; else m_pBitmap[(i*iDibWidth)+j] = 0; } } m_pPalette = new CPalette; m_pPalette->CreatePalette(pLogPalette); delete[] pLogPalette; // Store the bitmap size m_Size = CSize(iWidth,iHeight); }
void CMagneticView::OnDraw(CDC* pDrawDC) { CMagneticApp* pApp = (CMagneticApp*)AfxGetApp(); // Don't draw anything if there isn't a loaded game if (pApp->GetGameLoaded() == 0) return; CDC BitmapDC; BitmapDC.CreateCompatibleDC(pDrawDC); CRect Client; GetClientRect(Client); CBitmap Bitmap; CSize Size(Client.Width(),Client.Height()); Bitmap.CreateCompatibleBitmap(pDrawDC,Size.cx,Size.cy); CBitmap* pOldBitmap = BitmapDC.SelectObject(&Bitmap); // Set up the font CFont* pOldFont = NULL; TEXTMETRIC FontInfo; pOldFont = BitmapDC.SelectObject(m_pTextFont); BitmapDC.GetTextMetrics(&FontInfo); int iFontHeight = (int)(FontInfo.tmHeight*1.1); int iPicWidth = 0; int iPicHeight = 0; CRect TextClient(Client); CSize Margins(GetMargins()); if (m_bStatusBar) { TextClient.top += iFontHeight; // Display the status line LONG lStatSpace = (LONG)(Client.Width()*0.075); SolidRect(&BitmapDC,CRect(Client.left,0,Client.right,iFontHeight), pApp->GetForeColour()); BitmapDC.SetTextColor(pApp->GetBackColour()); BitmapDC.SetBkColor(pApp->GetForeColour()); BitmapDC.TextOut(lStatSpace,0,m_strStatLocation,m_strStatLocation.GetLength()); BitmapDC.TextOut(lStatSpace*10,0,m_strStatScore,m_strStatScore.GetLength()); } // If the picture is to be drawn in the main window, leave enough // space and draw both background and picture if (pApp->GetShowGraphics() == CMagneticApp::ShowGraphics::MainWindow) { int dpi = DPI::getWindowDPI(this); iPicWidth = m_Picture.GetScaledWidth(dpi); iPicHeight = m_Picture.GetScaledHeight(dpi); if (iPicWidth > 0 && iPicHeight > 0) { TextClient.top += iPicHeight; int iOffset = m_bStatusBar ? iFontHeight : 0; BitmapDC.FillSolidRect(Client.left,Client.top+iOffset,Client.Width(), iPicHeight,pApp->GetGfxColour()); CRect PicArea((Client.Width()-iPicWidth)/2,iOffset, (Client.Width()+iPicWidth)/2,iOffset+iPicHeight); m_Picture.Paint(&BitmapDC,PicArea,m_AnimFrames); } } BitmapDC.FillSolidRect(TextClient,pApp->GetBackColour()); int y = TextClient.top; // Repaginate if necessary TrimOutput(); if (m_PageTable.GetSize() == 0) { Paginate(&BitmapDC,0,0); if (m_bMorePrompt) m_PageTable.RemoveAt(m_PageTable.GetSize()-1); } LPCSTR lpszOutput = m_strOutput; BitmapDC.SetTextColor(pApp->GetForeColour()); BitmapDC.SetBkColor(pApp->GetBackColour()); // Work out the number of lines of text to draw m_iMaxLines = (TextClient.Height()-(2*Margins.cy)) / iFontHeight; y += Margins.cy; // Starting position in the text output buffer int i = m_PageTable.GetSize() - m_iMaxLines - 1; // Adjust for a More... prompt int offset = 0; if (m_bMorePrompt) { if (iPicWidth > 0 && iPicHeight > 0) { if (m_iLines > m_iMaxLines) { if (m_iLines - m_iMaxLines - 1 > 0) { offset = m_iLines - m_iMaxLines - 1; i -= offset; } } } } if (i < 0) i = 0; // Draw the text int iCount = 0; while (i < m_PageTable.GetSize()-1-offset) { iCount = m_PageTable[i+1]-m_PageTable[i]-1; if (iCount > 0) { if (*(lpszOutput+m_PageTable[i]+iCount-1) == '\0') iCount--; } BitmapDC.TextOut(Margins.cx,y,lpszOutput+m_PageTable[i],iCount); y += iFontHeight; i++; } // Store information on the last line for updating later CRect LastLine(0,y-iFontHeight,TextClient.Width(),y); m_LastLineRect = LastLine; // Clear the end of the last line to allow input editing if (i > 0) { CSize TextLen = BitmapDC.GetTextExtent(lpszOutput+m_PageTable[i-1], m_PageTable[i]-m_PageTable[i-1]-1); LastLine.left += TextLen.cx + Margins.cx; SolidRect(&BitmapDC,LastLine,pApp->GetBackColour()); } // Remove the font BitmapDC.SelectObject(pOldFont); pDrawDC->BitBlt(0,0,Size.cx,Size.cy,&BitmapDC,0,0,SRCCOPY); BitmapDC.SelectObject(pOldBitmap); }