Beispiel #1
0
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()));
}
Beispiel #6
0
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;
        }
    }
}
Beispiel #7
0
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);
}
Beispiel #11
0
	void 
	display::start(
		__in_opt const mirra::parameter_t &parameter
		)
	{
		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();
	}
Beispiel #12
0
/**
 * @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;
    }
}
Beispiel #13
0
/**
 * @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;
    }
}
Beispiel #14
0
/**
* \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;
}