home *** CD-ROM | disk | FTP | other *** search
- // FrotzCEView.cpp : implementation of the CFrotzCEView class
- //
-
- #include "stdafx.h"
- #include "FrotzCE.h"
-
- #include "FrotzCEDoc.h"
- #include "FrotzCEView.h"
- #include "MainFrm.h"
-
- extern "C"
- {
- #include "Frotz/Frotz.h"
-
- extern char euro_substitute[];
- }
-
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
-
- /////////////////////////////////////////////////////////////////////////////
- // CFrotzCEView
-
- IMPLEMENT_DYNCREATE(CFrotzCEView, CView)
-
- BEGIN_MESSAGE_MAP(CFrotzCEView, CView)
- //{{AFX_MSG_MAP(CFrotzCEView)
- ON_WM_CHAR()
- ON_WM_SYSCHAR()
- ON_WM_KEYDOWN()
- ON_MESSAGE(WM_CREATE_CURSOR, OnCreateCursor)
- ON_MESSAGE(WM_UPDATE_CURSOR, OnUpdateCursor)
- ON_MESSAGE(WM_SHOW_CURSOR, OnShowCursor)
- ON_MESSAGE(WM_TAKE_FOCUS, OnTakeFocus)
- ON_COMMAND(ID_DOWN, OnDown)
- ON_COMMAND(ID_EAST, OnEast)
- ON_COMMAND(ID_INVENTORY, OnInventory)
- ON_COMMAND(ID_LOOK, OnLook)
- ON_COMMAND(ID_NORTH, OnNorth)
- ON_COMMAND(ID_SOUTH, OnSouth)
- ON_COMMAND(ID_TAKE, OnTake)
- ON_COMMAND(ID_UP, OnUp)
- ON_COMMAND(ID_WEST, OnWest)
- ON_WM_LBUTTONDOWN()
- ON_COMMAND(ID_RESTORE, OnRestore)
- ON_COMMAND(ID_SAVE, OnSave)
- ON_COMMAND(ID_UNDO, OnUndo)
- ON_COMMAND(ID_OPEN, OnOpen)
- ON_COMMAND(ID_GO, OnGo)
- ON_COMMAND(ID_DROP, OnDrop)
- ON_COMMAND(ID_QUIT, OnQuit)
- ON_WM_TIMER()
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
-
- /////////////////////////////////////////////////////////////////////////////
- // CFrotzCEView construction/destruction
-
- CFrotzCEView::CFrotzCEView()
- {
- m_pScreen = NULL;
- m_pAttributes = NULL;
-
- m_pcReadKeyBuffer = m_acKeyBuffer;
- m_pcWriteKeyBuffer = m_acKeyBuffer;
-
- m_bExpectingInput = FALSE;
-
- m_bRedraw = TRUE;
-
- m_bInstantRefresh = FALSE;
-
- m_nState = STATE_NONE;
-
- m_hCurrentFont = NULL;
-
- // Set up pallette
- m_acPallette[PALLETTE_BLACK] = RGB(0,0,0);
- m_acPallette[PALLETTE_DARKGREY] = RGB(0x7f,0x7f,0x7f);
- m_acPallette[PALLETTE_LIGHTGREY] = RGB(0xaf,0xaf,0xaf);
- m_acPallette[PALLETTE_WHITE] = RGB(0xff,0xff,0xff);
- }
-
- CFrotzCEView::~CFrotzCEView()
- {
- // Free font object
- if (m_hCurrentFont) ::DeleteObject( m_hCurrentFont );
-
- // Free screen buffers
- if (m_pScreen) ::LocalFree( m_pScreen );
- if (m_pAttributes) ::LocalFree( m_pAttributes );
- }
-
- BOOL CFrotzCEView::PreCreateWindow(CREATESTRUCT& cs)
- {
- return CView::PreCreateWindow(cs);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CFrotzCEView drawing
-
- void CFrotzCEView::OnDraw( CDC* pDC )
- {
- // Is there a screen to draw?
- if (m_pScreen)
- {
- ::EnterCriticalSection( &m_cScrnCriticalSection );
-
- BYTE nOldColour = m_nCurrentColour;
- int nOldStyle = m_nCurrentStyle;
-
- // Set default colour
- m_nCurrentColour = DEF_TEXT_COLOUR;
-
- // Set default style
- m_nCurrentStyle = NORMAL_STYLE;
-
- // Update the entire screen
- UpdateScreenArea( pDC, 0, 0, m_nHeight-1, m_nWidth-1 );
-
- // Restore previous style and colours
- if (nOldColour != m_nCurrentColour) SetColour( pDC, nOldColour );
- if (nOldStyle != m_nCurrentStyle)
- {
- HFONT hOldFont;
-
- hOldFont = SetStyle( pDC, nOldStyle );
- pDC->SelectObject( hOldFont );
- }
-
- ::LeaveCriticalSection( &m_cScrnCriticalSection );
- }
- else CView::OnDraw( pDC );
- }
-
- void CFrotzCEView::UpdateScreenArea( CDC* pDC, int nTop, int nLeft, int nBottom, int nRight )
- {
- HFONT hOldFont;
-
- // Hide cursor
- SendMessage( WM_SHOW_CURSOR, FALSE );
-
- // Set colour
- SetColour( pDC, m_nCurrentColour );
-
- // Select font into device context
- hOldFont = SetStyle( pDC, m_nCurrentStyle );
-
- // Go through each row in the screen buffer
- for (int nRow = nTop, nYPos = nTop*m_nCharHeight;
- nRow <= nBottom;
- nRow++, nYPos += m_nCharHeight)
- {
- for (int nCol = nLeft, nXPos = nLeft*m_nCharWidth, nChars = 0;;)
- {
- // Count no. of chars with current colour and style
- for (nChars = 0; (nCol + nChars) <= nRight
- && COLOUR(m_pAttributes[(nRow*m_nWidth) + (nCol + nChars)]) == m_nCurrentColour
- && STYLE(m_pAttributes[(nRow*m_nWidth) + (nCol + nChars)]) == m_nCurrentStyle;
- nChars++);
-
- // Any chars to output with this style?
- if (nChars)
- {
- // Output the char to the device context
- pDC->ExtTextOut( nCol*m_nCharWidth, nRow*m_nCharHeight, ETO_OPAQUE,
- CRect( nCol*m_nCharWidth, nRow*m_nCharHeight,
- (nCol+1)*m_nCharWidth, (nRow+1)*m_nCharHeight),
- (LPCTSTR) &m_pScreen[(nRow*m_nWidth) + nCol],
- nChars, NULL );
-
- nCol += nChars;
- nXPos += (nChars * m_nCharWidth);
- }
-
- // Not reached end of line?
- if (nCol <= nRight)
- {
- // Colour changed?
- if (COLOUR(m_pAttributes[(nRow*m_nWidth) + nCol]) != m_nCurrentColour)
- {
- // Set current colour
- SetColour( pDC, COLOUR(m_pAttributes[(nRow*m_nWidth) + nCol]) );
- }
- // Style changed?
- if (STYLE(m_pAttributes[(nRow*m_nWidth) + nCol]) != m_nCurrentStyle)
- {
- // Select previous font into device context
- pDC->SelectObject( hOldFont );
- // Set current style
- hOldFont = SetStyle( pDC, STYLE(m_pAttributes[(nRow*m_nWidth) + nCol]) );
- }
- }
- else break;
- }
- }
-
- // Select original font back into device context
- pDC->SelectObject( hOldFont );
-
- // Show cursor
- SendMessage( WM_SHOW_CURSOR, TRUE );
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CFrotzCEView diagnostics
-
- #ifdef _DEBUG
- void CFrotzCEView::AssertValid() const
- {
- CView::AssertValid();
- }
-
- void CFrotzCEView::Dump(CDumpContext& dc) const
- {
- CView::Dump(dc);
- }
-
- CFrotzCEDoc* CFrotzCEView::GetDocument() // non-debug version is inline
- {
- ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CFrotzCEDoc)));
- return (CFrotzCEDoc*)m_pDocument;
- }
- #endif //_DEBUG
-
- // Initialises the display
- void CFrotzCEView::InitialiseScreen()
- {
- CRect cRect;
- TEXTMETRIC sTextMetrics;
- CDC *pDC;
- HFONT hOldFont;
-
- // Copy screen info
- m_bUseStyles = FROTZCEAPP->m_bUseStyles;
- m_nDefaultStyle = FROTZCEAPP->m_nDefaultStyle;
- m_nDefaultFontHeight = FROTZCEAPP->m_nFontHeight;
- m_nDefaultFontWidth = FROTZCEAPP->m_nFontWidth;
- m_bUseEuroChars = FROTZCEAPP->m_bUseEuroChars;
- m_bUseColours = FROTZCEAPP->m_bUseColours;
-
- // Create keypress event object
- m_hKeyEvent = ::CreateEvent( NULL, FALSE, FALSE, NULL );
-
- // Initialise critical sections
- memset( &m_cKbdCriticalSection, 0, sizeof( m_cKbdCriticalSection ) );
- ::InitializeCriticalSection( &m_cKbdCriticalSection );
- memset( &m_cScrnCriticalSection, 0, sizeof( m_cScrnCriticalSection ) );
- ::InitializeCriticalSection( &m_cScrnCriticalSection );
-
- // Set cursor state
- m_bCursorOn = FALSE;
- m_bCursorSet = TRUE;
-
- // Reset widths etc.
- m_nWidth = 0;
- m_nCharWidth = 0;
- m_nHeight = 0;
- m_nCharHeight = 0;
-
- // Get frame window rectangle
- MAINFRAME->GetClientRect( cRect );
-
- // Subtract size of command bar if it's showing
- if (MAINFRAME->m_bShowCommandBar)
- cRect.top += MAINFRAME->m_nCmdBarHeight;
-
- // Resize the view to cover the entire frame window client area
- MoveWindow( cRect, FALSE );
-
- // Get window rectangle
- GetClientRect( cRect );
-
- // Get device context
- pDC = GetDC();
-
- // Set colour
- SetColour( pDC, DEF_TEXT_COLOUR );
-
- // Using text styles?
- if (m_bUseStyles)
- {
- // Select font into device context
- hOldFont = SetStyle( pDC, NORMAL_STYLE | BOLDFACE_STYLE | EMPHASIS_STYLE, TRUE );
- }
- else
- {
- // Select font into device context
- hOldFont = SetStyle( pDC, NORMAL_STYLE, TRUE );
- }
-
- // Get the font metrics
- pDC->GetTextMetrics( &sTextMetrics );
-
- // Save character dimensions
- m_nCharWidth = (USHORT) sTextMetrics.tmMaxCharWidth + sTextMetrics.tmOverhang;
- m_nCharHeight = (USHORT) sTextMetrics.tmHeight;
-
- // Set colour
- SetColour( pDC, DEF_TEXT_COLOUR );
-
- // Using text styles?
- if (m_bUseStyles)
- {
- // Select previous font into device context
- pDC->SelectObject( hOldFont );
- // Select font into device context
- hOldFont = SetStyle( pDC, m_nDefaultStyle );
- }
-
- // Select previous font into device context
- pDC->SelectObject( hOldFont );
-
- // Release device context
- ReleaseDC( pDC );
-
- // Save screen dimensions
- m_nWidth = cRect.Width() / m_nCharWidth;
- m_nHeight = cRect.Height() / m_nCharHeight;
-
- // Allocate screen buffers
- m_pScreen =
- (TCHAR *) ::LocalAlloc( LPTR, m_nWidth * m_nHeight * sizeof( TCHAR ) );
- m_pAttributes =
- (BYTE *) ::LocalAlloc( LPTR, m_nWidth * m_nHeight );
-
- // Clear the screen
- ClearScreen( FALSE );
-
- // Send a message to the view to create the caret
- SendMessage( WM_CREATE_CURSOR );
-
- // Create timer to do update
- m_hUpdateTimer = SetTimer( ID_UPDATE_TIMER, FROTZCE_UPDATE_MS, NULL );
- }
-
- void CFrotzCEView::ResetScreen()
- {
- CRect cRect;
-
- // Free event object
- ::CloseHandle( m_hKeyEvent );
-
- // Release critical sections
- ::DeleteCriticalSection( &m_cKbdCriticalSection );
- ::DeleteCriticalSection( &m_cScrnCriticalSection );
-
- // Free font object
- if (m_hCurrentFont)
- {
- ::DeleteObject( m_hCurrentFont );
- m_hCurrentFont = NULL;
- }
-
- // Free screen buffers
- if (m_pScreen)
- {
- ::LocalFree( m_pScreen );
- m_pScreen = NULL;
- }
- if (m_pAttributes)
- {
- ::LocalFree( m_pAttributes );
- m_pAttributes = NULL;
- }
-
- // Get frame window rectangle
- MAINFRAME->GetClientRect( cRect );
- cRect.top += MAINFRAME->m_nCmdBarHeight;
-
- // Resize the view to cover the entire frame window client area
- MoveWindow( cRect, FALSE );
-
- // Free timer
- if (m_hUpdateTimer) KillTimer( m_hUpdateTimer );
-
- // Clear screen
- Invalidate( TRUE );
- }
-
- void CFrotzCEView::ClearScreen( BOOL bUpdate )
- {
- // Erase the entire screen
- EraseScreenArea( 0, 0, m_nHeight-1, m_nWidth-1 );
-
- // Set the cursor position to upper left-hand corner
- SetCursorPos( 0, 0 );
- }
-
- void CFrotzCEView::EraseScreenArea( int nTop, int nLeft, int nBottom, int nRight )
- {
- // Make sure extents are in range
- if (nBottom > m_nHeight-1) nBottom = m_nHeight-1;
- if (nRight > m_nWidth-1) nRight = m_nWidth - 1;
-
- ::EnterCriticalSection( &m_cScrnCriticalSection );
-
- // Fill screen buffer with spaces
- for (int nRow = nTop; nRow <= nBottom; nRow++)
- {
- for (int nCol = nLeft; nCol <= nRight; nCol++)
- {
- m_pScreen[(nRow * m_nWidth) + nCol] = _T(' ');
- m_pAttributes[(nRow * m_nWidth) + nCol] =
- (m_nCurrentColour << NUM_STYLE_BITS) | m_nCurrentStyle;
- }
- }
-
- ::LeaveCriticalSection( &m_cScrnCriticalSection );
-
- // Refresh instantly?
- if (m_bInstantRefresh)
- {
- // Get device context
- CDC *pDC = GetDC();
-
- ::EnterCriticalSection( &m_cScrnCriticalSection );
-
- // Update scrolled area
- UpdateScreenArea( pDC, nTop, nLeft, nBottom, nRight );
-
- ::LeaveCriticalSection( &m_cScrnCriticalSection );
-
- // Release device context
- ReleaseDC( pDC );
- }
- else
- {
- // Flag that screen must be redrawn
- m_bRedraw = TRUE;
- }
- }
-
- void CFrotzCEView::GetCursorPos( int *pnRow, int *pnCol )
- {
- // Save cursor position
- *pnRow = m_nCursorRow;
- *pnCol = m_nCursorCol;
- }
-
- void CFrotzCEView::SetCursorPos( int nRow, int nCol, BOOL bUpdate )
- {
- // Make sure row and column are in range
- if (nRow < 0) nRow = 0;
- else if (nRow > m_nHeight-1) nRow = m_nHeight - 1;
- if (nCol < 0) nCol = 0;
- else if (nCol > m_nWidth-1) nCol = m_nWidth - 1;
-
- // Save cursor position
- m_nCursorRow = nRow;
- m_nCursorCol = nCol;
-
- // Update caret position
- if (bUpdate) UpdateCaretPos();
- }
-
-
- void CFrotzCEView::UpdateCaretPos()
- {
- // Send a message to the view to update the caret
- SendMessage( WM_UPDATE_CURSOR );
- }
-
- void CFrotzCEView::OnCreateCursor()
- {
- // Create a cursor
- CreateSolidCaret( m_nCharWidth, m_nCharHeight );
- }
-
- void CFrotzCEView::OnUpdateCursor()
- {
- POINT sCaretPos;
-
- // Calculate new caret position
- sCaretPos.x = m_nCursorCol * m_nCharWidth;
- sCaretPos.y = m_nCursorRow * m_nCharHeight;
-
- SetCaretPos( sCaretPos );
-
- // Cursor state needs setting
- if (!m_bCursorSet)
- {
- m_bCursorSet = TRUE;
-
- // Show or hide cursor
- OnShowCursor( m_bCursorOn );
- }
- }
-
- void CFrotzCEView::OnShowCursor( UINT bShow )
- {
- // Show or hide cursor
- if (bShow) ShowCaret();
- else HideCaret();
- }
-
- void CFrotzCEView::OnTakeFocus()
- {
- SetFocus();
- }
-
- void CFrotzCEView::SetCursorState( BOOL bCursorOn )
- {
- // Changing state?
- if (m_bCursorOn != bCursorOn)
- {
- // Set cursor state
- m_bCursorOn = bCursorOn;
- // Flag that state has changed
- m_bCursorSet = FALSE;
-
- // Update caret
- UpdateCaretPos();
- }
- }
-
- void CFrotzCEView::SetColour( CDC* pDC, BYTE nColour )
- {
- // Set current text colour
- m_nCurrentColour = nColour;
-
- // Reverse mode?
- if (m_nCurrentStyle & REVERSE_STYLE)
- {
- // Set text and background colours to reverse
- pDC->SetTextColor(
- pDC->GetNearestColor( m_acPallette[m_nCurrentColour>>2] ) );
- pDC->SetBkColor(
- pDC->GetNearestColor( m_acPallette[m_nCurrentColour&3] ) );
- }
- else
- {
- // Set text and background colours
- pDC->SetTextColor(
- pDC->GetNearestColor( m_acPallette[m_nCurrentColour&3] ) );
- pDC->SetBkColor(
- pDC->GetNearestColor( m_acPallette[m_nCurrentColour>>2] ) );
- }
- }
-
- HFONT CFrotzCEView::SetStyle( CDC* pDC, BYTE nStyle, BOOL bForce )
- {
- // Not using text styles?
- if (!m_bUseStyles)
- {
- // Remove style flags
- nStyle &= ~BOLDFACE_STYLE;
- nStyle &= ~EMPHASIS_STYLE;
- }
-
- // Use default style
- nStyle |= m_nDefaultStyle;
-
- // Style changed?
- if (nStyle != m_nCurrentStyle || bForce)
- {
- LOGFONT sLogFont;
- HFONT hNewFont;
-
- // Reverse style changing?
- if ((m_nCurrentStyle & REVERSE_STYLE) != (nStyle & REVERSE_STYLE))
- {
- // Set current text style
- m_nCurrentStyle = nStyle;
-
- // Set current text colour
- SetColour( pDC, m_nCurrentColour );
- }
- // Set current text style
- else m_nCurrentStyle = nStyle;
-
- // Set up logical font structure
- memset ((char *) &sLogFont, 0, sizeof( sLogFont ));
- sLogFont.lfPitchAndFamily = FIXED_PITCH | FF_MODERN;
- sLogFont.lfCharSet = ANSI_CHARSET;
-
- // Set font quality
- sLogFont.lfQuality = DRAFT_QUALITY;
-
- // Small font?
- if (m_nDefaultFontWidth == SMALL_FONT_WIDTH)
- {
- // Set up font name
- #define TERMINAL_FONT TEXT("Courier New")
- memcpy( sLogFont.lfFaceName, TERMINAL_FONT, sizeof( TERMINAL_FONT ) );
- #undef TERMINAL_FONT
-
- // Set font width
- sLogFont.lfWidth = m_nDefaultFontWidth;
- // Set font height
- sLogFont.lfHeight = m_nDefaultFontHeight;
- }
- else
- {
- // Set font height
- if (m_nCharHeight) sLogFont.lfHeight = m_nCharHeight;
- else sLogFont.lfHeight = m_nDefaultFontHeight;
-
- // Set font width
- if (m_nCharWidth) sLogFont.lfWidth = m_nCharWidth;
- else sLogFont.lfWidth = m_nDefaultFontWidth;
- }
-
- // Bold?
- if (m_nCurrentStyle & BOLDFACE_STYLE)
- sLogFont.lfWeight = FW_BOLD;
-
- // Italic?
- if (m_nCurrentStyle & EMPHASIS_STYLE)
- {
- sLogFont.lfWeight = FW_BOLD;
- sLogFont.lfItalic = TRUE;
- }
-
- // Create font
- if ((hNewFont = ::CreateFontIndirect( &sLogFont )) != NULL)
- {
- // Replace current font
- if (m_hCurrentFont) ::DeleteObject( (HGDIOBJ) m_hCurrentFont );
- m_hCurrentFont = hNewFont;
-
- // Select font into device context
- return (HFONT) pDC->SelectObject( hNewFont );
- }
- else return NULL;
- }
- else
- {
- // Select current font into device context
- return (HFONT) pDC->SelectObject( m_hCurrentFont );
- }
- }
-
- void CFrotzCEView::DisplayChar( char ch, BOOL bUpdateCaret )
- {
- // Check for special characters
- switch( ch )
- {
- // Paragraph indent?
- case 11:
- DisplayChar( ' ' );
- // Tab?
- case 9:
- DisplayChar( ' ' );
- ch = ' ';
- // Everything else
- default:
- int nCurrPos;
-
- // Save cursor pos.
- nCurrPos = m_nCursorCol;
-
- // Update cursor position
- m_nCursorCol++;
- if (bUpdateCaret) UpdateCaretPos();
-
- // On screen?
- if (nCurrPos < m_nWidth && m_nCursorRow < m_nHeight)
- {
- ::EnterCriticalSection( &m_cScrnCriticalSection );
-
- // Put the char into the screen buffer
- m_pScreen[(m_nCursorRow * m_nWidth) + nCurrPos] = (TCHAR) ch;
-
- m_pAttributes[(m_nCursorRow * m_nWidth) + nCurrPos] =
- (BYTE) ((m_nCurrentColour << NUM_STYLE_BITS) | m_nCurrentStyle);
-
- // Refresh instantly?
- if (m_bInstantRefresh || m_bExpectingInput)
- {
- HFONT hOldFont;
-
- // Get device context
- CDC *pDC = GetDC();
-
- // Set colour
- SetColour( pDC, m_nCurrentColour );
-
- // Select font into device context
- hOldFont = SetStyle( pDC, m_nCurrentStyle );
-
- // Output the char to the device context
- pDC->ExtTextOut( nCurrPos*m_nCharWidth, m_nCursorRow*m_nCharHeight, ETO_OPAQUE,
- CRect( nCurrPos*m_nCharWidth, m_nCursorRow*m_nCharHeight, (nCurrPos+1)*m_nCharWidth, (m_nCursorRow+1)*m_nCharHeight),
- (LPCTSTR) &m_pScreen[(m_nCursorRow * m_nWidth) + nCurrPos],
- 1, NULL );
-
- // Select previous font into device context
- pDC->SelectObject( hOldFont );
-
- // Release device context
- ReleaseDC( pDC );
- }
- else
- {
- // Flag that screen must be redrawn
- m_bRedraw = TRUE;
- }
-
- ::LeaveCriticalSection( &m_cScrnCriticalSection );
- }
- }
- }
-
- void CFrotzCEView::DisplayString( const char* acString )
- {
- const unsigned char *pcCurr = (unsigned char *) acString;
- int nStartCol = m_nCursorCol;
- int nCurrentStyle;
- int nCurrentColour;
-
-
- ::EnterCriticalSection( &m_cScrnCriticalSection );
-
- // Save current style and colours
- nCurrentStyle = m_nCurrentStyle;
- nCurrentColour = m_nCurrentColour;
-
- ::LeaveCriticalSection( &m_cScrnCriticalSection );
-
- // Process string
- for (; *pcCurr; pcCurr++)
- {
- // New style?
- if (*pcCurr == NEW_FONT || *pcCurr == NEW_STYLE)
- {
- // Style change?
- if (*pcCurr == NEW_STYLE)
- {
- pcCurr++;
-
- // Set current style
- nCurrentStyle = *pcCurr;
-
- // Not using text styles?
- if (!m_bUseStyles)
- {
- // Remove style flags
- nCurrentStyle &= ~BOLDFACE_STYLE;
- nCurrentStyle &= ~EMPHASIS_STYLE;
- }
-
- // Use default style
- nCurrentStyle |= m_nDefaultStyle;
- }
- else
- {
- pcCurr++;
- }
- }
- else
- {
- // European char?
- if (m_bUseEuroChars && *pcCurr >= EURO_MIN && *pcCurr <= EURO_MAX)
- {
- int c1 = euro_substitute[2 * (*pcCurr - EURO_MIN)];
- int c2 = euro_substitute[2 * (*pcCurr - EURO_MIN) + 1];
-
- // On screen?
- if (m_nCursorCol < m_nWidth && m_nCursorRow < m_nHeight)
- {
- // Put the char into the screen buffer
- m_pScreen[(m_nCursorRow * m_nWidth) + m_nCursorCol] = (TCHAR) c1;
- m_pAttributes[(m_nCursorRow * m_nWidth) + m_nCursorCol] =
- (BYTE) ((nCurrentColour << NUM_STYLE_BITS) | nCurrentStyle);
- m_nCursorCol++;
- }
-
- // Second char to display?
- if (c2 != ' ')
- {
- // On screen?
- if (m_nCursorCol < m_nWidth && m_nCursorRow < m_nHeight)
- {
- // Put the char into the screen buffer
- m_pScreen[(m_nCursorRow * m_nWidth) + m_nCursorCol] = (TCHAR) c2;
- m_pAttributes[(m_nCursorRow * m_nWidth) + m_nCursorCol] =
- (BYTE) ((nCurrentColour << NUM_STYLE_BITS) | nCurrentStyle);
- m_nCursorCol++;
- }
- }
- }
- // Display char
- else
- {
- char ch = (char) *pcCurr;
-
- // Check for special characters
- switch( *pcCurr )
- {
- // Paragraph indent?
- case 11:
- // On screen?
- if (m_nCursorCol < m_nWidth && m_nCursorRow < m_nHeight)
- {
- // Put the char into the screen buffer
- m_pScreen[(m_nCursorRow * m_nWidth) + m_nCursorCol] = _T(' ');
- m_pAttributes[(m_nCursorRow * m_nWidth) + m_nCursorCol] =
- (BYTE) ((nCurrentColour << NUM_STYLE_BITS) | nCurrentStyle);
- m_nCursorCol++;
- }
- // Tab?
- case 9:
- // On screen?
- if (m_nCursorCol < m_nWidth && m_nCursorRow < m_nHeight)
- {
- // Put the char into the screen buffer
- m_pScreen[(m_nCursorRow * m_nWidth) + m_nCursorCol] = _T(' ');
- m_pAttributes[(m_nCursorRow * m_nWidth) + m_nCursorCol] =
- (BYTE) ((nCurrentColour << NUM_STYLE_BITS) | nCurrentStyle);
- m_nCursorCol++;
- }
- ch = ' ';
- // Everything else
- default:
- // On screen?
- if (m_nCursorCol < m_nWidth && m_nCursorRow < m_nHeight)
- {
- // Put the char into the screen buffer
- m_pScreen[(m_nCursorRow * m_nWidth) + m_nCursorCol] = (TCHAR) ch;
- m_pAttributes[(m_nCursorRow * m_nWidth) + m_nCursorCol] =
- (BYTE) ((nCurrentColour << NUM_STYLE_BITS) | nCurrentStyle);
- m_nCursorCol++;
- }
- break;
- }
- }
- }
- }
-
- // Refresh instantly?
- if (m_bInstantRefresh)
- {
- // Get device context
- CDC *pDC = GetDC();
-
- ::EnterCriticalSection( &m_cScrnCriticalSection );
-
- // Anything to display?
- if (m_nCursorCol > nStartCol)
- {
- // Update display
- UpdateScreenArea( pDC, m_nCursorRow, nStartCol, m_nCursorRow, m_nCursorCol-1 );
- }
-
- // Set style?
- if (nCurrentStyle != m_nCurrentStyle)
- {
- HFONT hOldFont;
-
- hOldFont = SetStyle( pDC, nCurrentStyle );
-
- // Select previous font into device context
- pDC->SelectObject( hOldFont );
- }
-
-
- ::LeaveCriticalSection( &m_cScrnCriticalSection );
-
- // Release device context
- ReleaseDC( pDC );
- }
- else
- {
- ::EnterCriticalSection( &m_cScrnCriticalSection );
-
- // Set style
- if (nCurrentStyle != m_nCurrentStyle)
- m_nCurrentStyle = nCurrentStyle;
-
- ::LeaveCriticalSection( &m_cScrnCriticalSection );
-
- // Flag that screen must be redrawn
- m_bRedraw = TRUE;
- }
- }
-
- // Gets a key
- int CFrotzCEView::GetKey( int nTimeOut )
- {
- DWORD dwTimeOut = INFINITE;
- unsigned char ch = 0;
-
- // Update cursor position
- UpdateCaretPos();
-
- // Timeout specified?
- if (nTimeOut > 0) dwTimeOut = nTimeOut * 100;
-
- // Set flag to indicate we're expecting input
- m_bExpectingInput = TRUE;
-
- // Got a key?
- if (m_pcReadKeyBuffer != m_pcWriteKeyBuffer
- || ::WaitForSingleObject( m_hKeyEvent, dwTimeOut ) != WAIT_TIMEOUT)
- {
- // Was a key pressed?
- if (m_pcReadKeyBuffer != m_pcWriteKeyBuffer)
- {
- // Get key from buffer
- ch = *m_pcReadKeyBuffer;
- m_pcReadKeyBuffer++;
-
- // Gone past end of buffer?
- if (m_pcReadKeyBuffer > &m_acKeyBuffer[KEYBUFFER_SIZE-1])
- {
- // Go back to beginning of buffer
- m_pcReadKeyBuffer = &m_acKeyBuffer[0];
- }
- }
- }
-
- m_bExpectingInput = FALSE;
-
- return (int) ch;
- }
-
- #define MAX_LINE 80
- #define MAX_HISTORY 5
-
- // Gets a line
- int CFrotzCEView::GetLine( char *acBuffer, int nMax, int nTimeOut )
- {
- DWORD dwTimeOut = INFINITE;
- int ch = 0;
- int nCurrChar = strlen( acBuffer );
- static nNextHistoryPos = 0, nCurrHistoryPos = 0;
- static char acHistory[MAX_HISTORY][MAX_LINE];
-
- // Timeout specified?
- if (nTimeOut > 0) dwTimeOut = nTimeOut * 100;
-
- // Update cursor position
- UpdateCaretPos();
-
- // Set flag to indicate we're expecting input
- m_bExpectingInput = TRUE;
-
- do
- {
- // Was a key pressed?
- if (m_pcReadKeyBuffer != m_pcWriteKeyBuffer)
- {
- // Get key from buffer
- ch = *m_pcReadKeyBuffer;
- m_pcReadKeyBuffer++;
-
- // Gone past end of buffer?
- if (m_pcReadKeyBuffer > &m_acKeyBuffer[KEYBUFFER_SIZE-1])
- {
- // Go back to beginning of buffer
- m_pcReadKeyBuffer = &m_acKeyBuffer[0];
- }
- }
- else
- {
- // Received a keypress notification?
- if (::WaitForSingleObject( m_hKeyEvent, dwTimeOut ) != WAIT_TIMEOUT)
- {
- continue;
- }
- else ch = 0;
- }
-
- // Add character to buffer
- if (ch && !is_terminator( (int) ch ))
- {
- // Check key pressed
- switch (ch)
- {
- case BACKSPACE_KEY:
- // At beginning of line?
- if (nCurrChar > 0)
- {
- nCurrChar--;
- m_nCursorCol--;
- DisplayChar( ' ', TRUE );
- m_nCursorCol--;
- UpdateCaretPos();
- }
- break;
-
- case TAB_KEY:
- char acExt[16];
- int nExtSize;
-
- // Terminate buffer
- acBuffer[nCurrChar] = '\0';
-
- // Completion successful?
- completion( acBuffer, acExt );
- if ((nExtSize = strlen( acExt )) > 0)
- {
- // Copy chars into buffer and display them
- for (int i=0; i < nExtSize && nCurrChar <= nMax; i++)
- {
- acBuffer[nCurrChar++] = acExt[i];
- DisplayChar( acExt[i], TRUE );
- }
- }
- break;
-
- case ESC_KEY:
- // Go until beginning of line
- while (nCurrChar > 0)
- {
- nCurrChar--;
- m_nCursorCol--;
- DisplayChar( ' ', TRUE );
- m_nCursorCol--;
- }
- UpdateCaretPos();
- break;
-
- case UP_ARROW_KEY:
- case DOWN_ARROW_KEY:
- int nHistorySize;
-
- // Go until beginning of line
- while (nCurrChar > 0)
- {
- nCurrChar--;
- m_nCursorCol--;
- DisplayChar( ' ', TRUE );
- m_nCursorCol--;
- }
- UpdateCaretPos();
-
- // Up arrow?
- if (ch == UP_ARROW_KEY)
- {
- nCurrHistoryPos--;
- if (nCurrHistoryPos < 0)
- nCurrHistoryPos = MAX_HISTORY - 1;
- }
- else
- {
- nCurrHistoryPos++;
- if (nCurrHistoryPos >= MAX_HISTORY)
- nCurrHistoryPos = 0;
- }
-
- // Got anything?
- if ((nHistorySize = strlen( acHistory[nCurrHistoryPos] )) > 0)
- {
- // Copy chars into buffer and display them
- for (int i=0; i < nHistorySize && nCurrChar <= nMax; i++)
- {
- acBuffer[nCurrChar++] = acHistory[nCurrHistoryPos][i];
- DisplayChar( acHistory[nCurrHistoryPos][i], TRUE );
- }
-
- nNextHistoryPos = nCurrHistoryPos;
- UpdateCaretPos();
- }
- break;
-
- case SPECIAL_KEY_HOME:
- case SPECIAL_KEY_END:
- case SPECIAL_KEY_DELETE:
- case SPECIAL_KEY_INSERT:
- case SPECIAL_KEY_PAGE_UP:
- case SPECIAL_KEY_PAGE_DOWN:
- case LEFT_ARROW_KEY:
- case RIGHT_ARROW_KEY:
- break;
-
- // Any other key...
- default:
- acBuffer[nCurrChar++] = (unsigned char) ch;
- DisplayChar( ch, TRUE );
- UpdateCaretPos();
- break;
- }
- }
- else break;
- }
- while (nCurrChar <= nMax);
-
- // Null-terminate buffer
- acBuffer[nCurrChar] = '\0';
-
- // Anything entered?
- if (strlen( acBuffer ) > 0 && acBuffer[0] != '\n')
- {
- // Copy string to history buffer
- strcpy( acHistory[nNextHistoryPos], acBuffer );
- nNextHistoryPos++;
- nCurrHistoryPos = nNextHistoryPos;
- if (nNextHistoryPos >= MAX_HISTORY) nNextHistoryPos = 0;
- }
-
- m_bExpectingInput = FALSE;
- m_nState = STATE_NONE;
-
- return ch;
- }
-
- // Scrolls an area of the screen
- void CFrotzCEView::ScrollScreenArea( int nTop, int nLeft, int nBottom, int nRight, int nUnits )
- {
- int nRow;
-
- // Scroll each line upwards
- for (nRow = nTop + nUnits; nRow <= nBottom; nRow++)
- {
- memcpy( &m_pScreen[((nRow - nUnits) * m_nWidth) + nLeft],
- &m_pScreen[(nRow * m_nWidth) + nLeft],
- ((nRight - nLeft) + 1) * sizeof( TCHAR ) );
- memcpy( &m_pAttributes[((nRow - nUnits) * m_nWidth) + nLeft],
- &m_pAttributes[(nRow * m_nWidth) + nLeft],
- ((nRight - nLeft) + 1) );
- }
-
- ::EnterCriticalSection( &m_cScrnCriticalSection );
-
- // Fill rows below scrolled area with spaces
- for (nRow = nBottom; nRow > nBottom - nUnits; nRow--)
- {
- for (int nCol = nLeft; nCol <= nRight; nCol++)
- {
- m_pScreen[(nRow * m_nWidth) + nCol] = _T(' ');
- m_pAttributes[(nRow * m_nWidth) + nCol] =
- (BYTE) ((m_nCurrentColour << NUM_STYLE_BITS) | m_nCurrentStyle);
- }
- }
-
- ::LeaveCriticalSection( &m_cScrnCriticalSection );
-
- // Refresh instantly?
- if (m_bInstantRefresh)
- {
- // Get device context
- CDC *pDC = GetDC();
-
- ::EnterCriticalSection( &m_cScrnCriticalSection );
-
- // Update scrolled area
- UpdateScreenArea( pDC, nTop, nLeft, nBottom, nRight );
-
- ::LeaveCriticalSection( &m_cScrnCriticalSection );
-
- // Release device context
- ReleaseDC( pDC );
- }
- else
- {
- // Flag that screen must be redrawn
- m_bRedraw = TRUE;
- }
- }
-
- // Sets the current text style
- void CFrotzCEView::SetTextStyle( int nStyle )
- {
- // Style change?
- if (nStyle != m_nCurrentStyle)
- {
- HFONT hOldFont;
-
- ::EnterCriticalSection( &m_cScrnCriticalSection );
-
- CDC *pDC = GetDC();
-
- // Set current style
- hOldFont = SetStyle( pDC, nStyle );
-
- // Select previous font into device context
- pDC->SelectObject( hOldFont );
-
- // Release device context
- ReleaseDC( pDC );
-
- ::LeaveCriticalSection( &m_cScrnCriticalSection );
- }
- }
-
- // Sets the current text colour
- void CFrotzCEView::SetTextColour( int nFgCol, int nBkCol )
- {
- BYTE nColour = 0;
-
- // Use colours?
- if (m_bUseColours)
- {
- // Map foreground colour
- switch (nFgCol)
- {
- case WHITE_COLOUR:
- nColour = PALLETTE_WHITE;
- break;
- case GREY_COLOUR:
- case RED_COLOUR:
- case GREEN_COLOUR:
- case BLUE_COLOUR:
- nColour = PALLETTE_DARKGREY;
- break;
- case MEDIUMGREY_COLOUR:
- case YELLOW_COLOUR:
- case MAGENTA_COLOUR:
- case CYAN_COLOUR:
- nColour = PALLETTE_LIGHTGREY;
- break;
- case DARKGREY_COLOUR:
- case BLACK_COLOUR:
- case 0:
- default:
- nColour = PALLETTE_BLACK;
- break;
- }
-
- // Map background colour
- switch (nBkCol)
- {
- case WHITE_COLOUR:
- case 0:
- nColour |= (PALLETTE_WHITE<<2);
- break;
- case GREY_COLOUR:
- case RED_COLOUR:
- case GREEN_COLOUR:
- case BLUE_COLOUR:
- nColour |= (PALLETTE_DARKGREY<<2);
- break;
- case MEDIUMGREY_COLOUR:
- case YELLOW_COLOUR:
- case MAGENTA_COLOUR:
- case CYAN_COLOUR:
- nColour |= (PALLETTE_LIGHTGREY<<2);
- break;
- case DARKGREY_COLOUR:
- case BLACK_COLOUR:
- default:
- nColour |= (PALLETTE_BLACK<<2);
- break;
- }
- }
- else nColour = DEF_TEXT_COLOUR;
-
- ::EnterCriticalSection( &m_cScrnCriticalSection );
-
- // Colour change?
- if (nColour != m_nCurrentColour)
- {
- CDC *pDC = GetDC();
-
- // Set current colour
- SetColour( pDC, nColour );
-
- // Release device context
- ReleaseDC( pDC );
- }
-
- ::LeaveCriticalSection( &m_cScrnCriticalSection );
- }
-
- void CFrotzCEView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
- {
- // Expecting input?
- if (m_bExpectingInput)
- {
- ::EnterCriticalSection( &m_cKbdCriticalSection );
-
- // Add key to buffer
- *m_pcWriteKeyBuffer = nChar;
- m_pcWriteKeyBuffer++;
-
- // Gone past end of buffer?
- if (m_pcWriteKeyBuffer > &m_acKeyBuffer[KEYBUFFER_SIZE-1])
- {
- // Go back to beginning of buffer
- m_pcWriteKeyBuffer = &m_acKeyBuffer[0];
- }
-
- ::LeaveCriticalSection( &m_cKbdCriticalSection );
-
- // Signal that a keypress event has occurred
- ::SetEvent( m_hKeyEvent );
- }
- else CView::OnChar( nChar, nRepCnt, nFlags);
- }
-
- void CFrotzCEView::OnSysChar(UINT nChar, UINT nRepCnt, UINT nFlags)
- {
- // Expecting input?
- if (m_bExpectingInput)
- {
- // Alt key pressed?
- if ((nFlags & (1 << 13)) != 0)
- {
- int ch;
-
- // Check for special keys
- switch (nChar)
- {
- case 'H':
- case 'h':
- ch = HOT_KEY_HELP;
- break;
-
- case 'D':
- case 'd':
- ch = HOT_KEY_DEBUGGING;
- break;
-
- case 'N':
- case 'n':
- ch = HOT_KEY_RESTART;
- break;
-
- case 'P':
- case 'p':
- ch = HOT_KEY_PLAYBACK;
- break;
-
- case 'R':
- case 'r':
- ch = HOT_KEY_RECORDING;
- break;
-
- case 'S':
- case 's':
- ch = HOT_KEY_SEED;
- break;
-
- case 'U':
- case 'u':
- ch = HOT_KEY_UNDO;
- break;
-
- case 'X':
- case 'x':
- ch = HOT_KEY_QUIT;
- break;
-
- default:
- ch = 0;
- break;
- }
-
- // Got anything?
- if (ch)
- {
- ::EnterCriticalSection( &m_cKbdCriticalSection );
-
- // Add hotkey to buffer
- *m_pcWriteKeyBuffer = ch;
- m_pcWriteKeyBuffer++;
-
- // Gone past end of buffer?
- if (m_pcWriteKeyBuffer > &m_acKeyBuffer[KEYBUFFER_SIZE-1])
- {
- // Go back to beginning of buffer
- m_pcWriteKeyBuffer = &m_acKeyBuffer[0];
- }
-
- ::LeaveCriticalSection( &m_cKbdCriticalSection );
-
- // Signal that a keypress event has occurred
- ::SetEvent( m_hKeyEvent );
- }
- else CView::OnSysChar( nChar, nRepCnt, nFlags );
- }
- }
- else CView::OnSysChar( nChar, nRepCnt, nFlags );
- }
-
- void CFrotzCEView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
- {
- // Expecting input?
- if (m_bExpectingInput)
- {
- int ch;
-
- // Check for recognised keys
- switch (nChar)
- {
- // Left arrow
- case 37:
- ch = LEFT_ARROW_KEY;
- break;
- // Right arrow
- case 39:
- ch = RIGHT_ARROW_KEY;
- break;
- // Up arrow
- case 38:
- ch = UP_ARROW_KEY;
- break;
- // Down arrow
- case 40:
- ch = DOWN_ARROW_KEY;
- break;
- // Page up
- case 33:
- ch = SPECIAL_KEY_PAGE_UP;
- break;
- // Page down
- case 34:
- ch = SPECIAL_KEY_PAGE_DOWN;
- break;
- // Home
- case 36:
- ch = SPECIAL_KEY_HOME;
- break;
- // End
- case 35:
- ch = SPECIAL_KEY_END;
- break;
- // Del
- case 46:
- ch = SPECIAL_KEY_DELETE;
- break;
- // Insert
- case 45:
- ch = SPECIAL_KEY_INSERT;
- break;
- default:
- ch = 0;
- break;
- }
-
- // Got anything?
- if (ch)
- {
- ::EnterCriticalSection( &m_cKbdCriticalSection );
-
- // Add hotkey to buffer
- *m_pcWriteKeyBuffer = ch;
- m_pcWriteKeyBuffer++;
-
- // Gone past end of buffer?
- if (m_pcWriteKeyBuffer > &m_acKeyBuffer[KEYBUFFER_SIZE-1])
- {
- // Go back to beginning of buffer
- m_pcWriteKeyBuffer = &m_acKeyBuffer[0];
- }
-
- ::LeaveCriticalSection( &m_cKbdCriticalSection );
-
- // Signal that a keypress event has occurred
- ::SetEvent( m_hKeyEvent );
- }
- else CView::OnKeyDown(nChar, nRepCnt, nFlags);
- }
- else CView::OnKeyDown(nChar, nRepCnt, nFlags);
- }
-
- void CFrotzCEView::StuffKeyboard( const char *pchChars, BOOL bReturn, BOOL bEsc )
- {
- ::EnterCriticalSection( &m_cKbdCriticalSection );
-
- // Clear input first?
- if (bEsc)
- {
- // Add ESC key to buffer
- *m_pcWriteKeyBuffer = ESC_KEY;
- m_pcWriteKeyBuffer++;
-
- // Gone past end of buffer?
- if (m_pcWriteKeyBuffer > &m_acKeyBuffer[KEYBUFFER_SIZE-1])
- {
- // Go back to beginning of buffer
- m_pcWriteKeyBuffer = &m_acKeyBuffer[0];
- }
- }
-
- // Stuff chars into buffer
- while (*pchChars)
- {
- // Add char to buffer
- *m_pcWriteKeyBuffer = (int) *pchChars;
- pchChars++;
- m_pcWriteKeyBuffer++;
-
- // Gone past end of buffer?
- if (m_pcWriteKeyBuffer > &m_acKeyBuffer[KEYBUFFER_SIZE-1])
- {
- // Go back to beginning of buffer
- m_pcWriteKeyBuffer = &m_acKeyBuffer[0];
- }
- }
-
- // Want a return?
- if (bReturn)
- {
- // Add return key to buffer
- *m_pcWriteKeyBuffer = ENTER_KEY;
- m_pcWriteKeyBuffer++;
-
- // Gone past end of buffer?
- if (m_pcWriteKeyBuffer > &m_acKeyBuffer[KEYBUFFER_SIZE-1])
- {
- // Go back to beginning of buffer
- m_pcWriteKeyBuffer = &m_acKeyBuffer[0];
- }
- }
-
- ::LeaveCriticalSection( &m_cKbdCriticalSection );
-
- // Signal that a keypress event has occurred
- ::SetEvent( m_hKeyEvent );
- }
-
- void CFrotzCEView::OnRestore()
- {
- if (m_bExpectingInput) StuffKeyboard( "Restore", TRUE, TRUE );
- }
-
- void CFrotzCEView::OnSave()
- {
- if (m_bExpectingInput) StuffKeyboard( "Save", TRUE, TRUE );
- }
-
- void CFrotzCEView::OnUndo()
- {
- // Expecting input?
- if (m_bExpectingInput)
- {
- ::EnterCriticalSection( &m_cKbdCriticalSection );
-
- // Add char to buffer
- *m_pcWriteKeyBuffer = HOT_KEY_UNDO;
- m_pcWriteKeyBuffer++;
-
- // Gone past end of buffer?
- if (m_pcWriteKeyBuffer > &m_acKeyBuffer[KEYBUFFER_SIZE-1])
- {
- // Go back to beginning of buffer
- m_pcWriteKeyBuffer = &m_acKeyBuffer[0];
- }
-
- ::LeaveCriticalSection( &m_cKbdCriticalSection );
-
- // Signal that a keypress event has occurred
- ::SetEvent( m_hKeyEvent );
- }
- }
-
- void CFrotzCEView::OnDown()
- {
- if (m_bExpectingInput) StuffKeyboard( "Down", TRUE, TRUE );
- }
-
- void CFrotzCEView::OnEast()
- {
- if (m_bExpectingInput)
- {
- BOOL bReturn = (m_nState == STATE_MOVING);
-
- m_nState = STATE_MOVING;
-
- StuffKeyboard( "East", bReturn );
- }
- }
-
- void CFrotzCEView::OnInventory()
- {
- if (m_bExpectingInput) StuffKeyboard( "Inventory", TRUE, TRUE );
- }
-
- void CFrotzCEView::OnLook()
- {
- if (m_bExpectingInput)
- {
- m_nState = STATE_LOOKING;
-
- StuffKeyboard( "Look", FALSE, TRUE );
- }
- }
-
- void CFrotzCEView::OnOpen()
- {
- if (m_bExpectingInput)
- {
- m_nState = STATE_OPENING;
-
- StuffKeyboard( "Open ", FALSE, TRUE );
- }
- }
-
- void CFrotzCEView::OnNorth()
- {
- if (m_bExpectingInput)
- {
- m_nState = STATE_MOVING;
-
- StuffKeyboard( "North", FALSE, TRUE );
- }
- }
-
- void CFrotzCEView::OnSouth()
- {
- if (m_bExpectingInput)
- {
- m_nState = STATE_MOVING;
-
- StuffKeyboard( "South", FALSE, TRUE );
- }
- }
-
- void CFrotzCEView::OnTake()
- {
- if (m_bExpectingInput)
- {
- m_nState = STATE_TAKING;
-
- StuffKeyboard( "Take ", FALSE, TRUE );
- }
- }
-
- void CFrotzCEView::OnDrop()
- {
- if (m_bExpectingInput)
- {
- m_nState = STATE_TAKING;
-
- StuffKeyboard( "Drop ", FALSE, TRUE );
- }
- }
-
- void CFrotzCEView::OnGo()
- {
- if (m_bExpectingInput)
- {
- m_nState = STATE_GOING;
-
- StuffKeyboard( "Go to ", FALSE, TRUE );
- }
- }
-
- void CFrotzCEView::OnUp()
- {
- if (m_bExpectingInput) StuffKeyboard( "Up", TRUE, TRUE );
- }
-
- void CFrotzCEView::OnWest()
- {
- if (m_bExpectingInput)
- {
- BOOL bReturn = (m_nState == STATE_MOVING);
-
- m_nState = STATE_MOVING;
-
- StuffKeyboard( "West", bReturn );
- }
- }
-
- void CFrotzCEView::OnLButtonDown(UINT nFlags, CPoint point)
- {
- // Expecting input?
- if (m_bExpectingInput)
- {
- int nCharRow, nCharCol;
- char *pszBuffer = new char[m_nWidth+1];
- int i = 0;
- BOOL bReturn = TRUE;
-
- // Calculate char position
- nCharRow = point.y / m_nCharHeight;
- nCharCol = point.x / m_nCharWidth;
-
- // Go backwards until beginning of word
- while (nCharCol)
- {
- if (m_pScreen[(nCharRow * m_nWidth) + nCharCol-1] != _T(' ')) nCharCol--;
- else break;
- }
-
- // Valid row?
- if (nCharRow < m_nHeight)
- {
- // Copy word to buffer
- for (; nCharCol < m_nWidth; i++)
- {
- pszBuffer[i] = (char) m_pScreen[(nCharRow * m_nWidth) + nCharCol + i];
-
- if (pszBuffer[i] == ' ') break;
- }
- }
-
- pszBuffer[i] = '\0';
-
- // Check current state
- switch (m_nState)
- {
- case STATE_NONE:
- if (strlen( pszBuffer )) bReturn = FALSE;
- break;
- case STATE_LOOKING:
- if (strlen( pszBuffer )) StuffKeyboard( " at ", FALSE );
- break;
- case STATE_TAKING:
- if (!strlen( pszBuffer )) StuffKeyboard( "all", FALSE );
- break;
- case STATE_OPENING:
- if (!strlen( pszBuffer )) StuffKeyboard( "Door", FALSE );
- break;
- case STATE_MOVING:
- pszBuffer[0] = '\0';
- break;
- }
-
- // Copy buffer into keyboard buffer
- StuffKeyboard( pszBuffer, bReturn );
-
- // Add a space if we're not adding a return
- if (!bReturn) StuffKeyboard( " ", FALSE );
-
- delete [] pszBuffer;
- }
-
- CView::OnLButtonDown(nFlags, point);
- }
-
- void CFrotzCEView::OnQuit()
- {
- // Expecting input?
- if (m_bExpectingInput)
- {
- ::EnterCriticalSection( &m_cKbdCriticalSection );
-
- // Add hotkey to buffer
- *m_pcWriteKeyBuffer = HOT_KEY_QUIT;
- m_pcWriteKeyBuffer++;
-
- // Gone past end of buffer?
- if (m_pcWriteKeyBuffer > &m_acKeyBuffer[KEYBUFFER_SIZE-1])
- {
- // Go back to beginning of buffer
- m_pcWriteKeyBuffer = &m_acKeyBuffer[0];
- }
-
- ::LeaveCriticalSection( &m_cKbdCriticalSection );
-
- // Signal that a keypress event has occurred
- ::SetEvent( m_hKeyEvent );
- }
- }
-
- void CFrotzCEView::OnTimer(UINT nIDEvent)
- {
- // Need to do a refresh?
- if (m_bRedraw)
- {
- // Using text styles?
- if (m_bUseStyles)
- {
- // Invalidate and clear client area
- Invalidate( TRUE );
- }
- else
- {
- // Invalidate client area
- Invalidate( FALSE );
- }
-
- // Flag that refresh has been done
- m_bRedraw = FALSE;
- }
- }
-