int main() { REG_DISPCTL = MODE4 | BG2_ENABLE; // Splash screen here setPalette(mainScreen_palette); drawImage4(0, 0, 240, 160, mainScreen); waitForVBlank(); flipPage(); int screen = 1; int currentMode = EDITMODE; const u16 colors[] = {WHITE, BLACK, RED, GREEN}; // alive = black = 1 // dead = white = 0 // alive + cursor = green = 3 // dead + cursor = red = 2 while (1) { if (screen) { setPalette(mainScreen_palette); drawImage4(0, 0, 240, 160, mainScreen); waitForVBlank(); flipPage(); if (KEY_DOWN_NOW(BUTTON_SELECT)) { screen = 0; setPalette(colors); fillScreen4(DEAD); flipPage(); copy(); while (KEY_DOWN_NOW(BUTTON_SELECT)) { } } } else { int draw = 0; // Select (backspace) = toggle between edit and simmode if (KEY_DOWN_NOW(BUTTON_SELECT)) { if (currentMode == EDITMODE) { currentMode = SIMMODE; eraseCursor(); } else { currentMode = EDITMODE; } while (KEY_DOWN_NOW(BUTTON_SELECT)) { // Won't do anything while select button is down } } // SIMMODE = 1 // EDITMODE = 0 // ***************SIM MODE******************* if (currentMode) { int paused = 0; int sim = 1; while (sim) { while (~paused & currentMode) { currentMode = simTick(); if (KEY_DOWN_NOW(BUTTON_SELECT)) { currentMode = EDITMODE; sim = 0; while (KEY_DOWN_NOW(BUTTON_SELECT)) { } } if (KEY_DOWN_NOW(BUTTON_A)) { paused = 1; while (KEY_DOWN_NOW(BUTTON_A)) { } } } //******************PAUSED**************** while (paused) { // Button B is X // This toggles next frame if (KEY_DOWN_NOW(BUTTON_B)) { simTick(); } if (KEY_DOWN_NOW(BUTTON_SELECT)) { currentMode = EDITMODE; while (KEY_DOWN_NOW(BUTTON_SELECT)) { } sim = 0; paused = 0; } if (KEY_DOWN_NOW(BUTTON_A)) { paused = 0; while (KEY_DOWN_NOW(BUTTON_A)) { } } } // end of paused } // end of sim } // end of currentMode if // ************EDIT MODE************** if (~currentMode) { copy(); drawCursor(); draw = cursorMoves(); if (KEY_DOWN_NOW(BUTTON_L)) { fillScreen4(DEAD); flipPage(); copy(); while (KEY_DOWN_NOW(BUTTON_L)) { } } } drawCursor(); if (draw) { waitForVBlank(); flipPage(); draw = 0; } } // end of else } }
reg_t GfxControls32::kernelEditText(const reg_t controlObject) { SegManager *segMan = _segMan; TextEditor editor; reg_t textObject = readSelector(_segMan, controlObject, SELECTOR(text)); editor.text = _segMan->getString(textObject); editor.foreColor = readSelectorValue(_segMan, controlObject, SELECTOR(fore)); editor.backColor = readSelectorValue(_segMan, controlObject, SELECTOR(back)); editor.skipColor = readSelectorValue(_segMan, controlObject, SELECTOR(skip)); editor.fontId = readSelectorValue(_segMan, controlObject, SELECTOR(font)); editor.maxLength = readSelectorValue(_segMan, controlObject, SELECTOR(width)); editor.bitmap = readSelector(_segMan, controlObject, SELECTOR(bitmap)); editor.cursorCharPosition = 0; editor.cursorIsDrawn = false; editor.borderColor = readSelectorValue(_segMan, controlObject, SELECTOR(borderColor)); reg_t titleObject = readSelector(_segMan, controlObject, SELECTOR(title)); int16 titleHeight = 0; GuiResourceId titleFontId = readSelectorValue(_segMan, controlObject, SELECTOR(titleFont)); if (!titleObject.isNull()) { GfxFont *titleFont = _gfxCache->getFont(titleFontId); titleHeight += _gfxText32->scaleUpHeight(titleFont->getHeight()) + 1; if (editor.borderColor != -1) { titleHeight += 2; } } int16 width = 0; int16 height = titleHeight; GfxFont *editorFont = _gfxCache->getFont(editor.fontId); height += _gfxText32->scaleUpHeight(editorFont->getHeight()) + 1; _gfxText32->setFont(editor.fontId); int16 emSize = _gfxText32->getCharWidth('M', true); width += editor.maxLength * emSize + 1; if (editor.borderColor != -1) { width += 4; height += 2; } Common::Rect editorPlaneRect(width, height); editorPlaneRect.translate(readSelectorValue(_segMan, controlObject, SELECTOR(x)), readSelectorValue(_segMan, controlObject, SELECTOR(y))); reg_t planeObj = readSelector(_segMan, controlObject, SELECTOR(plane)); Plane *sourcePlane = g_sci->_gfxFrameout->getVisiblePlanes().findByObject(planeObj); if (sourcePlane == nullptr) { sourcePlane = g_sci->_gfxFrameout->getPlanes().findByObject(planeObj); if (sourcePlane == nullptr) { error("Could not find plane %04x:%04x", PRINT_REG(planeObj)); } } editorPlaneRect.translate(sourcePlane->_gameRect.left, sourcePlane->_gameRect.top); editor.textRect = Common::Rect(2, titleHeight + 2, width - 1, height - 1); editor.width = width; if (editor.bitmap.isNull()) { TextAlign alignment = (TextAlign)readSelectorValue(_segMan, controlObject, SELECTOR(mode)); if (titleObject.isNull()) { bool dimmed = readSelectorValue(_segMan, controlObject, SELECTOR(dimmed)); editor.bitmap = _gfxText32->createFontBitmap(width, height, editor.textRect, editor.text, editor.foreColor, editor.backColor, editor.skipColor, editor.fontId, alignment, editor.borderColor, dimmed, true, false); } else { error("Titled bitmaps are not known to be used by any game. Please submit a bug report with details about the game you were playing and what you were doing that triggered this error. Thanks!"); } } drawCursor(editor); Plane *plane = new Plane(editorPlaneRect, kPlanePicTransparent); plane->changePic(); g_sci->_gfxFrameout->addPlane(*plane); CelInfo32 celInfo; celInfo.type = kCelTypeMem; celInfo.bitmap = editor.bitmap; ScreenItem *screenItem = new ScreenItem(plane->_object, celInfo, Common::Point(), ScaleInfo()); plane->_screenItemList.add(screenItem); // frameOut must be called after the screen item is // created, and before it is updated at the end of the // event loop, otherwise it has both created and updated // flags set which crashes the engine (it runs updates // before creations) g_sci->_gfxFrameout->frameOut(true); EventManager *eventManager = g_sci->getEventManager(); bool clearTextOnInput = true; bool textChanged = false; for (;;) { // We peek here because the last event needs to be allowed to // dispatch a second time to the normal event handling system. // In the actual engine, the event is always consumed and then // the last event just gets posted back to the event manager for // reprocessing, but instead, we only remove the event from the // queue *after* we have determined it is not a defocusing event const SciEvent event = eventManager->getSciEvent(SCI_EVENT_ANY | SCI_EVENT_PEEK); bool focused = true; // Original engine did not have a QUIT event but we have to handle it if (event.type == SCI_EVENT_QUIT) { focused = false; break; } else if (event.type == SCI_EVENT_MOUSE_PRESS && !editorPlaneRect.contains(event.mousePosSci)) { focused = false; } else if (event.type == SCI_EVENT_KEYBOARD) { switch (event.character) { case SCI_KEY_ESC: case SCI_KEY_UP: case SCI_KEY_DOWN: case SCI_KEY_TAB: case SCI_KEY_SHIFT_TAB: case SCI_KEY_ENTER: focused = false; break; } } if (!focused) { break; } // Consume the event now that we know it is not one of the // defocusing events above if (event.type != SCI_EVENT_NONE) eventManager->getSciEvent(SCI_EVENT_ANY); // NOTE: In the original engine, the font and bitmap were // reset here on each iteration through the loop, but it // doesn't seem like this should be necessary since // control is not yielded back to the VM until input is // received, which means there is nothing that could modify // the GfxText32's state with a different font in the // meantime bool shouldDeleteChar = false; bool shouldRedrawText = false; uint16 lastCursorPosition = editor.cursorCharPosition; if (event.type == SCI_EVENT_KEYBOARD) { switch (event.character) { case SCI_KEY_LEFT: clearTextOnInput = false; if (editor.cursorCharPosition > 0) { --editor.cursorCharPosition; } break; case SCI_KEY_RIGHT: clearTextOnInput = false; if (editor.cursorCharPosition < editor.text.size()) { ++editor.cursorCharPosition; } break; case SCI_KEY_HOME: clearTextOnInput = false; editor.cursorCharPosition = 0; break; case SCI_KEY_END: clearTextOnInput = false; editor.cursorCharPosition = editor.text.size(); break; case SCI_KEY_INSERT: clearTextOnInput = false; // Redrawing also changes the cursor rect to // reflect the new insertion mode shouldRedrawText = true; _overwriteMode = !_overwriteMode; break; case SCI_KEY_DELETE: clearTextOnInput = false; if (editor.cursorCharPosition < editor.text.size()) { shouldDeleteChar = true; } break; case SCI_KEY_BACKSPACE: clearTextOnInput = false; shouldDeleteChar = true; if (editor.cursorCharPosition > 0) { --editor.cursorCharPosition; } break; case SCI_KEY_ETX: editor.text.clear(); editor.cursorCharPosition = 0; shouldRedrawText = true; break; default: { if (event.character >= 20 && event.character < 257) { if (clearTextOnInput) { clearTextOnInput = false; editor.text.clear(); } if ( (_overwriteMode && editor.cursorCharPosition < editor.maxLength) || (editor.text.size() < editor.maxLength && _gfxText32->getCharWidth(event.character, true) + _gfxText32->getStringWidth(editor.text) < editor.textRect.width()) ) { if (_overwriteMode && editor.cursorCharPosition < editor.text.size()) { editor.text.setChar(event.character, editor.cursorCharPosition); } else { editor.text.insertChar(event.character, editor.cursorCharPosition); } ++editor.cursorCharPosition; shouldRedrawText = true; } } } } } if (shouldDeleteChar) { shouldRedrawText = true; if (editor.cursorCharPosition < editor.text.size()) { editor.text.deleteChar(editor.cursorCharPosition); } } if (shouldRedrawText) { eraseCursor(editor); _gfxText32->erase(editor.textRect, true); _gfxText32->drawTextBox(editor.text); drawCursor(editor); textChanged = true; screenItem->_updated = g_sci->_gfxFrameout->getScreenCount(); } else if (editor.cursorCharPosition != lastCursorPosition) { eraseCursor(editor); drawCursor(editor); screenItem->_updated = g_sci->_gfxFrameout->getScreenCount(); } else { flashCursor(editor); screenItem->_updated = g_sci->_gfxFrameout->getScreenCount(); } g_sci->_gfxFrameout->frameOut(true); g_sci->getSciDebugger()->onFrame(); g_sci->_gfxFrameout->throttle(); } g_sci->_gfxFrameout->deletePlane(*plane); if (readSelectorValue(segMan, controlObject, SELECTOR(frameOut))) { g_sci->_gfxFrameout->frameOut(true); } _segMan->freeBitmap(editor.bitmap); if (textChanged) { editor.text.trim(); SciArray &string = *_segMan->lookupArray(textObject); string.fromString(editor.text); } return make_reg(0, textChanged); }
void QgsGrassShell::printStdout() { // Debug #ifdef QGISDEBUG QString str; for ( int i = 0; i < ( int )mStdoutBuffer.length(); i++ ) { int c = mStdoutBuffer[i]; QString s = ""; if ( c > '\037' && c != '\177' ) // control characters { str += c; } else { str += "(c=" + QString::number( c, 8 ) + ")"; } } QgsDebugMsg( "****** buffer ******" ); QgsDebugMsg( QString( "-->%1<--" ).arg( str.toLocal8Bit().constData() ) ); #endif eraseCursor(); // To make it faster we want to print maximum lenght blocks from buffer while ( mStdoutBuffer.length() > 0 ) { QgsDebugMsg( "------ cycle ------" ); // Search control character int control = -1; for ( int i = 0; i < ( int )mStdoutBuffer.length(); i++ ) { int c = mStdoutBuffer[i]; if ( c < '\037' || c == '\177' ) { control = i; break; } } QgsDebugMsg( QString( "control = %1" ).arg( control ) ); // Process control character if found at index 0 if ( control == 0 ) { int c = mStdoutBuffer[0]; QgsDebugMsg( QString( "c = %1" ).arg( QString::number( c, 8 ).local8Bit().data() ) ); // control sequence if ( c == '\033' ) { // QgsDebugMsg("control sequence"); bool found = false; // It is sequence, so it should be at least one more character // wait for more data if ( mStdoutBuffer.length() < 2 ) break; if ( mStdoutBuffer[1] == ']' && mStdoutBuffer.length() < 3 ) break; // ESC ] Ps ; Pt BEL (xterm title hack) QRegExp rx( "\\](\\d+);([^\\a]+)\\a" ); if ( rx.search( mStdoutBuffer, 1 ) == 1 ) { int mlen = rx.matchedLength(); QgsDebugMsg( QString( "ESC(set title): %1" ).arg( rx.cap( 2 ).local8Bit().data() ) ); mStdoutBuffer.remove( 0, mlen + 1 ); found = true; } if ( !found ) { // ESC [ Pn ; Pn FINAL // or ESC [ = Pn ; Pn FINAL // or ESC [ = Pn ; Pn FINAL // TODO: QRegExp captures only last of repeated patterns // ( ; separated nums - (;\\d+)* ) rx.setPattern( "\\[([?=])*(\\d+)*(;\\d+)*([A-z])" ); if ( rx.search( mStdoutBuffer, 1 ) == 1 ) { int mlen = rx.matchedLength(); char final = rx.cap( 4 ).at( 0 ).latin1(); QgsDebugMsg( QString( "final = %1" ).arg( final ) ); // QgsDebugMsg(QString("ESC: %1").arg(rx.cap(0))); switch ( final ) { case 'l' : // RM - Reset Mode case 'h' : // SM - Set Mode { int mode = -1; switch ( rx.cap( 2 ).toInt() ) { case 4 : mode = Insert; break; default: QgsDebugMsg( QString( "ESC ignored: %1" ).arg( rx.cap( 0 ).local8Bit().data() ) ); break; } if ( mode >= 0 ) { if ( final == 'l' ) resetMode( mode ); else setMode( mode ); } break; } case 'm' : // SGR - Select Graphic Rendition if ( rx.cap( 2 ).isEmpty() || rx.cap( 2 ).toInt() == 0 ) { for ( int i = 0; i < RendetionCount; i++ ) { mRendetion[i] = false; } } else { QgsDebugMsg( QString( "ESC SGR ignored: %1" ).arg( rx.cap( 0 ).local8Bit().data() ) ); } break; case 'P' : // DCH - Delete Character { int n = rx.cap( 2 ).toInt(); mText->setSelection( mParagraph, mIndex, mParagraph, mIndex + n, 0 ); mText->removeSelectedText( 0 ); break; } case 'K' : // EL - Erase In Line if ( rx.cap( 2 ).isEmpty() || rx.cap( 2 ).toInt() == 0 ) { //mText->setSelectionAttributes ( 1, QColor(255,255,255), true ); mText->setSelection( mParagraph, mIndex, mParagraph, mText->paragraphLength( mParagraph ), 0 ); mText->removeSelectedText( 0 ); } break; // TODO: multiple tab stops case 'H' : // Horizontal Tabulation Set (HTS) mTabStop[mIndex] = true; QgsDebugMsg( QString( "TAB set on %1" ).arg( mIndex ) ); break; case 'g' : // Tabulation Clear (TBC) // ESC [ g Clears tab stop at the cursor // ESC [ 2 g Clears all tab stops in the line // ESC [ 3 g Clears all tab stops in the Page QgsDebugMsg( "TAB reset" ); if ( rx.cap( 2 ).isEmpty() || rx.cap( 2 ).toInt() == 0 ) { mTabStop[mIndex] = false; } else { for ( int i = 0; i < ( int )mTabStop.size(); i++ ) mTabStop[mIndex] = false; } break; default: QgsDebugMsg( QString( "ESC ignored: %1" ).arg( rx.cap( 0 ).local8Bit().data() ) ); break; } mStdoutBuffer.remove( 0, mlen + 1 ); found = true; }