XBMCVideoChecker::XBMCVideoChecker(const std::string & address, uint16_t port, bool grabVideo, bool grabPhoto, bool grabAudio, bool grabMenu, bool grabScreensaver, bool enable3DDetection) : QObject(), _address(QString::fromStdString(address)), _port(port), _activePlayerRequest(R"({"id":666,"jsonrpc":"2.0","method":"Player.GetActivePlayers"})"), _currentPlayingItemRequest(R"({"id":667,"jsonrpc":"2.0","method":"Player.GetItem","params":{"playerid":%1,"properties":["file"]}})"), _checkScreensaverRequest(R"({"id":668,"jsonrpc":"2.0","method":"XBMC.GetInfoBooleans","params":{"booleans":["System.ScreenSaverActive"]}})"), _getStereoscopicMode(R"({"jsonrpc":"2.0","method":"GUI.GetProperties","params":{"properties":["stereoscopicmode"]},"id":669})"), _getXbmcVersion(R"({"jsonrpc":"2.0","method":"Application.GetProperties","params":{"properties":["version"]},"id":670})"), _socket(), _grabVideo(grabVideo), _grabPhoto(grabPhoto), _grabAudio(grabAudio), _grabMenu(grabMenu), _grabScreensaver(grabScreensaver), _enable3DDetection(enable3DDetection), _previousScreensaverMode(false), _previousGrabbingMode(GRABBINGMODE_INVALID), _previousVideoMode(VIDEO_2D), _xbmcVersion(0) { // setup socket connect(&_socket, SIGNAL(readyRead()), this, SLOT(receiveReply())); connect(&_socket, SIGNAL(disconnected()), this, SLOT(disconnected())); connect(&_socket, SIGNAL(connected()), this, SLOT(connected())); connect(&_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(connectionError(QAbstractSocket::SocketError))); } void XBMCVideoChecker::start() { reconnect(); } void XBMCVideoChecker::receiveReply() { // expect that the reply is received as a single message. Probably oke considering the size of the expected reply QString reply(_socket.readAll()); std::cout << "Message from XBMC: " << reply.toStdString() << std::endl; if (reply.contains("\"method\":\"Player.OnPlay\"")) { // send a request for the current player state _socket.write(_activePlayerRequest.toUtf8()); return; } else if (reply.contains("\"method\":\"Player.OnStop\"")) { // the player has stopped setGrabbingMode(_grabMenu ? GRABBINGMODE_MENU : GRABBINGMODE_OFF); setVideoMode(VIDEO_2D); } else if (reply.contains("\"method\":\"GUI.OnScreensaverActivated\"")) { setScreensaverMode(!_grabScreensaver); } else if (reply.contains("\"method\":\"GUI.OnScreensaverDeactivated\"")) { setScreensaverMode(false); } else if (reply.contains("\"id\":666")) { // Result of Player.GetActivePlayers // always start a new video in 2D mode emit videoMode(VIDEO_2D); if (reply.contains("video")) { // video is playing setGrabbingMode(_grabVideo ? GRABBINGMODE_VIDEO : GRABBINGMODE_OFF); // we need to get the filename // first retrieve the playerid QString key = "\"playerid\":"; QRegExp regex(key + "(\\d+)"); int pos = regex.indexIn(reply); if (pos > 0) { // now request info of the playing item QStringRef idText(&reply, pos + key.length(), regex.matchedLength() - key.length()); _socket.write(_currentPlayingItemRequest.arg(idText.toString()).toUtf8()); } } else if (reply.contains("picture")) { // picture viewer is playing setGrabbingMode(_grabPhoto ? GRABBINGMODE_PHOTO : GRABBINGMODE_OFF); } else if (reply.contains("audio")) { // audio is playing setGrabbingMode(_grabAudio ? GRABBINGMODE_AUDIO : GRABBINGMODE_OFF); } else { // Nothing is playing. setGrabbingMode(_grabMenu ? GRABBINGMODE_MENU : GRABBINGMODE_OFF); } } else if (reply.contains("\"id\":667")) { if (_xbmcVersion >= 13) { // check of active stereoscopicmode _socket.write(_getStereoscopicMode.toUtf8()); } else { // result of Player.GetItem // TODO: what if the filename contains a '"'. In Json this should have been escaped QRegExp regex("\"file\":\"((?!\").)*\""); int pos = regex.indexIn(reply); if (pos > 0) { QStringRef filename = QStringRef(&reply, pos+8, regex.matchedLength()-9); if (filename.contains("3DSBS", Qt::CaseInsensitive) || filename.contains("HSBS", Qt::CaseInsensitive)) { setVideoMode(VIDEO_3DSBS); } else if (filename.contains("3DTAB", Qt::CaseInsensitive) || filename.contains("HTAB", Qt::CaseInsensitive)) { setVideoMode(VIDEO_3DTAB); } else { setVideoMode(VIDEO_2D); } } } } else if (reply.contains("\"id\":668")) { // result of System.ScreenSaverActive bool active = reply.contains("\"System.ScreenSaverActive\":true"); setScreensaverMode(!_grabScreensaver && active); // check here xbmc version if (_socket.state() == QTcpSocket::ConnectedState) { if (_xbmcVersion == 0) { _socket.write(_getXbmcVersion.toUtf8()); } } } else if (reply.contains("\"id\":669")) { QRegExp regex("\"mode\":\"(split_vertical|split_horizontal)\""); int pos = regex.indexIn(reply); if (pos > 0) { QString sMode = regex.cap(1); if (sMode == "split_vertical") { setVideoMode(VIDEO_3DSBS); } else if (sMode == "split_horizontal") { setVideoMode(VIDEO_3DTAB); } } } else if (reply.contains("\"id\":670")) { QRegExp regex("\"major\":(\\d+)"); int pos = regex.indexIn(reply); if (pos > 0) { _xbmcVersion = regex.cap(1).toInt(); } } }
int main() { // // // Because I need it to randomize // duck's vector and spikes // srand(time(NULL)); // // Create Window // sf::VideoMode videoMode(WINDOW_X, WINDOW_Y); sf::RenderWindow window(videoMode, WINDOW_TITLE, sf::Style::Titlebar); // // Set Window max FPS to 100 // and play music in background // window.setFramerateLimit(100); sf::Music music; music.openFromFile( MUSIC_FOLDER "Courage.ogg" ); music.play(); // // // Create window border: line by line. // // line thickness 10px; // color Black // sf::RectangleShape lineTOP; lineTOP.setFillColor(sf::Color::Black); lineTOP.setPosition(sf::Vector2f(0, 0)); lineTOP.setSize(sf::Vector2f(300, 10)); sf::RectangleShape lineLEFT; lineLEFT.setFillColor(sf::Color::Black); lineLEFT.setPosition(sf::Vector2f(0, 0)); lineLEFT.setSize(sf::Vector2f(10, 450)); sf::RectangleShape lineRIGHT; lineRIGHT.setFillColor(sf::Color::Black); lineRIGHT.setPosition(sf::Vector2f(290, 0)); lineRIGHT.setSize(sf::Vector2f(10, 440)); sf::RectangleShape LineBOTTOM; LineBOTTOM.setFillColor(sf::Color::Black); LineBOTTOM.setPosition(sf::Vector2f(0, 440)); LineBOTTOM.setSize(sf::Vector2f(300, 10)); // // // Create Circle // With color RGB(242,242,242) and alpha 199 where alhpa is between 0 and 255; // // Circle radius : 100px; // Circle position: center of window sf::CircleShape circle(100); circle.setFillColor(sf::Color(242, 242, 242, 199)); circle.setOrigin(sf::Vector2f(100, 100)); circle.setPosition(sf::Vector2f(WINDOW_X / 2, WINDOW_Y / 2)); // // // Create 10 el array of colors // sf::Color colors[10]; colors[0] = sf::Color(209, 250, 142); colors[1] = sf::Color(168, 255, 142); colors[2] = sf::Color(250, 255, 142); colors[3] = sf::Color(255, 189, 190); colors[4] = sf::Color(255, 189, 223); colors[5] = sf::Color(221, 189, 255); colors[6] = sf::Color(189, 190, 255); colors[7] = sf::Color(195, 195, 216); colors[8] = sf::Color(213, 213, 213); colors[9] = sf::Color(233, 255, 142); // // Load Font from file to font object; // // if font not exist them return FONT_NOT_FOUND; sf::Font font; if (!font.loadFromFile(WINDOW_FONT)) return FONT_NOT_FOUND; currentCOLOR = colors[0]; // set starts color colorbyPoint = colors[0]; // set starts color // // Create and initialize Duck object // // @param App wios // @param array of randomized bool values // CDuck Duck(window, SpikeTab); // player is playing ? bool Game = false; // // // Main Game loop // executing until player don't close window. // // // while (window.isOpen()) { // // Text object // @param current points // @param loaded font; sf::Text circleText(points, font); setFadeColor(currentCOLOR, colorbyPoint, window, circleText); // // Keys Support // sf::Event event; while (window.pollEvent(event)) { if ((event.type == sf::Event::Closed) || (event.type == sf::Event::KeyPressed)) { if (event.key.code == sf::Keyboard::Escape) window.close(); if (event.key.code == sf::Keyboard::Space && Game == true) Duck.Jump(); if (event.key.code == sf::Keyboard::Space && Game == false) Game = true; } } // end While window.pollEvent // // // If player is playing // if (Game == true) { // // set text size to 102 // set text pos to center of window // set text origin circleText.setCharacterSize(102); circleText.setPosition(sf::Vector2f(WINDOW_X / 2, WINDOW_Y / 2 -25)); circleText.setOrigin((circleText.getLocalBounds().width / 2) + 5, (circleText.getLocalBounds().height / 2)); // // from unsigned to string; // if uPoints < 10 add 0 to string; points = (uPoints < 10 ? "0" + std::to_string(uPoints) : std::to_string(uPoints)); // // Change next background // switch (uPoints) { case 5: colorbyPoint = colors[1]; break; case 10: colorbyPoint = colors[2]; break; case 15: colorbyPoint = colors[3]; break; case 20: colorbyPoint = colors[4]; break; case 25: colorbyPoint = colors[5]; break; case 30: colorbyPoint = colors[6]; break; case 40: colorbyPoint = colors[7]; break; case 45: colorbyPoint = colors[8]; break; case 50: colorbyPoint = colors[9]; break; default: break; } // // Create Left or Right spikes // // for (int z = 0; z < static_cast<unsigned>(WINDOW_Y / SPIKE_H) - 1; z++) { if (SpikeTab[z] == true) { // // Create spikes // // @param Window // @param enum Position // @param x cord // @param y cord CSpike Spike(window, (Duck.cSide == 0 ? Right : Left), 10, (z * 41) + 11); //if (z != static_cast<unsigned>(WINDOW_Y / SPIKE_H) - 1) Spike.Update(); // // Detect collision between Duck and Spike // if (Collision::PixelPerfectTest(Duck.model, Spike.model)) { Game = false; // player lose Duck.model.setPosition(WINDOW_X / 2, WINDOW_Y / 2); // set model pos to center Duck.cSide = rand() % 2; // rand duck's vector uPoints = 0; // set 0 points Duck.modelMove.y = 0; // set grav to 0 Duck.RandSpike(); // randomize Spikes currentCOLOR = colors[0]; // set current color to default } } } for (int z = 0; z <= static_cast<unsigned>(WINDOW_X / SPIKE_H); z++) { // // Top and bottom spikes // CSpike Spike2(window, Top, (z * SPIKE_H) + 10, 10); Spike2.Update(); CSpike Spike3(window, Bottom, (z * SPIKE_H) + 10, WINDOW_Y - 10); if (z != static_cast<unsigned>(WINDOW_X / SPIKE_H)) Spike3.Update(); if (Collision::PixelPerfectTest(Duck.model, Spike2.model) || Collision::PixelPerfectTest(Duck.model, Spike3.model)) { Game = false; Duck.model.setPosition(WINDOW_X / 2, WINDOW_Y / 2); Duck.cSide = rand() % 2; uPoints = 0; Duck.modelMove.y = 0; Duck.RandSpike(); currentCOLOR = colors[0]; } } } // if GAME true else { // // Create Start Screen // // sf::Texture start_modelTeX; // Texture file sf::Sprite start_model; // Model // Load model // set texture // position // set origin if (!start_modelTeX.loadFromFile(TEXTURE_FOLDER "logo.png")) exit(TEXTURE_NOT_FOUND); start_model.setTexture(start_modelTeX); start_model.setTextureRect(sf::IntRect(0, 0, 274, 291)); start_model.setOrigin(274 / 2, 291 / 2); start_model.setPosition(WINDOW_X / 2, (WINDOW_Y / 2)); // score text circleText.setCharacterSize(50); circleText.setPosition(sf::Vector2f(WINDOW_X / 2, WINDOW_Y / 2 -25)); circleText.setOrigin((circleText.getLocalBounds().width / 2) + 5, (circleText.getLocalBounds().height / 2)); // // window.draw(start_model); window.draw(circleText); } // else game false // // window.draw(lineTOP); window.draw(lineLEFT); window.draw(lineRIGHT); window.draw(LineBOTTOM); if (Game == true) { // layer with circle and text on it window.draw(circle); window.draw(circleText); // firs layer : ONLY MOVING OBJECT Duck.Update(); } window.display(); } // end while window.isOpen return EXIT_SUCCESS; }
void App::createWindow() { // Creamos un modo de video con los valores por defecto sf::VideoMode videoMode(this->DEFAULT_VIDEO_WIDTH, this->DEFAULT_VIDEO_HEIGHT, this->DEFAULT_VIDEO_BPP); // Creamos un estilo por defecto sf::Int32 style = sf::Style::Default; // Establecemos fullscreen a false bool fullscreen = false; // Valor inicial del redisionamiento de la ventana bool resize = true; // Activamos la sincronización vertical por defecto bool vsync = true; GDE::ConfigReader conf; // Si existe un archivo de configuración lo usamos para cargar los datos if(conf.loadFromFile("window.cfg")) // FIX: Deberá ser argado con el gestor de recursos { // Comprobamos si esta activado el modo fullscreen if (conf.getBool("window", "fullscreen", false)) { fullscreen = true; // Si esta en modo fullscreen obtenemos la resolución del escritorio videoMode = sf::VideoMode::getDesktopMode(); // Establecemos el estilo de fullScreen style = sf::Style::Fullscreen; } else { // Establecemos la configuración obtenida del archivo videoMode.width = conf.getUint32("window", "width", this->DEFAULT_VIDEO_WIDTH); videoMode.height = conf.getUint32("window", "height", this->DEFAULT_VIDEO_HEIGHT); videoMode.bitsPerPixel = conf.getUint32("window", "bpp", this->DEFAULT_VIDEO_BPP); // Comprobamos si la ventana se puede redimensionar if (!conf.getBool("window", "resize", true)) { resize = false; style = sf::Style::Close | sf::Style::Titlebar; } } // Comprobamos si vsync está activado vsync = (conf.getBool("this->window", "vsync", true)); } // Creamos la ventana con los valores resulantes this->window.create(videoMode, "Genbeta Dev Engine", style); // FIX: Hay que dar opción también a usar setFrameLimit this->window.setVerticalSyncEnabled(vsync); // Escribimos la configuración en el archivo GDE::ConfigCreate newConf; newConf.open("window.cfg"); newConf.putSection("window"); newConf.putValue("width", GDE::convertInt32(videoMode.width)); newConf.putValue("height", GDE::convertInt32(videoMode.height)); newConf.putValue("bpp", GDE::convertInt32(videoMode.bitsPerPixel)); newConf.putValue("fullscreen", GDE::convertBool(fullscreen)); newConf.putValue("resize", GDE::convertBool(resize)); newConf.putValue("vsync", GDE::convertBool(vsync)); newConf.close(); // Escribimos en el log GDE::Log::info("App::createWindow", "Ventana creada"); GDE::Log::info("Modo de Video", GDE::convertInt32(videoMode.width) + "x" + GDE::convertInt32(videoMode.height) + "x" + GDE::convertInt32(videoMode.bitsPerPixel)); GDE::Log::info("Vsync", GDE::convertBool(vsync)); GDE::Log::info("Fullscreen", GDE::convertBool(fullscreen)); }
int main(int argc, char** argv) { std::cout << "Application build time: " << __DATE__ << " " << __TIME__ << std::endl; // Initialising QCoreApplication QCoreApplication app(argc, argv); std::cout << "QCoreApplication initialised" << std::endl; signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); // force the locale setlocale(LC_ALL, "C"); QLocale::setDefault(QLocale::c()); if (argc < 2) { std::cout << "Missing required configuration file. Usage:" << std::endl; std::cout << "hyperiond [config.file]" << std::endl; return 1; } const std::string configFile = argv[1]; std::cout << "Selected configuration file: " << configFile.c_str() << std::endl; const Json::Value config = loadConfig(configFile); Hyperion hyperion(config); std::cout << "Hyperion created and initialised" << std::endl; // create boot sequence if the configuration is present if (config.isMember("bootsequence")) { const Json::Value effectConfig = config["bootsequence"]; // Get the parameters for the bootsequence const std::string effectName = effectConfig["effect"].asString(); const unsigned duration_ms = effectConfig["duration_ms"].asUInt(); const int priority = 0; hyperion.setColor(priority+1, ColorRgb::BLACK, duration_ms, false); if (effectConfig.isMember("args")) { const Json::Value effectConfigArgs = effectConfig["args"]; if (hyperion.setEffect(effectName, effectConfigArgs, priority, duration_ms) == 0) { std::cout << "Boot sequence(" << effectName << ") with user-defined arguments created and started" << std::endl; } else { std::cout << "Failed to start boot sequence: " << effectName << " with user-defined arguments" << std::endl; } } else { if (hyperion.setEffect(effectName, priority, duration_ms) == 0) { std::cout << "Boot sequence(" << effectName << ") created and started" << std::endl; } else { std::cout << "Failed to start boot sequence: " << effectName << std::endl; } } } // create XBMC video checker if the configuration is present XBMCVideoChecker * xbmcVideoChecker = nullptr; if (config.isMember("xbmcVideoChecker")) { const Json::Value & videoCheckerConfig = config["xbmcVideoChecker"]; xbmcVideoChecker = new XBMCVideoChecker( videoCheckerConfig["xbmcAddress"].asString(), videoCheckerConfig["xbmcTcpPort"].asUInt(), videoCheckerConfig["grabVideo"].asBool(), videoCheckerConfig["grabPictures"].asBool(), videoCheckerConfig["grabAudio"].asBool(), videoCheckerConfig["grabMenu"].asBool(), videoCheckerConfig.get("grabScreensaver", true).asBool(), videoCheckerConfig.get("enable3DDetection", true).asBool()); xbmcVideoChecker->start(); std::cout << "XBMC video checker created and started" << std::endl; } #ifdef ENABLE_DISPMANX // Construct and start the frame-grabber if the configuration is present DispmanxWrapper * dispmanx = nullptr; if (config.isMember("framegrabber")) { const Json::Value & frameGrabberConfig = config["framegrabber"]; dispmanx = new DispmanxWrapper( frameGrabberConfig["width"].asUInt(), frameGrabberConfig["height"].asUInt(), frameGrabberConfig["frequency_Hz"].asUInt(), &hyperion); if (xbmcVideoChecker != nullptr) { QObject::connect(xbmcVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), dispmanx, SLOT(setGrabbingMode(GrabbingMode))); QObject::connect(xbmcVideoChecker, SIGNAL(videoMode(VideoMode)), dispmanx, SLOT(setVideoMode(VideoMode))); } dispmanx->start(); std::cout << "Frame grabber created and started" << std::endl; } #else #if !defined(ENABLE_OSX) && !defined(ENABLE_FB) if (config.isMember("framegrabber")) { std::cerr << "The dispmanx framegrabber can not be instantiated, becuse it has been left out from the build" << std::endl; } #endif #endif #ifdef ENABLE_V4L2 // construct and start the v4l2 grabber if the configuration is present V4L2Wrapper * v4l2Grabber = nullptr; if (config.isMember("grabber-v4l2")) { const Json::Value & grabberConfig = config["grabber-v4l2"]; v4l2Grabber = new V4L2Wrapper( grabberConfig.get("device", "/dev/video0").asString(), grabberConfig.get("input", 0).asInt(), parseVideoStandard(grabberConfig.get("standard", "no-change").asString()), parsePixelFormat(grabberConfig.get("pixelFormat", "no-change").asString()), grabberConfig.get("width", -1).asInt(), grabberConfig.get("height", -1).asInt(), grabberConfig.get("frameDecimation", 2).asInt(), grabberConfig.get("sizeDecimation", 8).asInt(), grabberConfig.get("redSignalThreshold", 0.0).asDouble(), grabberConfig.get("greenSignalThreshold", 0.0).asDouble(), grabberConfig.get("blueSignalThreshold", 0.0).asDouble(), &hyperion, grabberConfig.get("priority", 800).asInt()); v4l2Grabber->set3D(parse3DMode(grabberConfig.get("mode", "2D").asString())); v4l2Grabber->setCropping( grabberConfig.get("cropLeft", 0).asInt(), grabberConfig.get("cropRight", 0).asInt(), grabberConfig.get("cropTop", 0).asInt(), grabberConfig.get("cropBottom", 0).asInt()); v4l2Grabber->start(); std::cout << "V4l2 grabber created and started" << std::endl; } #else if (config.isMember("grabber-v4l2")) { std::cerr << "The v4l2 grabber can not be instantiated, becuse it has been left out from the build" << std::endl; } #endif #ifdef ENABLE_FB // Construct and start the framebuffer grabber if the configuration is present FramebufferWrapper * fbGrabber = nullptr; if (config.isMember("framegrabber")) { const Json::Value & grabberConfig = config["framegrabber"]; fbGrabber = new FramebufferWrapper( grabberConfig.get("device", "/dev/fb0").asString(), grabberConfig["width"].asUInt(), grabberConfig["height"].asUInt(), grabberConfig["frequency_Hz"].asUInt(), &hyperion); if (xbmcVideoChecker != nullptr) { QObject::connect(xbmcVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), fbGrabber, SLOT(setGrabbingMode(GrabbingMode))); QObject::connect(xbmcVideoChecker, SIGNAL(videoMode(VideoMode)), fbGrabber, SLOT(setVideoMode(VideoMode))); } fbGrabber->start(); std::cout << "Framebuffer grabber created and started" << std::endl; } #else #if !defined(ENABLE_DISPMANX) && !defined(ENABLE_OSX) if (config.isMember("framegrabber")) { std::cerr << "The framebuffer grabber can not be instantiated, becuse it has been left out from the build" << std::endl; } #endif #endif #ifdef ENABLE_OSX // Construct and start the osx grabber if the configuration is present OsxWrapper * osxGrabber = nullptr; if (config.isMember("framegrabber")) { const Json::Value & grabberConfig = config["framegrabber"]; osxGrabber = new OsxWrapper( grabberConfig.get("display", 0).asUInt(), grabberConfig["width"].asUInt(), grabberConfig["height"].asUInt(), grabberConfig["frequency_Hz"].asUInt(), &hyperion); if (xbmcVideoChecker != nullptr) { QObject::connect(xbmcVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), osxGrabber, SLOT(setGrabbingMode(GrabbingMode))); QObject::connect(xbmcVideoChecker, SIGNAL(videoMode(VideoMode)), osxGrabber, SLOT(setVideoMode(VideoMode))); } osxGrabber->start(); std::cout << "OSX grabber created and started" << std::endl; } #else #if !defined(ENABLE_DISPMANX) && !defined(ENABLE_FB) if (config.isMember("framegrabber")) { std::cerr << "The osx grabber can not be instantiated, becuse it has been left out from the build" << std::endl; } #endif #endif // Create Json server if configuration is present JsonServer * jsonServer = nullptr; if (config.isMember("jsonServer")) { const Json::Value & jsonServerConfig = config["jsonServer"]; jsonServer = new JsonServer(&hyperion, jsonServerConfig["port"].asUInt()); std::cout << "Json server created and started on port " << jsonServer->getPort() << std::endl; } #ifdef ENABLE_PROTOBUF // Create Proto server if configuration is present ProtoServer * protoServer = nullptr; if (config.isMember("protoServer")) { const Json::Value & protoServerConfig = config["protoServer"]; protoServer = new ProtoServer(&hyperion, protoServerConfig["port"].asUInt()); std::cout << "Proto server created and started on port " << protoServer->getPort() << std::endl; } #endif // Create Boblight server if configuration is present BoblightServer * boblightServer = nullptr; if (config.isMember("boblightServer")) { const Json::Value & boblightServerConfig = config["boblightServer"]; boblightServer = new BoblightServer(&hyperion, boblightServerConfig["port"].asUInt()); std::cout << "Boblight server created and started on port " << boblightServer->getPort() << std::endl; } // run the application int rc = app.exec(); std::cout << "Application closed with code " << rc << std::endl; // Delete all component #ifdef ENABLE_DISPMANX delete dispmanx; #endif #ifdef ENABLE_FB delete fbGrabber; #endif #ifdef ENABLE_OSX delete osxGrabber; #endif #ifdef ENABLE_V4L2 delete v4l2Grabber; #endif delete xbmcVideoChecker; delete jsonServer; #ifdef ENABLE_PROTOBUF delete protoServer; #endif delete boblightServer; // leave application return rc; }
sfBool sfVideoMode_isValid(sfVideoMode mode) { sf::VideoMode videoMode(mode.width, mode.height, mode.bitsPerPixel); return videoMode.isValid() ? sfTrue : sfFalse; }
int main(int argc, char** argv) { std::cout << "Application build time: " << __DATE__ << " " << __TIME__ << std::endl; // Initialising QCoreApplication QCoreApplication app(argc, argv); std::cout << "QCoreApplication initialised" << std::endl; signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); if (argc < 2) { std::cout << "Missing required configuration file. Usage:" << std::endl; std::cout << "hyperiond [config.file]" << std::endl; return 1; } const std::string configFile = argv[1]; std::cout << "Selected configuration file: " << configFile.c_str() << std::endl; const Json::Value config = loadConfig(configFile); Hyperion hyperion(config); std::cout << "Hyperion created and initialised" << std::endl; // create boot sequence if the configuration is present if (config.isMember("bootsequence")) { const Json::Value effectConfig = config["bootsequence"]; // Get the parameters for the bootsequence const std::string effectName = effectConfig["effect"].asString(); const unsigned duration_ms = effectConfig["duration_ms"].asUInt(); const int priority = 0; if (hyperion.setEffect(effectName, priority, duration_ms) == 0) { std::cout << "Boot sequence(" << effectName << ") created and started" << std::endl; } else { std::cout << "Failed to start boot sequence: " << effectName << std::endl; } } // create XBMC video checker if the configuration is present XBMCVideoChecker * xbmcVideoChecker = nullptr; if (config.isMember("xbmcVideoChecker")) { const Json::Value & videoCheckerConfig = config["xbmcVideoChecker"]; xbmcVideoChecker = new XBMCVideoChecker( videoCheckerConfig["xbmcAddress"].asString(), videoCheckerConfig["xbmcTcpPort"].asUInt(), videoCheckerConfig["grabVideo"].asBool(), videoCheckerConfig["grabPictures"].asBool(), videoCheckerConfig["grabAudio"].asBool(), videoCheckerConfig["grabMenu"].asBool(), videoCheckerConfig.get("grabScreensaver", true).asBool(), videoCheckerConfig.get("enable3DDetection", true).asBool()); xbmcVideoChecker->start(); std::cout << "XBMC video checker created and started" << std::endl; } #ifdef ENABLE_DISPMANX // Construct and start the frame-grabber if the configuration is present DispmanxWrapper * dispmanx = nullptr; if (config.isMember("framegrabber")) { const Json::Value & frameGrabberConfig = config["framegrabber"]; dispmanx = new DispmanxWrapper( frameGrabberConfig["width"].asUInt(), frameGrabberConfig["height"].asUInt(), frameGrabberConfig["frequency_Hz"].asUInt(), &hyperion); if (xbmcVideoChecker != nullptr) { QObject::connect(xbmcVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), dispmanx, SLOT(setGrabbingMode(GrabbingMode))); QObject::connect(xbmcVideoChecker, SIGNAL(videoMode(VideoMode)), dispmanx, SLOT(setVideoMode(VideoMode))); } dispmanx->start(); std::cout << "Frame grabber created and started" << std::endl; } #else if (config.isMember("framegrabber")) { std::cerr << "The dispmanx framegrabber can not be instantiated, becuse it has been left out from the build" << std::endl; } #endif // Create Json server if configuration is present JsonServer * jsonServer = nullptr; if (config.isMember("jsonServer")) { const Json::Value & jsonServerConfig = config["jsonServer"]; jsonServer = new JsonServer(&hyperion, jsonServerConfig["port"].asUInt()); std::cout << "Json server created and started on port " << jsonServer->getPort() << std::endl; } // Create Proto server if configuration is present ProtoServer * protoServer = nullptr; if (config.isMember("protoServer")) { const Json::Value & protoServerConfig = config["protoServer"]; protoServer = new ProtoServer(&hyperion, protoServerConfig["port"].asUInt()); std::cout << "Proto server created and started on port " << protoServer->getPort() << std::endl; } // Create Boblight server if configuration is present BoblightServer * boblightServer = nullptr; if (config.isMember("boblightServer")) { const Json::Value & boblightServerConfig = config["boblightServer"]; boblightServer = new BoblightServer(&hyperion, boblightServerConfig["port"].asUInt()); std::cout << "Boblight server created and started on port " << boblightServer->getPort() << std::endl; } // run the application int rc = app.exec(); std::cout << "Application closed with code " << rc << std::endl; // Delete all component #ifdef ENABLE_DISPMANX delete dispmanx; #endif delete xbmcVideoChecker; delete jsonServer; delete protoServer; delete boblightServer; // leave application return rc; }
bool Client::applyDisplaySettings() { //The context settings apply to the opengl context that we create. sf::ContextSettings contextSettings; contextSettings.depthBits = 24; contextSettings.stencilBits = 8; contextSettings.antialiasingLevel = Config::getAALevel(); contextSettings.majorVersion = 4; contextSettings.minorVersion = 4; // We want to create the window after the settings were loaded in case // anything client setting is different that the defaults. sf::VideoMode videoMode(Config::getWidth(), Config::getHeight(), 32); // Don't warn in fullscreen since anything works really. if (!Config::getFullscreen()) { //Just warn the user if they have a non optimal video mode selected. if (!videoMode.isValid()) { Log::error(std::string("non optimal video mode selected in the config file!")); //return false; } } //Here we check to go full screen //We just get the first full screen mode. //TODO (Tyler): Figure out a way to properly handle this stuff. if (Config::getFullscreen()) { m_window.create(sf::VideoMode::getFullscreenModes()[0], WINDOW_TITLE, sf::Style::Fullscreen, contextSettings); } else { m_window.create(videoMode, WINDOW_TITLE, sf::Style::Default, contextSettings); } m_window.setVerticalSyncEnabled(Config::getVSync()); //Make sure we don't set the framerate limit to zero. if (Config::getFpsLimit() > 0) { m_window.setFramerateLimit(Config::getFpsLimit()); } //Here we are just getting the settings after we have created the window. //And simply writing some debug about the current context settings. sf::ContextSettings windowSettings = m_window.getSettings(); std::stringstream sb; sb << "depthBits: " << windowSettings.depthBits << ", "; sb << "stencilBits: " << windowSettings.stencilBits << ", "; sb << "antialiasingLevel: " << windowSettings.antialiasingLevel << ", "; sb << "majorVersion: " << windowSettings.majorVersion << ", "; sb << "minorVersion: " << windowSettings.minorVersion << ", "; //The renderer is the device that is actually getting the data from opengl. sb << "renderer: " << std::string((char*)glGetString(GL_RENDERER)); Log::debug(sb.str()); //Return true since the display settings were applied properly. return true; }
int main() { std::mt19937 generator(time(nullptr)); sys::ComputeSystem cs; cs.create(sys::ComputeSystem::_gpu); sys::ComputeProgram prog; prog.loadFromFile("resources/neoKernels.cl", cs); std::vector<neo::AgentSPG::LayerDesc> layerDescs(3); layerDescs[0]._size = { 32, 32 }; layerDescs[0]._alpha = { 0.1f, 0.001f }; layerDescs[0]._predictiveRadius = 12; layerDescs[0]._feedBackRadius = 12; layerDescs[1]._size = { 24, 24 }; layerDescs[2]._size = { 16, 16 }; neo::AgentSPG agent; int inWidth = 32; int inHeight = 32; int aWidth = 3; int aHeight = 3; int frameSkip = 3; agent.createRandom(cs, prog, { inWidth, inHeight }, { aWidth, aHeight }, 12, layerDescs, { -0.05f, 0.05f }, generator); cl::Image2D inputImage = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), inWidth, inHeight); cl::Image2D actionImage = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), aWidth, aHeight); sf::VideoMode videoMode(1280, 720); sf::RenderWindow renderWindow; renderWindow.create(videoMode, "Reinforcement Learning", sf::Style::Default); renderWindow.setVerticalSyncEnabled(true); renderWindow.setFramerateLimit(60); // --------------------------------- Game Init ----------------------------------- const float slimeRadius = 94.5f; const float ballRadius = 23.5f; const float wallRadius = 22.5f; const float fieldRadius = 640.0f; const float gravity = 900.0f; const float slimeBounce = 100.0f; const float wallBounceDecay = 0.8f; const float slimeJump = 500.0f; const float maxSlimeSpeed = 1000.0f; const float slimeMoveAccel = 5000.0f; const float slimeMoveDeccel = 8.0f; std::uniform_real_distribution<float> dist01(0.0f, 1.0f); sf::Vector2f fieldCenter = sf::Vector2f(renderWindow.getSize().x * 0.5f, renderWindow.getSize().y * 0.5f + 254.0f); sf::Vector2f wallCenter = fieldCenter + sf::Vector2f(0.0f, -182.0f); PhyObj blue; PhyObj red; PhyObj ball; blue._position = fieldCenter + sf::Vector2f(-200.0f, 0.0f); blue._velocity = sf::Vector2f(0.0f, 0.0f); red._position = fieldCenter + sf::Vector2f(200.0f, 0.0f); red._velocity = sf::Vector2f(0.0f, 0.0f); ball._position = fieldCenter + sf::Vector2f(2.0f, -300.0f); ball._velocity = sf::Vector2f((dist01(generator)) * 600.0f, -(dist01(generator)) * 500.0f); sf::Texture backgroundTexture; backgroundTexture.loadFromFile("resources/slimevolleyball/background.png"); sf::Texture blueSlimeTexture; blueSlimeTexture.loadFromFile("resources/slimevolleyball/slimeBodyBlue.png"); sf::Texture redSlimeTexture; redSlimeTexture.loadFromFile("resources/slimevolleyball/slimeBodyRed.png"); sf::Texture ballTexture; ballTexture.loadFromFile("resources/slimevolleyball/ball.png"); sf::Texture eyeTexture; eyeTexture.loadFromFile("resources/slimevolleyball/slimeEye.png"); eyeTexture.setSmooth(true); sf::Texture arrowTexture; arrowTexture.loadFromFile("resources/slimevolleyball/arrow.png"); sf::Font scoreFont; scoreFont.loadFromFile("resources/slimevolleyball/scoreFont.ttf"); int scoreRed = 0; int scoreBlue = 0; int prevScoreRed = 0; int prevScoreBlue = 0; float prevBallX = fieldCenter.x; sf::RenderTexture blueRT; blueRT.create(inWidth, inHeight); // ------------------------------- Simulation Loop ------------------------------- bool quit = false; float dt = 0.017f; int skipFrameCounter = 0; float blueReward = 0.0f; float redReward = 0.0f; std::vector<float> actionTemp(aWidth * aHeight, 0.5f); std::vector<float> actionTemp2(aWidth * aHeight * 2, 0.5f); do { sf::Event event; while (renderWindow.pollEvent(event)) { switch (event.type) { case sf::Event::Closed: quit = true; break; } } if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) quit = true; // ---------------------------------- Physics ---------------------------------- bool blueBounced = false; bool redBounced = false; // Ball { ball._velocity.y += gravity * dt; ball._position += ball._velocity * dt; // To floor (game restart) if (ball._position.y + ballRadius > fieldCenter.y) { if (ball._position.x < fieldCenter.x) scoreRed++; else scoreBlue++; blue._position = fieldCenter + sf::Vector2f(-200.0f, 0.0f); blue._velocity = sf::Vector2f(0.0f, 0.0f); red._position = fieldCenter + sf::Vector2f(200.0f, 0.0f); red._velocity = sf::Vector2f(0.0f, 0.0f); ball._position = fieldCenter + sf::Vector2f(2.0f, -300.0f); ball._velocity = sf::Vector2f(((dist01(generator))) * -600.0f, -(dist01(generator)) * 500.0f); } // To wall if (((ball._position.x + ballRadius) > (wallCenter.x - wallRadius) && ball._position.x < wallCenter.x) || ((ball._position.x - ballRadius) < (wallCenter.x + wallRadius) && ball._position.x > wallCenter.x)) { // If above rounded part if (ball._position.y < wallCenter.y) { sf::Vector2f delta = ball._position - wallCenter; float dist = std::sqrt(delta.x * delta.x + delta.y * delta.y); if (dist < wallRadius + ballRadius) { sf::Vector2f normal = delta / dist; // Reflect velocity sf::Vector2f reflectedVelocity = ball._velocity - 2.0f * (ball._velocity.x * normal.x + ball._velocity.y * normal.y) * normal; ball._velocity = reflectedVelocity * wallBounceDecay; ball._position = wallCenter + normal * (wallRadius + ballRadius); } } else { // If on left side if (ball._position.x < wallCenter.x) { ball._velocity.x = wallBounceDecay * -ball._velocity.x; ball._position.x = wallCenter.x - wallRadius - ballRadius; } else { ball._velocity.x = wallBounceDecay * -ball._velocity.x; ball._position.x = wallCenter.x + wallRadius + ballRadius; } } } // To blue slime { sf::Vector2f delta = ball._position - blue._position; float dist = std::sqrt(delta.x * delta.x + delta.y * delta.y); if (dist < slimeRadius + ballRadius) { sf::Vector2f normal = delta / dist; // Reflect velocity sf::Vector2f reflectedVelocity = ball._velocity - 2.0f * (ball._velocity.x * normal.x + ball._velocity.y * normal.y) * normal; float magnitude = std::sqrt(reflectedVelocity.x * reflectedVelocity.x + reflectedVelocity.y * reflectedVelocity.y); sf::Vector2f normalizedReflected = reflectedVelocity / magnitude; ball._velocity = blue._velocity + (magnitude > slimeBounce ? reflectedVelocity : normalizedReflected * slimeBounce); ball._position = blue._position + normal * (wallRadius + slimeRadius); blueBounced = true; } } // To red slime { sf::Vector2f delta = ball._position - red._position; float dist = std::sqrt(delta.x * delta.x + delta.y * delta.y); if (dist < slimeRadius + ballRadius) { sf::Vector2f normal = delta / dist; // Reflect velocity sf::Vector2f reflectedVelocity = ball._velocity - 2.0f * (ball._velocity.x * normal.x + ball._velocity.y * normal.y) * normal; float magnitude = std::sqrt(reflectedVelocity.x * reflectedVelocity.x + reflectedVelocity.y * reflectedVelocity.y); sf::Vector2f normalizedReflected = reflectedVelocity / magnitude; ball._velocity = red._velocity + (magnitude > slimeBounce ? reflectedVelocity : normalizedReflected * slimeBounce); ball._position = red._position + normal * (wallRadius + slimeRadius); redBounced = true; } } // Out of field, left and right { if (ball._position.x - ballRadius < fieldCenter.x - fieldRadius) { ball._velocity.x = wallBounceDecay * -ball._velocity.x; ball._position.x = fieldCenter.x - fieldRadius + ballRadius; } else if (ball._position.x + ballRadius > fieldCenter.x + fieldRadius) { ball._velocity.x = wallBounceDecay * -ball._velocity.x; ball._position.x = fieldCenter.x + fieldRadius - ballRadius; } } } // Blue slime { blue._velocity.y += gravity * dt; blue._velocity.x += -slimeMoveDeccel * blue._velocity.x * dt; blue._position += blue._velocity * dt; bool moveLeft; bool moveRight; bool jump; sf::Image img = blueRT.getTexture().copyToImage(); std::vector<float> greyData(img.getSize().x * img.getSize().y); for (int x = 0; x < img.getSize().x; x++) for (int y = 0; y < img.getSize().y; y++) { sf::Color c = img.getPixel(x, y); greyData[x + y * img.getSize().x] = 0.333f * (c.r / 255.0f + c.g / 255.0f + c.b / 255.0f); } if (skipFrameCounter == 0) { cs.getQueue().enqueueWriteImage(inputImage, CL_TRUE, { 0, 0, 0 }, { static_cast<cl::size_type>(inWidth), static_cast<cl::size_type>(inHeight), 1 }, 0, 0, greyData.data()); cs.getQueue().enqueueWriteImage(actionImage, CL_TRUE, { 0, 0, 0 }, { static_cast<cl::size_type>(inWidth), static_cast<cl::size_type>(inHeight), 1 }, 0, 0, actionTemp.data()); agent.simStep(cs, blueReward * 0.01f, inputImage, actionImage, generator); cs.getQueue().enqueueReadImage(agent.getAction(), CL_TRUE, { 0, 0, 0 }, { static_cast<cl::size_type>(aWidth), static_cast<cl::size_type>(aHeight), 1 }, 0, 0, actionTemp2.data()); for (int i = 0; i < actionTemp.size(); i++) { if (dist01(generator) < 0.1f) actionTemp[i] = dist01(generator); else actionTemp[i] = actionTemp2[i * 2 + 0]; } actionTemp[2] = actionTemp[0] * 3.0f + 1.0f; actionTemp[3] = actionTemp[0] * -2.0f + 0.4f; actionTemp[4] = actionTemp[0] * 2.0f - 0.4f; actionTemp[5] = actionTemp[0] * -2.0f - 0.4f; actionTemp[6] = actionTemp[1] * -1.5f + 0.2f; actionTemp[7] = actionTemp[1] * 2.1f - 0.4f; actionTemp[8] = actionTemp[1] * -2.0f + 0.4f; cs.getQueue().finish(); } moveLeft = actionTemp[0] > 0.75f; moveRight = actionTemp[0] < 0.25f; jump = actionTemp[1] > 0.75f; std::cout << blueReward << " " << actionTemp[0 * 2 + 0] << " " << actionTemp[1 * 2 + 0] << std::endl; if (moveLeft) { blue._velocity.x += -slimeMoveAccel * dt; if (blue._velocity.x < -maxSlimeSpeed) blue._velocity.x = -maxSlimeSpeed; } else if (moveRight) { blue._velocity.x += slimeMoveAccel * dt; if (blue._velocity.x > maxSlimeSpeed) blue._velocity.x = maxSlimeSpeed; } if (blue._position.y > fieldCenter.y) { blue._velocity.y = 0.0f; blue._position.y = fieldCenter.y; if (jump) blue._velocity.y -= slimeJump; } if (blue._position.x - slimeRadius < fieldCenter.x - fieldRadius) { blue._velocity.x = 0.0f; blue._position.x = fieldCenter.x - fieldRadius + slimeRadius; } if (blue._position.x + slimeRadius > wallCenter.x - wallRadius) { blue._velocity.x = 0.0f; blue._position.x = wallCenter.x - wallRadius - slimeRadius; } } // Red slime { red._velocity.y += gravity * dt; red._velocity.x += -slimeMoveDeccel * red._velocity.x * dt; red._position += red._velocity * dt; bool moveLeft; bool moveRight; bool jump; moveLeft = sf::Keyboard::isKeyPressed(sf::Keyboard::Left); moveRight = sf::Keyboard::isKeyPressed(sf::Keyboard::Right); jump = sf::Keyboard::isKeyPressed(sf::Keyboard::Up); if (moveLeft) { red._velocity.x += -slimeMoveAccel * dt; if (red._velocity.x < -maxSlimeSpeed) red._velocity.x = -maxSlimeSpeed; } else if (moveRight) { red._velocity.x += slimeMoveAccel * dt; if (red._velocity.x > maxSlimeSpeed) red._velocity.x = maxSlimeSpeed; } if (red._position.y > fieldCenter.y) { red._velocity.y = 0.0f; red._position.y = fieldCenter.y; if (jump) red._velocity.y -= slimeJump; } if (red._position.x + slimeRadius > fieldCenter.x + fieldRadius) { red._velocity.x = 0.0f; red._position.x = fieldCenter.x + fieldRadius - slimeRadius; } if (red._position.x - slimeRadius < wallCenter.x + wallRadius) { red._velocity.x = 0.0f; red._position.x = wallCenter.x + wallRadius + slimeRadius; } } blueReward = scoreBlue - prevScoreBlue - (scoreRed - prevScoreRed);// -0.00005f * std::abs(ball._position.x - blue._position.x) + (blueBounced ? 0.2f : 0.0f); redReward = scoreRed - prevScoreRed - (scoreBlue - prevScoreBlue);// -0.00005f * std::abs(ball._position.x - red._position.x) + (redBounced ? 0.2f : 0.0f); prevScoreRed = scoreRed; prevScoreBlue = scoreBlue; prevBallX = ball._position.x; // --------------------------------- Rendering --------------------------------- if (!sf::Keyboard::isKeyPressed(sf::Keyboard::T)) { { renderWindow.clear(); { sf::Sprite s; s.setTexture(backgroundTexture); s.setOrigin(backgroundTexture.getSize().x * 0.5f, backgroundTexture.getSize().y * 0.5f); s.setPosition(renderWindow.getSize().x * 0.5f, renderWindow.getSize().y * 0.5f); renderWindow.draw(s); } { sf::Sprite s; s.setTexture(blueSlimeTexture); s.setOrigin(blueSlimeTexture.getSize().x * 0.5f, blueSlimeTexture.getSize().y); s.setPosition(blue._position); renderWindow.draw(s); } { sf::Sprite s; s.setTexture(eyeTexture); s.setOrigin(eyeTexture.getSize().x * 0.5f, eyeTexture.getSize().y * 0.5f); s.setPosition(blue._position + sf::Vector2f(50.0f, -28.0f)); sf::Vector2f delta = ball._position - s.getPosition(); float angle = std::atan2(delta.y, delta.x); s.setRotation(angle * 180.0f / 3.141596f); renderWindow.draw(s); } { sf::Sprite s; s.setTexture(redSlimeTexture); s.setOrigin(redSlimeTexture.getSize().x * 0.5f, redSlimeTexture.getSize().y); s.setPosition(red._position); renderWindow.draw(s); } { sf::Sprite s; s.setTexture(eyeTexture); s.setOrigin(eyeTexture.getSize().x * 0.5f, eyeTexture.getSize().y * 0.5f); s.setPosition(red._position + sf::Vector2f(-50.0f, -28.0f)); sf::Vector2f delta = ball._position - s.getPosition(); float angle = std::atan2(delta.y, delta.x); s.setRotation(angle * 180.0f / 3.141596f); renderWindow.draw(s); } { sf::Sprite s; s.setTexture(ballTexture); s.setOrigin(ballTexture.getSize().x * 0.5f, ballTexture.getSize().y * 0.5f); s.setPosition(ball._position); renderWindow.draw(s); } if (ball._position.y + ballRadius < 0.0f) { sf::Sprite s; s.setTexture(arrowTexture); s.setOrigin(arrowTexture.getSize().x * 0.5f, 0.0f); s.setPosition(ball._position.x, 0.0f); renderWindow.draw(s); } { sf::Text scoreText; scoreText.setFont(scoreFont); scoreText.setString(std::to_string(scoreBlue)); scoreText.setCharacterSize(100); float width = scoreText.getLocalBounds().width; scoreText.setPosition(fieldCenter.x - width * 0.5f - 100.0f, 10.0f); scoreText.setColor(sf::Color(100, 133, 255)); renderWindow.draw(scoreText); } { sf::Text scoreText; scoreText.setFont(scoreFont); scoreText.setString(std::to_string(scoreRed)); scoreText.setCharacterSize(100); float width = scoreText.getLocalBounds().width; scoreText.setPosition(fieldCenter.x - width * 0.5f + 100.0f, 10.0f); scoreText.setColor(sf::Color(255, 100, 100)); renderWindow.draw(scoreText); } { sf::Sprite visionSprite; visionSprite.setTexture(blueRT.getTexture()); visionSprite.scale(4.0f, 4.0f); renderWindow.draw(visionSprite); } } renderWindow.display(); } blueRT.setView(renderWindow.getView()); { blueRT.clear(); { sf::Sprite s; s.setTexture(backgroundTexture); s.setOrigin(backgroundTexture.getSize().x * 0.5f, backgroundTexture.getSize().y * 0.5f); s.setPosition(renderWindow.getSize().x * 0.5f, renderWindow.getSize().y * 0.5f); blueRT.draw(s); } { sf::Sprite s; s.setTexture(blueSlimeTexture); s.setOrigin(blueSlimeTexture.getSize().x * 0.5f, blueSlimeTexture.getSize().y); s.setPosition(blue._position); blueRT.draw(s); } { sf::Sprite s; s.setTexture(eyeTexture); s.setOrigin(eyeTexture.getSize().x * 0.5f, eyeTexture.getSize().y * 0.5f); s.setPosition(blue._position + sf::Vector2f(50.0f, -28.0f)); sf::Vector2f delta = ball._position - s.getPosition(); float angle = std::atan2(delta.y, delta.x); s.setRotation(angle * 180.0f / 3.141596f); blueRT.draw(s); } { sf::Sprite s; s.setTexture(redSlimeTexture); s.setOrigin(redSlimeTexture.getSize().x * 0.5f, redSlimeTexture.getSize().y); s.setPosition(red._position); blueRT.draw(s); } { sf::Sprite s; s.setTexture(eyeTexture); s.setOrigin(eyeTexture.getSize().x * 0.5f, eyeTexture.getSize().y * 0.5f); s.setPosition(red._position + sf::Vector2f(-50.0f, -28.0f)); sf::Vector2f delta = ball._position - s.getPosition(); float angle = std::atan2(delta.y, delta.x); s.setRotation(angle * 180.0f / 3.141596f); blueRT.draw(s); } { sf::Sprite s; s.setTexture(ballTexture); s.setOrigin(ballTexture.getSize().x * 0.5f, ballTexture.getSize().y * 0.5f); s.setPosition(ball._position); blueRT.draw(s); } if (ball._position.y + ballRadius < 0.0f) { sf::Sprite s; s.setTexture(arrowTexture); s.setOrigin(arrowTexture.getSize().x * 0.5f, 0.0f); s.setPosition(ball._position.x, 0.0f); blueRT.draw(s); } { sf::Text scoreText; scoreText.setFont(scoreFont); scoreText.setString(std::to_string(scoreBlue)); scoreText.setCharacterSize(100); float width = scoreText.getLocalBounds().width; scoreText.setPosition(fieldCenter.x - width * 0.5f - 100.0f, 10.0f); scoreText.setColor(sf::Color(100, 133, 255)); blueRT.draw(scoreText); } { sf::Text scoreText; scoreText.setFont(scoreFont); scoreText.setString(std::to_string(scoreRed)); scoreText.setCharacterSize(100); float width = scoreText.getLocalBounds().width; scoreText.setPosition(fieldCenter.x - width * 0.5f + 100.0f, 10.0f); scoreText.setColor(sf::Color(255, 100, 100)); blueRT.draw(scoreText); } blueRT.display(); } skipFrameCounter = (skipFrameCounter + 1) % frameSkip; } while (!quit); return 0; }