/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "common/events.h" #include "common/keyboard.h" #include "common/rect.h" #include "common/str.h" #include "common/system.h" #include "common/util.h" #include "engines/engine.h" #include "graphics/cursorman.h" #include "graphics/font.h" #include "graphics/fontman.h" #include "graphics/surface.h" #include "testbed/events.h" #include "testbed/graphics.h" namespace Testbed { struct keycodeToChar { Common::KeyCode code; char value; } keyCodeLUT[] = { {Common::KEYCODE_a, 'a'}, {Common::KEYCODE_b, 'b'}, {Common::KEYCODE_c, 'c'}, {Common::KEYCODE_d, 'd'}, {Common::KEYCODE_e, 'e'}, {Common::KEYCODE_f, 'f'}, {Common::KEYCODE_g, 'g'}, {Common::KEYCODE_h, 'h'}, {Common::KEYCODE_i, 'i'}, {Common::KEYCODE_j, 'j'}, {Common::KEYCODE_k, 'k'}, {Common::KEYCODE_l, 'l'}, {Common::KEYCODE_m, 'm'}, {Common::KEYCODE_n, 'n'}, {Common::KEYCODE_o, 'o'}, {Common::KEYCODE_p, 'p'}, {Common::KEYCODE_q, 'q'}, {Common::KEYCODE_r, 'r'}, {Common::KEYCODE_s, 's'}, {Common::KEYCODE_t, 't'}, {Common::KEYCODE_u, 'u'}, {Common::KEYCODE_v, 'v'}, {Common::KEYCODE_w, 'w'}, {Common::KEYCODE_x, 'x'}, {Common::KEYCODE_y, 'y'}, {Common::KEYCODE_z, 'z'}, {Common::KEYCODE_0, '0'}, {Common::KEYCODE_1, '1'}, {Common::KEYCODE_2, '2'}, {Common::KEYCODE_3, '3'}, {Common::KEYCODE_4, '4'}, {Common::KEYCODE_5, '5'}, {Common::KEYCODE_6, '6'}, {Common::KEYCODE_7, '7'}, {Common::KEYCODE_8, '8'}, {Common::KEYCODE_9, '9'}, {Common::KEYCODE_SPACE, ' '} }; char EventTests::keystrokeToChar() { Common::EventManager *eventMan = g_system->getEventManager(); Common::Event event; // handle all keybd events while (true) { while (eventMan->pollEvent(event)) { // Quit if explicitly requested! if (Engine::shouldQuit()) { return 0; } switch (event.type) { case Common::EVENT_KEYDOWN: if (event.kbd.keycode == Common::KEYCODE_ESCAPE) { return 0; } for (int i = 0; i < ARRAYSIZE(keyCodeLUT); i++) { if (event.kbd.keycode == keyCodeLUT[i].code) { return keyCodeLUT[i].value; } } break; default: break; // Ignore other events } } } } Common::Rect EventTests::drawFinishZone() { Graphics::Surface *screen = g_system->lockScreen(); const Graphics::Font &font(*FontMan.getFontByUsage(Graphics::FontManager::kBigGUIFont)); int width = 35; int height = 20; int right = g_system->getWidth(); Common::Rect rect(0, 0, right, height); Common::Rect rect2(0, 0, right - width, height); screen->fillRect(rect, kColorSpecial); screen->fillRect(rect2, kColorBlack); g_system->unlockScreen(); font.drawString(screen, "Close", rect.left, rect.top, screen->w, kColorBlack, Graphics::kTextAlignRight); g_system->updateScreen(); return Common::Rect(right - width, 0, right, height); } TestExitStatus EventTests::mouseEvents() { Testsuite::clearScreen(); Common::String info = "Testing Mouse events.\n " "Any movement/click generated by L/R/M mouse buttons or the mouse wheel should be detected.\n" "Press X to exit"; if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { Testsuite::logPrintf("Info! Skipping test : keyboard events\n"); return kTestSkipped; } Common::EventManager *eventMan = g_system->getEventManager(); Common::Point pt(0, 30); Common::Rect rectInfo = Testsuite::writeOnScreen("Generate mouse events make L/R/M button clicks, move wheel", pt); pt.y += 15; Testsuite::writeOnScreen("Press X to exit", pt); pt.y = 70; Common::Rect rectLB = Testsuite::writeOnScreen("Left-button click : Not tested", pt); pt.y += 15; Common::Rect rectRB = Testsuite::writeOnScreen("Right-button click : Not tested", pt); pt.y += 15; Common::Rect rectMB = Testsuite::writeOnScreen("Middle-button click : Not tested", pt); pt.y += 15; Common::Rect rectWheel = Testsuite::writeOnScreen("Wheel Movements : Not tested", pt); // Init Mouse Palette GFXtests::initMousePalette(); Common::Rect finishZone = drawFinishZone(); bool quitLoop = false; TestExitStatus passed = kTestPassed; // handle all mouse events Common::Event event; while (!quitLoop) { // Show mouse CursorMan.showMouse(true); g_system->updateScreen(); while (eventMan->pollEvent(event)) { // Quit if explicitly requested if (Engine::shouldQuit()) { return passed; } switch (event.type) { case Common::EVENT_MOUSEMOVE: // Movements havee already been tested in GFX break; case Common::EVENT_LBUTTONDOWN: Testsuite::clearScreen(rectInfo); Testsuite::writeOnScreen("Mouse left-button pressed", Common::Point(rectInfo.left, rectInfo.top)); break; case Common::EVENT_RBUTTONDOWN: Testsuite::clearScreen(rectInfo); Testsuite::writeOnScreen("Mouse right-button pressed", Common::Point(rectInfo.left, rectInfo.top)); break; case Common::EVENT_WHEELDOWN: Testsuite::clearScreen(rectInfo); Testsuite::writeOnScreen("Mouse wheel moved down", Common::Point(rectInfo.left, rectInfo.top)); Testsuite::writeOnScreen("Wheel Movements : Done!", Common::Point(rectWheel.left, rectWheel.top)); break; case Common::EVENT_MBUTTONDOWN: Testsuite::clearScreen(rectInfo); Testsuite::writeOnScreen("Mouse middle-button pressed ", Common::Point(rectInfo.left, rectInfo.top)); break; case Common::EVENT_LBUTTONUP: Testsuite::clearScreen(rectInfo); if (finishZone.contains(eventMan->getMousePos())) { quitLoop = true; } Testsuite::writeOnScreen("Mouse left-button released", Common::Point(rectInfo.left, rectInfo.top)); Testsuite::writeOnScreen("Left-button clicks : Done!", Common::Point(rectLB.left, rectLB.top)); break; case Common::EVENT_RBUTTONUP: Testsuite::clearScreen(rectInfo); Testsuite::writeOnScreen("Mouse right-button released", Common::Point(rectInfo.left, rectInfo.top)); Testsuite::writeOnScreen("Right-button clicks : Done!", Common::Point(rectRB.left, rectRB.top)); break; case Common::EVENT_WHEELUP: Testsuite::clearScreen(rectInfo); Testsuite::writeOnScreen("Mouse wheel moved up", Common::Point(rectInfo.left, rectInfo.top)); Testsuite::writeOnScreen("Wheel Movements : Done!", Common::Point(rectWheel.left, rectWheel.top)); break; case Common::EVENT_MBUTTONUP: Testsuite::clearScreen(rectInfo); Testsuite::writeOnScreen("Mouse middle-button released ", Common::Point(rectInfo.left, rectInfo.top)); Testsuite::writeOnScreen("Middle-button clicks : Done!", Common::Point(rectMB.left, rectMB.top)); break; case Common::EVENT_KEYDOWN: if (event.kbd.keycode == Common::KEYCODE_x) { Testsuite::clearScreen(rectInfo); Testsuite::writeOnScreen("Exit requested", Common::Point(rectInfo.left, rectInfo.top)); quitLoop = true; } break; default: break; } } } CursorMan.showMouse(false); // Verify results now! if (Testsuite::handleInteractiveInput("Were mouse clicks (L/R/M buttons) and wheel movements identfied ?", "Yes", "No", kOptionRight)) { Testsuite::logDetailedPrintf("Mouse clicks (L/R/M buttons) and wheel movements failed"); passed = kTestFailed; } return passed; } TestExitStatus EventTests::kbdEvents() { Testsuite::clearScreen(); Common::String info = "Testing keyboard events.\n " "Testbed should be able to figure out any alphanumeric keystrokes made by the user and display them back.\n" "Press ESC key when done of the input."; if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { Testsuite::logPrintf("Info! Skipping test : keyboard events\n"); return kTestSkipped; } // Make user type some word and display the output on screen Common::String text = "You Entered : "; Common::Point pt(0, 100); Testsuite::clearScreen(); Testsuite::writeOnScreen("Enter your word, press ESC when done, it will be echoed back", pt); pt.y += 20; Common::Rect rect = Testsuite::writeOnScreen(text, pt); char letter; while ((letter = keystrokeToChar()) != 0) { Testsuite::clearScreen(rect); text += letter; rect = Testsuite::writeOnScreen(text, pt); } TestExitStatus passed = kTestPassed; if (Testsuite::handleInteractiveInput("Was the word you entered same as that displayed on screen?", "Yes", "No", kOptionRight)) { Testsuite::logDetailedPrintf("Keyboard Events failed"); passed = kTestFailed; } Testsuite::clearScreen(); return passed; } TestExitStatus EventTests::showMainMenu() { Testsuite::clearScreen(); Common::String info = "Testing Main Menu events.\n " "Main Menu event is normally trigerred by user pressing (Ctrl + f5).\n" "Click 'resume'(the topmost button) to continue testbed."; if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { Testsuite::logPrintf("Info! Skipping test : Main Menu\n"); return kTestSkipped; } Common::EventManager *eventMan = g_system->getEventManager(); Common::Event mainMenuEvent; mainMenuEvent.type = Common::EVENT_MAINMENU; eventMan->pushEvent(mainMenuEvent); TestExitStatus passed = kTestPassed; if (Testsuite::handleInteractiveInput("Were you able to see a main menu widget?", "Yes", "No", kOptionRight)) { Testsuite::logDetailedPrintf("Event MAINMENU failed"); passed = kTestFailed; } return passed; } EventTestSuite::EventTestSuite() { addTest("MouseEvents", &EventTests::mouseEvents); addTest("KeyboardEvents", &EventTests::kbdEvents); addTest("MainmenuEvent", &EventTests::showMainMenu); } } // End of namespace Testbed