int main(int argc, char ** argv) { //Demo of splitting code into multiple .cpp and .h files std::cout << "add 5 and 7: " << add(5, 7) << std::endl; bool quit = false; bool isBallLaunched = false; bool isBallHit = false; //bool isBallControllable = true; int counter = 0; int r, g, b; r = g = b = 0; const int PADDLE_VELOCITY = 2; int paddleVelocity = PADDLE_VELOCITY; const int BALL_VELOCITY_LIMIT = 5; //maximum ball velocity //int ballVelocity = 0; //int xBallVelocity = 1; //int yBallVelocity = 1; //int ballInitialXDirection = 0; //int ballInitialYDirection = 0; //SDL_Renderer* renderer = nullptr; SDL_Rect paddle = {}; SDL_Rect ball = {}; SDL_Rect screenRect = {}; screenRect.x = screenRect.y = 0; struct xy { int x, y; }; //const xy BALL_VELOCITY = {1, 1}; xy ballVelocity = { 1, 1 }; const xy BALL_ACCELERATION = { 5, 5 }; //xy ballAcceleration = {}; const int PADDLE_ACCELERATION = 5; int paddleAcceleration = PADDLE_ACCELERATION; //const xy PADDLE_ACCELERATION = {1,1}; xy ballDirection = { 1, 1 }; enum direction { STATIONARY, LEFT, RIGHT }; direction currentPaddleDirection = STATIONARY; direction previousPaddleDirection = STATIONARY; //paddle.x = paddle.y = 600; //get and use screen dimensions. start paddle in middle of screen. paddle.x = 600; paddle.y = 400; paddle.w = 100; paddle.h = 20; ball.h = ball.w = 10; ball.x = paddle.x + paddle.w / 2 - ball.w / 2; //centralise the ball on top of the paddle ball.y = paddle.y - ball.h; //centralise the ball on top of the paddle int buttonCount = 0; Mix_Chunk * ballBounceSound = nullptr; SDL_Init(SDL_INIT_EVERYTHING); SDL_Event event; SDL_Window * screen = SDL_CreateWindow("My First Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_MAXIMIZED | SDL_WINDOW_RESIZABLE); SDL_Renderer * renderer = SDL_CreateRenderer(screen, -1, 0); SDL_GetRendererOutputSize(renderer, &screenRect.w, &screenRect.h); SDL_SetRenderDrawColor(renderer, r, g, b, 255); SDL_RenderClear(renderer); IMG_Init(IMG_INIT_PNG); SDL_Surface* fighterPlane = IMG_Load("images/Plane1.png"); SDL_Texture * fighterPlaneTexture = SDL_CreateTextureFromSurface(renderer, fighterPlane); SDL_RenderCopy(renderer, fighterPlaneTexture, NULL, NULL); SDL_RenderPresent(renderer); if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0) { std::cout << "SDL_mixer could not initialize! SDL_mixer Error: " << Mix_GetError() << std::endl; } ballBounceSound = Mix_LoadWAV("sounds/ball_bounce.wav"); while (!quit) { //SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); if (buttonCount % 3 == 0) { r = 255; g = 0; b = 0; } else if (buttonCount % 3 == 1) { r = 0; g = 255; b = 0; } else if (buttonCount % 3 == 2) { r = 0; g = 0; b = 255; } SDL_SetRenderDrawColor(renderer, r, g, b, 255); SDL_RenderClear(renderer); SDL_PollEvent(&event); switch (event.type) { case SDL_KEYDOWN: switch (event.key.keysym.sym) { case SDLK_UP: /* paddle.y -= paddleVelocity; if(!ballLaunched) { ball.y -= paddleVelocity; //ballVelocity.y = -yBallVelocity; } //SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); //++buttonCount; */ break; case SDLK_DOWN: /* paddle.y += paddleVelocity; if(!ballLaunched) { ball.y += paddleVelocity; ballVelocity.y = yBallVelocity; } //SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255); //++buttonCount; */ break; case SDLK_LEFT: currentPaddleDirection = LEFT; if (currentPaddleDirection != previousPaddleDirection) paddleVelocity = 0; //stop paddle movement when its direction is changed, so that it moves off gradually in the new direction //if(paddle.x <= screenRect.x && paddle.x >= screenRect.x - 1) //{ // if(currentPaddleDirection == LEFT) // { // paddleVelocity = 0; // paddleAcceleration = PADDLE_ACCELERATION * 0; // } //} //else if(currentPaddleDirection) //{ paddleVelocity += paddleAcceleration; paddle.x -= paddleVelocity; //} if (!isBallLaunched) { ball.x -= paddleVelocity; // set the ball's direction for launch ballDirection.x = -1; //ball needs to move left ballDirection.y = -1; //ball needs to move up //ballVelocity.x = BALL_VELOCITY.x; //ballVelocity.y = BALL_VELOCITY.y; //ballVelocity.x = BALL_VELOCITY.x * -1; //ballVelocity.y = BALL_VELOCITY.y * -1; //ballAcceleration.x = BALL_ACCELERATION.x; //ballAcceleration.y = BALL_ACCELERATION.y; } //else if(isBallHit) ballDirection.x = -1; //when ball hits paddle while paddle is moving left, ball moves left previousPaddleDirection = LEFT; //if(ballLaunched) //{ // ball.x -= ballVelocity; // ball.y -= ballVelocity; //} //else ball.x -= paddleVelocity; //SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255); //++buttonCount; break; case SDLK_RIGHT: currentPaddleDirection = RIGHT; if (currentPaddleDirection != previousPaddleDirection) paddleVelocity = 0; //stop paddle movement when its direction is changed, so that it moves off gradually in the new direction paddleVelocity += paddleAcceleration; paddle.x += paddleVelocity; if (!isBallLaunched) { ball.x += paddleVelocity; // set the ball's direction for launch ballDirection.x = 1; //ball needs to move right ballDirection.y = -1; //ball needs to move up //ballVelocity.x = BALL_VELOCITY.x; //ballVelocity.y = BALL_VELOCITY.y; //ballVelocity.y = BALL_VELOCITY.y * -1; //ballAcceleration.x = BALL_ACCELERATION.x; //ballAcceleration.y = BALL_ACCELERATION.y; } //else if(isBallHit) ballDirection.x = 1; //when ball hits paddle while paddle is moving right, move the ball right previousPaddleDirection = RIGHT; //if(ballLaunched) //{ // ball.x += ballVelocity; // ball.y += ballVelocity; //} //else // ball.x += paddleVelocity; //SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); //++buttonCount; break; case SDLK_SPACE: if (currentPaddleDirection != STATIONARY) //don't launch the ball when paddle hasn't been moved isBallLaunched = true; //std::cout << "spacebar pressed" << std::endl; break; } break; case SDL_MOUSEBUTTONDOWN: switch (event.button.button) { case SDL_BUTTON_LEFT: SDL_SetRenderDrawColor(renderer, r, g, b, 255); ++buttonCount; //std::cout << buttonCount << ": " << r << "," << g << "," << b << std::endl; break; } break; case SDL_QUIT: quit = true; //std::cout << "quit" << std::endl; break; } //collision detection for paddle against sides of screen //don't allow the paddle to move further if it hits the sides of the screen //if(paddle.x <= screenRect.x || (paddle.x + paddle.w >= screenRect.x + screenRect.w)) //{ // if(currentPaddleDirection == previousPaddleDirection) // { // paddleVelocity = 0; // paddleAcceleration = PADDLE_ACCELERATION * 0; // } // else paddleAcceleration = PADDLE_ACCELERATION; //} if (isBallLaunched) { isBallHit = false; //calculate acceleration and speed, with speed limit //ballVelocity.x += BALL_ACCELERATION.x; //ballVelocity.y += BALL_ACCELERATION.y; if (ballVelocity.x >= BALL_VELOCITY_LIMIT) ballVelocity.x += BALL_ACCELERATION.x * 0; else ballVelocity.x += BALL_ACCELERATION.x; if (ballVelocity.y >= BALL_VELOCITY_LIMIT) ballVelocity.y += BALL_ACCELERATION.y * 0; else ballVelocity.y += BALL_ACCELERATION.y; ball.x += ballVelocity.x * ballDirection.x; ball.y += ballVelocity.y * ballDirection.y; //std::cout << "ballVelocity x,y: " << ballVelocity.x << "," << //ballVelocity.y << std::endl; //std::cout << "ball x,y: " << ball.x << "," << //ball.y << std::endl; //collision with screen top or bottom if (ball.y <= screenRect.y || (ball.y + ball.h) >= screenRect.h) //std::cout << "collided with screen top or bottom" << std::endl; //ballVelocity.y = -ballVelocity.y; { Mix_PlayChannel(-1, ballBounceSound, 0); ballDirection.y = ballDirection.y * -1; } //collision with screen left or right if (ball.x <= screenRect.x || (ball.x + ball.w) >= screenRect.w) //std::cout << "collided with screen left or right" << std::endl; //ballVelocity.x = -ballVelocity.x; { Mix_PlayChannel(-1, ballBounceSound, 0); ballDirection.x = ballDirection.x * -1; } //collision detection between ball and paddle //check if ball's bottom is within paddle's top and 1 pixel more than paddle's top //and check if ball's x position is within the range of paddle's x position and paddle's width if ((ball.y + ball.h >= paddle.y && ball.y + ball.h <= paddle.y + paddle.h) && ((ball.x >= paddle.x) && ball.x + ball.w <= paddle.x + paddle.w)) { isBallHit = true; Mix_PlayChannel(-1, ballBounceSound, 0); ballDirection.y = ballDirection.y * -1; //paddle direction controls direction the ball will move in if (currentPaddleDirection == RIGHT) ballDirection.x = 1; else ballDirection.x = -1; } } SDL_RenderClear(renderer); SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_RenderFillRect(renderer, &paddle); SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); SDL_RenderFillRect(renderer, &ball); SDL_RenderPresent(renderer); //std::cout << counter << std::endl; counter++; SDL_Delay(50); }//game loop ends //SDL_Delay(3000); // game code eventually goes here SDL_Quit(); return 0; }
void SFAsset::MoveVertical(float speed) { // For this to stop instances going off-screen // need to get height and width of screen int w, h; SDL_GetRendererOutputSize(sf_window->getRenderer(), &w, &h); // Handle movement for type player if(SFASSET_PLAYER == type) { Vector2 c = *(bbox->centre) + Vector2(0.0f, speed); if(!(c.getY() < 64.0f) && !(c.getY()-18.0f > h)) { bbox->centre.reset(); bbox->centre = make_shared<Vector2>(c); } } // Handle movement for type projectile if(SFASSET_PROJECTILE == type){ Vector2 c = *(bbox->centre) + Vector2(0.0f, speed); if(!(c.getY() > h + 32.0f)) { bbox->centre.reset(); bbox->centre = make_shared<Vector2>(c); } else { this->SetNotAlive(); } } // Handle movement for type powerup if(SFASSET_POWERUP == type){ Vector2 c = *(bbox->centre) + Vector2(0.0f, speed); if(!(c.getY() > h + 32.0f)) { bbox->centre.reset(); bbox->centre = make_shared<Vector2>(c); } else { this->SetNotAlive(); } } // Handle movement for type projectile if(SFASSET_EPROJECTILE == type){ Vector2 c = *(bbox->centre) + Vector2(0.0f, speed); if(!(c.getY() > h + 32.0f)) { bbox->centre.reset(); bbox->centre = make_shared<Vector2>(c); } else { this->SetNotAlive(); } } // Handle movement for type coin if(SFASSET_COIN == type) { Vector2 c = *(bbox->centre) + Vector2(0.0f, speed); if(!(c.getY() < 0.0f)) { bbox->centre.reset(); bbox->centre = make_shared<Vector2>(c); } else{ auto pos = Point2(rand() % 600 + 32, rand() % 400 + 600); this->SetPosition(pos); } } // Handle movement for the background if(SFASSET_STARS == type) { Vector2 c = *(bbox->centre) + Vector2(0.0f, speed); if(!(c.getY() < 0.0f)) { bbox->centre.reset(); bbox->centre = make_shared<Vector2>(c); } else{ auto pos = Point2(320, 1600); this->SetPosition(pos); } } // Handle movement for type alien if(SFASSET_ALIEN == type) { Vector2 c = *(bbox->centre) + Vector2(0.0f, speed); if(!(c.getY() < 0.0f)) { bbox->centre.reset(); bbox->centre = make_shared<Vector2>(c); } else{ auto pos = Point2(rand() % 600 + 32, rand() % 400 + 600); this->SetPosition(pos); this->SetHealth(15); } } }
// Handing object collisions int SFAsset::HandleCollision() { // Collisions for projectiles if(SFASSET_PROJECTILE == type) { SetNotAlive(); } // Handle collision for the powerup if(SFASSET_POWERUP == type) { SetNotAlive(); } // Collisions for aliens if(SFASSET_ALIEN == type){ int canvas_w, canvas_h; SDL_GetRendererOutputSize(sf_window->getRenderer(), &canvas_w, &canvas_h); // For removing enemy health and checking if it died if(this->GetHealth() > 0){ // Hurt the enemy for 5 HP this->SetHealth(this->GetHealth() - 5); // Get HP as string int tempHP = this->GetHealth(); // Convert the HP to string form string HPTempString; ostringstream HPConvert; HPConvert << tempHP; HPTempString = HPConvert.str(); // Tell player it was hurt cout << "Hurt enemy " << this->GetId() << " for 5 HP. (EnemyHP: " << (this->GetHealth() <= 0 ? "DEAD" : HPTempString) << ")" << endl; // Do another check because we can reach 0, but it won't check until next collision. if(this->GetHealth() <= 0){ // Enemy died, so set new position and health auto pos = Point2(rand() % 600 + 32, rand() % 400 + 600); this->SetPosition(pos); this->SetHealth(10); // Return special condition back to call return 1; } } else{ // Enemy died, so set new position and health auto pos = Point2(rand() % 600 + 32, rand() % 400 + 600); this->SetPosition(pos); this->SetHealth(15); // Tell player cout << "Enemy " << this->GetId() << " died!" << endl; // Return special condition back to call return 1; } } // Collisions for coins if(SFASSET_COIN == type) { // Kill the coin this->SetNotAlive(); } return 0; }
void SDLRenderer::do_take_screenshot() { // [Christoph] TODO: Yes, this method also takes care of the actual disk I/O. Split it? int width; int height; if (SDL_GetRendererOutputSize(m_renderer, &width, &height) != 0) { log_warning << "SDL_GetRenderOutputSize failed: " << SDL_GetError() << std::endl; } else { #if SDL_BYTEORDER == SDL_BIG_ENDIAN Uint32 rmask = 0xff000000; Uint32 gmask = 0x00ff0000; Uint32 bmask = 0x0000ff00; Uint32 amask = 0x000000ff; #else Uint32 rmask = 0x000000ff; Uint32 gmask = 0x0000ff00; Uint32 bmask = 0x00ff0000; Uint32 amask = 0xff000000; #endif SDL_Surface* surface = SDL_CreateRGBSurface(0, width, height, 32, rmask, gmask, bmask, amask); if (!surface) { log_warning << "SDL_CreateRGBSurface failed: " << SDL_GetError() << std::endl; } else { int ret = SDL_RenderReadPixels(m_renderer, NULL, SDL_PIXELFORMAT_ABGR8888, surface->pixels, surface->pitch); if (ret != 0) { log_warning << "SDL_RenderReadPixels failed: " << SDL_GetError() << std::endl; } else { // save screenshot static const std::string writeDir = PHYSFS_getWriteDir(); static const std::string dirSep = PHYSFS_getDirSeparator(); static const std::string baseName = "screenshot"; static const std::string fileExt = ".bmp"; std::string fullFilename; for (int num = 0; num < 1000; num++) { std::ostringstream oss; oss << baseName; oss << std::setw(3) << std::setfill('0') << num; oss << fileExt; std::string fileName = oss.str(); fullFilename = writeDir + dirSep + fileName; if (!PHYSFS_exists(fileName.c_str())) { SDL_SaveBMP(surface, fullFilename.c_str()); log_info << "Wrote screenshot to \"" << fullFilename << "\"" << std::endl; return; } } log_warning << "Did not save screenshot, because all files up to \"" << fullFilename << "\" already existed" << std::endl; } } } }
/** * The logical coordinates in the game assume that the screen * is indexed from 0,0 in the bottom left corner. The blittable * coordinates of the screen map 0,0 to the top left corner. We * need to convert between the two coordinate spaces. We assume * that there is a 1-to-1 quantisation. */ Vector2 GameSpaceToScreenSpace(SDL_Renderer* renderer, Vector2 &r) { int w, h; SDL_GetRendererOutputSize(renderer, &w, &h); return Vector2 (r.getX(), (h - r.getY())); }
void jt_text_render (jt_text *text, SDL_Renderer *renderer) { int i = 0; SDL_Rect source_rect; SDL_Rect dest_rect; uint32_t text_width; uint32_t text_height; uint32_t border_width; uint32_t border_height; uint32_t left_start; uint32_t right_shift; uint32_t top_start; uint32_t bottom_shift; uint32_t x_start; uint32_t y_start; uint32_t scale; int output_width; int output_height; /* Position in tile-space */ uint32_t tile_x; uint32_t tile_y; uint32_t line_size; uint32_t remaining_space; uint32_t word_length; if (text->text == NULL) return; /* Calculate text destination area */ SDL_GetRendererOutputSize (renderer, &output_width, &output_height); border_width = output_width * JT_BORDER_X; border_height = output_height * JT_BORDER_Y; /* Select font size */ scale = (output_width - border_width * 2) / (text->size * 17 - 1); if (scale < 1) scale = 1; /* We have a goal size of text->size, but we can actually fit * line_size tiles at our best font size. */ line_size = (output_width - border_width * 2) / (17 * scale); /* X Axis */ text_width = 17 * scale * text->length - scale; left_start = border_width; right_shift = output_width - border_width * 2 - text_width; x_start = left_start + text->x_position * right_shift; /* Y Axis */ text_height = 32 * scale; top_start = border_height; bottom_shift = output_height - border_height * 2 - text_height; y_start = top_start + text->y_position * bottom_shift; tile_x = 0; tile_y = 0; for (i = text->visible_index; text->text[i]; i++) { /* Select character from font */ source_rect.x = 16 * (text->text[i] - ' '); source_rect.y = 0; source_rect.w = 16; source_rect.h = 32; /* Calculate tile destination */ dest_rect.x = x_start + (16 + 1) * tile_x * scale; dest_rect.y = y_start + (32 + 8) * tile_y * scale; dest_rect.w = 16 * scale; dest_rect.h = 32 * scale; /* For now, animation is assumed. Perhaps make it optional in * the future */ jt_text_animate (&dest_rect); if (i < text->index && text->typed_texture) SDL_RenderCopy (renderer, text->typed_texture, &source_rect, &dest_rect); else if (i >= text->index && text->untyped_texture) SDL_RenderCopy (renderer, text->untyped_texture, &source_rect, &dest_rect); /* Calculate next tile positon */ if (text->text[i] == '\x7F') { tile_x = 0; tile_y++; } else if (text->text[i] == ' ') { /* Is there enough room for the next word? */ remaining_space = line_size - tile_x - 1; word_length = min ( strchr (&text->text[i + 1], ' ') - &text->text[i + 1], strlen (&text->text[i + 1])); if (word_length > remaining_space) { tile_x = 0; tile_y++; } else { tile_x++; } } else { tile_x++; } /* Have we managed to run out of line? */ if (tile_x == line_size) { tile_x = 0; tile_y++; } /* Scroll the text */ if (tile_x == 0 && tile_y == 1 && i < text->index) { text->visible_index = i + 1; } } }
size2 SDLRenderer::outputSize() { size2 size; SDL_GetRendererOutputSize(_renderer, &size.width, &size.height); return size; }
static void CreateUpscaledTexture(boolean force) { int w, h; int h_upscale, w_upscale; static int h_upscale_old, w_upscale_old; SDL_Texture *new_texture, *old_texture; // Get the size of the renderer output. The units this gives us will be // real world pixels, which are not necessarily equivalent to the screen's // window size (because of highdpi). if (SDL_GetRendererOutputSize(renderer, &w, &h) != 0) { I_Error("Failed to get renderer output size: %s", SDL_GetError()); } // When the screen or window dimensions do not match the aspect ratio // of the texture, the rendered area is scaled down to fit. Calculate // the actual dimensions of the rendered area. if (w * actualheight < h * SCREENWIDTH) { // Tall window. h = w * actualheight / SCREENWIDTH; } else { // Wide window. w = h * SCREENWIDTH / actualheight; } // Pick texture size the next integer multiple of the screen dimensions. // If one screen dimension matches an integer multiple of the original // resolution, there is no need to overscale in this direction. w_upscale = (w + SCREENWIDTH - 1) / SCREENWIDTH; h_upscale = (h + SCREENHEIGHT - 1) / SCREENHEIGHT; // Minimum texture dimensions of 320x200. if (w_upscale < 1) { w_upscale = 1; } if (h_upscale < 1) { h_upscale = 1; } LimitTextureSize(&w_upscale, &h_upscale); // Create a new texture only if the upscale factors have actually changed. if (h_upscale == h_upscale_old && w_upscale == w_upscale_old && !force) { return; } h_upscale_old = h_upscale; w_upscale_old = w_upscale; // Set the scaling quality for rendering the upscaled texture to "linear", // which looks much softer and smoother than "nearest" but does a better // job at downscaling from the upscaled texture to screen. SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); new_texture = SDL_CreateTexture(renderer, pixel_format, SDL_TEXTUREACCESS_TARGET, w_upscale*SCREENWIDTH, h_upscale*SCREENHEIGHT); old_texture = texture_upscaled; texture_upscaled = new_texture; if (old_texture != NULL) { SDL_DestroyTexture(old_texture); } }
int main(int argc, char**argv) { SDL_Window* win = NULL; SDL_Renderer* ren = NULL; SDL_Texture* tex = NULL; SDL_Event eve; char*smoothing="nearest"; //nearest or linear unsigned width = 3000; unsigned height = 4000; unsigned i,r,g,b,x,y; int sizew,sizeh; //actual window size uint32_t*buff=NULL; srand(time(NULL)); assert(buff = calloc(width*height,sizeof(uint32_t))); for(x=0; x<width; x++) { for(y=0; y<height; y++) { r = x % 256; g = y % 256; //i / 256; b = 0; //rand() % 256; //buff[y*width+x] = (r<<16)+(g<<8)+b; setpixel(buff,x,y,width,r,g,b); } } if (SDL_Init(SDL_INIT_VIDEO) != 0) { printf("SDL_Init Error: %s\n",SDL_GetError()); return 1; } assert(win = SDL_CreateWindow("Hello World!", SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED, 100, 100,SDL_WINDOW_SHOWN|SDL_WINDOW_MAXIMIZED|SDL_WINDOW_RESIZABLE)); //SDL_WINDOW_FULLSCREEN_DESKTOP)); assert(ren = SDL_CreateRenderer(win, -1, 0)); SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, smoothing); //"linear" or "nearest" //SDL_RenderSetLogicalSize(ren, width, height);- assert(tex = SDL_CreateTexture(ren,SDL_PIXELFORMAT_ARGB8888,SDL_TEXTUREACCESS_STREAMING, width, height)); SDL_UpdateTexture(tex, NULL, buff, width * sizeof (uint32_t)); SDL_RenderClear(ren); SDL_RenderCopy(ren, tex, NULL, NULL); SDL_RenderPresent(ren); SDL_PollEvent(&eve); SDL_RenderClear(ren); SDL_RenderCopy(ren, tex, NULL, NULL); SDL_RenderPresent(ren); SDL_Rect src; SDL_Rect dst; double vx = (double)width / 2.0; double vy = (double)height / 2.0; double scl = 0.5; src.x = 0; src.y = 0; src.w = width; src.h = height; SDL_GetWindowSize(win,&sizew,&sizeh); printf("window size: %d,%d\n",sizew,sizeh); SDL_GetWindowMaximumSize(win,&sizew,&sizeh); printf("max window size: %d,%d\n",sizew,sizeh); SDL_GetRendererOutputSize(ren,&sizew,&sizeh); printf("renderer size: %d,%d\n",sizew,sizeh); while(1) { SDL_WaitEvent(&eve); if(eve.type == SDL_QUIT) break; if(eve.type == SDL_KEYDOWN) { //quit if(eve.key.keysym.sym == SDLK_q) break; if(eve.key.keysym.sym == SDLK_ESCAPE) break; //scaling method if(eve.key.keysym.sym == SDLK_n) SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY,"nearest"); if(eve.key.keysym.sym == SDLK_l) SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY,"linear"); //reset view if(eve.key.keysym.sym == SDLK_RETURN || eve.key.keysym.sym == SDLK_RETURN2) { vx = (double)width / 2.0; vy = (double)height / 2.0; scl = 0.5; } //zoom in / out if(eve.key.keysym.sym == SDLK_PLUS || eve.key.keysym.sym == SDLK_KP_PLUS) { scl /= 1.01; } if(eve.key.keysym.sym == SDLK_MINUS || eve.key.keysym.sym == SDLK_KP_MINUS) { scl *= 1.01; } } if(eve.type == SDL_MOUSEBUTTONDOWN) { printf("(%d,%d)\n",eve.button.x,eve.button.y); } dst.x = vx - scl * (double)width; dst.y = vy - scl * (double)height; dst.w = 2.0 * scl * (double)width; dst.h = 2.0 * scl * (double)height; SDL_RenderClear(ren); SDL_RenderCopy(ren, tex, &src, &dst); SDL_RenderPresent(ren); } SDL_Quit(); return 0; }
ScreenServiceImpl::ScreenServiceImpl(SDL_Renderer *renderer) { this->renderer = renderer; SDL_GetRendererOutputSize(renderer, &width, &height); }
void display::start( __in_opt const mirra::parameter_t ¶meter ) { std::string title; uint32_t height, width; mirra::parameter_t::const_iterator iter; mirra::object_parameter_t::const_iterator attribute_iter; if(!m_initialized) { THROW_MIRRA_DISPLAY_EXCEPTION(MIRRA_DISPLAY_EXCEPTION_UNINITIALIZED); } if(m_started) { THROW_MIRRA_DISPLAY_EXCEPTION(MIRAR_DISPLAY_EXCEPTION_STARTED); } height = DISPLAY_PARAMETER_DEFAULT_HEIGHT; title = DISPLAY_PARAMETER_DEFAULT_TITLE; width = DISPLAY_PRAAMETER_DEFAULT_WIDTH; iter = parameter.find(OBJECT_DISPLAY); if(iter != parameter.end()) { attribute_iter = iter->second.find(DISPLAY_PARAMETER_HEIGHT); if(attribute_iter != iter->second.end()) { if(attribute_iter->second.type != DATA_UNSIGNED) { THROW_MIRRA_DISPLAY_EXCEPTION_FORMAT(MIRRA_DISPLAY_EXCEPTION_INVALID_PARAMETER, "%s: %s (expecting %s)", DISPLAY_PARAMETER_STRING(DISPLAY_PARAMETER_HEIGHT), DATA_STRING(attribute_iter->second.type), DATA_STRING(DATA_UNSIGNED)); } height = attribute_iter->second.data.uvalue; } attribute_iter = iter->second.find(DISPLAY_PARAMETER_TITLE); if(attribute_iter != iter->second.end()) { if(attribute_iter->second.type != DATA_STRING) { THROW_MIRRA_DISPLAY_EXCEPTION_FORMAT(MIRRA_DISPLAY_EXCEPTION_INVALID_PARAMETER, "%s: %s (expecting %s)", DISPLAY_PARAMETER_STRING(DISPLAY_PARAMETER_TITLE), DATA_STRING(attribute_iter->second.type), DATA_STRING(DATA_STRING)); } title = (attribute_iter->second.data.strvalue ? attribute_iter->second.data.strvalue : STRING_EMPTY); } attribute_iter = iter->second.find(DISPLAY_PARAMETER_WIDTH); if(attribute_iter != iter->second.end()) { if(attribute_iter->second.type != DATA_UNSIGNED) { THROW_MIRRA_DISPLAY_EXCEPTION_FORMAT(MIRRA_DISPLAY_EXCEPTION_INVALID_PARAMETER, "%s: %s (expecting %s)", DISPLAY_PARAMETER_STRING(DISPLAY_PARAMETER_WIDTH), DATA_STRING(attribute_iter->second.type), DATA_STRING(DATA_UNSIGNED)); } width = attribute_iter->second.data.uvalue; } } m_window = SDL_CreateWindow(STRING_CHECK(title), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, WINDOW_INIT_FLAGS); if(!m_window) { THROW_MIRRA_DISPLAY_EXCEPTION_FORMAT(MIRRA_DISPLAY_EXCEPTION_EXTERNAL, "SDL_CreateWindow: %s", SDL_GetError()); } m_window_renderer = SDL_CreateRenderer(m_window, SCALAR_INVALID(int), WINDOW_RENDERER_INIT_FLAGS); if(!m_window_renderer) { THROW_MIRRA_DISPLAY_EXCEPTION_FORMAT(MIRRA_DISPLAY_EXCEPTION_EXTERNAL, "SDL_CreateRenderer: %s", SDL_GetError()); } if(SDL_GetRendererOutputSize(m_window_renderer, &m_renderer_width, &m_renderer_height)) { THROW_MIRRA_DISPLAY_EXCEPTION_FORMAT(MIRRA_DISPLAY_EXCEPTION_EXTERNAL, "SDL_GetRendererOutputSize: %s", SDL_GetError()); } if(SDL_SetRenderDrawBlendMode(m_window_renderer, SDL_BLENDMODE_BLEND)) { THROW_MIRRA_DISPLAY_EXCEPTION_FORMAT(MIRRA_DISPLAY_EXCEPTION_EXTERNAL, "SDL_SetRenderDrawBlendMode: %s", SDL_GetError()); } m_window_texture = SDL_CreateTexture(m_window_renderer, SDL_PIXELFORMAT_BGRA8888, SDL_TEXTUREACCESS_STREAMING, width, height); if(!m_window_texture) { THROW_MIRRA_DISPLAY_EXCEPTION_FORMAT(MIRRA_DISPLAY_EXCEPTION_EXTERNAL, "SDL_CreateTexture: %s", SDL_GetError()); } if(SDL_SetTextureBlendMode(m_window_texture, SDL_BLENDMODE_BLEND)) { THROW_MIRRA_DISPLAY_EXCEPTION_FORMAT(MIRRA_DISPLAY_EXCEPTION_EXTERNAL, "SDL_SetTextureBlendMode: %s", SDL_GetError()); } m_started = true; clear(); }
/** * @brief Create RGB Surface, then Converts to RGBA on the fly. * @param surfaceType */ void SurfaceManager::createSurface(int surfaceType) { // Run Through Surface Alias and create surface. switch(surfaceType) { // Handle Individual Character Surfaces case SURFACE_CHARACTER: case SURFACE_CURSOR_ON: case SURFACE_CURSOR_OFF: { // If Exists, Recreate it. if(surfaceExists(surfaceType)) { delSurface(surfaceType); } // Create Surface with Smart pointer. surface_ptr surface( new Surfaces( SDL_CreateRGBSurface( SDL_SWSURFACE, m_characterWidth, m_characterHeight, m_surfaceBits, m_redMask, m_greenMask, m_blueMask, m_alphaMask ) ) ); convertAndAdd(surfaceType, surface); } break; // Handles Main Screen Surfaces case SURFACE_MAIN_SCREEN: { // If Exists, Recreate it. if(surfaceExists(surfaceType)) { delSurface(surfaceType); } window_manager_ptr window = m_weak_window_manager.lock(); if (window) { // Create Surface with Smart pointer surface_ptr surface( new Surfaces( SDL_CreateRGBSurface( SDL_SWSURFACE, window->getWindowWidth(), window->getWindowHeight(), m_surfaceBits, m_redMask, m_greenMask, m_blueMask, m_alphaMask ) ) ); convertAndAdd(surfaceType, surface); } } break; // Handles Screen Surface Scaled to Match Texture Dimensions. case SURFACE_MAIN_SCALED: { // If Exists, Recreate it. if(surfaceExists(surfaceType)) { delSurface(surfaceType); } // Handle to Window Manager window_manager_ptr window = m_weak_window_manager.lock(); if (!window) { return; } // Get the Actual size of the Renderer to match the surface for scaling. int screenWidth, screenHeight; SDL_GetRendererOutputSize( window->getRenderer(), &screenWidth, &screenHeight ); // Create Surface with Smart pointer surface_ptr surface( new Surfaces( SDL_CreateRGBSurface( SDL_SWSURFACE, screenWidth, screenHeight, m_surfaceBits, m_redMask, m_greenMask, m_blueMask, m_alphaMask ) ) ); convertAndAdd(surfaceType, surface); } break; // Handles Last Row of a Surface for Scrolling // Currently used for Main Screen, might need scaled version instead? case SURFACE_BOTTOM_ROW: { // If Exists, Recreate it. if(surfaceExists(surfaceType)) { delSurface(surfaceType); } if(!surfaceExists(SURFACE_MAIN_SCREEN)) { SDL_Log("Main Screen Doesn't Exist for Bottom Row Surface!"); assert(false); } // Create Surface with Smart pointer, uses with of Main Screen, Must exist first! surface_ptr surface( new Surfaces( SDL_CreateRGBSurface( SDL_SWSURFACE, m_surfaceList[SURFACE_MAIN_SCREEN]->getSurface()->w, m_characterHeight, m_surfaceBits, m_redMask, m_greenMask, m_blueMask, m_alphaMask ) ) ); convertAndAdd(surfaceType, surface); } break; default: break; } }
/** * @brief Creates / Recreate Textures * @param textureType * @param surface */ void SurfaceManager::createTexture(int textureType, SDL_Surface *surface) { // Handle to Window Manager window_manager_ptr window = m_weak_window_manager.lock(); if (!window) { return; } switch(textureType) { case TEXTURE_MAIN_SCREEN: { // If Exists, Recreate it. if(textureExists(textureType)) { delTexture(textureType); } // Handle to Window Manager window_manager_ptr window = m_weak_window_manager.lock(); if (!window) { return; } // Get the Actual size of the Renderer to match the surface for scaling. // m_is_scalling_surface!! Add Toggle for Scaling here, // Otherwise should use same size as main surface! int screenWidth, screenHeight; SDL_GetRendererOutputSize( window->getRenderer(), &screenWidth, &screenHeight ); // Create Texture: SDL_TEXTUREACCESS_STREAMING texture_ptr texture( new Textures( SDL_CreateTexture( window->getRenderer(), SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, screenWidth, screenHeight ) ) ); addTexture(textureType, texture); // Set the Blend Mode of the Texture NONE if(SDL_SetTextureBlendMode( texture->getTexture(), SDL_BLENDMODE_NONE) < 0) { SDL_Log("Error Setting Blend on Texture - %s", SDL_GetError()); } } break; case TEXTURE_SELECTION: case TEXTURE_HILIGHT: { // If Exists, Recreate it. if(textureExists(textureType)) { delTexture(textureType); } // Create Texture: SDL_TEXTUREACCESS_TARGET texture_ptr texture( new Textures( SDL_CreateTexture( window->getRenderer(), SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, surface->w, surface->h ) ) ); addTexture(textureType, texture); // Set the Blend Mode of the Texture ADD if(SDL_SetTextureBlendMode( texture->getTexture(), SDL_BLENDMODE_ADD) < 0) { SDL_Log("Error Setting Blend on Texture - %s", SDL_GetError()); } } break; default: break; } }
/** * \fn void getMousePosition(SDL_Renderer * pRenderer, Input * pInput, SDL_Rect * camera, int * x, int *y) * \brief Réajuste la taille de la caméra pour un rétrécissement de l'image. * * \param[in] pRenderer, le renderer de la fenêtre courante. * * \param[in] pInput, les inputs utilisateur. * * \param[in] camera, le rect de la camera courante. * * \param[in] x, le pointeur sur un int pour stocker x. * * \param[in] y, le pointeur sur un int pour stocker y. * * \returns void */ void getMousePosition(SDL_Renderer * pRenderer, Input * pInput, SDL_Rect * camera, int * x, int *y){ int w = 0, h = 0; SDL_GetRendererOutputSize(pRenderer, &w, &h); x = (int)(((float)pInput->cursor.now.x / w)*camera->w) + camera->x; y = (int)(((float)pInput->cursor.now.y / h)*camera->h) + camera->y; }