// Convert the normal tiles to masked tiles
void CEGALatch::applyMasks()
{
	SDL_Surface *frontSfc = gGraphics.getTileMap(1).getSDLSurface();
	SDL_Surface *backSfc = gGraphics.getTileMap(0).getSDLSurface();

#if SDL_VERSION_ATLEAST(2, 0, 0)

    SDL_SetSurfaceBlendMode(frontSfc, SDL_BLENDMODE_BLEND);

#endif


	if(SDL_MUSTLOCK(frontSfc)) SDL_LockSurface(frontSfc);
	if(SDL_MUSTLOCK(backSfc)) SDL_LockSurface(backSfc);

	const Uint8 bpp = frontSfc->format->BytesPerPixel;

	for( Uint16 t=0 ; t<m_num16tiles ; t++ )
	{
		if( g_pBehaviorEngine->getTileProperties().at(t).behaviour == -2 )  // This is for masked tiles.
		{
			SDL_Rect srGsRect, dstRect;
			srGsRect.w = srGsRect.h = 16;
			dstRect.w = dstRect.h = 16;
			
			srGsRect.x = 16*(t%13);
			srGsRect.y = 16*(t/13);		  
		  
			SDL_FillRect( frontSfc, &srGsRect, SDL_MapRGBA(frontSfc->format, 0, 0, 0, 0) );
		  
			for( Uint16 x=0 ; x<16 ; x++ ) for( Uint16 y=0 ; y<16 ; y++ )
			{	
				Uint32 u_colour = 0;
				Uint8 r,g,b;
				Uint8 *u_offset = (Uint8*)backSfc->pixels + bpp*((y+16*((t+1)/13))*13*16 + 16*((t+1)%13) + x);
				memcpy( &u_colour, u_offset, bpp );
				SDL_GetRGB( u_colour, backSfc->format, &r, &g, &b );

				Uint8 alpha;
					
				if( r>=250 && g>=250 && b>=250 ) // In this case set it to zero
				{
				    alpha = r = g = b = 0;
				}
				else // Get the pixel of the previous tile. If the mask has colour, use alpha channel, black is opaque
				{
				    alpha = 255 - (r+g+b)/3;
				    u_offset = (Uint8*)backSfc->pixels + bpp*((y+16*(t/13))*13*16 + 16*(t%13) + x);
				    memcpy( &u_colour, u_offset, bpp);
				    SDL_GetRGB( u_colour, backSfc->format, &r, &g, &b);					    
				}
				
				SDL_Rect srGsRect;
				srGsRect.w = srGsRect.h = 1;
				srGsRect.x = 16*((t)%13) + x;
				srGsRect.y = y+16*((t)/13);
				
				SDL_FillRect( frontSfc, &srGsRect, SDL_MapRGBA(frontSfc->format, r, g, b, alpha) );
			}
		}
	}

	if(SDL_MUSTLOCK(backSfc)) 
	  SDL_UnlockSurface(backSfc);
	if(SDL_MUSTLOCK(frontSfc)) 
	  SDL_UnlockSurface(frontSfc);
}
示例#2
0
void drawall(gamedata &g){

  int ypos;
  int ypos2;

  // Set screenheight
  int screenheight = 0;
  if (g.players == 1){
    screenheight = limit(GAME_HEIGHT,GAME_HEIGHT,240); //464);
  }else{
    screenheight = limit(GAME_HEIGHT,GAME_HEIGHT,120);
  }

  if(!g.scoreBarPos) // top
  {
	ypos = 0;
	ypos2 = 8;
  }
  else // bottom
  {
	ypos = screenheight - 16;
	ypos2 = screenheight - 8;
  }

  // Player 1
//  int x1 = limit(int(g.player1->x)-308, 0, GAME_WIDTH-320);
  int x1 = limit(int(g.player1->x)-160, 0, GAME_WIDTH-320);
  int y1 = limit(int(g.player1->y)-54, 0, GAME_HEIGHT-screenheight);
  SDL_Rect srcrect;
    srcrect.x = x1;
    srcrect.y = y1;
    srcrect.w = 320;
    srcrect.h = screenheight;
  SDL_BlitSurface(g.gamescreen, &srcrect, g.virtualscreen, NULL);
  SDL_Rect cliprect;
    cliprect.x = 0;
    cliprect.y = 0;
    cliprect.w = 320;
    cliprect.h = screenheight;
  SDL_SetClipRect(g.virtualscreen, &cliprect);
  drawblits(g,x1,y1);
  SDL_SetClipRect(g.virtualscreen, NULL);

  if (g.players == 1){
  if(GameState == STATE_GAME)
//	  display_playinfo(g.virtualscreen, 1, *g.player1, screenheight - 16, g.images, g.mission,
//                   g.targetscore, g.whitefont, g.greenfont, g);
	  display_playinfo(g.virtualscreen, 1, *g.player1, ypos, g.images, g.mission,
                   g.targetscore, g.whitefont, g.greenfont, g);
  }else{
  if(GameState == STATE_GAME)
	  display_playinfo(g.virtualscreen, 1, *g.player1, screenheight - 8, g.images, g.mission,
                   g.targetscore, g.whitefont, g.greenfont, g);
  }

/*
  display_playinfo(g.virtualscreen, 1, *g.player1, screenheight, g.images, g.mission,
                   g.targetscore, g.whitefont, g.greenfont, g);
*/

  // Player 2
  if (g.players == 2){
    int x2 = limit(int(g.player2->x)-160, 0, GAME_WIDTH-320);
    int y2 = limit(int(g.player2->y)-54, 0, GAME_HEIGHT-screenheight);//-208); //224);
    SDL_Rect srcrect;
      srcrect.x = x2;
      srcrect.y = y2;
      srcrect.w = 320;
      srcrect.h = screenheight;
    SDL_Rect desrect;
      desrect.x = 0;
      desrect.y = 120;
      desrect.w = 320;
      desrect.h = screenheight;
    SDL_BlitSurface(g.gamescreen, &srcrect, g.virtualscreen, &desrect);
    SDL_Rect cliprect;
      cliprect.x = 0;
      cliprect.y = 120;
      cliprect.w = 320;
      cliprect.h = screenheight;
    SDL_SetClipRect(g.virtualscreen, &cliprect);
    drawblits(g,x2,y2-120);
    SDL_SetClipRect(g.virtualscreen, NULL);

    if(GameState == STATE_GAME)
  	  display_playinfo(g.virtualscreen, 2, *g.player2, 240 - 8, g.images, g.mission,
                     g.targetscore, g.whitefont, g.greenfont, g);
/*
    display_playinfo(g.virtualscreen, 2, *g.player2, 464, g.images, g.mission,
                     g.targetscore, g.whitefont, g.greenfont, g);
*/
  }

  if(GameState == STATE_INTRO || GameState == STATE_MENU)
  {
	if(CurrentMenu == MenuMainIntro)
		menuDraw(CurrentMenu, 140, 100, g);
	else if(CurrentMenu == MenuMain)
		menuDraw(CurrentMenu, 120, 100, g);
	else if(CurrentMenu == MenuOptions)
		menuDraw(CurrentMenu, 110, 100,g);
	else if(CurrentMenu == MenuGameOptions)
		menuDraw(CurrentMenu, 20, 80, g);
	else
		menuDraw(CurrentMenu, 140, 100, g);
  }
  else if(GameState == STATE_MENU_PLANE_SELECT)
  {
	menuPlanesDraw(20, 10, g);
  }
  else if(GameState == STATE_MENU_PLAYER_CONTROL_SELECT)
  {
	menuSelectPlayerDraw(g);
  }

  // Best AI Score
  if (g.planes > g.players){
    plane bestp;
    bool found = false;
    g.p.reset();
    while (g.p.next()){
      if ((g.p().control == 0) && (g.p().side > 0)){
        if (!found){
          bestp = g.p();
          found = true;
        }else{
          if ((g.mission == 0) || (g.mission == 1)){
            if (g.p().score > bestp.score){
              bestp = g.p();
            }
          }else{
            if (g.p().targetscore < bestp.targetscore){
              bestp = g.p();
            }          
          }
        }
      }
    }
    // Display AI
    if(GameState == STATE_GAME){
	    SDL_Rect rect;
	    char compstring[] = "Plane x";
	    compstring[6] = '0' + bestp.side;

	    if (g.players == 1){
	        rect.x = 304;
	        rect.y = ypos;
	        rect.w = 16;
	        rect.h = 16;
	        SDL_FillRect(g.virtualscreen,&rect,16);
	        g.images[bestp.image+13].blit(g.virtualscreen,304,ypos);
		g.whitefont.write(g.virtualscreen, 24, ypos2, compstring);
	    }
	    else{
		// TODO: display the best player score
	    }
	    // Display score
	    if (g.players == 1){
	    display_score(g.virtualscreen, bestp, 112, ypos2, g.mission, g.targetscore,
		          g.whitefont, g.greenfont);
	    }else{
	    display_score(g.virtualscreen, bestp, 112, screenheight-8, g.mission, g.targetscore,
		          g.whitefont, g.greenfont);
	    }
    }

  }

  // Update screen display
  SDL_Rect rect;
    rect.x = 0;
    rect.y = 0;
    rect.w = 320;
    rect.h = 240;
  SDL_BlitSurface(g.virtualscreen, &rect, g.physicalscreen, NULL);

  //SDL_Flip(g.physicalscreen);
	if(SDL_MUSTLOCK(ScreenSurface)) SDL_LockSurface(ScreenSurface);
		SDL_Surface *p = SDL_ConvertSurface(g.physicalscreen, ScreenSurface->format, 0);
		SDL_SoftStretch(p, NULL, ScreenSurface, NULL);
	if(SDL_MUSTLOCK(ScreenSurface)) SDL_UnlockSurface(ScreenSurface);
		SDL_Flip(ScreenSurface);
		SDL_FreeSurface(p);
  //SDL_UpdateRect(g.physicalscreen, 0, 0, 0, 0);

  g.sound.update();

}
示例#3
0
文件: SDLStage.cpp 项目: ubald/lime
 void EndRender()
 {
     if (SDL_MUSTLOCK(mSurf) && !mLockedForHitTest)
         SDL_UnlockSurface(mSurf);
 }
示例#4
0
static void video_write(void){
  int i;
  th_ycbcr_buffer yuv;
  int y_offset, uv_offset;
  th_decode_ycbcr_out(td,yuv);
  /* Lock SDL_yuv_overlay */
  if ( SDL_MUSTLOCK(screen) ) {
    if ( SDL_LockSurface(screen) < 0 ) return;
  }
  if (SDL_LockYUVOverlay(yuv_overlay) < 0) return;

  /* let's draw the data on a SDL screen (*screen) */
  /* deal with border stride */
  /* reverse u and v for SDL */
  /* and crop input properly, respecting the encoded frame rect */
  /* problems may exist for odd frame rect for some encodings */

  y_offset=(ti.pic_x&~1)+yuv[0].stride*(ti.pic_y&~1);

  if (px_fmt==TH_PF_422) {
    uv_offset=(ti.pic_x/2)+(yuv[1].stride)*(ti.pic_y);
    /* SDL doesn't have a planar 4:2:2 */ 
    for(i=0;i<yuv_overlay->h;i++) {
      int j;
      char *in_y  = (char *)yuv[0].data+y_offset+yuv[0].stride*i;
      char *out = (char *)(yuv_overlay->pixels[0]+yuv_overlay->pitches[0]*i);
      for (j=0;j<yuv_overlay->w;j++)
        out[j*2] = in_y[j];
      char *in_u  = (char *)yuv[1].data+uv_offset+yuv[1].stride*i;
      char *in_v  = (char *)yuv[2].data+uv_offset+yuv[2].stride*i;
      for (j=0;j<yuv_overlay->w>>1;j++) {
        out[j*4+1] = in_u[j];
        out[j*4+3] = in_v[j];
      }
    }
  } else {
    uv_offset=(ti.pic_x/2)+(yuv[1].stride)*(ti.pic_y/2);
    for(i=0;i<yuv_overlay->h;i++)
      memcpy(yuv_overlay->pixels[0]+yuv_overlay->pitches[0]*i,
           yuv[0].data+y_offset+yuv[0].stride*i,
           yuv_overlay->w);
    for(i=0;i<yuv_overlay->h/2;i++){
      memcpy(yuv_overlay->pixels[1]+yuv_overlay->pitches[1]*i,
           yuv[2].data+uv_offset+yuv[2].stride*i,
           yuv_overlay->w/2);
      memcpy(yuv_overlay->pixels[2]+yuv_overlay->pitches[2]*i,
           yuv[1].data+uv_offset+yuv[1].stride*i,
           yuv_overlay->w/2);
    }
  }

  /* Unlock SDL_yuv_overlay */
  if ( SDL_MUSTLOCK(screen) ) {
    SDL_UnlockSurface(screen);
  }
  SDL_UnlockYUVOverlay(yuv_overlay);


  /* Show, baby, show! */
  SDL_DisplayYUVOverlay(yuv_overlay, &rect);

}
示例#5
0
/* The general purpose software blit routine */
static int
SDL_SoftBlit(SDL_Surface * src, SDL_Rect * srcrect,
             SDL_Surface * dst, SDL_Rect * dstrect)
{
    int okay;
    int src_locked;
    int dst_locked;

    /* Everything is okay at the beginning...  */
    okay = 1;

    /* Lock the destination if it's in hardware */
    dst_locked = 0;
    if (SDL_MUSTLOCK(dst)) {
        if (SDL_LockSurface(dst) < 0) {
            okay = 0;
        } else {
            dst_locked = 1;
        }
    }
    /* Lock the source if it's in hardware */
    src_locked = 0;
    if (SDL_MUSTLOCK(src)) {
        if (SDL_LockSurface(src) < 0) {
            okay = 0;
        } else {
            src_locked = 1;
        }
    }

    /* Set up source and destination buffer pointers, and BLIT! */
    if (okay && srcrect->w && srcrect->h) {
        SDL_BlitFunc RunBlit;
        SDL_BlitInfo *info = &src->map->info;

        /* Set up the blit information */
        info->src = (Uint8 *) src->pixels +
            (Uint16) srcrect->y * src->pitch +
            (Uint16) srcrect->x * info->src_fmt->BytesPerPixel;
        info->src_w = srcrect->w;
        info->src_h = srcrect->h;
        info->src_pitch = src->pitch;
        info->src_skip =
            info->src_pitch - info->src_w * info->src_fmt->BytesPerPixel;
        info->dst =
            (Uint8 *) dst->pixels + (Uint16) dstrect->y * dst->pitch +
            (Uint16) dstrect->x * info->dst_fmt->BytesPerPixel;
        info->dst_w = dstrect->w;
        info->dst_h = dstrect->h;
        info->dst_pitch = dst->pitch;
        info->dst_skip =
            info->dst_pitch - info->dst_w * info->dst_fmt->BytesPerPixel;
        RunBlit = (SDL_BlitFunc) src->map->data;

        /* Run the actual software blit */
        RunBlit(info);
    }

    /* We need to unlock the surfaces if they're locked */
    if (dst_locked) {
        SDL_UnlockSurface(dst);
    }
    if (src_locked) {
        SDL_UnlockSurface(src);
    }
    /* Blit is done! */
    return (okay ? 0 : -1);
}
示例#6
0
void UnlockScreen(SDL_Surface *screen)
{
    if ( SDL_MUSTLOCK(screen) ) {
        SDL_UnlockSurface(screen);
    }
}
示例#7
0
bool CEGASprit::loadData(const std::string& filename, bool compresseddata)
{
	byte *RawData;
    SDL_Surface *sfc;
    Uint8* pixel;
    Uint32 percent = 0;
	
	FILE* latchfile = OpenGameFile(filename.c_str(),"rb");
	
	if(!latchfile)
		return false;
	
	gResourceLoader.setPermilage(10);

	RawData = new byte[m_planesize * 5];
    // get the data out of the file into the memory, decompressing it if necessary.
    if (compresseddata)
    {
		if (lz_decompress(latchfile, RawData))
			return 1;
    }
    else
    {
    	for(int i=0 ; i<(m_planesize*5) ; i++)
    		RawData[i] = fgetc(latchfile);
    }
	
    fclose(latchfile);

	gResourceLoader.setPermilage(50);
	
    // TODO: Try to blit the Font map here!
	// these are the offsets of the different video planes as
	// relative to each other--that is if a pixel in plane1
	// is at N, the byte for that same pixel in plane3 will be
	// at (N + plane3).
	unsigned long plane1, plane2, plane3, plane4, plane5;
	
	plane1 = 0;
	plane2 = (m_planesize * 1);
	plane3 = (m_planesize * 2);
	plane4 = (m_planesize * 3);
	plane5 = (m_planesize * 4);
	
	CPlanes Planes(RawData + m_spriteloc);
	Planes.setOffsets(plane1, plane2, plane3, plane4, plane5);
	
	// load the image data
    gGraphics.createEmptySprites(4,MAX_SPRITES+1);
	for(int i=0 ; i<m_numsprites ; i++)
	{
        GsSprite &Sprite = gGraphics.getSprite(0,i);
		Sprite.setSize( EGASpriteModell[i].width, EGASpriteModell[i].height );
		Sprite.setBoundingBoxCoordinates( (EGASpriteModell[i].hitbox_l << STC),
				(EGASpriteModell[i].hitbox_u << STC),
				(EGASpriteModell[i].hitbox_r << STC),
				(EGASpriteModell[i].hitbox_b << STC) );
		Sprite.createSurface( gVideoDriver.mpVideoEngine->getBlitSurface()->flags,
				gGraphics.Palette.m_Palette );

		percent = (i*50)/m_numsprites;
		gResourceLoader.setPermilage(50+percent);
	}

	gResourceLoader.setPermilage(100);

	for(int p=0 ; p<4 ; p++)
	{
		for(int s=0 ; s<m_numsprites ; s++)
		{
            sfc = gGraphics.getSprite(0,s).getSDLSurface();
			if(SDL_MUSTLOCK(sfc)) SDL_LockSurface(sfc);
			pixel = (Uint8*) sfc->pixels;

			Planes.readPlane(p, pixel, sfc->w, sfc->h);

			if(SDL_MUSTLOCK(sfc)) SDL_UnlockSurface(sfc);

			percent = (s*100)/m_numsprites;
			gResourceLoader.setPermilage(100+percent);
		}
	}

	gResourceLoader.setPermilage(200);

	// now load the 5th plane, which contains the sprite masks.
	// note that we invert the mask because our graphics functions
	// use white on black masks whereas keen uses black on white.
	for(int s=0 ; s<m_numsprites ; s++)
	{
        GsSprite &Sprite = gGraphics.getSprite(0,s);
		SDL_Surface *pixsfc = Sprite.getSDLSurface();
		SDL_Surface *masksfc = Sprite.getSDLMaskSurface();

		if(SDL_MUSTLOCK(pixsfc)) SDL_LockSurface(pixsfc);
		if(SDL_MUSTLOCK(masksfc)) SDL_LockSurface(masksfc);

		pixel = (Uint8*) masksfc->pixels;

		for(int y=0 ; y<masksfc->h ; y++)
		{
			for(int x=0 ; x<masksfc->w ; x++)
			{
				if(Planes.getbit(4))
                    pixel[y*masksfc->w + x] = ((Uint8*)pixsfc->pixels)[y*pixsfc->w + x];
				else
					pixel[y*masksfc->w + x] = 15;
			}
		}
		if(SDL_MUSTLOCK(masksfc)) SDL_UnlockSurface(masksfc);
		if(SDL_MUSTLOCK(pixsfc)) SDL_UnlockSurface(pixsfc);

		percent = (s*100)/m_numsprites;
		gResourceLoader.setPermilage(200+percent);
	}

	gResourceLoader.setPermilage(300);
	
	if(RawData){ delete[] RawData; RawData = NULL;}
	
    LoadSpecialSprites( gGraphics.getSpriteVec(0) );

    for(unsigned int i=1 ; i<4 ; i++)
    {
        gGraphics.getSpriteVec(i) = gGraphics.getSpriteVec(0);
    }

    // For the other variant let's exchange some colors
    auto &SpriteVecPlayer2 = gGraphics.getSpriteVec(1);
    //for( auto &sprite : SpriteVecPlayer2)
    for( unsigned int i = 0 ; i < SpriteVecPlayer2.size() ; i++)
    {
        auto &sprite = SpriteVecPlayer2[i];
        // Red against Purple
        sprite.exchangeSpriteColor( 5, 4, 0 );
        sprite.exchangeSpriteColor( 13, 12, 0 );

        // Yellow against Green
        sprite.exchangeSpriteColor( 2, 6, 0 );
        sprite.exchangeSpriteColor( 10, 14, 0 );
    }

    auto &SpriteVecPlayer3 = gGraphics.getSpriteVec(2);
    for( auto &sprite : SpriteVecPlayer3)
    {
        // Red against Green
        sprite.exchangeSpriteColor( 2, 4, 0 );
        sprite.exchangeSpriteColor( 10, 12, 0 );

        // Yellow against Purple
        sprite.exchangeSpriteColor( 5, 6, 0 );
        sprite.exchangeSpriteColor( 13, 14, 0 );
    }

    auto &SpriteVecPlayer4 = gGraphics.getSpriteVec(3);
    for( auto &sprite : SpriteVecPlayer4)
    {
        // Red against Yellow
        sprite.exchangeSpriteColor( 6, 4, 0 );
        sprite.exchangeSpriteColor( 14, 12, 0 );

        // Green against Purple
        sprite.exchangeSpriteColor( 2, 5, 0 );
        sprite.exchangeSpriteColor( 10, 13, 0 );
    }


    for(unsigned int i=0 ; i<4 ; i++)
    {
        for(Uint16 s=0 ; s<gGraphics.getSpriteVec(i).size() ; s++)
        {
            GsSprite &Sprite = gGraphics.getSprite(i,s);
            Sprite.optimizeSurface();

            percent = (s*50)/m_numsprites;
            gResourceLoader.setPermilage(300+percent);
        }
    }

    gResourceLoader.setPermilage(350);

    std::set<std::string> filelist;
	FileListAdder fileListAdder;
	std::string gfxpath = JoinPaths(m_gamepath, "gfx");
	GetFileList(filelist, fileListAdder, gfxpath, false, FM_REG);
	FilterFilelist(filelist, "sprite");

	std::set<std::string>::iterator it = filelist.begin();
	int listsize = filelist.size();
	for( int c=0 ; it != filelist.end() ; it++, c++ )
	{
		std::string name=*it;
		int num = getRessourceID(name, "sprite");
		if(num < m_numsprites )
		{
            GsSprite &Sprite = gGraphics.getSprite(0,num);
			std::string filename = getResourceFilename("gfx/"+name, m_gamepath, false, true);
			Sprite.loadHQSprite(filename);
		}

		percent = (c*150)/listsize;
		gResourceLoader.setPermilage(350+percent);
    }

	gResourceLoader.setPermilage(500);

    for(unsigned int i=0 ; i<4 ; i++)
    {
        const int NoSprites = gGraphics.getSpriteVec(i).size();
        for(Uint16 s=0 ; s<NoSprites ; s++)
        {
            gGraphics.getSprite(i,s).applyTransparency();

            percent = (s*250)/NoSprites;
            gResourceLoader.setPermilage(500+percent);
        }
    }

    gResourceLoader.setPermilage(750);

	// Now create special sprites, like those for effects and the doors!
    DeriveSpecialSprites( gGraphics.getTileMap(1), gGraphics.getSpriteVec(0) );
    gResourceLoader.setPermilage(800);

	// Here special Effects are applied, only when the option is enabled for it
	if(gVideoDriver.getSpecialFXConfig())
		ApplySpecialFX();

    gResourceLoader.setPermilage(900);

    // Apply the sprites for player 2,3 and 4
    DerivePlayerSprites( 1,gGraphics.getSpriteVec(1) );
    DerivePlayerSprites( 2,gGraphics.getSpriteVec(2) );
    DerivePlayerSprites( 3,gGraphics.getSpriteVec(3) );
    gResourceLoader.setPermilage(1000);


	return true;
}
示例#8
0
文件: SDL_render.c 项目: phossy/bloq
SDL_Texture *
SDL_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface)
{
    const SDL_PixelFormat *fmt;
    SDL_bool needAlpha;
    Uint32 i;
    Uint32 format;
    SDL_Texture *texture;

    CHECK_RENDERER_MAGIC(renderer, NULL);

    if (!surface) {
        SDL_SetError("SDL_CreateTextureFromSurface() passed NULL surface");
        return NULL;
    }

    /* See what the best texture format is */
    fmt = surface->format;
    if (fmt->Amask || SDL_GetColorKey(surface, NULL) == 0) {
        needAlpha = SDL_TRUE;
    } else {
        needAlpha = SDL_FALSE;
    }
    format = renderer->info.texture_formats[0];
    for (i = 0; i < renderer->info.num_texture_formats; ++i) {
        if (!SDL_ISPIXELFORMAT_FOURCC(renderer->info.texture_formats[i]) &&
            SDL_ISPIXELFORMAT_ALPHA(renderer->info.texture_formats[i]) == needAlpha) {
            format = renderer->info.texture_formats[i];
            break;
        }
    }

    texture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_STATIC,
                                surface->w, surface->h);
    if (!texture) {
        return NULL;
    }

    if (format == surface->format->format) {
        if (SDL_MUSTLOCK(surface)) {
            SDL_LockSurface(surface);
            SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch);
            SDL_UnlockSurface(surface);
        } else {
            SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch);
        }
    } else {
        SDL_PixelFormat *dst_fmt;
        SDL_Surface *temp = NULL;

        /* Set up a destination surface for the texture update */
        dst_fmt = SDL_AllocFormat(format);
        temp = SDL_ConvertSurface(surface, dst_fmt, 0);
        SDL_FreeFormat(dst_fmt);
        if (temp) {
            SDL_UpdateTexture(texture, NULL, temp->pixels, temp->pitch);
            SDL_FreeSurface(temp);
        } else {
            SDL_DestroyTexture(texture);
            return NULL;
        }
    }

    {
        Uint8 r, g, b, a;
        SDL_BlendMode blendMode;

        SDL_GetSurfaceColorMod(surface, &r, &g, &b);
        SDL_SetTextureColorMod(texture, r, g, b);

        SDL_GetSurfaceAlphaMod(surface, &a);
        SDL_SetTextureAlphaMod(texture, a);

        if (SDL_GetColorKey(surface, NULL) == 0) {
            /* We converted to a texture with alpha format */
            SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
        } else {
            SDL_GetSurfaceBlendMode(surface, &blendMode);
            SDL_SetTextureBlendMode(texture, blendMode);
        }
    }
    return texture;
}
示例#9
0
void UnlockScreen()
{
	if(SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen);

    SDL_Flip(screen);
}
示例#10
0
文件: image.cpp 项目: Aethyra/Client
Image* Image::merge(Image* image, const int x, const int y)
{
    SDL_Surface* surface = new SDL_Surface(*(image->mImage));

    Uint32 surface_pix, cur_pix;
    Uint8 r, g, b, a, p_r, p_g, p_b, p_a;
    double f_a, f_ca, f_pa;
    SDL_PixelFormat *current_fmt = mImage->format;
    SDL_PixelFormat *surface_fmt = surface->format;
    int current_offset, surface_offset;
    int offsetX = 0, offsetY = 0;

    if (SDL_MUSTLOCK(mImage))
    {
        SDL_LockSurface(surface);
        SDL_LockSurface(mImage);
    }

    // for each pixel lines of a source image
    for (offsetY = (y > 0 ? 0 : -y); offsetY < image->getHeight() &&
                    y + offsetY < getHeight(); offsetY++)
    {
        for (offsetX = (x > 0 ? 0 : -x); offsetX < image->getWidth() &&
                        x + offsetX < getWidth(); offsetX++)
        {
            // Computing offset on both images
            current_offset = (y + offsetY) * getWidth() + x + offsetX;
            surface_offset = offsetY * surface->w + offsetX;

            // Retrieving a pixel to merge
            surface_pix = ((Uint32*) surface->pixels)[surface_offset];
            cur_pix = ((Uint32*) mImage->pixels)[current_offset];

            // Retreiving each channel of the pixel using pixel format
            r = (Uint8)(((surface_pix & surface_fmt->Rmask) >> 
                          surface_fmt->Rshift) << surface_fmt->Rloss);
            g = (Uint8)(((surface_pix & surface_fmt->Gmask) >>
                          surface_fmt->Gshift) << surface_fmt->Gloss);
            b = (Uint8)(((surface_pix & surface_fmt->Bmask) >>
                          surface_fmt->Bshift) << surface_fmt->Bloss);
            a = (Uint8)(((surface_pix & surface_fmt->Amask) >>
                          surface_fmt->Ashift) << surface_fmt->Aloss);

            // Retreiving previous alpha value
            p_a = (Uint8)(((cur_pix & current_fmt->Amask) >>
                            current_fmt->Ashift) << current_fmt->Aloss);

            // new pixel with no alpha or nothing on previous pixel
            if (a == SDL_ALPHA_OPAQUE || (p_a == 0 && a > 0))
                ((Uint32 *)(surface->pixels))[current_offset] = 
                    SDL_MapRGBA(current_fmt, r, g, b, a);
            else if (a > 0) 
            { // alpha is lower => merge color with previous value
                f_a = (double) a / 255.0;
                f_ca = 1.0 - f_a;
                f_pa = (double) p_a / 255.0;
                p_r = (Uint8)(((cur_pix & current_fmt->Rmask) >> 
                                current_fmt->Rshift) << current_fmt->Rloss);
                p_g = (Uint8)(((cur_pix & current_fmt->Gmask) >>
                                current_fmt->Gshift) << current_fmt->Gloss);
                p_b = (Uint8)(((cur_pix & current_fmt->Bmask) >>
                                current_fmt->Bshift) << current_fmt->Bloss);
                r = (Uint8)((double) p_r * f_ca * f_pa + (double)r * f_a);
                g = (Uint8)((double) p_g * f_ca * f_pa + (double)g * f_a);
                b = (Uint8)((double) p_b * f_ca * f_pa + (double)b * f_a);
                a = (a > p_a ? a : p_a);
               ((Uint32 *)(surface->pixels))[current_offset] =
                   SDL_MapRGBA(current_fmt, r, g, b, a);
            }
        }
    }
示例#11
0
文件: spectrogram.c 项目: petersn/tsr
void DrawScreen(SDL_Surface* screen, Audio *audio, int xx)
{

    if(SDL_MUSTLOCK(screen))
    {
        if(SDL_LockSurface(screen) < 0) return;
    }

    int ii, xs, ys;
    Real value;
    int red, green, blue;

    for (ii=0; ii<(HEIGHT/Y_STRETCH); ii++) {
        value = frequency_component( audio, frequency( FREQ_BASE + (((double)(ii*Y_STRETCH)) * FREQ_MULT) ) );
#ifdef FORMAT_AMP
        value = value * (Real)ii;
#endif
        ((Real *)fourier->data)[ii] = value;
    }

#ifdef NORMALIZE_FOURIER
    normalize( fourier );
    audio_scale( fourier, 20000.0 );
#endif

    for (ii=0; ii<(HEIGHT/Y_STRETCH); ii++) {
        value = ((Real *)fourier->data)[ii];
#ifdef SQUARE_SUPPRESS
        value *= 0.001;
        value *= value;
#endif

        value *= 0.001;

#ifndef SQUARE_SUPPRESS
        if (value < 0) value = -value;
#endif
/*
#ifdef FORMANT_AMP
        value *= (Real)ii;
#endif
*/

          // If capturing, sum the frequencies
        if (capturing) {
            ((Real *)captured->data)[ii] += value;
            captured_slices++;
        }

        red   = (int)value;
        green = 0;
        blue  = 0;
        if (red > 16000) {
            red = 0;
            green = 255;
            blue = 0;
        } else if (red > 255) {
            green = (int)((value-255.0)/20.0);
            if (blue > 512) {
                blue  = (int)((value-512.0)/100.0);
            }
            red   = 255;
        }

          // x stretch
        for (xs=0; xs<X_STRETCH; xs++) {
            for (ys=0; ys<Y_STRETCH; ys++) {
                setpixel(screen, xx+xs, (HEIGHT-1)-(ii*Y_STRETCH)-ys, red, green, blue);
            }
        }

        if (xx+X_STRETCH < WIDTH-X_STRETCH) {
            for (ys=Y_STRETCH; ys<HEIGHT; ys++) {
                if (windowing) {
                    setpixel(screen, xx+X_STRETCH, ys, 0, 0, 255);
                } else {
                    setpixel(screen, xx+X_STRETCH, ys, 0, 255, 0);
                }
            }
        }

    }

    if(SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen);

    SDL_Flip(screen);
}
示例#12
0
文件: image.cpp 项目: Aethyra/Client
Image *Image::load(SDL_Surface *tmpImage)
{
#ifdef USE_OPENGL
    if (mUseOpenGL)
    {
        // Flush current error flag.
        glGetError();

        int width = tmpImage->w;
        int height = tmpImage->h;
        int realWidth = powerOfTwo(width);
        int realHeight = powerOfTwo(height);

        if (realWidth < width || realHeight < height)
        {
            logger->log("Warning: image too large, cropping to %dx%d texture!",
                    tmpImage->w, tmpImage->h);
        }

        // Make sure the alpha channel is not used, but copied to destination
        SDL_SetAlpha(tmpImage, 0, SDL_ALPHA_OPAQUE);

        // Determine 32-bit masks based on byte order
        Uint32 rmask, gmask, bmask, amask;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
        rmask = 0xff000000;
        gmask = 0x00ff0000;
        bmask = 0x0000ff00;
        amask = 0x000000ff;
#else
        rmask = 0x000000ff;
        gmask = 0x0000ff00;
        bmask = 0x00ff0000;
        amask = 0xff000000;
#endif

        SDL_Surface *oldImage = tmpImage;
        tmpImage = SDL_CreateRGBSurface(SDL_SWSURFACE, realWidth, realHeight,
                                        32, rmask, gmask, bmask, amask);

        if (!tmpImage)
        {
            logger->log("Error, image convert failed: out of memory");
            return NULL;
        }

        SDL_BlitSurface(oldImage, NULL, tmpImage, NULL);

        GLuint texture;
        glGenTextures(1, &texture);
        OpenGLGraphics::bindTexture(mTextureType, texture);

        if (SDL_MUSTLOCK(tmpImage))
            SDL_LockSurface(tmpImage);

        glTexImage2D(mTextureType, 0, 4, tmpImage->w, tmpImage->h,
                     0, GL_RGBA, GL_UNSIGNED_BYTE, tmpImage->pixels);

        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
        glTexParameteri(mTextureType, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(mTextureType, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        if (SDL_MUSTLOCK(tmpImage))
            SDL_UnlockSurface(tmpImage);

        SDL_FreeSurface(tmpImage);

        GLenum error = glGetError();
        if (error)
        {
            std::string errmsg = "Unknown error";
            switch (error)
            {
                case GL_INVALID_ENUM:
                    errmsg = "GL_INVALID_ENUM";
                    break;
                case GL_INVALID_VALUE:
                    errmsg = "GL_INVALID_VALUE";
                    break;
                case GL_INVALID_OPERATION:
                    errmsg = "GL_INVALID_OPERATION";
                    break;
                case GL_STACK_OVERFLOW:
                    errmsg = "GL_STACK_OVERFLOW";
                    break;
                case GL_STACK_UNDERFLOW:
                    errmsg = "GL_STACK_UNDERFLOW";
                    break;
                case GL_OUT_OF_MEMORY:
                    errmsg = "GL_OUT_OF_MEMORY";
                    break;
            }
            logger->log("Error: Image GL import failed: %s", errmsg.c_str());
            return NULL;
        }

        return new Image(texture, width, height, realWidth, realHeight);
    }
#endif

    bool hasAlpha = false;

    Uint8* imageAlphas = new Uint8[tmpImage->w * tmpImage->h];
    if (tmpImage->format->BitsPerPixel == 32)
    {
        // Figure out whether the image uses its alpha layer
        for (int i = 0; i < tmpImage->w * tmpImage->h; ++i)
        {
            Uint8 r, g, b, a;
            SDL_GetRGBA(((Uint32*) tmpImage->pixels)[i],
                          tmpImage->format, &r, &g, &b, &a);

            imageAlphas[i] = a;

            if (a != 255)
                hasAlpha = true;
        }
    }

    SDL_Surface *image;

    // Convert the surface to the current display format
    if (hasAlpha)
        image = SDL_DisplayFormatAlpha(tmpImage);
    else
        image = SDL_DisplayFormat(tmpImage);

    if (!image)
    {
        logger->log("Error: Image convert failed.");
        delete [] imageAlphas;
        return NULL;
    }

    return new Image(image, imageAlphas);
}
示例#13
0
static int
SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * texture,
                const SDL_Rect * srcrect, const SDL_Rect * final_rect,
                const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip)
{
    SDL_Surface *src = (SDL_Surface *) texture->driverdata;
    SDL_Rect tmp_rect;
    SDL_Surface *src_clone, *src_rotated, *src_scaled;
    SDL_Surface *mask = NULL, *mask_rotated = NULL;
    int retval = 0, dstwidth, dstheight, abscenterx, abscentery;
    double cangle, sangle, px, py, p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y;
    SDL_BlendMode blendmode;
    Uint8 alphaMod, rMod, gMod, bMod;
    int applyModulation = SDL_FALSE;
    int blitRequired = SDL_FALSE;
    int isOpaque = SDL_FALSE;

    if (!surface) {
        return -1;
    }

    tmp_rect.x = 0;
    tmp_rect.y = 0;
    tmp_rect.w = final_rect->w;
    tmp_rect.h = final_rect->h;

    /* It is possible to encounter an RLE encoded surface here and locking it is
     * necessary because this code is going to access the pixel buffer directly.
     */
    if (SDL_MUSTLOCK(src)) {
        SDL_LockSurface(src);
    }

    /* Clone the source surface but use its pixel buffer directly.
     * The original source surface must be treated as read-only.
     */
    src_clone = SDL_CreateRGBSurfaceFrom(src->pixels, src->w, src->h, src->format->BitsPerPixel, src->pitch,
                                         src->format->Rmask, src->format->Gmask,
                                         src->format->Bmask, src->format->Amask);
    if (src_clone == NULL) {
        if (SDL_MUSTLOCK(src)) {
            SDL_UnlockSurface(src);
        }
        return -1;
    }

    SDL_GetSurfaceBlendMode(src, &blendmode);
    SDL_GetSurfaceAlphaMod(src, &alphaMod);
    SDL_GetSurfaceColorMod(src, &rMod, &gMod, &bMod);

    /* SDLgfx_rotateSurface only accepts 32-bit surfaces with a 8888 layout. Everything else has to be converted. */
    if (src->format->BitsPerPixel != 32 || SDL_PIXELLAYOUT(src->format->format) != SDL_PACKEDLAYOUT_8888 || !src->format->Amask) {
        blitRequired = SDL_TRUE;
    }

    /* If scaling and cropping is necessary, it has to be taken care of before the rotation. */
    if (!(srcrect->w == final_rect->w && srcrect->h == final_rect->h && srcrect->x == 0 && srcrect->y == 0)) {
        blitRequired = SDL_TRUE;
    }

    /* srcrect is not selecting the whole src surface, so cropping is needed */
    if (!(srcrect->w == src->w && srcrect->h == src->h && srcrect->x == 0 && srcrect->y == 0)) {
        blitRequired = SDL_TRUE;
    }

    /* The color and alpha modulation has to be applied before the rotation when using the NONE and MOD blend modes. */
    if ((blendmode == SDL_BLENDMODE_NONE || blendmode == SDL_BLENDMODE_MOD) && (alphaMod & rMod & gMod & bMod) != 255) {
        applyModulation = SDL_TRUE;
        SDL_SetSurfaceAlphaMod(src_clone, alphaMod);
        SDL_SetSurfaceColorMod(src_clone, rMod, gMod, bMod);
    }

    /* Opaque surfaces are much easier to handle with the NONE blend mode. */
    if (blendmode == SDL_BLENDMODE_NONE && !src->format->Amask && alphaMod == 255) {
        isOpaque = SDL_TRUE;
    }

    /* The NONE blend mode requires a mask for non-opaque surfaces. This mask will be used
     * to clear the pixels in the destination surface. The other steps are explained below.
     */
    if (blendmode == SDL_BLENDMODE_NONE && !isOpaque) {
        mask = SDL_CreateRGBSurface(0, final_rect->w, final_rect->h, 32,
                                    0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
        if (mask == NULL) {
            retval = -1;
        } else {
            SDL_SetSurfaceBlendMode(mask, SDL_BLENDMODE_MOD);
        }
    }

    /* Create a new surface should there be a format mismatch or if scaling, cropping,
     * or modulation is required. It's possible to use the source surface directly otherwise.
     */
    if (!retval && (blitRequired || applyModulation)) {
        SDL_Rect scale_rect = tmp_rect;
        src_scaled = SDL_CreateRGBSurface(0, final_rect->w, final_rect->h, 32,
                                          0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
        if (src_scaled == NULL) {
            retval = -1;
        } else {
            SDL_SetSurfaceBlendMode(src_clone, SDL_BLENDMODE_NONE);
            retval = SDL_BlitScaled(src_clone, srcrect, src_scaled, &scale_rect);
            SDL_FreeSurface(src_clone);
            src_clone = src_scaled;
            src_scaled = NULL;
        }
    }

    /* SDLgfx_rotateSurface is going to make decisions depending on the blend mode. */
    SDL_SetSurfaceBlendMode(src_clone, blendmode);

    if (!retval) {
        SDLgfx_rotozoomSurfaceSizeTrig(tmp_rect.w, tmp_rect.h, angle, &dstwidth, &dstheight, &cangle, &sangle);
        src_rotated = SDLgfx_rotateSurface(src_clone, angle, dstwidth/2, dstheight/2, (texture->scaleMode == SDL_ScaleModeNearest) ? 0 : 1, flip & SDL_FLIP_HORIZONTAL, flip & SDL_FLIP_VERTICAL, dstwidth, dstheight, cangle, sangle);
        if (src_rotated == NULL) {
            retval = -1;
        }
        if (!retval && mask != NULL) {
            /* The mask needed for the NONE blend mode gets rotated with the same parameters. */
            mask_rotated = SDLgfx_rotateSurface(mask, angle, dstwidth/2, dstheight/2, SDL_FALSE, 0, 0, dstwidth, dstheight, cangle, sangle);
            if (mask_rotated == NULL) {
                retval = -1;
            }
        }
        if (!retval) {
            /* Find out where the new origin is by rotating the four final_rect points around the center and then taking the extremes */
            abscenterx = final_rect->x + (int)center->x;
            abscentery = final_rect->y + (int)center->y;
            /* Compensate the angle inversion to match the behaviour of the other backends */
            sangle = -sangle;

            /* Top Left */
            px = final_rect->x - abscenterx;
            py = final_rect->y - abscentery;
            p1x = px * cangle - py * sangle + abscenterx;
            p1y = px * sangle + py * cangle + abscentery;

            /* Top Right */
            px = final_rect->x + final_rect->w - abscenterx;
            py = final_rect->y - abscentery;
            p2x = px * cangle - py * sangle + abscenterx;
            p2y = px * sangle + py * cangle + abscentery;

            /* Bottom Left */
            px = final_rect->x - abscenterx;
            py = final_rect->y + final_rect->h - abscentery;
            p3x = px * cangle - py * sangle + abscenterx;
            p3y = px * sangle + py * cangle + abscentery;

            /* Bottom Right */
            px = final_rect->x + final_rect->w - abscenterx;
            py = final_rect->y + final_rect->h - abscentery;
            p4x = px * cangle - py * sangle + abscenterx;
            p4y = px * sangle + py * cangle + abscentery;

            tmp_rect.x = (int)MIN(MIN(p1x, p2x), MIN(p3x, p4x));
            tmp_rect.y = (int)MIN(MIN(p1y, p2y), MIN(p3y, p4y));
            tmp_rect.w = dstwidth;
            tmp_rect.h = dstheight;

            /* The NONE blend mode needs some special care with non-opaque surfaces.
             * Other blend modes or opaque surfaces can be blitted directly.
             */
            if (blendmode != SDL_BLENDMODE_NONE || isOpaque) {
                if (applyModulation == SDL_FALSE) {
                    /* If the modulation wasn't already applied, make it happen now. */
                    SDL_SetSurfaceAlphaMod(src_rotated, alphaMod);
                    SDL_SetSurfaceColorMod(src_rotated, rMod, gMod, bMod);
                }
                retval = SDL_BlitSurface(src_rotated, NULL, surface, &tmp_rect);
            } else {
                /* The NONE blend mode requires three steps to get the pixels onto the destination surface.
                 * First, the area where the rotated pixels will be blitted to get set to zero.
                 * This is accomplished by simply blitting a mask with the NONE blend mode.
                 * The colorkey set by the rotate function will discard the correct pixels.
                 */
                SDL_Rect mask_rect = tmp_rect;
                SDL_SetSurfaceBlendMode(mask_rotated, SDL_BLENDMODE_NONE);
                retval = SDL_BlitSurface(mask_rotated, NULL, surface, &mask_rect);
                if (!retval) {
                    /* The next step copies the alpha value. This is done with the BLEND blend mode and
                     * by modulating the source colors with 0. Since the destination is all zeros, this
                     * will effectively set the destination alpha to the source alpha.
                     */
                    SDL_SetSurfaceColorMod(src_rotated, 0, 0, 0);
                    mask_rect = tmp_rect;
                    retval = SDL_BlitSurface(src_rotated, NULL, surface, &mask_rect);
                    if (!retval) {
                        /* The last step gets the color values in place. The ADD blend mode simply adds them to
                         * the destination (where the color values are all zero). However, because the ADD blend
                         * mode modulates the colors with the alpha channel, a surface without an alpha mask needs
                         * to be created. This makes all source pixels opaque and the colors get copied correctly.
                         */
                        SDL_Surface *src_rotated_rgb;
                        src_rotated_rgb = SDL_CreateRGBSurfaceFrom(src_rotated->pixels, src_rotated->w, src_rotated->h,
                                                                   src_rotated->format->BitsPerPixel, src_rotated->pitch,
                                                                   src_rotated->format->Rmask, src_rotated->format->Gmask,
                                                                   src_rotated->format->Bmask, 0);
                        if (src_rotated_rgb == NULL) {
                            retval = -1;
                        } else {
                            SDL_SetSurfaceBlendMode(src_rotated_rgb, SDL_BLENDMODE_ADD);
                            retval = SDL_BlitSurface(src_rotated_rgb, NULL, surface, &tmp_rect);
                            SDL_FreeSurface(src_rotated_rgb);
                        }
                    }
                }
                SDL_FreeSurface(mask_rotated);
            }
            if (src_rotated != NULL) {
                SDL_FreeSurface(src_rotated);
            }
        }
    }

    if (SDL_MUSTLOCK(src)) {
        SDL_UnlockSurface(src);
    }
    if (mask != NULL) {
        SDL_FreeSurface(mask);
    }
    if (src_clone != NULL) {
        SDL_FreeSurface(src_clone);
    }
    return retval;
}
示例#14
0
void DrawGradientText( const char* text, _sge_TTFont* font, int y, SDL_Surface* target, bool a_bTranslate )
{
	int i;

	if ( a_bTranslate )
	{
		text = Translate( text );
	}

	// 1. CREATE OFFSCREEN SURFACE
	
	SDL_Rect size = sge_TTF_TextSize( font, (char*)text );
	size.w += 2;
	size.h += 2;
	size.x = 320 - size.w / 2;
	if ( size.x < 0 ) size.x = 0;
	size.y = y;
	SDL_Surface* surface = SDL_CreateRGBSurface( SDL_SRCCOLORKEY, size.w, size.h, 8, 0,0,0,0 );


	if ( NULL == surface )
	{
		debug( "DrawGradientText: Couldn't allocate %d by %d surface!\n", size.w, size.h );
		return;
	}

	// 2. SET OFFSCREEN SURFACE COLORS

	SDL_SetColorKey( surface, SDL_SRCCOLORKEY, 0 );
	SDL_Color colors[256];
	colors[0].r = colors[0].g = colors[0].b = 0;
	colors[1] = colors[0];

	// The rest is red->yellow gradient.

	for ( i=2; i<255; ++i )
	{
		int j = i > 25 ? i-25 : 0;
		colors[i].r = 255;
		colors[i].g = 255-j;
		colors[i].b = 0;
	}

	SDL_SetColors( surface, colors, 0, 256 );

	// 3. DRAW TEXT, APPLY BORDER, APPLY GRADIENT.

	int y1 = sge_TTF_FontAscent(font);
	sge_tt_textout( surface, font, text,
		1, y1, 255, 0, 255);


	if ( SDL_MUSTLOCK(surface) ) SDL_LockSurface(surface);
	for ( y=1; y<size.h-1; ++y )
	{
		int color = 254 * y / (size.h-1) + 1;
		unsigned char *p0, *p1, *p2;
		p1 = (unsigned char*) surface->pixels;
		p1 += surface->pitch * y + 1;
		p0 = p1 - surface->pitch;
		p2 = p1 + surface->pitch;
		
		for ( int x=1; x<size.w-1; ++x, ++p0, ++p1, ++p2 )
		{
			if ( *p1 > 2 )
			{
				*p1 = color;
			}
			else
			{
				if ( (*(p1-1) > 2) || (*(p1+1) > 2) || *p0 > 2 || *p2 > 2 )
				{
					*p1 = 1;
				}
			}
		}
	}
	if ( SDL_MUSTLOCK(surface) ) SDL_UnlockSurface(surface);

	// 4. FINALLY

	SDL_BlitSurface( surface, NULL, target, &size );
	SDL_FreeSurface( surface );
	SDL_UpdateRect( target, size.x, size.y, size.w, size.h );
}
示例#15
0
// Draw a string in the specified font
void BaseEngine::DrawString(int iX, int iY, const char* pText, 
							unsigned int uiColour, Font* pFont, SDL_Surface* pTarget )
{
	if ( pTarget == NULL )
		pTarget = m_pActualScreen;

	if ( pFont == NULL )
		pFont = g_pMainFont;

	if ( m_bInsideDraw )
		if (SDL_MUSTLOCK(m_pActualScreen)) 
			SDL_UnlockSurface(m_pActualScreen);

	SDL_Color color = { (uiColour&0xff0000)>>16, (uiColour&0xff00)>>8, (uiColour&0xff), 0 };

	if ( ( pFont != NULL ) && ( pFont->GetFont() != NULL ) )
	{
		SDL_Surface *sText = TTF_RenderText_Solid( pFont->GetFont(), pText, color );
		SDL_Rect rcDest = {iX,iY,0,0};

		SDL_BlitSurface( sText, NULL, pTarget, &rcDest );
		SDL_FreeSurface( sText );
	}

	if ( m_bInsideDraw )
		if (SDL_MUSTLOCK(m_pActualScreen))
			SDL_LockSurface(m_pActualScreen);
}


// Draw a triangle, as two vertical sided regions.
void BaseEngine::DrawTriangle(
		double fX1, double fY1,
		double fX2, double fY2,
		double fX3, double fY3, 
		unsigned int uiColour, 
		SDL_Surface* pTarget )
{
	if ( pTarget == NULL )
		pTarget = m_pActualScreen;

	// Ensure order is 1 2 3 from left to right
	if ( fX1 > fX2 ) { Swap( fX1,fX2 ); Swap( fY1,fY2 ); } // Bigger of 1 and 2 is in position 2
	if ( fX2 > fX3 ) { Swap( fX2,fX3 ); Swap( fY2,fY3 ); } // Bigger of new 2 and 3 is in position 3
	if ( fX1 > fX2 ) { Swap( fX1,fX2 ); Swap( fY1,fY2 ); } // Bigger of 1 and new 2 is in position 2

	if ( fX1 == fX2 )
		DrawVerticalSidedRegion( fX1, fX3, fY1, fY3, fY2, fY3, uiColour, pTarget );
	else if ( fX2 == fX3 )
		DrawVerticalSidedRegion( fX1, fX3, fY1, fY2, fY1, fY3, uiColour, pTarget );
	else
	{
		// Split into two triangles. Find position on line 1-3 to split at
		double dSplitPointY = (double)fY1 + 
			(   ( (double)((fX2-fX1)*(fY3-fY1)) )
			/ (double)(fX3-fX1)   );
		DrawVerticalSidedRegion( fX1, fX2, fY1, fY2, fY1, dSplitPointY, uiColour, pTarget );
		DrawVerticalSidedRegion( fX2, fX3, fY2, fY3, dSplitPointY, fY3, uiColour, pTarget );
	}
}


// Draw a vertical sided region.
// If two points are the same then it is a triangle.
// To do an arbitrary triangle, just draw two next to each other, one for left and one for right.
void BaseEngine::DrawVerticalSidedRegion(
         double fX1, double fX2,// X positions
         double fY1a, double fY2a, // Start y positions for x1 and x2
         double fY1b, double fY2b, // End y positions for x1 and x2
         unsigned int uiColour,
         SDL_Surface* pTarget)
{
     if ( pTarget == NULL )
         pTarget = m_pActualScreen;

     // Ensure X1<  X2, otherwise steps will go wrong!
     // Switch the points if x and y are wrong way round
     if ( fX2<  fX1 ) { Swap(fX1,fX2); Swap(fY1a,fY2a); Swap(fY1b,fY2b);  }

     int iXStart = (int)(fX1+0.5);
     int iXEnd = (int)(fX2+0.5);

     // If integer x positions are the same then avoid floating point inaccuracy problems by a special case
     if ( iXStart == iXEnd )
     {
         int iYStart = (int)(fY1a+0.5);
         int iYEnd = (int)(fY2a+0.5);
         for ( int iY = iYStart ; iY<= iYEnd ; iY++ )
             SafeSetPixel( iXStart, iY, uiColour, pTarget );
     }
     else
     {
         // Draw left hand side
         int iYStart = (int)(fY1a+0.5);
         int iYEnd = (int)(fY1b+0.5);
         if ( iYStart>  iYEnd ) Swap( iYStart, iYEnd );
         //printf( "Firstline %d to %d (%f to %f)\n", iYStart, iYEnd, fY1a, fY1b );
         for ( int iY = iYStart ; iY<= iYEnd ; iY++ )
             SafeSetPixel( iXStart, iY, uiColour, pTarget );

         // Draw the middle
         for ( int iX = iXStart+1 ; iX<  iXEnd ; iX++ )
         {
             double fYStart = fY1a + ( (((double)iX)-fX1)*(fY2a-fY1a)) /(fX2-fX1);
             double fYEnd = fY1b + ((((double)iX)-fX1)*(fY2b-fY1b))/(fX2-fX1);
             if ( fYEnd<  fYStart ) Swap( fYStart, fYEnd );
             int iYStart = (int)(fYStart+0.5);
             int iYEnd = (int)(fYEnd+0.5);
             //printf( "Line from %d to %d (%f to %f)\n", iYStart, iYEnd, fYStart, fYEnd );
             for ( int iY = iYStart ; iY<= iYEnd ; iY++ )
                 SafeSetPixel( iX, iY, uiColour, pTarget );
         }

         // Draw right hand side
         iYStart = (int)(fY2a+0.5);
         iYEnd = (int)(fY2b+0.5);
         if ( iYStart>  iYEnd ) Swap( iYStart, iYEnd );
         //printf( "Last line %d to %d (%f to %f)\n", iYStart, iYEnd, fY2a, fY2b );
         for ( int iY = iYStart ; iY<= iYEnd ; iY++ )
             SafeSetPixel( iXEnd, iY, uiColour, pTarget );
     }
}



// Draw a rectangle on the specified surface
void BaseEngine::DrawRectangle(int iX1, int iY1, int iX2, int iY2, 
									  unsigned int uiColour, SDL_Surface* pTarget)
{
	if ( pTarget == NULL )
		pTarget = m_pActualScreen;

	if ( iX2 < iX1 ) { int t = iX1; iX1 = iX2; iX2 = t; }
	if ( iY2 < iY1 ) { int t = iY1; iY1 = iY2; iY2 = t; }

	for ( int iX = iX1 ; iX <= iX2 ; iX++ )
		for ( int iY = iY1 ; iY <= iY2 ; iY++ )
			SafeSetPixel( iX, iY, uiColour, pTarget );
}

// Draw an oval on the specified surface
void BaseEngine::DrawOval(int iX1, int iY1, int iX2, int iY2, 
									unsigned int uiColour, SDL_Surface* pTarget)
{
	if ( pTarget == NULL )
		pTarget = m_pActualScreen;

	if ( iX2 < iX1 ) { int t = iX1; iX1 = iX2; iX2 = t; }
	if ( iY2 < iY1 ) { int t = iY1; iY1 = iY2; iY2 = t; }

	double fCentreX = ((double)(iX2+iX1))/2.0;
	double fCentreY = ((double)(iY2+iY1))/2.0;
	double fXFactor = (double)((iX2-iX1) * (iX2-iX1))/4.0;
	double fYFactor = (double)((iY2-iY1) * (iY2-iY1))/4.0;
	double fDist;
	
	for ( int iX = iX1 ; iX <= iX2 ; iX++ )
		for ( int iY = iY1 ; iY <= iY2 ; iY++ )
		{
			fDist = ((double)iX - fCentreX) * ((double)iX - fCentreX)/fXFactor
				+ ((double)iY - fCentreY) * ((double)iY - fCentreY)/fYFactor;
			if ( fDist <= 1.0 )
				SafeSetPixel( iX, iY, uiColour, pTarget );
		}
}

// Draw an oval on the specified surface
void BaseEngine::DrawHollowOval(	int iX1, int iY1, int iX2, int iY2, 
									int iX3, int iY3, int iX4, int iY4, 
									unsigned int uiColour, SDL_Surface* pTarget)
{
	if ( pTarget == NULL )
		pTarget = m_pActualScreen;

	if ( iX2 < iX1 ) Swap( iX1, iX2 );
	if ( iY2 < iY1 ) Swap( iY1, iY2 );
	if ( iX4 < iX3 ) Swap( iX3, iX4 );
	if ( iY4 < iY3 ) Swap( iY3, iY4 );

	double fCentreX1 = ((double)(iX2+iX1))/2.0;
	double fCentreY1 = ((double)(iY2+iY1))/2.0;
	double fXFactor1 = (double)((iX2-iX1) * (iX2-iX1))/4.0;
	double fYFactor1 = (double)((iY2-iY1) * (iY2-iY1))/4.0;
	double fCentreX2 = ((double)(iX4+iX3))/2.0;
	double fCentreY2 = ((double)(iY4+iY3))/2.0;
	double fXFactor2 = (double)((iX4-iX3) * (iX4-iX3))/4.0;
	double fYFactor2 = (double)((iY4-iY3) * (iY4-iY3))/4.0;
	double fDist1, fDist2;
	
	for ( int iX = iX1 ; iX <= iX2 ; iX++ )
		for ( int iY = iY1 ; iY <= iY2 ; iY++ )
		{
			fDist1 = ((double)iX - fCentreX1) * ((double)iX - fCentreX1)/fXFactor1
				+ ((double)iY - fCentreY1) * ((double)iY - fCentreY1)/fYFactor1;
			fDist2 = ((double)iX - fCentreX2) * ((double)iX - fCentreX2)/fXFactor2
				+ ((double)iY - fCentreY2) * ((double)iY - fCentreY2)/fYFactor2;
			if ( ( fDist1 <= 1.0 ) && ( fDist2 >= 1.0 ) )
				SafeSetPixel( iX, iY, uiColour, pTarget );
		}
}


// Draw a line on the specified surface
void BaseEngine::DrawLine(double fX1, double fY1, double fX2, double fY2, 
						unsigned int uiColour, SDL_Surface* pTarget)
{
	if ( pTarget == NULL )
		pTarget = m_pActualScreen;

	int iX1 = (int)(fX1+0.5);
	int iX2 = (int)(fX2+0.5);
	int iY1 = (int)(fY1+0.5);
	int iY2 = (int)(fY2+0.5);

	int iSteps = (iX2-iX1);
	if ( iSteps < 0 ) iSteps = -iSteps;
	if ( iY2 > iY1 ) iSteps += (iY2-iY1); else iSteps += (iY1-iY2);
	iSteps+=2;

	double fXStep = ((double)(fX2-fX1))/iSteps;
	double fYStep = ((double)(fY2-fY1))/iSteps;

	for ( int i = 0 ; i <= iSteps ; i++ )
	{
		SafeSetPixel( (int)(0.5 + fX1 + fXStep*i), (int)(0.5 + fY1 + fYStep*i), uiColour, pTarget );
	}
}



// Draw a thick line on the specified surface
void BaseEngine::DrawThickLine( double fX1, double fY1, double fX2, double fY2, 
							 unsigned int uiColour, int iThickness, SDL_Surface* pTarget)
{
	if ( pTarget == NULL )
		pTarget = m_pActualScreen;

	if ( iThickness < 2 )
	{ // Go to the quicker draw function
		DrawLine(fX1, fY1, fX2, fY2, uiColour, pTarget);
		return;
	}

	double fAngle1 = GetAngle( fX1, fY1, fX2, fY2 );
	double fAngle1a = fAngle1 - ((5 * M_PI) / 4.0);
	double fAngle1b = fAngle1 + ((5 * M_PI) / 4.0);
	double fRectX1 = fX1 + iThickness * cos(fAngle1a) * 0.5;
	double fRectY1 = fY1 + iThickness * sin(fAngle1a) * 0.5;
	double fRectX2 = fX1 + iThickness * cos(fAngle1b) * 0.5;
	double fRectY2 = fY1 + iThickness * sin(fAngle1b) * 0.5;

	double fAngle2 = fAngle1 + M_PI;
	double fAngle2a = fAngle2 - ((5 * M_PI) / 4.0);
	double fAngle2b = fAngle2 + ((5 * M_PI) / 4.0);
	double fRectX3 = fX2 + iThickness * cos(fAngle2a) * 0.5;
	double fRectY3 = fY2 + iThickness * sin(fAngle2a) * 0.5;
	double fRectX4 = fX2 + iThickness * cos(fAngle2b) * 0.5;
	double fRectY4 = fY2 + iThickness * sin(fAngle2b) * 0.5;

	DrawTriangle( fRectX1, fRectY1, fRectX2, fRectY2, fRectX3, fRectY3, uiColour, pTarget );
	DrawTriangle( fRectX3, fRectY3, fRectX4, fRectY4, fRectX1, fRectY1, uiColour, pTarget );
}



// Draw a polygon on the specified surface
void BaseEngine::DrawPolygon( 
		int iPoints, double* pXArray, double* pYArray,
		unsigned int uiColour, SDL_Surface* pTarget)
{
	if ( pTarget == NULL )
		pTarget = m_pActualScreen;

	if ( iPoints == 1 )
	{
		SafeSetPixel( pXArray[0], pYArray[0], uiColour, pTarget );
		return;
	}

	if ( iPoints == 2 )
	{
		DrawLine( pXArray[0], pYArray[0], pXArray[1], pYArray[1], uiColour, pTarget );
		return;
	}

/*	if ( iPoints == 3 )
	{
		printf( "Draw triangle for points 0, 1, 2 of %d available\n", iPoints );
		DrawTriangle( pXArray[0], pYArray[0], pXArray[1], pYArray[1], pXArray[2], pYArray[2],
				uiColour, pTarget );
		return;
	}
*/

	// Otherwise attempt to eliminate a point by filling the polygon, then call this again
	double fXCentre, fYCentre; //fX1, fX2, fX3, fY1, fY2, fY3;
	int i2, i3;
	double fAngle1, fAngle2, fAngle3;

	for ( int i1 = 0 ; i1 < iPoints ; i1++ )
	{
		i2 = i1 + 1; if ( i2 >= iPoints ) i2 -= iPoints;
		i3 = i1 + 2; if ( i3 >= iPoints ) i3 -= iPoints;
		fXCentre = (pXArray[i1] + pXArray[i2] + pXArray[i3]) / 3.0;
		fYCentre = (pYArray[i1] + pYArray[i2] + pYArray[i3]) / 3.0;
		fAngle1 = GetAngle( fXCentre, fYCentre, pXArray[i1], pYArray[i1] );
		fAngle2 = GetAngle( fXCentre, fYCentre, pXArray[i2], pYArray[i2] );
		fAngle3 = GetAngle( fXCentre, fYCentre, pXArray[i3], pYArray[i3] );
		// Now work out the relative angle positions and make sure all are positive
		fAngle2 -= fAngle1; if ( fAngle2 < 0 ) fAngle2 += 2*M_PI;
		fAngle3 -= fAngle1; if ( fAngle3 < 0 ) fAngle3 += 2*M_PI;
		if ( fAngle2 < fAngle3 )
		{ // Then points are in clockwise order so central one can be eliminated as long as we don't
			// fill an area that we shouldn't
			bool bPointIsWithinTriangle = false;
			if ( iPoints > 3 )
			{ // Need to check that there isn't a point within the area - for convex shapes
				double fLineAngle12 = GetAngle( pXArray[i1], pYArray[i1], pXArray[i2], pYArray[i2] );
				if ( fLineAngle12 < 0 )
					fLineAngle12 += M_PI * 2.0;
				double fLineAngle23 = GetAngle( pXArray[i2], pYArray[i2], pXArray[i3], pYArray[i3] );
				if ( fLineAngle23 < 0 )
					fLineAngle23 += M_PI * 2.0;
				double fLineAngle31 = GetAngle( pXArray[i3], pYArray[i3], pXArray[i1], pYArray[i1] );
				if ( fLineAngle31 < 0 )
					fLineAngle31 += M_PI * 2.0;

				for ( int i = i3+1 ; i != i1 ; i++ )
				{
					if ( i >= iPoints )
					{
						i = 0;
						if ( i1 == 0 )
							break; // From the for loop - finished
					}

					// Otherwise we need to work out whether point i is to right of line  i3 to i1
					double fPointAngle1 = GetAngle( pXArray[i1], pYArray[i1], pXArray[i], pYArray[i] );
					if ( fPointAngle1 < 0 )
						fPointAngle1 += M_PI * 2.0;
					fPointAngle1 -= fLineAngle12;
					if ( fPointAngle1 < 0 )
						fPointAngle1 += M_PI * 2.0;

					double fPointAngle2 = GetAngle( pXArray[i2], pYArray[i2], pXArray[i], pYArray[i] );
					if ( fPointAngle2 < 0 )
						fPointAngle2 += M_PI * 2.0;
					fPointAngle2 -= fLineAngle23;
					if ( fPointAngle2 < 0 )
						fPointAngle2 += M_PI * 2.0;

					double fPointAngle3 = GetAngle( pXArray[i3], pYArray[i3], pXArray[i], pYArray[i] );
					if ( fPointAngle3 < 0 )
						fPointAngle3 += M_PI * 2.0;
					fPointAngle3 -= fLineAngle31;
					if ( fPointAngle3 < 0 )
						fPointAngle3 += M_PI * 2.0;

					if ( ( fPointAngle1 < M_PI ) && ( fPointAngle2 < M_PI ) && ( fPointAngle3 < M_PI ) )
						bPointIsWithinTriangle = true;
				}
			}

			if ( !bPointIsWithinTriangle )
			{// If not then try the next position
				printf( "Draw for points %d, %d, %d of %d available\n", i1, i2, i3, iPoints );
				DrawTriangle( pXArray[i1], pYArray[i1], pXArray[i2], pYArray[i2], 
							pXArray[i3], pYArray[i3], /*GetColour(iPoints)*/uiColour, pTarget );
				// Remove the point i2 and then recurse			
				for ( int i = i2 ; i < (iPoints-1) ; i++ )
				{
					printf( "\tCopy point %d to %d\n", i+1, i );
					pXArray[i] = pXArray[i+1];
					pYArray[i] = pYArray[i+1];
				}
				if ( iPoints > 3 )
					DrawPolygon( iPoints - 1, pXArray, pYArray, uiColour, pTarget );
				return; // Done
			}
		}
	}
}
示例#16
0
bool texture_class::load_spritesheet(std::string file_name, int index_number, int w, int h)
{
    texture_class::ref_number = index_number;
    texture_class::width      = w;
    texture_class::height     = h;
    int             frames_x;
    int             frames_y;
    int             frame_number = 0;
    int             num_sprites  = 0;
    SDL_Surface    *sprite_sheet = NULL;
    SDL_Surface    *temp_surface = NULL;
    int             flags        = 0;
    GLenum          texture_format;
    GLint           number_of_colors;
    bool            return_value = false;
    if ((sprite_sheet = IMG_Load(file_name.c_str())))
    {
        return_value = true;
        frames_x = sprite_sheet->w / texture_class::width;
        frames_y = sprite_sheet->h / texture_class::height;
        num_sprites = frames_x * frames_y;
        texture_class::frame_max = num_sprites-1;
        number_of_colors = sprite_sheet->format->BytesPerPixel;
        if (number_of_colors == 4)
        {
            if (sprite_sheet->format->Rmask == 0x000000ff) texture_format = GL_RGBA;
            else texture_format = GL_BGRA;
        }
        else if (number_of_colors == 3)
        {
            if (sprite_sheet->format->Rmask == 0x000000ff) texture_format = GL_RGB;
            else texture_format = GL_BGR;
        }
        temp_surface = SDL_CreateRGBSurface(flags,texture_class::width-1,texture_class::height-1,sprite_sheet->format->BitsPerPixel,sprite_sheet->format->Rmask,sprite_sheet->format->Gmask,sprite_sheet->format->Bmask,sprite_sheet->format->Amask);
        int32_t     *in_pixels       = (int32_t*)sprite_sheet->pixels;
        int32_t     *out_pixels      = (int32_t*)temp_surface->pixels;
        for (int current_sprite = 0; current_sprite < num_sprites; current_sprite++)
        {
            int out_pixel_count = 0;
            if(SDL_MUSTLOCK(sprite_sheet)) SDL_LockSurface(sprite_sheet);
            for(int y_count = 0; y_count < texture_class::height-1; y_count++)
            {
                for(int x_count = 0; x_count < texture_class::width-1; x_count++)
                {
                    out_pixels[out_pixel_count] = in_pixels[((sprite_sheet->w*y_count)+(((current_sprite)*(texture_class::width))+x_count))];
                    out_pixel_count++;
                }
            }
            if(SDL_MUSTLOCK(sprite_sheet)) SDL_UnlockSurface(sprite_sheet);

            texture_class::frame[frame_number].active = true;
            glGenTextures( 1, &texture_class::frame[frame_number].data);
            glBindTexture( GL_TEXTURE_2D, texture_class::frame[frame_number].data);
            glEnable(GL_BLEND);
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
            glTexImage2D( GL_TEXTURE_2D, 0, number_of_colors, temp_surface->w, temp_surface->h, 0, texture_format, GL_UNSIGNED_BYTE, temp_surface->pixels );
            frame_number++;
        }
    }
    else
    {
        return_value = false;
        SDL_Quit();
    }
    if ( sprite_sheet ) SDL_FreeSurface( sprite_sheet );
    if ( temp_surface ) SDL_FreeSurface( temp_surface );
    return(return_value);
}
示例#17
0
/* CON_AlphaGL() -- sets the alpha channel of an SDL_Surface to the
 * specified value.  Preconditions: the surface in question is RGBA.
 * 0 <= a <= 255, where 0 is transparent and 255 is opaque. */
void CON_AlphaGL(SDL_Surface *s, int alpha) {
	Uint8 val;
	int x, y, w, h;
	Uint32 pixel;
	Uint8 r, g, b, a;
	SDL_PixelFormat *format;
	static char errorPrinted = 0;


	/* debugging assertions -- these slow you down, but hey, crashing sucks */
	if(!s) {
		PRINT_ERROR("NULL Surface passed to CON_AlphaGL\n");
		return;
	}

	/* clamp alpha value to 0...255 */
	if(alpha < SDL_ALPHA_TRANSPARENT)
		val = SDL_ALPHA_TRANSPARENT;
	else if(alpha > SDL_ALPHA_OPAQUE)
		val = SDL_ALPHA_OPAQUE;
	else
		val = alpha;

	/* loop over alpha channels of each pixel, setting them appropriately. */
	w = s->w;
	h = s->h;
	format = s->format;
	switch (format->BytesPerPixel) {
	case 2:
		/* 16-bit surfaces don't seem to support alpha channels. */
		if(!errorPrinted) {
			errorPrinted = 1;
			PRINT_ERROR("16-bit SDL surfaces do not support alpha-blending under OpenGL.\n");
		}
		break;
	case 4: {
			/* we can do this very quickly in 32-bit mode.  24-bit is more
			 * difficult.  And since 24-bit mode is reall the same as 32-bit,
			 * so it usually ends up taking this route too.  Win!  Unroll loop
			 * and use pointer arithmetic for extra speed. */
			int numpixels = h * (w << 2);
			Uint8 *pix = (Uint8 *) (s->pixels);
			Uint8 *last = pix + numpixels;
			Uint8 *pixel;
			if((numpixels & 0x7) == 0)
				for(pixel = pix + 3; pixel < last; pixel += 32)
					*pixel = *(pixel + 4) = *(pixel + 8) = *(pixel + 12) = *(pixel + 16) = *(pixel + 20) = *(pixel + 24) = *(pixel + 28) = val;
			else
				for(pixel = pix + 3; pixel < last; pixel += 4)
					*pixel = val;
			break;
		}
	default:
		/* we have no choice but to do this slowly.  <sigh> */
		for(y = 0; y < h; ++y)
            for(x = 0; x < w; ++x) {
				/* Lock the surface for direct access to the pixels */
				if(SDL_MUSTLOCK(s) && SDL_LockSurface(s) < 0) {
					PRINT_ERROR("Can't lock surface: ");
					fprintf(stderr, "%s\n", SDL_GetError());
					return;
				}
                pixel = DT_GetPixel(s, x, y);
				SDL_GetRGBA(pixel, format, &r, &g, &b, &a);
				pixel = SDL_MapRGBA(format, r, g, b, val);
				SDL_GetRGBA(pixel, format, &r, &g, &b, &a);
				DT_PutPixel(s, x, y, pixel);

				/* unlock surface again */
				if(SDL_MUSTLOCK(s))
					SDL_UnlockSurface(s);
			}
		break;
	}
}
示例#18
0
int IMG_SavePNG_RW(SDL_RWops *src, SDL_Surface *surf,int compression){
#ifdef IMPLEMENT_SAVE_PNG
	png_structp png_ptr;
	png_infop info_ptr;
	SDL_PixelFormat *fmt=NULL;
	SDL_Surface *tempsurf=NULL;
	int ret,funky_format;
	unsigned int i;
#if SDL_VERSION_ATLEAST(2, 0, 0)
	SDL_BlendMode temp_blend;
	bool used_blend = false;
#else
	Uint8 temp_alpha;
	bool used_alpha = false;
#endif
	png_colorp palette;
	Uint8 *palette_alpha=NULL;
	png_byte **row_pointers=NULL;
	png_ptr=NULL;info_ptr=NULL;palette=NULL;ret=-1;
	funky_format=0;
	
	if( !src || !surf) {
		goto savedone; /* Nothing to do. */
	}

	row_pointers=(png_byte **)malloc(surf->h * sizeof(png_byte*));
	if (!row_pointers) { 
		SDL_SetError("Couldn't allocate memory for rowpointers");
		goto savedone;
	}
	
	png_ptr=png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,NULL,NULL);
	if (!png_ptr){
		SDL_SetError("Couldn't allocate memory for PNG file");
		goto savedone;
	}
	info_ptr= png_create_info_struct(png_ptr);
	if (!info_ptr){
		SDL_SetError("Couldn't allocate image information for PNG file");
		goto savedone;
	}
	/* setup custom writer functions */
	png_set_write_fn(png_ptr,(voidp)src,png_write_data,NULL);

	if (setjmp(png_jmpbuf(png_ptr))){
		SDL_SetError("Unknown error writing PNG");
		goto savedone;
	}

	if(compression>Z_BEST_COMPRESSION)
		compression=Z_BEST_COMPRESSION;

	if(compression == Z_NO_COMPRESSION) // No compression
	{
		png_set_filter(png_ptr,0,PNG_FILTER_NONE);
		png_set_compression_level(png_ptr,Z_NO_COMPRESSION);
	}
        else if(compression<0) // Default compression
		png_set_compression_level(png_ptr,Z_DEFAULT_COMPRESSION);
        else
		png_set_compression_level(png_ptr,compression);

	fmt=surf->format;
	if(fmt->BitsPerPixel==8){ /* Paletted */
		png_set_IHDR(png_ptr,info_ptr,
			surf->w,surf->h,8,PNG_COLOR_TYPE_PALETTE,
			PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT,
			PNG_FILTER_TYPE_DEFAULT);
		palette=(png_colorp) malloc(fmt->palette->ncolors * sizeof(png_color));
		if (!palette) {
			SDL_SetError("Couldn't create memory for palette");
			goto savedone;
		}
		for (i=0;i<fmt->palette->ncolors;i++) {
			palette[i].red=fmt->palette->colors[i].r;
			palette[i].green=fmt->palette->colors[i].g;
			palette[i].blue=fmt->palette->colors[i].b;
		}
		png_set_PLTE(png_ptr,info_ptr,palette,fmt->palette->ncolors);
#if SDL_VERSION_ATLEAST(2, 0, 0)
		Uint32 colorkey; 
		if (SDL_GetColorKey(surf, &colorkey) == 0) {
#else
		if (surf->flags&SDL_SRCCOLORKEY) {
			Uint32 colorkey = fmt->colorkey; 
#endif
			palette_alpha=(Uint8 *)malloc((colorkey+1)*sizeof(Uint8));
			if (!palette_alpha) {
				SDL_SetError("Couldn't create memory for palette transparency");
				goto savedone;
			}
			/* FIXME: memset? */
			for (i=0;i<(colorkey+1);i++) {
				palette_alpha[i]=255;
			}
			palette_alpha[colorkey]=0;
			png_set_tRNS(png_ptr,info_ptr,palette_alpha,colorkey+1,NULL);
		}
	}else{ /* Truecolor */
		if (fmt->Amask) {
			png_set_IHDR(png_ptr,info_ptr,
				surf->w,surf->h,8,PNG_COLOR_TYPE_RGB_ALPHA,
				PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT,
				PNG_FILTER_TYPE_DEFAULT);
		} else {
			png_set_IHDR(png_ptr,info_ptr,
				surf->w,surf->h,8,PNG_COLOR_TYPE_RGB,
				PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT,
				PNG_FILTER_TYPE_DEFAULT);
		}
	}
	png_write_info(png_ptr, info_ptr);

	if (fmt->BitsPerPixel==8) { /* Paletted */
		for(i=0;i<surf->h;i++){
			row_pointers[i]= ((png_byte*)surf->pixels) + i*surf->pitch;
		}
		if(SDL_MUSTLOCK(surf)){
			SDL_LockSurface(surf);
		}
		png_write_image(png_ptr, row_pointers);
		if(SDL_MUSTLOCK(surf)){
			SDL_UnlockSurface(surf);
		}
	}else{ /* Truecolor */
		if(fmt->BytesPerPixel==3){
			if(fmt->Amask){ /* check for 24 bit with alpha */
				funky_format=1;
			}else{
				/* Check for RGB/BGR/GBR/RBG/etc surfaces.*/
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
				if(fmt->Rmask!=0xFF0000 
				|| fmt->Gmask!=0x00FF00
				|| fmt->Bmask!=0x0000FF){
#else
				if(fmt->Rmask!=0x0000FF 
				|| fmt->Gmask!=0x00FF00
				|| fmt->Bmask!=0xFF0000){
#endif
					funky_format=1;
				}
			}
		}else if (fmt->BytesPerPixel==4){
			if (!fmt->Amask) { /* check for 32bit but no alpha */
				funky_format=1; 
			}else{
				/* Check for ARGB/ABGR/GBAR/RABG/etc surfaces.*/
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
				if(fmt->Rmask!=0xFF000000
				|| fmt->Gmask!=0x00FF0000
				|| fmt->Bmask!=0x0000FF00
				|| fmt->Amask!=0x000000FF){
#else
				if(fmt->Rmask!=0x000000FF
				|| fmt->Gmask!=0x0000FF00
				|| fmt->Bmask!=0x00FF0000
				|| fmt->Amask!=0xFF000000){
#endif
					funky_format=1;
				}
			}
		}else{ /* 555 or 565 16 bit color */
			funky_format=1;
		}
		if (funky_format) {
			/* Allocate non-funky format, and copy pixeldata in*/
			if(fmt->Amask){
#if SDL_VERSION_ATLEAST(2, 0, 0)
				tempsurf = SDL_CreateRGBSurface(0, surf->w, surf->h, 24, SURFACE_MASK_WITH_ALPHA);
#else
				tempsurf = SDL_CreateRGBSurface(SDL_SWSURFACE, surf->w, surf->h, 24, SURFACE_MASK_WITH_ALPHA);
#endif
			}else{
#if SDL_VERSION_ATLEAST(2, 0, 0)
				tempsurf = SDL_CreateRGBSurface(0, surf->w, surf->h, 24, SURFACE_MASK_WITHOUT_ALPHA);
#else
				tempsurf = SDL_CreateRGBSurface(SDL_SWSURFACE, surf->w, surf->h, 24, SURFACE_MASK_WITHOUT_ALPHA);
#endif
			}
			if(!tempsurf){
				SDL_SetError("Couldn't allocate temp surface");
				goto savedone;
			}
#if SDL_VERSION_ATLEAST(2, 0, 0)
			if(SDL_GetSurfaceBlendMode(surf, &temp_blend) == 0){
				used_blend = true;
				SDL_SetSurfaceBlendMode(surf, SDL_BLENDMODE_NONE);
			}
#else
			if(surf->flags&SDL_SRCALPHA) {
				temp_alpha = fmt->alpha;
					used_alpha = true;
					SDL_SetAlpha(surf,0,255); /* Set for an opaque blit */
			}
#endif
			if(SDL_BlitSurface(surf, NULL, tempsurf, NULL)!=0){
				SDL_SetError("Couldn't blit surface to temp surface");
				SDL_FreeSurface(tempsurf);
				goto savedone;
			}
#if SDL_VERSION_ATLEAST(2, 0, 0)
			if (used_blend) {
				SDL_SetSurfaceBlendMode(surf, temp_blend); /* Restore blend settings*/
			}
#else
			if(used_alpha) {
					SDL_SetAlpha(surf, SDL_SRCALPHA, (Uint8)temp_alpha); /* Restore alpha settings*/
			}
#endif
			for(i=0;i<tempsurf->h;i++){
				row_pointers[i]= ((png_byte*)tempsurf->pixels) + i*tempsurf->pitch;
			}
			if(SDL_MUSTLOCK(tempsurf)){
				SDL_LockSurface(tempsurf);
			}
			png_write_image(png_ptr, row_pointers);
			if(SDL_MUSTLOCK(tempsurf)){
				SDL_UnlockSurface(tempsurf);
			}
			SDL_FreeSurface(tempsurf);
		} else {
			for(i=0;i<surf->h;i++){
				row_pointers[i]= ((png_byte*)surf->pixels) + i*surf->pitch;
			}
			if(SDL_MUSTLOCK(surf)){
				SDL_LockSurface(surf);
			}
			png_write_image(png_ptr, row_pointers);
			if(SDL_MUSTLOCK(surf)){
				SDL_UnlockSurface(surf);
			}
		}
	}

	png_write_end(png_ptr, NULL);
	ret=0; /* got here, so nothing went wrong. YAY! */

savedone: /* clean up and return */
	png_destroy_write_struct(&png_ptr,&info_ptr);
	if (palette) {
		free(palette);
	}
	if (palette_alpha) {
		free(palette_alpha);
	}
	if (row_pointers) {
		free(row_pointers);
	}
	return ret;
#else
	return -1;
#endif
}
示例#19
0
文件: initsdl.c 项目: koo5/lemon-3
SDL_Surface *initsdl(int *w,int *h,int *bppp,Uint32 flags)
{
	// SDL_INIT_EVENTTHREAD
	if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
		fprintf(stderr,"Couldn't initialize SDL: %s\n",SDL_GetError());
		exit( 1 );
	}
	
	SDL_Surface *s;
	static int bpp=0; 
	Uint32 video_flags;
	video_flags = flags;
	int rgb_size[3]={0,0,0};
	printf("yoyoyo\n");
	if (flags& SDL_OPENGL)
	{
/*
	if ( SDL_GetVideoInfo()->vfmt->BitsPerPixel <= 8 ) {
		bpp = 8;
	} else {
		bpp = 16;  // More doesn't seem to work 
	}*/
	bpp=SDL_GetVideoInfo()->vfmt->BitsPerPixel;
	switch (bpp) {
	    case 8:
		rgb_size[0] = 3;
		rgb_size[1] = 3;
		rgb_size[2] = 2;
		break;
	    case 15:
	    case 16:
		rgb_size[0] = 5;
		rgb_size[1] = 5;
		rgb_size[2] = 5;
		break;
            default:
		rgb_size[0] = 8;
		rgb_size[1] = 8;
		rgb_size[2] = 8;
		break;
	}
	SDL_GL_SetAttribute( SDL_GL_RED_SIZE, rgb_size[0] );
	SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, rgb_size[1] );
	SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, rgb_size[2] );
	SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
	SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
	}
	
	video_flags|=(SDL_RESIZABLE|SDL_ANYFORMAT|SDL_DOUBLEBUF);
	
	s= SDL_SetVideoMode( *w, *h, bpp, video_flags );
	if (s == NULL ) {
		fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError());
		SDL_Quit();
		exit(1);
	}
	
#ifdef chaos
	printf("Screen BPP: %d\n", SDL_GetVideoSurface()->format->BitsPerPixel);
	printf("\n");
#ifdef GL

	printf( "Vendor     : %s\n", glGetString( GL_VENDOR ) );
	printf( "Renderer   : %s\n", glGetString( GL_RENDERER ) );
	printf( "Version    : %s\n", glGetString( GL_VERSION ) );
	printf( "Extensions : %s\n", glGetString( GL_EXTENSIONS ) );
	printf("\n");
	int value;
	SDL_GL_GetAttribute( SDL_GL_RED_SIZE, &value );
	printf( "SDL_GL_RED_SIZE: requested %d, got %d\n", rgb_size[0],value);
	SDL_GL_GetAttribute( SDL_GL_GREEN_SIZE, &value );
	printf( "SDL_GL_GREEN_SIZE: requested %d, got %d\n", rgb_size[1],value);
	SDL_GL_GetAttribute( SDL_GL_BLUE_SIZE, &value );
	printf( "SDL_GL_BLUE_SIZE: requested %d, got %d\n", rgb_size[2],value);
	SDL_GL_GetAttribute( SDL_GL_DEPTH_SIZE, &value );
	printf( "SDL_GL_DEPTH_SIZE: requested %d, got %d\n", bpp, value );
	SDL_GL_GetAttribute( SDL_GL_DOUBLEBUFFER, &value );
	printf( "SDL_GL_DOUBLEBUFFER: requested 1, got %d\n", value );
#endif
#endif
	
	printf("mustlock=%i\n", SDL_MUSTLOCK(s));

	const SDL_VideoInfo* m = SDL_GetVideoInfo();
	*w=m->current_w;
	*h=m->current_h;
	*bppp=bpp;
	char * x= (char*)malloc(20);
	if(x&&SDL_VideoDriverName(x,20))
	    printf("Current SDL video driver is %s.\n",x);
    printf("%i x %i\n",*w,*h);
	   


	return s;
}
示例#20
0
文件: fire.c 项目: ckkashyap/pedigree
void scrunlock(void)
{
	if(SDL_MUSTLOCK(thescreen))
		SDL_UnlockSurface(thescreen);
	SDL_UpdateRect(thescreen, 0, 0, 0, 0);
}
示例#21
0
// Does not account for converting luminance...
SDL_Surface * ILAPIENTRY ilutConvertToSDLSurface(unsigned int flags)
{
	SDL_Surface *Bitmap;
	ILuint	i = 0, Pad, BppPal;
	ILubyte	*Dest;

	ilutCurImage = ilGetCurImage();
	if (ilutCurImage == NULL) {
		ilSetError(ILUT_ILLEGAL_OPERATION);
		return NULL;
	}

	InitSDL();

	// Should be IL_BGR(A).
	if (ilutCurImage->Format == IL_RGB || ilutCurImage->Format == IL_RGBA) {
		if (!isBigEndian)
			iluSwapColours();
	}

	if (ilutCurImage->Origin == IL_ORIGIN_LOWER_LEFT)
		iluFlipImage();
	if (ilutCurImage->Type > IL_UNSIGNED_BYTE) {}  // Can't do anything about this right now...
	if (ilutCurImage->Type == IL_BYTE) {}  // Can't do anything about this right now...

	Bitmap = SDL_CreateRGBSurface(flags,ilutCurImage->Width,ilutCurImage->Height,ilutCurImage->Bpp * 8,
					rmask,gmask,bmask,amask);

	if (Bitmap == NULL) {
		return IL_FALSE;
	}

	if (SDL_MUSTLOCK(Bitmap))
		SDL_LockSurface(Bitmap);

	Pad = Bitmap->pitch - ilutCurImage->Bps;
	if (Pad == 0) {
		memcpy(Bitmap->pixels, ilutCurImage->Data, ilutCurImage->SizeOfData);
	}
	else {  // Must pad the lines on some images.
		Dest = Bitmap->pixels;
		for (i = 0; i < ilutCurImage->Height; i++) {
			memcpy(Dest, ilutCurImage->Data + i * ilutCurImage->Bps, ilutCurImage->Bps);
			imemclear(Dest + ilutCurImage->Bps, Pad);
			Dest += Bitmap->pitch;
		}
	}

	if (SDL_MUSTLOCK(Bitmap))
		SDL_UnlockSurface(Bitmap);

	if (ilutCurImage->Bpp == 1) {
		BppPal = ilGetBppPal(ilutCurImage->Pal.PalType);
		switch (ilutCurImage->Pal.PalType)
		{
			case IL_PAL_RGB24:
			case IL_PAL_RGB32:
			case IL_PAL_RGBA32:
				for (i = 0; i < ilutCurImage->Pal.PalSize / BppPal; i++) {
					(Bitmap->format)->palette->colors[i].r = ilutCurImage->Pal.Palette[i*BppPal+0];
					(Bitmap->format)->palette->colors[i].g = ilutCurImage->Pal.Palette[i*BppPal+1];
					(Bitmap->format)->palette->colors[i].b = ilutCurImage->Pal.Palette[i*BppPal+2];
					(Bitmap->format)->palette->colors[i].unused = 255;
				}
				break;
			case IL_PAL_BGR24:
			case IL_PAL_BGR32:
			case IL_PAL_BGRA32:
				for (i = 0; i < ilutCurImage->Pal.PalSize / BppPal; i++) {
					(Bitmap->format)->palette->colors[i].b = ilutCurImage->Pal.Palette[i*BppPal+0];
					(Bitmap->format)->palette->colors[i].g = ilutCurImage->Pal.Palette[i*BppPal+1];
					(Bitmap->format)->palette->colors[i].r = ilutCurImage->Pal.Palette[i*BppPal+2];
					(Bitmap->format)->palette->colors[i].unused = 255;
				}
				break;
			default:
				ilSetError(IL_INTERNAL_ERROR);  // Do anything else?
		}
	}

	return Bitmap;
}
示例#22
0
/**
**	Initialze the video part for SDL.
*/
global void InitVideoSdl(void)
{
    Uint32 flags;

    //	Initialize the SDL library

    if( SDL_WasInit(SDL_INIT_VIDEO) == 0 ) {

	if ( SDL_Init(
#ifdef USE_SDLA
	    // FIXME: doesn't work with SDL SVGAlib
	    SDL_INIT_AUDIO |
#endif
#ifdef DEBUG
	    SDL_INIT_NOPARACHUTE|
#endif
	    SDL_INIT_VIDEO|SDL_INIT_TIMER) < 0 ) {
	    fprintf(stderr,"Couldn't initialize SDL: %s\n", SDL_GetError());
	    exit(1);
	}

	//	Clean up on exit

	atexit(SDL_Quit);

	// Set WindowManager Title

	SDL_WM_SetCaption("FreeCraft","FreeCraft");
    } else {
	if( VideoBpp == 32 && VideoDepth == 24 ) {
	    VideoDepth = 0;
	}
    }

    // Initialize the display

    if( !VideoWidth ) {
	VideoWidth = DEFAULT_VIDEO_WIDTH;
	VideoHeight = DEFAULT_VIDEO_HEIGHT;
    }

    flags = 0;
    // Sam said: better for windows.
    /* SDL_HWSURFACE|SDL_HWPALETTE | */
    if( VideoFullScreen ) {
	flags |= SDL_FULLSCREEN;
    }
#ifdef USE_OPENGL
    flags |= SDL_OPENGL;
#endif
    Screen = SDL_SetVideoMode(VideoWidth, VideoHeight, VideoDepth, flags);

    if ( Screen == NULL ) {
	fprintf(stderr, "Couldn't set %dx%dx%d video mode: %s\n"
		,VideoWidth,VideoHeight,VideoDepth,SDL_GetError());
	exit(1);
    }

    IfDebug(
	if( SDL_MUSTLOCK(Screen) ) {
	    DebugLevel0Fn("Must locksurface!\n");
	}
    );
示例#23
0
void TCOD_sys_console_to_bitmap(void *vbitmap, int console_width, int console_height, char_t *console_buffer, char_t *prev_console_buffer) {
	int x,y;
	SDL_Surface *bitmap=(SDL_Surface *)vbitmap;
	Uint32 sdl_back=0,sdl_fore=0;
	TCOD_color_t fading_color = TCOD_console_get_fading_color();
	int fade = (int)TCOD_console_get_fade();
	bool track_changes=(oldFade == fade && prev_console_buffer);
   	Uint8 bpp = charmap->format->BytesPerPixel;
	char_t *c=&console_buffer[0];
	char_t *oc=&prev_console_buffer[0];
	int hdelta;
	if ( bpp == 4 ) {
		hdelta=(charmap->pitch - TCOD_ctx.font_width*bpp)/4;
	} else {
		hdelta=(charmap->pitch - TCOD_ctx.font_width*bpp);
	}
#ifdef USE_SDL_LOCKS
	if ( SDL_MUSTLOCK( bitmap ) && SDL_LockSurface( bitmap ) < 0 ) return;
#endif
	for (y=0;y<console_height;y++) {
		for (x=0; x<console_width; x++) {
			SDL_Rect srcRect,dstRect;
			bool changed=true;
			if ( c->cf == -1 ) c->cf = TCOD_ctx.ascii_to_tcod[c->c];
			if ( track_changes ) {
				changed=false;
				if ( c->dirt || ascii_updated[ c->c ] || c->back.r != oc->back.r || c->back.g != oc->back.g
					|| c->back.b != oc->back.b || c->fore.r != oc->fore.r
					|| c->fore.g != oc->fore.g || c->fore.b != oc->fore.b
					|| c->c != oc->c || c->cf != oc->cf) {
					changed=true;
				}
			}
			c->dirt=0;
			if ( changed ) {
				TCOD_color_t b=c->back;
				dstRect.x=x*TCOD_ctx.font_width;
				dstRect.y=y*TCOD_ctx.font_height;
				dstRect.w=TCOD_ctx.font_width;
				dstRect.h=TCOD_ctx.font_height;
				/* draw background */
				if ( fade != 255 ) {
					b.r = ((int)b.r) * fade / 255 + ((int)fading_color.r) * (255-fade)/255;
					b.g = ((int)b.g) * fade / 255  + ((int)fading_color.g) * (255-fade)/255;
					b.b = ((int)b.b) * fade / 255 + ((int)fading_color.b) * (255-fade)/255;
				}
				sdl_back=SDL_MapRGB(bitmap->format,b.r,b.g,b.b);
				if ( bitmap == screen && TCOD_ctx.fullscreen ) {
					dstRect.x+=TCOD_ctx.fullscreen_offsetx;
					dstRect.y+=TCOD_ctx.fullscreen_offsety;
				}
				SDL_FillRect(bitmap,&dstRect,sdl_back);
				if ( c->c != ' ' ) {
					/* draw foreground */
					int ascii=c->cf;
					TCOD_color_t *curtext = &charcols[ascii];
					bool first = first_draw[ascii];
					TCOD_color_t f=c->fore;

					if ( fade != 255 ) {
						f.r = ((int)f.r) * fade / 255 + ((int)fading_color.r) * (255-fade)/255;
						f.g = ((int)f.g) * fade / 255 + ((int)fading_color.g) * (255-fade)/255;
						f.b = ((int)f.b) * fade / 255 + ((int)fading_color.b) * (255-fade)/255;
					}
					/* only draw character if foreground color != background color */
					if ( ascii_updated[c->c] || f.r != b.r || f.g != b.g || f.b != b.b ) {
						if ( charmap->format->Amask == 0
							&& f.r == fontKeyCol.r && f.g == fontKeyCol.g && f.b == fontKeyCol.b ) {
							/* cannot draw with the key color... */
							if ( f.r < 255 ) f.r++; else f.r--;
						}
						srcRect.x = (ascii%TCOD_ctx.fontNbCharHoriz)*TCOD_ctx.font_width;
						srcRect.y = (ascii/TCOD_ctx.fontNbCharHoriz)*TCOD_ctx.font_height;
						srcRect.w=TCOD_ctx.font_width;
						srcRect.h=TCOD_ctx.font_height;

						if ( charmap && (first || curtext->r != f.r || curtext->g != f.g || curtext->b!=f.b) ) {
							/* change the character color in the font */
					    	first_draw[ascii]=false;
							sdl_fore=SDL_MapRGB(charmap->format,f.r,f.g,f.b) & rgb_mask;
							*curtext=f;
#ifdef USE_SDL_LOCKS
							if ( SDL_MUSTLOCK(charmap) ) {
								if ( SDL_LockSurface(charmap) < 0 ) return;
							}
#endif
							if ( bpp == 4 ) {
								/* 32 bits font : fill the whole character with color */
								Uint32 *pix = (Uint32 *)(((Uint8 *)charmap->pixels)+srcRect.x*bpp + srcRect.y*charmap->pitch);
								int h=TCOD_ctx.font_height;
								while ( h-- ) {
									int w=TCOD_ctx.font_width;
									while ( w-- ) {
										(*pix) &= nrgb_mask;
										(*pix) |= sdl_fore;
										pix++;
									}
									pix += hdelta;
								}
							} else	{
								/* 24 bits font : fill only non key color pixels */
								Uint32 *pix = (Uint32 *)(((Uint8 *)charmap->pixels)+srcRect.x*bpp + srcRect.y*charmap->pitch);
								int h=TCOD_ctx.font_height;
								while ( h-- ) {
									int w=TCOD_ctx.font_width;
									while ( w-- ) {
										if (((*pix) & rgb_mask) != sdl_key ) {
											(*pix) &= nrgb_mask;
											(*pix) |= sdl_fore;
										}
										pix = (Uint32 *) (((Uint8 *)pix)+3);
									}
									pix = (Uint32 *) (((Uint8 *)pix)+hdelta);
								}
							}
#ifdef USE_SDL_LOCKS
							if ( SDL_MUSTLOCK(charmap) ) {
								SDL_UnlockSurface(charmap);
							}
#endif
						}
						SDL_BlitSurface(charmap,&srcRect,bitmap,&dstRect);
					}
				}
			}
			c++;oc++;
		}
	}
#ifdef USE_SDL_LOCKS
	if ( SDL_MUSTLOCK( bitmap ) ) SDL_UnlockSurface( bitmap );
#endif
}
示例#24
0
/*
 * Função retirada dos tutoriais do LadyFoo.
 * ( http://lazyfoo.net/SDL_tutorials/lesson31/index.php )
 */
SDL_Surface* Sprite::flipSurface(SDL_Surface *surface, int flags) {
	//Pointer to the soon to be flipped surface
	SDL_Surface *flipped = NULL;

	//If the image is color keyed
	if( surface->flags & SDL_SRCCOLORKEY )
	{
		flipped = SDL_CreateRGBSurface( SDL_SWSURFACE, surface->w, surface->h, surface->format->BitsPerPixel, surface->format->Rmask, surface->format->Gmask, surface->format->Bmask, 0 );
	}
	//Otherwise
	else
	{
		flipped = SDL_CreateRGBSurface( SDL_SWSURFACE, surface->w, surface->h, surface->format->BitsPerPixel, surface->format->Rmask, surface->format->Gmask, surface->format->Bmask, surface->format->Amask );
	}

	//If the surface must be locked
	if( SDL_MUSTLOCK( surface ) )
	{
		//Lock the surface
		SDL_LockSurface( surface );
	}

	//Go through columns
	for( int x = 0, rx = flipped->w - 1; x < flipped->w; x++, rx-- )
	{
		//Go through rows
		for( int y = 0, ry = flipped->h - 1; y < flipped->h; y++, ry-- )
		{

			//Get pixel
			Uint32 pixel = get_pixel32( surface, x, y );

			//Copy pixel
			if( ( flags & FLIP_VERTICAL ) && ( flags & FLIP_HORIZONTAL ) )
			{
				put_pixel32( flipped, rx, ry, pixel );
			}
			else if( flags & FLIP_HORIZONTAL )
			{
				put_pixel32( flipped, rx, y, pixel );
			}
			else if( flags & FLIP_VERTICAL )
			{
				put_pixel32( flipped, x, ry, pixel );
			}
		}
	}

	//Unlock surface
	if( SDL_MUSTLOCK( surface ) )
	{
		SDL_UnlockSurface( surface );
	}

	//Copy color key
	if( surface->flags & SDL_SRCCOLORKEY )
	{
		SDL_SetColorKey( flipped, SDL_RLEACCEL | SDL_SRCCOLORKEY, surface->format->colorkey );
	}

	//Return flipped surface
	return flipped;


}
示例#25
0
/** Write the specified surface to a SDL RWops data source at the requested 
 *  compression. This function writes the specified surface pixels to the RWops
 *  as png data, where the RWops goes to shouldn't actually matter to this.
 *
 *  \param dest        The SDL_RWops to write the surface to.
 *  \param surf        The surface to write as a png.
 *  \param compression The compression level to write the png at. Set to -1 to use
 *                     zlib's default compression, othewise this should be in the
 *                     range 0 (no compression) to Z_BEST_COMPRESSION (usually 9).
 *  \return -1 on error, 0 if the png was saved successfully.
 */
int IMG_SavePNG_RW(SDL_RWops *dest, SDL_Surface *surf, int compression)
{
  int isUsable;
	png_structp png_ptr;
	png_infop info_ptr;
		SDL_Surface *outsurf = surf;
    png_byte *line;
    int y;
    int start;         // rw position on invoking this function, for error handling

    // Clamp the compression
    if(compression < -1) compression = -1;

    // Do nothing if we have no destination or surface
    if(!dest) {
        SDL_SetError("No destination RWops specified.");
        return -1;
    }

    if(!surf) { 
        SDL_SetError("No surface specified.");
        return -1; 
    }

    // Determine whether the surface is in a usable format, and if it is not
    // attempt to create a usable copy of it. +
    isUsable = get_format_usability(surf);
    if(isUsable == PF_UNUSABLE || isUsable == PF_UNUSABLE_ALPHA) {
        if(!(outsurf = make_usable_format(surf, isUsable == PF_UNUSABLE_ALPHA))) {
            SDL_SetError("Unable to create temporary surface.");
            return -1;
        }
    }

    // Create the png write structure we need to generate the png output
	if(!(png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,NULL,NULL))) {
		SDL_SetError("Unable to allocate png write structure");
        return -1;
	}

    // And the corresponding info structure...
    if(!(info_ptr = png_create_info_struct(png_ptr))) {
		SDL_SetError("Unable to allocate png info structure");
        png_destroy_write_struct(&png_ptr, NULL);
        return -1;
	}

    // We need to use a custom writer, so that we can output to the RWops
    png_set_write_fn(png_ptr, (void *)dest, sdlrw_write_png, NULL);

    // Determine the current position in the RW so we can restore it on errors
    start = SDL_RWtell(dest);

    // Mark the location we want to come out if there is a fatal error
	if(setjmp(png_jmpbuf(png_ptr))) {
        // Something bad happend in libpng or the write callback, clean up and give up.
        png_destroy_write_struct(&png_ptr, &info_ptr);

        // kill the temporary surface if we created one.
        if(isUsable == PF_UNUSABLE || isUsable == PF_UNUSABLE_ALPHA) SDL_FreeSurface(outsurf);

        // Restore the position of the RWops to the location it was at when we started
        SDL_RWseek(dest, start, RW_SEEK_SET);
        SDL_SetError("PNG saving error, giving up.");
        return -1;
    }

    // handle compression
    png_set_compression_level(png_ptr, compression);

    // sort out the header, which might include a palette...
    if(isUsable == PF_PALETTE)
    {
        if(write_palette_chunk(png_ptr, info_ptr, outsurf) == -1)
        {
            png_destroy_write_struct(&png_ptr, &info_ptr);

            // kill the temporary surface if we created one.
            if(isUsable == PF_UNUSABLE || isUsable == PF_UNUSABLE_ALPHA) SDL_FreeSurface(outsurf);
            
            // Restore the position of the RWops to the location it was at when we started
            SDL_RWseek(dest, start, RW_SEEK_SET);
            return -1;
        }

    // not palettised, and with no alpha
    }
    else if(isUsable == PF_USABLE || isUsable == PF_UNUSABLE) \
    {
        png_set_IHDR(png_ptr, info_ptr, outsurf -> w, outsurf -> h, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
    }
    else     // not palettised, with alpha
    {
        png_set_IHDR(png_ptr, info_ptr, outsurf -> w, outsurf -> h, 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
    }

    // info setup done, so write it out and we can get to image data.
    png_write_info(png_ptr, info_ptr);

    // SDL does this lock/write/unlock when writing BMP so I'm fairly sure it's safe
    if(SDL_MUSTLOCK(outsurf)) SDL_LockSurface(outsurf);

    if( isUsable == PF_UNUSABLE_ALPHA )
    {
      unsigned char* b4 = new unsigned char[ outsurf->w * outsurf->h * 4 ];

      const unsigned char* bytes = (const unsigned char*)outsurf->pixels;
      for( unsigned int index=0; index < (unsigned int)(outsurf->w * outsurf->h); index++ )
      {
        b4[ index*4+3] = bytes[index*4+0];
        b4[ index*4+2] = bytes[index*4+1];
        b4[ index*4+1] = bytes[index*4+2];
        b4[ index*4+0] = bytes[index*4+3];
      }

      // Write out the png...
      for( y = 0, line = (png_byte*)b4;
           y < outsurf->h;
           y++, line += outsurf->pitch)
      {
          png_write_row(png_ptr, line);
      }

      delete [] b4;
    }
    else
    {
      for( y = 0, line = (png_byte *)outsurf -> pixels;
           y < outsurf -> h;
           y++, line += outsurf -> pitch)
      {
          png_write_row(png_ptr, line);
      }
    }

    if(SDL_MUSTLOCK(outsurf)) SDL_UnlockSurface(outsurf);
    
    // kill the temporary surface if we created one.
    if(isUsable == PF_UNUSABLE || isUsable == PF_UNUSABLE_ALPHA) SDL_FreeSurface(outsurf);

    // All done by this point...
    png_write_end(png_ptr, NULL);
    png_destroy_write_struct(&png_ptr,&info_ptr);

    return 0;
}
示例#26
0
void gr_unlock_screen()
{
    if ( !screen_locked || !screen->pixels ) return ;

    screen_locked = 0 ;

    if ( scale_resolution != -1 )
    {
        uint8_t  * src8  = screen->pixels, * dst8  = scale_screen->pixels , * pdst = scale_screen->pixels ;
        uint16_t * src16 = screen->pixels, * dst16 = scale_screen->pixels ;
        uint32_t * src32 = screen->pixels, * dst32 = scale_screen->pixels ;
        int h, w;

        switch ( scale_screen->format->BitsPerPixel )
        {
            case    8:
                    if ( scale_resolution_orientation == 1 || scale_resolution_orientation == 3 )
                    {
                        if ( scale_resolution_aspectratio )
                        {
                            for ( w = 0; w < scale_screen->w; w++ )
                            {
                                if ( scale_resolution_table_w[w] != -1 )
                                {
                                    src8 = screen->pixels + scale_resolution_table_w[w];
                                    for ( h = scale_screen->h - 1; h-- ; )
                                    {
                                        if ( scale_resolution_table_h[h] != -1 ) *dst8 = src8[scale_resolution_table_h[h]];
                                        dst8 += scale_screen->pitch ;
                                    }
                                }
                                dst8 = pdst += scale_screen->format->BytesPerPixel ;
                            }
                        }
                        else
                        {
                            for ( w = 0; w < scale_screen->w; w++ )
                            {
                                src8 = screen->pixels + scale_resolution_table_w[w];
                                for ( h = scale_screen->h - 1; h-- ; )
                                {
                                    *dst8 = src8[scale_resolution_table_h[h]];
                                    dst8 += scale_screen->pitch ;
                                }
                            }
                            dst8 = pdst += scale_screen->format->BytesPerPixel ;
                        }
                    }
                    else
                    {
                        if ( scale_resolution_aspectratio )
                        {
                            for ( h = 0; h < scale_screen->h; h++ )
                            {
                                if ( scale_resolution_table_h[h] != -1 )
                                {
                                    src8 = screen->pixels + scale_resolution_table_h[h];
                                    for ( w = 0; w < scale_screen->w; w++ )
                                    {
                                        if ( scale_resolution_table_w[w] != -1 ) *dst8 = src8[scale_resolution_table_w[w]];
                                        dst8++;
                                    }
                                }
                                dst8 = pdst += scale_screen->pitch ;
                            }
                        }
                        else
                        {
                            for ( h = 0; h < scale_screen->h; h++ )
                            {
                                src8 = screen->pixels + scale_resolution_table_h[h];
                                for ( w = 0; w < scale_screen->w; w++ )
                                {
                                    *dst8 = src8[scale_resolution_table_w[w]];
                                    dst8++;
                                }
                                dst8 = pdst += scale_screen->pitch ;
                            }
                        }
                    }
                    break;

            case    16:
                    if ( scale_resolution_orientation == 1 || scale_resolution_orientation == 3 )
                    {
                        if ( scale_resolution_aspectratio )
                        {
                            int inc = scale_screen->pitch / scale_screen->format->BytesPerPixel;
                            for ( w = 0; w < scale_screen->w; w++ )
                            {
                                if ( scale_resolution_table_w[w] != -1 )
                                {
                                    src16 = screen->pixels + scale_resolution_table_w[w];
                                    for ( h = scale_screen->h - 1; h-- ; )
                                    {
                                        if ( scale_resolution_table_h[h] != -1 ) *dst16 = src16[scale_resolution_table_h[h]];
                                        dst16 += inc;
                                    }
                                }
                                dst16 = ( uint16_t * ) ( pdst += scale_screen->format->BytesPerPixel ) ;
                            }
                        }
                        else
                        {
                            int inc = scale_screen->pitch / scale_screen->format->BytesPerPixel;
                            for ( w = 0; w < scale_screen->w; w++ )
                            {
                                src16 = screen->pixels + scale_resolution_table_w[w];
                                for ( h = scale_screen->h - 1; h-- ; )
                                {
                                    *dst16 = src16[scale_resolution_table_h[h]];
                                    dst16 += inc;
                                }
                                dst16 = ( uint16_t * ) ( pdst += scale_screen->format->BytesPerPixel ) ;
                            }
                        }
                    }
                    else
                    {
                        if ( scale_resolution_aspectratio )
                        {
                            for ( h = 0; h < scale_screen->h; h++ )
                            {
                                if ( scale_resolution_table_h[h] != -1 )
                                {
                                    src16 = screen->pixels + scale_resolution_table_h[h];
                                    for ( w = 0; w < scale_screen->w; w++ )
                                    {
                                        if ( scale_resolution_table_w[w] != -1 ) *dst16 = src16[scale_resolution_table_w[w]];
                                        dst16++;
                                    }
                                }
                                dst16 = ( uint16_t * ) ( pdst += scale_screen->pitch ) ;
                            }
                        }
                        else
                        {
                            for ( h = 0; h < scale_screen->h; h++ )
                            {
                                src16 = screen->pixels + scale_resolution_table_h[h];
                                for ( w = 0; w < scale_screen->w; w++ )
                                {
                                    *dst16 = src16[scale_resolution_table_w[w]];
                                    dst16++;
                                }
                                dst16 = ( uint16_t * ) ( pdst += scale_screen->pitch ) ;
                            }
                        }
                    }
                    break;

            case    32:
                    if ( scale_resolution_orientation == 1 || scale_resolution_orientation == 3 )
                    {
                        if ( scale_resolution_aspectratio )
                        {
                            int inc = scale_screen->pitch / scale_screen->format->BytesPerPixel;
                            for ( w = 0; w < scale_screen->w; w++ )
                            {
                                if ( scale_resolution_table_w[w] != -1 )
                                {
                                    src32 = screen->pixels + scale_resolution_table_w[w];
                                    for ( h = scale_screen->h - 1; h-- ; )
                                    {
                                        if ( scale_resolution_table_h[h] != -1 ) *dst32 = src32[scale_resolution_table_h[h]];
                                        dst32 += inc;
                                    }
                                }
                                dst32 = ( uint32_t * ) ( pdst += scale_screen->format->BytesPerPixel ) ;
                            }
                        }
                        else
                        {
                            int inc = scale_screen->pitch / scale_screen->format->BytesPerPixel;
                            for ( w = 0; w < scale_screen->w; w++ )
                            {
                                src32 = screen->pixels + scale_resolution_table_w[w];
                                for ( h = scale_screen->h - 1; h-- ; )
                                {
                                    *dst32 = src32[scale_resolution_table_h[h]];
                                    dst32 += inc;
                                }
                                dst32 = ( uint32_t * ) ( pdst += scale_screen->format->BytesPerPixel ) ;
                            }
                        }
                    }
                    else
                    {
                        if ( scale_resolution_aspectratio )
                        {
                            for ( h = 0; h < scale_screen->h; h++ )
                            {
                                if ( scale_resolution_table_h[h] != -1 )
                                {
                                    src32 = screen->pixels + scale_resolution_table_h[h];
                                    for ( w = 0; w < scale_screen->w; w++ )
                                    {
                                        if ( scale_resolution_table_w[w] != -1 ) *dst32 = src32[scale_resolution_table_w[w]];
                                        dst32++;
                                    }
                                }
                                dst32 = ( uint32_t * ) ( pdst += scale_screen->pitch ) ;
                            }
                        }
                        else
                        {
                            for ( h = 0; h < scale_screen->h; h++ )
                            {
                                src32 = screen->pixels + scale_resolution_table_h[h];
                                for ( w = 0; w < scale_screen->w; w++ )
                                {
                                    *dst32 = src32[scale_resolution_table_w[w]];
                                    dst32++;
                                }
                                dst32 = ( uint32_t * ) ( pdst += scale_screen->pitch ) ;
                            }
                        }
                    }
                    break;
        }

        if ( SDL_MUSTLOCK( scale_screen ) ) SDL_UnlockSurface( scale_screen ) ;
        if ( waitvsync ) gr_wait_vsync();
        SDL_Flip( scale_screen ) ;
    }
    else if ( enable_scale )
    {
        GRAPH * scr;

        if ( scrbitmap->format->depth == 8 )
        {
            uint8_t * original, * poriginal;
            uint16_t * extra, * pextra;
            int n = scrbitmap->height, length;

            if (
                !scrbitmap_extra ||
                scrbitmap_extra->width != scrbitmap->width ||
                scrbitmap_extra->height != scrbitmap->height
            )
            {
                if ( scrbitmap_extra ) bitmap_destroy( scrbitmap_extra );
                scrbitmap_extra = bitmap_new( 0, scrbitmap->width, scrbitmap->height, 16 );
            }

            poriginal = scrbitmap->data;
            pextra = scrbitmap_extra->data;

            while ( n-- )
            {
                original = poriginal;
                extra = pextra;
                length = scrbitmap->width;
                while ( length-- ) *extra++ = sys_pixel_format->palette->colorequiv[ *original++ ];
                poriginal += scrbitmap->pitch;
                pextra = ( uint16_t * )((( uint8_t * ) pextra ) + scrbitmap_extra->pitch );
            }

            scr = scrbitmap_extra;
        }
        else
        {
            scr = scrbitmap;
        }

        /* Esto podria ir en un modulo aparte */
        switch ( scale_mode )
        {
            case SCALE_SCALE2X:
                scale2x( scr->data, scr->pitch, screen->pixels, screen->pitch, scr->width, scr->height );
                break;

            case SCALE_HQ2X:
                hq2x( scr->data, scr->pitch, screen->pixels, screen->pitch, scr->width, scr->height );
                break;

            case SCALE_SCANLINE2X:
                scanline2x( scr->data, scr->pitch, screen->pixels, screen->pitch, scr->width, scr->height );
                break;

            case SCALE_NOFILTER:
                scale_normal2x( scr->data, scr->pitch, screen->pixels, screen->pitch, scr->width, scr->height );
                break;

            case SCALE_NONE:
                // No usado
                break;
        }

        if ( SDL_MUSTLOCK( screen ) ) SDL_UnlockSurface( screen ) ;
        if ( waitvsync ) gr_wait_vsync();
        SDL_Flip( screen ) ;
    }
    else if ( scrbitmap->info_flags & GI_EXTERNAL_DATA )
    {
        if ( double_buffer ||
                (
                    updaterects_count == 1 &&
                    updaterects[0].x == 0 &&
                    updaterects[0].y == 0 &&
                    updaterects[0].x2 == scr_width - 1 &&
                    updaterects[0].y2 == scr_height - 1
                )
           )
        {
            if ( SDL_MUSTLOCK( screen ) ) SDL_UnlockSurface( screen ) ;
            if ( waitvsync ) gr_wait_vsync();
            SDL_Flip( screen ) ;
        }
        else
        {
            if ( updaterects_count )
            {
                int i;

                for ( i = 0 ; i < updaterects_count ; i++ )
                {
                    rects[ i ].x = updaterects[ i ].x;
                    rects[ i ].y = updaterects[ i ].y;
                    rects[ i ].w = ( updaterects[ i ].x2 - rects[ i ].x + 1 );
                    rects[ i ].h = ( updaterects[ i ].y2 - rects[ i ].y + 1 );
                }
                if ( SDL_MUSTLOCK( screen ) ) SDL_UnlockSurface( screen ) ;
                if ( waitvsync ) gr_wait_vsync();
                SDL_UpdateRects( screen, updaterects_count, rects ) ;
            }
        }
    }
}
示例#27
0
文件: SDLStage.cpp 项目: ubald/lime
 void Commit()
 {
     if (SDL_MUSTLOCK(mSurf))
         SDL_UnlockSurface(mSurf);
 }
示例#28
0
/*
Overridable function, if necessary, for doing all of the drawing.
Base class version checks whether a redraw is needed and does nothing if not. See Redraw() function.
If a redraw is needed then there is an option to either redraw the whole screen or just redraw the moving objects.
If redrawing the whole screen then:
1a) SetupBackgroundBuffer is called to draw the background to the background buffer.
1b) DrawScreen is called to copy the background buffer onto the screen, then draw the moving objects.
1c) SDL_UpdateRect() is called to actually redraw the whole screen.
If only redrawing the moving objects then:
2a) DrawChangingObjects() is called to remove the objects from their old positions, and redraw them in their new positions.
2b) GetUpdateRectanglesForChangingObjects() is called to calculate where on the screen needs redrawing.
2c) SDL_UpdateRects() is called to redraw the parts of the screen which changed.
*/
void BaseEngine::GameRender(void)
{
	if ( !m_bNeedsRedraw )
		return;

	// Just drawn so no more redraw needed
	m_bNeedsRedraw = false;
	// Note: the redraw flags must only be set early in this method, not at the end, since the drawing/moving of the moving objects may
	// potentially flag a win/lose condition and a state change, which will set the redraw flag again to force a full draw after the 
	// state changes.

	if ( m_bWholeScreenUpdate )
	{
		// Drawn whole screen now, so no need to draw it again. See note above about the importance of not resetting this after DrawChangingObjects()
		m_bWholeScreenUpdate = false;

		// Lock surface if needed
		if (SDL_MUSTLOCK(m_pActualScreen))
		{
			m_bInsideDraw = true;
			if (SDL_LockSurface(m_pActualScreen) < 0) 
				return;
		}

		// Draw the screen as it should appear now.
		DrawScreen();

		// Unlock if needed
		if (SDL_MUSTLOCK(m_pActualScreen)) 
			SDL_UnlockSurface(m_pActualScreen);
		m_bInsideDraw = false;

		SDL_UpdateRect(m_pActualScreen, 0, 0, m_iScreenWidth, m_iScreenHeight);    
	}
	else
	{
		// Here we assume that the background buffer has already been set up

		// Lock surface if needed
		if (SDL_MUSTLOCK(m_pActualScreen))
		{
			m_bInsideDraw = true;
			if (SDL_LockSurface(m_pActualScreen) < 0) 
				return;
		}

		// Remove objects from their old positions
		// Draw the text for the user
		// Draw objects at their new positions
		DrawChanges();

		// Unlock if needed
		if (SDL_MUSTLOCK(m_pActualScreen)) 
			SDL_UnlockSurface(m_pActualScreen);
		m_bInsideDraw = false;

		// Work out which parts of the screen need to be updated
		GetUpdateRectanglesForChangingObjects();

		// Now actually perform the updates
		if ( m_iUpdateRectsInUse >= m_iMaxObjects )
		{
			//printf( "Update whole window\n" );
			//SDL_UpdateRect(m_pActualScreen, 0, 0, m_iScreenWidth, m_iScreenHeight);    
			SDL_UpdateRect(m_pActualScreen, 0, 0, 0, 0);    
		}
		else
		{
			//printf( "Update %d rectangles\n", m_iUpdateRectsInUse );
			SDL_UpdateRects( m_pActualScreen, m_iUpdateRectsInUse, m_pUpdateRectangles );
		}
		// DEBUG
		//printf( "%d update rectangles found\n", m_iUpdateRectsInUse );
		//for ( int i = 0 ; i < m_iUpdateRectsInUse ; i++ )
		//	printf( "\tNumber %d : %d, %d, %d, %d\n", i, m_pUpdateRectangles[i].x, m_pUpdateRectangles[i].y, m_pUpdateRectangles[i].w, m_pUpdateRectangles[i].h );
		// End of debug
		m_iUpdateRectsInUse = 0;
	}

}
示例#29
0
文件: save.c 项目: beoran/eruta
/* Saves an SDL surface to a png file.
* TODO: support screen formats. 
*/
int sdl_surface_savepng(SDL_Surface * surf, const char * filename) {
  png_bytep       * rows  = NULL;
  png_colorp        pale  = NULL; 
  FILE            * fout  = NULL;
  png_structp       png   = NULL;
  png_infop         info  = NULL;
  int               colortype;
  int               i     = 0;
  Uint8           * tran  = NULL;
  SDL_PixelFormat * fmt   = NULL;
  SDL_Surface     * temp  = NULL;
  
  if (!surf) { return save_fail("Surface was NULL."); }
  if (!filename) { return save_fail("Filename was NULL."); }
    
  rows  =  gymalloc(sizeof(png_bytep)*surf->h);
  if (!rows) { return save_fail("Out of memory."); }
  
  for (i = 0; i < surf->h; i++) { 
    rows[i] = ((Uint8 *)surf->pixels) + i*surf->pitch;
  }
  
  /* Create palette and transparency table if needed. */
  fmt = surf->format;
  if (fmt->palette) {
    pale = malloc(fmt->palette->ncolors * sizeof(png_color));
    if (!pale) {
      savepng_done(rows, fout, png, info, temp, pale, tran);
      return save_fail("Out of memory in saving palette.");
    }    
    for (i = 0; i < fmt->palette->ncolors; i++) {
      pale[i].red    = fmt->palette->colors[i].r;
      pale[i].green  = fmt->palette->colors[i].g;
      pale[i].blue   = fmt->palette->colors[i].b;
    }
    
    if (surf->flags & SDL_SRCCOLORKEY) {
      Uint32 colorkey = 0; 
      SDL_GetColorKey(surf, &colorkey);
      tran = malloc(fmt->palette->ncolors * sizeof(Uint8));
      if(!tran) {
        savepng_done(rows, fout, png, info, temp, pale, tran);
        return save_fail("Out of memory in saving palette transparency.");
      }
      for (i = 0; i < fmt->palette->ncolors; i++) {
        tran[i] = (((unsigned)i) == colorkey) ? 255 : 0;
      }
    }
  }
    
  fout = fopen(filename, "wb");
  if(!fout) {
    savepng_done(rows, fout, png, info, temp, pale, tran);    
    return save_fail("Couldn't open file for writing."); 
  }
  
  png  = png_create_write_struct(PNG_LIBPNG_VER_STRING,  NULL, NULL, NULL);
  if (!png) {
    savepng_done(rows, fout, png, info, temp, pale, tran);
    return save_fail("Couldn't create png_structp");
  }  
  
  info = png_create_info_struct(png);
  if (!info) {
    savepng_done(rows, fout, png, info, temp, pale, tran);
    return save_fail("Couldn't create png_infop");
  }
  
  /* libpng rudely uses longjump to terminate on errors. 
    This in turns causes warning of pissbli clobered variables. Could it suck 
    more? */
  if (setjmp(png->jmpbuf)) {
    /* This give a warning, but it seems to be unavoidable. */
    savepng_done(rows, fout, png, info, temp, pale, tran);
    return save_fail("Error writing png file.");
  }
  
  /* Set file pointer. */
  png_init_io(png, fout);
  
  colortype = sdl_surface_pngcolortype(surf);
  png_set_IHDR(png, info, surf->w, surf->h, 8, colortype, PNG_INTERLACE_NONE, 
               PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
  
  /* Write palette if needed. */
  if(pale) { 
    png_set_PLTE(png, info, pale, fmt->palette->ncolors);
  }
    
  /* Write transparency table if needed. */
  if (tran) {  
    png_set_tRNS(png, info, tran, fmt->palette->ncolors, NULL);
  }
  
  /* Write the image. */
  png_write_info(png, info);
  png_set_packing(png);
  if(SDL_MUSTLOCK(surf)) {  SDL_LockSurface(surf);  }
  png_write_image(png, rows);
  if(SDL_MUSTLOCK(surf)) { SDL_UnlockSurface(surf); }
  png_write_end(png, info);
  
  
  /* Clean up. */
  savepng_done(rows, fout, png, info, temp, pale, tran);
  return 0;
}
bool CEGALatch::loadData( const std::string &path,
                          const short episode,
                          const int version,
                          const unsigned char *data,
                          const bool compresseddata )
{
	std::string filename;
	byte *RawData;
    Uint16 width, height;
    SDL_Surface *sfc;


	filename = getResourceFilename("egalatch.ck" + itoa(episode), path);

	FILE* latchfile = OpenGameFile(filename,"rb");

	if(!latchfile)
		return false;

	RawData = new byte[m_latchplanesize * 4];
    // get the data out of the file into the memory, decompressing it if necessary.
    if (compresseddata)
    {
		if (lz_decompress(latchfile, (unsigned char*) RawData))
		{
			return 1;
		}
    }
    else
    {
    	for(int i=0 ; i<(m_latchplanesize*4) ; i++)
    		RawData[i] = fgetc(latchfile);
    }

    fclose(latchfile);

	// these are the offsets of the different video planes as
	// relative to each other--that is if a pixel in plane1
	// is at N, the byte for that same pixel in plane3 will be
	// at (N + plane3).
	unsigned long plane1, plane2, plane3, plane4;

	plane1 = 0;
	plane2 = (m_latchplanesize * 1);
	plane3 = (m_latchplanesize * 2);
	plane4 = (m_latchplanesize * 3);

	// ** read the 8x8 tiles **
	// set up the getbit() function of CPlanes class
	CPlanes Planes(RawData);
	Planes.setOffsets(plane1 + m_fontlocation, plane2 + m_fontlocation,
					  plane3 + m_fontlocation, plane4 + m_fontlocation, 0);
	// Load these graphics into the GsFont Class of GsGraphics
	// The original vorticon engine only uses one fontmap, but we use another for
	// extra icons. For example sliders are in that map

	gGraphics.freeFonts();
	gGraphics.createEmptyFontmaps(3);

	gGraphics.getFont(0).loadinternalFont();

	GsFont &Font = gGraphics.getFont(1);
	Font.CreateSurface( gGraphics.Palette.m_Palette, SDL_SWSURFACE );
	sfc = Font.getSDLSurface();

	gGraphics.getFont(2).loadAlternateFont();


	if(SDL_MUSTLOCK(sfc)) SDL_LockSurface(sfc);

	Uint8 *pixel = (Uint8*) sfc->pixels;
	SDL_FillRect(sfc, NULL, 0);

	for(int p=0;p<4;p++)
		Planes.readPlaneofTiles(p, pixel, 16, 8, m_fonttiles);

	if(SDL_MUSTLOCK(sfc)) SDL_UnlockSurface(sfc);

	// prepare to ** read the 16x16 tiles **
	Planes.setOffsets(plane1 + m_tiles16location,
					 plane2 + m_tiles16location,
					 plane3 + m_tiles16location,
					 plane4 + m_tiles16location,
					 0);

	gGraphics.freeTilemap();
	gGraphics.createEmptyTilemaps(2);
	
	loadTilemap(gGraphics.getTileMap(0), Planes, episode, path);
	
	// prepare to ** read the 16x16 tiles **, this is for the second plane.
	Planes.setOffsets(plane1 + m_tiles16location,
					 plane2 + m_tiles16location,
					 plane3 + m_tiles16location,
					 plane4 + m_tiles16location,
					 0);	
	
	loadTilemap(gGraphics.getTileMap(1), Planes, episode, path);

    gGraphics.getTileMap(0).optimizeSurface();
    gGraphics.getTileMap(1).optimizeSurface();

	// make masked tiles according to it's surfaces
	applyMasks();

	////////////////////
	/// Load Bitmaps ///
	////////////////////

	Planes.setOffsets(plane1 + m_bitmaplocation,
					plane2 + m_bitmaplocation,
					plane3 + m_bitmaplocation,
					plane4 + m_bitmaplocation,
					0);

	// decode bitmaps into the BitmapData structure. The bitmaps are
	// loaded into one continuous stream of image data, with the bitmaps[]
	// array giving pointers to where each bitmap starts within the stream.

	for(int p=0 ; p<4 ; p++)
	{
		for(int b=0 ; b<m_bitmaps ; b++)
		{
            GsBitmap &bitmap = gGraphics.getBitmapFromId(b);
			// this points to the location that we're currently
			// decoding bitmap data to

			sfc= bitmap.getSDLSurface();
			if(SDL_MUSTLOCK(sfc)) SDL_LockSurface(sfc);
			Uint8* pixel = (Uint8*) sfc->pixels;
			if(p==0)
				SDL_FillRect(sfc, NULL, 0);
			width = bitmap.getWidth(); height = bitmap.getHeight();
			// Now read the raw data

			Planes.readPlane(p, pixel, width, height);

			if(SDL_MUSTLOCK(sfc)) SDL_UnlockSurface(sfc);
		}
	}

	std::set<std::string> filelist;
	FileListAdder fileListAdder;
	std::string gfxpath = JoinPaths(path, "gfx");
	GetFileList(filelist, fileListAdder, gfxpath, false, FM_REG);
	FilterFilelist(filelist, "bitmap");

	std::set<std::string>::iterator it = filelist.begin();

	for( ; it != filelist.end() ; it++ )
	{
		std::string filename=*it;
		int num = getRessourceID(filename, "bitmap");
        GsBitmap &bitmap = gGraphics.getBitmapFromId(num);
		filename = getResourceFilename("gfx/" + filename, path, false);
		bitmap.loadHQBitmap(filename);
	}

	if(RawData){ delete[] RawData; RawData = NULL;}

    // Create an intro in case it does not exist yet
    std::string fullpath = getResourceFilename("preview.bmp", path, false);
    if( fullpath == "" )
    {   // Not found create it
        fullpath = path + "/preview.bmp";
        fullpath = GetWriteFullFileName(fullpath, true);
        GsBitmap *pBitmap = gGraphics.getBitmapFromStr("TITLE");
        SDL_SaveBMP( pBitmap->getSDLSurface(), fullpath.c_str());
    }

	return true;
}