diff options
author | Johannes Schickel | 2010-10-13 03:57:44 +0000 |
---|---|---|
committer | Johannes Schickel | 2010-10-13 03:57:44 +0000 |
commit | 75e8452b6e6a2bf4fb2f588aa00b428a60d873b5 (patch) | |
tree | f29541d55309487a94bd1d38e8b53bb3dde9aec6 /engines/testbed/graphics.cpp | |
parent | 48ee83b88957dab86bc763e9ef21a70179fa8679 (diff) | |
parent | e9f50882ea5b6beeefa994040be9d3bab6a1f107 (diff) | |
download | scummvm-rg350-75e8452b6e6a2bf4fb2f588aa00b428a60d873b5.tar.gz scummvm-rg350-75e8452b6e6a2bf4fb2f588aa00b428a60d873b5.tar.bz2 scummvm-rg350-75e8452b6e6a2bf4fb2f588aa00b428a60d873b5.zip |
OPENGL: Merged from trunk, from rev 52105 to 53396.
This includes an rather hacky attempt to merge all the recent gp2x backend
changes into the branch. I suppose the gp2x backend and probably all new
backends, i.e. gph, dingux etc., might not compile anymore.
Since I have no way of testing those it would be nice if porters could look
into getting those up to speed in this branch.
svn-id: r53399
Diffstat (limited to 'engines/testbed/graphics.cpp')
-rw-r--r-- | engines/testbed/graphics.cpp | 1150 |
1 files changed, 1150 insertions, 0 deletions
diff --git a/engines/testbed/graphics.cpp b/engines/testbed/graphics.cpp new file mode 100644 index 0000000000..086db21c67 --- /dev/null +++ b/engines/testbed/graphics.cpp @@ -0,0 +1,1150 @@ +/* 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. + * + * $URL$ + * $Id$ + */ + +#include "common/events.h" +#include "common/list.h" +#include "common/random.h" + +#include "engines/engine.h" + +#include "testbed/graphics.h" +#include "testbed/testsuite.h" + +#include "graphics/cursorman.h" +#include "graphics/fontman.h" +#include "graphics/surface.h" +#include "graphics/VectorRendererSpec.h" + +namespace Testbed { + +byte GFXTestSuite::_palette[256 * 4] = {0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 0}; + +GFXTestSuite::GFXTestSuite() { + // Initialize color palettes + // The fourth field is for alpha channel which is unused + // Assuming 8bpp as of now + g_system->setPalette(_palette, 0, 3); + + // Init Mouse Palette (White-black-yellow) + GFXtests::initMousePalette(); + + // Add tests here + + // Blitting buffer on screen + addTest("BlitBitmaps", &GFXtests::copyRectToScreen); + + // GFX Transcations + addTest("FullScreenMode", &GFXtests::fullScreenMode); + addTest("AspectRatio", &GFXtests::aspectRatio); + addTest("IconifyingWindow", &GFXtests::iconifyWindow); + + // Mouse Layer tests (Palettes and movements) + addTest("PalettizedCursors", &GFXtests::palettizedCursors); + addTest("MouseMovements", &GFXtests::mouseMovements); + // FIXME: Scaled cursor crash with odd dimmensions + addTest("ScaledCursors", &GFXtests::scaledCursors); + + // Effects + addTest("shakingEffect", &GFXtests::shakingEffect); + // addTest("focusRectangle", &GFXtests::focusRectangle); + + // Overlay + addTest("Overlays", &GFXtests::overlayGraphics); + + // Specific Tests: + addTest("PaletteRotation", &GFXtests::paletteRotation); + addTest("cursorTrailsInGUI", &GFXtests::cursorTrails); + //addTest("Pixel Formats", &GFXtests::pixelFormats); +} + +void GFXTestSuite::setCustomColor(uint r, uint g, uint b) { + _palette[8] = r; + _palette[9] = g; + _palette[10] = b; + + // Set colorNum kColorSpecial with a special color. + int absIndx = kColorSpecial * 4; + _palette[absIndx + 1] = 173; + _palette[absIndx + 2] = 255; + _palette[absIndx + 3] = 47; + g_system->setPalette(_palette, 0, 256); +} + +// Helper functions used by GFX tests + +void GFXtests::initMousePalette() { + byte palette[3 * 4]; // Black, white and yellow + + palette[0] = palette[1] = palette[2] = 0; + palette[4] = palette[5] = palette[6] = 255; + palette[8] = palette[9] = 255; + palette[10] = 0; + + CursorMan.replaceCursorPalette(palette, 0, 3); +} + +Common::Rect GFXtests::computeSize(Common::Rect &cursorRect, int scalingFactor, int cursorTargetScale) { + if (cursorTargetScale == 1 || scalingFactor == 1) { + // Game data and cursor would be scaled equally. + // so dimensions would be same. + return Common::Rect(cursorRect.width(), cursorRect.height()); + } + + if (scalingFactor == 2) { + // Game data is scaled by 2, cursor is said to be scaled by 2 or 3. so it wud not be scaled any further + // So a w/2 x h/2 rectangle when scaled would match the cursor + return Common::Rect(cursorRect.width() / 2, cursorRect.height() / 2); + } + + if (scalingFactor == 3) { + // Cursor traget scale is 2 or 3. + return Common::Rect((cursorRect.width() / cursorTargetScale), (cursorRect.height() / cursorTargetScale)); + } else { + Testsuite::logPrintf("Unsupported scaler %dx\n", scalingFactor); + return Common::Rect(); + } +} + +void GFXtests::HSVtoRGB(int &rComp, int &gComp, int &bComp, int hue, int sat, int val) { + float r = rComp; + float g = gComp; + float b = bComp; + + float h = hue * (360 / 256.0); // All colors are tried + float s = sat; + float v = val; + + int i; + float f, p, q, t; + + if (s == 0) { + r = g = b = v * 255; + return; + } + + h /= 60; + i = (int)h; + f = h - i; + p = v * (1 - s); + q = v * (1 - s * f); + t = v * (1 - s * (1 - f)); + + switch (i) { + case 0: + r = v; + g = t; + b = p; + break; + case 1: + r = q; + g = v; + b = p; + break; + case 2: + r = p; + g = v; + b = t; + break; + case 3: + r = p; + g = q; + b = v; + break; + case 4: + r = t; + g = p; + b = v; + break; + default: + r = v; + g = p; + b = q; + break; + } + + rComp = (int)(r * 255); + gComp = (int)(g * 255); + bComp = (int)(b * 255); +} + +Common::Rect GFXtests::drawCursor(bool cursorPaletteDisabled, const char *gfxModeName, int cursorTargetScale) { + // Buffer initialized with yellow color + byte buffer[500]; + memset(buffer, 2, sizeof(buffer)); + + int cursorWidth = 12; + int cursorHeight = 12; + + /* Disable HotSpot highlighting as of now + + // Paint the cursor with yellow, except the hotspot + for (int i = 0; i < 16; i++) { + for (int j = 0; j < 16; j++) { + if (i != j && i != 15 - j) { + buffer[i * 16 + j] = 2; + } + } + } + + */ + + // Uncommenting the next line and commenting the line after that would reproduce the crash + // CursorMan.replaceCursor(buffer, 11, 11, 0, 0, 255, cursorTargetScale); + CursorMan.replaceCursor(buffer, 12, 12, 0, 0, 255, cursorTargetScale); + CursorMan.showMouse(true); + + if (cursorPaletteDisabled) { + CursorMan.disableCursorPalette(true); + } else { + initMousePalette(); + CursorMan.disableCursorPalette(false); + } + + g_system->updateScreen(); + return Common::Rect(0, 0, cursorWidth, cursorHeight); +} + +void rotatePalette(byte *palette, int size) { + // Rotate the colors starting from address palette "size" times + + // take a temporary palette color + byte tColor[4] = {0}; + // save first color in it. + memcpy(tColor, &palette[0], 4 * sizeof(byte)); + + // Move each color upward by 1 + for (int i = 0; i < size - 1; i++) { + memcpy(&palette[i * 4], &palette[(i + 1) * 4], 4 * sizeof(byte)); + } + // Assign last color to tcolor + memcpy(&palette[(size - 1) * 4], tColor, 4 * sizeof(byte)); +} + +/** + * Sets up mouse loop, exits when user clicks any of the mouse button + */ +void GFXtests::setupMouseLoop(bool disableCursorPalette, const char *gfxModeName, int cursorTargetScale) { + bool isFeaturePresent; + isFeaturePresent = g_system->hasFeature(OSystem::kFeatureCursorHasPalette); + Common::Rect cursorRect; + + if (isFeaturePresent) { + + cursorRect = GFXtests::drawCursor(disableCursorPalette, gfxModeName, cursorTargetScale); + + Common::EventManager *eventMan = g_system->getEventManager(); + Common::Event event; + Common::Point pt(0, 100); + + bool quitLoop = false; + uint32 lastRedraw = 0; + const uint32 waitTime = 1000 / 45; + + Testsuite::clearScreen(); + Common::String info = disableCursorPalette ? "Using Game Palette" : "Using cursor palette"; + info += " to render the cursor, Click to finish"; + + Common::String gfxScalarMode(gfxModeName); + + if (!gfxScalarMode.equals("")) { + info = "The cursor size (yellow) should match the red rectangle."; + } + + Testsuite::writeOnScreen(info, pt); + + info = "GFX Mode"; + info += gfxModeName; + info += " "; + + char cScale = cursorTargetScale + '0'; + info += "Cursor scale: "; + info += cScale; + + Common::Rect estimatedCursorRect; + + if (!gfxScalarMode.equals("")) { + + if (gfxScalarMode.contains("1x")) { + estimatedCursorRect = computeSize(cursorRect, 1, cursorTargetScale); + } else if (gfxScalarMode.contains("2x")) { + estimatedCursorRect = computeSize(cursorRect, 2, cursorTargetScale); + } else if (gfxScalarMode.contains("3x")) { + estimatedCursorRect = computeSize(cursorRect, 3, cursorTargetScale); + } else { + // If unable to detect scaler, default to 2 + Testsuite::writeOnScreen("Unable to detect scaling factor, assuming 2x", Common::Point(0, 5)); + estimatedCursorRect = computeSize(cursorRect, 2, cursorTargetScale); + } + Testsuite::writeOnScreen(info, Common::Point(0, 120)); + + // Move cursor to (20, 20) + g_system->warpMouse(20, 20); + // Move estimated rect to (20, 20) + estimatedCursorRect.moveTo(20, 20); + + Graphics::Surface *screen = g_system->lockScreen(); + GFXTestSuite::setCustomColor(255, 0, 0); + screen->fillRect(estimatedCursorRect, 2); + g_system->unlockScreen(); + g_system->updateScreen(); + } + + while (!quitLoop) { + while (eventMan->pollEvent(event)) { + if (Engine::shouldQuit()) { + // Quit directly + return; + } + if (lastRedraw + waitTime < g_system->getMillis()) { + g_system->updateScreen(); + lastRedraw = g_system->getMillis(); + } + + switch (event.type) { + case Common::EVENT_MOUSEMOVE: + break; + case Common::EVENT_LBUTTONDOWN: + case Common::EVENT_RBUTTONDOWN: + quitLoop = true; + Testsuite::clearScreen(); + Testsuite::writeOnScreen("Mouse clicked", pt); + g_system->delayMillis(1000); + break; + default: + break;// Ignore handling any other event + + } + } + } + } else { + Testsuite::displayMessage("feature not supported"); + } +} + +/** + * Used by aspectRatio() + */ +void GFXtests::drawEllipse(int cx, int cy, int a, int b) { + + // Take a buffer of screen size + int width = g_system->getWidth(); + int height = Testsuite::getDisplayRegionCoordinates().y; + byte *buffer = new byte[height * width]; + double theta; + int x, y, x1, y1; + + memset(buffer, 0, sizeof(byte) * width * height); + // Illuminate the center + buffer[cx * width + cy] = 1; + + // Illuminate the points lying on ellipse + + for (theta = 0; theta <= PI / 2; theta += PI / 360) { + x = (int)(b * sin(theta) + 0.5); + y = (int)(a * cos(theta) + 0.5); + + // This gives us four points + + x1 = x + cx; + y1 = y + cy; + + buffer[x1 * width + y1] = 1; + + x1 = (-1) * x + cx; + y1 = y + cy; + + buffer[x1 * width + y1] = 1; + + x1 = x + cx; + y1 = (-1) * y + cy; + + buffer[x1 * width + y1] = 1; + + x1 = (-1) * x + cx; + y1 = (-1) * y + cy; + + buffer[x1 * width + y1] = 1; + } + + g_system->copyRectToScreen(buffer, width, 0, 0, width, height); + g_system->updateScreen(); + delete[] buffer; +} + +// GFXtests go here + +/** + * Tests the fullscreen mode by: toggling between fullscreen and windowed mode + */ +TestExitStatus GFXtests::fullScreenMode() { + Testsuite::clearScreen(); + Common::String info = "Fullscreen test. Here you should expect a toggle between windowed and fullscreen states depending " + "upon your initial state."; + + Common::Point pt(0, 100); + Testsuite::writeOnScreen("Testing fullscreen mode", pt); + + if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { + Testsuite::logPrintf("Info! Skipping test : FullScreenMode\n"); + return kTestSkipped; + } + + bool isFeaturePresent; + bool isFeatureEnabled; + TestExitStatus passed = kTestPassed; + Common::String prompt; + OptionSelected shouldSelect; + + isFeaturePresent = g_system->hasFeature(OSystem::kFeatureFullscreenMode); + + if (isFeaturePresent) { + // Toggle + isFeatureEnabled = g_system->getFeatureState(OSystem::kFeatureFullscreenMode); + shouldSelect = isFeatureEnabled ? kOptionLeft : kOptionRight; + + g_system->delayMillis(1000); + + if (isFeatureEnabled) { + Testsuite::logDetailedPrintf("Current Mode is Fullsecreen\n"); + } else { + Testsuite::logDetailedPrintf("Current Mode is Windowed\n"); + } + + prompt = " Which mode do you see currently ? "; + + if (!Testsuite::handleInteractiveInput(prompt, "Fullscreen", "Windowed", shouldSelect)) { + // User selected incorrect current state + passed = kTestFailed; + Testsuite::logDetailedPrintf("g_system->getFeatureState() failed\n"); + } + + g_system->beginGFXTransaction(); + g_system->setFeatureState(OSystem::kFeatureFullscreenMode, !isFeatureEnabled); + g_system->endGFXTransaction(); + + // Current state should be now !isFeatureEnabled + isFeatureEnabled = g_system->getFeatureState(OSystem::kFeatureFullscreenMode); + shouldSelect = isFeatureEnabled ? kOptionLeft : kOptionRight; + + g_system->delayMillis(1000); + + prompt = " Which screen mode do you see now ? "; + + if (!Testsuite::handleInteractiveInput(prompt, "Fullscreen", "Windowed", shouldSelect)) { + // User selected incorrect mode + passed = kTestFailed; + Testsuite::logDetailedPrintf("g_system->setFeatureState() failed\n"); + } + + g_system->beginGFXTransaction(); + g_system->setFeatureState(OSystem::kFeatureFullscreenMode, !isFeatureEnabled); + g_system->endGFXTransaction(); + + g_system->delayMillis(1000); + + prompt = "This should be your initial state. Is it?"; + + if (!Testsuite::handleInteractiveInput(prompt, "Yes, it is", "Nopes", shouldSelect)) { + // User selected incorrect mode + Testsuite::logDetailedPrintf("switching back to initial state failed\n"); + passed = kTestFailed; + } + + } else { + Testsuite::displayMessage("feature not supported"); + } + + return passed; +} + +/** + * Tests the aspect ratio correction by: drawing an ellipse, when corrected the ellipse should render to a circle + */ +TestExitStatus GFXtests::aspectRatio() { + + Testsuite::clearScreen(); + Common::String info = "Aspect Ratio Correction test. If aspect ratio correction is enabled you should expect a circle on screen," + " an ellipse otherwise."; + + if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { + Testsuite::logPrintf("Info! Skipping test : Aspect Ratio\n"); + return kTestSkipped; + } + // Draw an ellipse on the screen + drawEllipse(80, 160, 72, 60); + + bool isFeaturePresent; + bool isFeatureEnabled; + TestExitStatus passed = kTestPassed; + Common::String prompt; + OptionSelected shouldSelect; + + isFeaturePresent = g_system->hasFeature(OSystem::kFeatureAspectRatioCorrection); + isFeatureEnabled = g_system->getFeatureState(OSystem::kFeatureAspectRatioCorrection); + g_system->delayMillis(1000); + + if (isFeaturePresent) { + // Toggle + shouldSelect = isFeatureEnabled ? kOptionLeft : kOptionRight; + prompt = " What does the curve on screen appears to you ?"; + if (!Testsuite::handleInteractiveInput(prompt, "Circle", "Ellipse", shouldSelect)) { + // User selected incorrect option + passed = kTestFailed; + Testsuite::logDetailedPrintf("Aspect Ratio Correction failed\n"); + } + + g_system->beginGFXTransaction(); + g_system->setFeatureState(OSystem::kFeatureAspectRatioCorrection, !isFeatureEnabled); + g_system->endGFXTransaction(); + + g_system->delayMillis(1000); + + shouldSelect = !isFeatureEnabled ? kOptionLeft : kOptionRight; + prompt = " What does the curve on screen appears to you ?"; + if (!Testsuite::handleInteractiveInput(prompt, "Circle", "Ellipse", shouldSelect)) { + // User selected incorrect option + passed = kTestFailed; + Testsuite::logDetailedPrintf("Aspect Ratio Correction failed\n"); + } + + g_system->beginGFXTransaction(); + g_system->setFeatureState(OSystem::kFeatureAspectRatioCorrection, isFeatureEnabled); + g_system->endGFXTransaction(); + } else { + Testsuite::displayMessage("feature not supported"); + } + + g_system->delayMillis(500); + + if (Testsuite::handleInteractiveInput("This should definetely be your initial state?", "Yes, it is", "Nopes", kOptionRight)) { + // User selected incorrect mode + Testsuite::logDetailedPrintf("Switching back to initial state failed\n"); + passed = kTestFailed; + } + + return passed; +} + +/** + * Tests Palettized cursors. + * Method: Create a yellow colored cursor, should be able to move it. Once you click test terminates + */ +TestExitStatus GFXtests::palettizedCursors() { + + Testsuite::clearScreen(); + Common::String info = "Palettized Cursors test.\n " + "Here you should expect to see a yellow mouse cursor rendered with mouse graphics.\n" + "You would be able to move the cursor. Later we use game graphics to render the cursor.\n" + "For cursor palette it should be yellow and will be red if rendered by the game palette.\n" + "The test finishes when mouse (L/R) is clicked."; + + + if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { + Testsuite::logPrintf("Info! Skipping test : Palettized Cursors\n"); + return kTestSkipped; + } + + TestExitStatus passed = kTestPassed; + + // Testing with cursor Palette + setupMouseLoop(); + + if (Testsuite::handleInteractiveInput("Which color did the cursor appeared to you?", "Yellow", "Any other", kOptionRight)) { + Testsuite::logDetailedPrintf("Couldn't use cursor palette for rendering cursor\n"); + passed = kTestFailed; + } + + // Testing with game Palette + GFXTestSuite::setCustomColor(255, 0, 0); + setupMouseLoop(true); + + if (Testsuite::handleInteractiveInput("Which color did the cursor appeared to you?", "Red", "Any other", kOptionRight)) { + Testsuite::logDetailedPrintf("Couldn't use Game palette for rendering cursor\n"); + passed = kTestFailed; + } + + if (!Testsuite::handleInteractiveInput(" Did test run as was described? ")) { + passed = kTestFailed; + } + + // re-enable cursor palette + CursorMan.disableCursorPalette(false); + // Done with cursors, make them invisible, any other test the could simply make it visible + CursorMan.showMouse(false); + return passed; +} + +/** + * Tests automated mouse movements. "Warp" functionality provided by the backend. + */ + +TestExitStatus GFXtests::mouseMovements() { + Testsuite::clearScreen(); + // Ensure that the cursor is visible + CursorMan.showMouse(true); + + Common::String info = "Testing Automated Mouse movements.\n" + "You should expect cursor hotspot(top-left corner) to automatically move from (0, 0) to (100, 100).\n" + "There we have a rectangle drawn, finally the cursor would lie centred in that rectangle."; + + if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { + Testsuite::logPrintf("Info! Skipping test : Mouse Movements\n"); + return kTestSkipped; + } + + // Draw Rectangle + Graphics::Surface *screen = g_system->lockScreen(); + // Ensure that 2 represents red in current palette + GFXTestSuite::setCustomColor(255, 0, 0); + screen->fillRect(Common::Rect::center(106, 106, 14, 14), 2); + g_system->unlockScreen(); + + // Testing Mouse Movements now! + Common::Point pt(0, 10); + Testsuite::writeOnScreen("Moving mouse hotspot automatically from (0, 0) to (100, 100)", pt); + g_system->warpMouse(0, 0); + g_system->updateScreen(); + g_system->delayMillis(1000); + + for (int i = 0; i <= 100; i++) { + g_system->delayMillis(20); + g_system->warpMouse(i, i); + g_system->updateScreen(); + } + + Testsuite::writeOnScreen("Mouse hotspot Moved to (100, 100)", pt); + g_system->delayMillis(1500); + CursorMan.showMouse(false); + + if (Testsuite::handleInteractiveInput("Was the cursor centred in the rectangle at (100, 100)?", "Yes", "No", kOptionRight)) { + return kTestFailed; + } + + return kTestPassed; +} + + + +/** + * This basically blits the screen by the contents of its buffer. + * + */ +TestExitStatus GFXtests::copyRectToScreen() { + + Testsuite::clearScreen(); + Common::String info = "Testing Blitting a Bitmap to screen.\n" + "You should expect to see a 20x40 yellow horizontal rectangle centred at the screen."; + + if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { + Testsuite::logPrintf("Info! Skipping test : Blitting Bitmap\n"); + return kTestSkipped; + } + + GFXTestSuite::setCustomColor(255, 255, 0); + byte buffer[20 * 40]; + memset(buffer, 2, 20 * 40); + + uint x = g_system->getWidth() / 2 - 20; + uint y = g_system->getHeight() / 2 - 10; + + g_system->copyRectToScreen(buffer, 40, x, y, 40, 20); + g_system->updateScreen(); + g_system->delayMillis(1000); + + if (Testsuite::handleInteractiveInput(" Did you see yellow rectangle ? ", "Yes", "No", kOptionRight)) { + return kTestFailed; + } + + return kTestPassed; +} + +/** + * Testing feature : Iconifying window + * It is expected the screen minimizes when this feature is enabled + */ +TestExitStatus GFXtests::iconifyWindow() { + + Testsuite::clearScreen(); + Common::String info = "Testing Iconify Window mode.\n If the feature is supported by the backend, " + "you should expect the window to be minimized.\n However you would manually need to de-iconify."; + + if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { + Testsuite::logPrintf("Info! Skipping test : Iconifying window\n"); + return kTestSkipped; + } + + Common::Point pt(0, 100); + Testsuite::writeOnScreen("Testing Iconifying window", pt); + + bool isFeaturePresent; + bool isFeatureEnabled; + + isFeaturePresent = g_system->hasFeature(OSystem::kFeatureIconifyWindow); + isFeatureEnabled = g_system->getFeatureState(OSystem::kFeatureIconifyWindow); + g_system->delayMillis(1000); + + if (isFeaturePresent) { + // Toggle + + g_system->beginGFXTransaction(); + g_system->setFeatureState(OSystem::kFeatureIconifyWindow, !isFeatureEnabled); + g_system->endGFXTransaction(); + + g_system->delayMillis(1000); + + g_system->beginGFXTransaction(); + g_system->setFeatureState(OSystem::kFeatureIconifyWindow, isFeatureEnabled); + g_system->endGFXTransaction(); + } else { + Testsuite::displayMessage("feature not supported"); + } + + if (Testsuite::handleInteractiveInput(" Did you see the window minimized? ", "Yes", "No", kOptionRight)) { + return kTestFailed; + } + + return kTestPassed; +} + +/** + * Testing feature: Scaled cursors + */ +TestExitStatus GFXtests::scaledCursors() { + + Testsuite::clearScreen(); + Common::String info = "Testing : Scaled cursors\n" + "Here every graphics mode is tried with a cursorTargetScale of 1, 2 and 3.\n" + "The expected cursor size is drawn as a rectangle.\n The cursor should approximately match that rectangle.\n" + "This may take time, You may skip the later scalers and just examine the first three i.e 1x, 2x and 3x"; + + bool isAspectRatioCorrected = g_system->getFeatureState(OSystem::kFeatureAspectRatioCorrection); + + if (isAspectRatioCorrected) { + info += "\nDisabling Aspect ratio correction, for letting cusors match exactly, will be restored after this test."; + } + + if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { + Testsuite::logPrintf("Info! Skipping test : Scaled Cursors\n"); + return kTestSkipped; + } + + int maxLimit = 1000; + if (!Testsuite::handleInteractiveInput("Do You want to restrict scalers to 1x, 2x and 3x only?", "Yes", "No", kOptionRight)) { + maxLimit = 3; + } + + + if (isAspectRatioCorrected) { + g_system->beginGFXTransaction(); + g_system->setFeatureState(OSystem::kFeatureAspectRatioCorrection, false); + g_system->endGFXTransaction(); + } + + const int currGFXMode = g_system->getGraphicsMode(); + const OSystem::GraphicsMode *gfxMode = g_system->getSupportedGraphicsModes(); + + while (gfxMode->name && maxLimit > 0) { + // for every graphics mode display cursors for cursorTargetScale 1, 2 and 3 + // Switch Graphics mode + // FIXME: Crashes with "3x" mode now.: + + info = Common::String::printf("Testing : Scaled cursors with GFX Mode %s\n", gfxMode->name); + if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { + Testsuite::logPrintf("\tInfo! Skipping sub-test : Scaled Cursors :: GFX Mode %s\n", gfxMode->name); + gfxMode++; + maxLimit--; + continue; + } + if (Engine::shouldQuit()) { + // Explicit exit requested + Testsuite::logPrintf("Info! Explicit exit requested during scaling test, this test may be incomplete\n"); + return kTestSkipped; + } + + g_system->beginGFXTransaction(); + + bool isGFXModeSet = g_system->setGraphicsMode(gfxMode->id); + g_system->initSize(320, 200); + + OSystem::TransactionError gfxError = g_system->endGFXTransaction(); + + if (gfxError == OSystem::kTransactionSuccess && isGFXModeSet) { + setupMouseLoop(false, gfxMode->name, 1); + Testsuite::clearScreen(); + + setupMouseLoop(false, gfxMode->name, 2); + Testsuite::clearScreen(); + + setupMouseLoop(false, gfxMode->name, 3); + Testsuite::clearScreen(); + } else { + Testsuite::logDetailedPrintf("Switching to graphics mode %s failed\n", gfxMode->name); + return kTestFailed; + } + gfxMode++; + maxLimit--; + + info = "Did the expected cursor size and the actual cursor size matched?"; + if (Testsuite::handleInteractiveInput(info, "Yes", "No", kOptionRight)) { + Testsuite::logPrintf("\tInfo! Failed sub-test : Scaled Cursors :: GFX Mode %s\n", gfxMode->name); + } + + if (Engine::shouldQuit()) { + // Explicit exit requested + Testsuite::logPrintf("Info! Explicit exit requested during scaling test, this test may be incomplete\n"); + return kTestSkipped; + } + + } + + // Restore Original State + g_system->beginGFXTransaction(); + bool isGFXModeSet = g_system->setGraphicsMode(currGFXMode); + g_system->initSize(320, 200); + + if (isAspectRatioCorrected) { + g_system->setFeatureState(OSystem::kFeatureAspectRatioCorrection, true); + } + + OSystem::TransactionError gfxError = g_system->endGFXTransaction(); + + if (gfxError != OSystem::kTransactionSuccess || !isGFXModeSet) { + Testsuite::logDetailedPrintf("Switcing to initial state failed\n"); + return kTestFailed; + } + + // Done with cursors, Make them invisible, any other test may enable and use it. + CursorMan.showMouse(false); + return kTestPassed; +} + +TestExitStatus GFXtests::shakingEffect() { + + Testsuite::clearScreen(); + Common::String info = "Shaking test. You should expect the graphics(text/bars etc) drawn on the screen to shake!"; + + if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { + Testsuite::logPrintf("Info! Skipping test : Shaking Effect\n"); + return kTestSkipped; + } + + Common::Point pt(0, 100); + Testsuite::writeOnScreen("If Shaking Effect works, this should shake!", pt); + int times = 15; + while (times--) { + g_system->setShakePos(25); + g_system->delayMillis(50); + g_system->updateScreen(); + g_system->setShakePos(0); + g_system->delayMillis(50); + g_system->updateScreen(); + } + g_system->delayMillis(1500); + + if (Testsuite::handleInteractiveInput("Did the Shaking test worked as you were expecting?", "Yes", "No", kOptionRight)) { + Testsuite::logDetailedPrintf("Shaking Effect didn't worked"); + return kTestFailed; + } + return kTestPassed; +} + +TestExitStatus GFXtests::focusRectangle() { + + Testsuite::clearScreen(); + Common::String info = "Testing : Setting and hiding Focus \n" + "If this feature is implemented, the focus should be toggled between the two rectangles on the corners"; + + if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { + Testsuite::logPrintf("Info! Skipping test : focus Rectangle\n"); + return kTestSkipped; + } + + const Graphics::Font &font(*FontMan.getFontByUsage(Graphics::FontManager::kConsoleFont)); + + Graphics::Surface *screen = g_system->lockScreen(); + int screenHeight = g_system->getHeight(); + int screenWidth = g_system->getWidth(); + + int height = font.getFontHeight(); + int width = screenWidth / 2; + + Common::Rect rectLeft(0, 0, width, height * 2); + screen->fillRect(rectLeft, kColorWhite); + font.drawString(screen, "Focus 1", rectLeft.left, rectLeft.top, width, kColorBlack, Graphics::kTextAlignLeft); + + Common::Rect rectRight(screenWidth - width, screenHeight - height * 2 , screenWidth, screenHeight); + screen->fillRect(rectRight, kColorWhite); + font.drawString(screen, "Focus 2", rectRight.left, rectRight.top, width, kColorBlack, Graphics::kTextAlignRight); + g_system->unlockScreen(); + g_system->updateScreen(); + + g_system->clearFocusRectangle(); + + g_system->setFocusRectangle(rectLeft); + g_system->updateScreen(); + + g_system->delayMillis(1000); + + g_system->setFocusRectangle(rectRight); + g_system->updateScreen(); + + g_system->clearFocusRectangle(); + + if (Testsuite::handleInteractiveInput("Did you noticed a variation in focus?", "Yes", "No", kOptionRight)) { + Testsuite::logDetailedPrintf("Focus Rectangle feature doesn't works. Check platform.\n"); + } + + return kTestPassed; +} + +TestExitStatus GFXtests::overlayGraphics() { + Testsuite::clearScreen(); + Common::String info = "Overlay Graphics. You should expect to see a green colored rectangle on the screen"; + + if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { + Testsuite::logPrintf("Info! Skipping test : Overlay Graphics\n"); + return kTestSkipped; + } + + Graphics::PixelFormat pf = g_system->getOverlayFormat(); + + OverlayColor buffer[50 * 100]; + OverlayColor value = pf.RGBToColor(0, 255, 0); + + for (int i = 0; i < 50 * 100; i++) { + buffer[i] = value; + } + + g_system->showOverlay(); + g_system->copyRectToOverlay(buffer, 100, 270, 175, 100, 50); + g_system->updateScreen(); + + g_system->delayMillis(1000); + + g_system->hideOverlay(); + g_system->updateScreen(); + + if (Testsuite::handleInteractiveInput("Did you see a green overlayed rectangle?", "Yes", "No", kOptionRight)) { + Testsuite::logDetailedPrintf("Overlay Rectangle feature doesn't works\n"); + return kTestFailed; + } + + return kTestPassed; +} + +TestExitStatus GFXtests::paletteRotation() { + + Common::String info = "Palette rotation. Here we draw a full 256 colored rainbow and then rotate it.\n" + "Note that the screen graphics change without having to draw anything.\n" + "The palette should appear to rotate, as a result, the background will change its color too.\n" + "Click the mouse button to exit."; + + if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { + Testsuite::logPrintf("Info! Skipping test : palette Rotation\n"); + return kTestSkipped; + } + Common::Point pt(0, 10); + Testsuite::clearEntireScreen(); + + // Use 256 colors + byte palette[256 * 4] = {0}; + + int r, g, b; + int colIndx; + + for (int i = 0; i < 256; i++) { + HSVtoRGB(r, g, b, i, 1, 1); + colIndx = i * 4; + palette[colIndx] = r; + palette[colIndx + 1] = g; + palette[colIndx + 2] = b; + } + + // Initialize this palette. + g_system->setPalette(palette, 0, 256); + + // Draw 256 Rectangles, each 1 pixel wide and 10 pixels long + // one for 0-255 color range other for 0-127-255 range + byte buffer[256 * 30] = {0}; + + for (int i = 0; i < 30; i++) { + for (int j = 0; j < 256; j++) { + if (i < 10) { + buffer[i * 256 + j] = j + 2; + } else if (i < 20) { + buffer[i * 256 + j] = 0; + } else { + buffer[i * 256 + j] = ((j + 127) % 256) + 2; + } + } + } + + g_system->copyRectToScreen(buffer, 256, 22, 50, 256, 30); + + // Show mouse + CursorMan.showMouse(true); + g_system->updateScreen(); + + + bool toRotate = true; + Common::Event event; + + while (toRotate) { + while (g_system->getEventManager()->pollEvent(event)) { + if (event.type == Common::EVENT_LBUTTONDOWN || event.type == Common::EVENT_RBUTTONDOWN) { + toRotate = false; + } + } + + rotatePalette(palette, 256); + + g_system->delayMillis(10); + g_system->setPalette(palette, 0, 256); + g_system->updateScreen(); + } + + CursorMan.showMouse(false); + // Reset initial palettes + GFXTestSuite::setCustomColor(255, 0, 0); + Testsuite::clearScreen(); + + if(Testsuite::handleInteractiveInput("Did you see a rotation in colors of rectangles displayed on screen?", "Yes", "No", kOptionRight)) { + return kTestFailed; + } + + return kTestPassed; +} + +TestExitStatus GFXtests::cursorTrails() { + Common::String info = "With some shake offset the cursor was known to leave trails in the GUI\n" + "Here we set some offset and ask user to check for mouse trails, \n" + "the test is passed when there are no trails"; + + if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { + Testsuite::logPrintf("Info! Skipping test : Cursor Trails\n"); + return kTestSkipped; + } + TestExitStatus passed = kTestFailed; + g_system->setShakePos(25); + g_system->updateScreen(); + if (Testsuite::handleInteractiveInput("Does the cursor leaves trails while moving?", "Yes", "No", kOptionRight)) { + passed = kTestPassed; + } + g_system->setShakePos(0); + g_system->updateScreen(); + return passed; +} + +TestExitStatus GFXtests::pixelFormats() { + Testsuite::clearScreen(); + Common::String info = "Testing pixel formats. Here we iterate over all the supported pixel formats and display some colors using them\n" + "This may take long, especially if the backend supports many pixel formats"; + + if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { + Testsuite::logPrintf("Info! Skipping test : Pixel Formats\n"); + return kTestSkipped; + } + + Common::List<Graphics::PixelFormat> pfList = g_system->getSupportedFormats(); + Common::List<Graphics::PixelFormat>::const_iterator iter = pfList.begin(); + + int numFormatsTested = 0; + int numPassed = 0; + int numFailed = 0; + + Testsuite::logDetailedPrintf("Testing Pixel Formats. Size of list : %d\n", pfList.size()); + + for (iter = pfList.begin(); iter != pfList.end(); iter++) { + numFormatsTested++; + if (iter->bytesPerPixel == 1) { + // Palettes already tested + continue; + } else if (iter->bytesPerPixel > 2) { + Testsuite::logDetailedPrintf("Can't test pixels with bpp > 2\n"); + continue; + } + + // Switch to that pixel Format + g_system->beginGFXTransaction(); + g_system->initSize(320, 200, &(*iter)); + g_system->endGFXTransaction(); + Testsuite::clearScreen(true); + + // Draw some nice gradients + // Pick up some colors + uint colors[6]; + + colors[0] = iter->RGBToColor(255, 255, 255); + colors[1] = iter->RGBToColor(135, 48, 21); + colors[2] = iter->RGBToColor(205, 190, 87); + colors[3] = iter->RGBToColor(0, 32, 64); + colors[4] = iter->RGBToColor(181, 126, 145); + colors[5] = iter->RGBToColor(47, 78, 36); + + Common::Point pt(0, 170); + Common::String msg; + msg = Common::String::printf("Testing Pixel Formats, %d of %d", numFormatsTested, pfList.size()); + Testsuite::writeOnScreen(msg, pt, true); + + // CopyRectToScreen could have been used, but that may involve writing code which + // already resides in graphics/surface.h + // So using Graphics::Surface + + Graphics::Surface *screen = g_system->lockScreen(); + + // Draw 6 rectangles centred at (50, 160), piled over one another + // each with color in colors[] + for (int i = 0; i < 6; i++) { + screen->fillRect(Common::Rect::center(160, 20 + i * 10, 100, 10), colors[i]); + } + + g_system->unlockScreen(); + g_system->updateScreen(); + g_system->delayMillis(500); + + if(Testsuite::handleInteractiveInput("Were you able to notice the colored rectangles on the screen for this format?", "Yes", "No", kOptionLeft)) { + numPassed++; + } else { + numFailed++; + Testsuite::logDetailedPrintf("Testing pixel format failed for format #%d on the list\n", numFormatsTested); + } + } + + // Revert back to 8bpp + g_system->beginGFXTransaction(); + g_system->initSize(320, 200); + g_system->endGFXTransaction(); + GFXTestSuite::setCustomColor(255, 0, 0); + initMousePalette(); + Testsuite::clearScreen(); + + if (numFailed) { + Testsuite::logDetailedPrintf("Pixel Format test: Failed : %d, Passed : %d, Ignored %d\n",numFailed, numPassed, numFormatsTested - (numPassed + numFailed)); + return kTestFailed; + } + + return kTestPassed; +} + +} // End of namespace Testbed |