static SDL_Surface *com2alphasurface(agsurface_t *src, int cl, SDL_Surface **opaque) { SDL_Surface *s; int x,y; BYTE *sp, *dp, *op = NULL; SDL_Rect r_src; Uint32 pixel; if (sdl_dib->format->BitsPerPixel == 8) { s = SDL_AllocSurface(SDL_SWSURFACE, src->width, src->height, 32, 0xFF0000, 0xFF00, 0xFF, 0xFF000000); *opaque = SDL_AllocSurface(SDL_SWSURFACE, src->width, src->height, 8, 0, 0, 0, 0); pixel = sdl_col[cl].r << 16 | sdl_col[cl].g << 8 | sdl_col[cl].b; } else { s = SDL_AllocSurface(SDL_SWSURFACE, src->width, src->height, sdl_dib->format->BitsPerPixel <= 24 ? sdl_dib->format->BitsPerPixel+8:32, sdl_dib->format->Rmask,sdl_dib->format->Gmask, sdl_dib->format->Bmask, sdl_dib->format->BitsPerPixel<24?0xFF0000:0xFF000000); pixel = SDL_MapRGB(sdl_dib->format, sdl_col[cl].r, sdl_col[cl].g, sdl_col[cl].b); } setRect(r_src, 0, 0, src->width, src->height); SDL_FillRect(s, &r_src, pixel); SDL_LockSurface(s); if (*opaque) SDL_LockSurface(*opaque); for (y = 0; y < src->height; y++) { sp = src->pixel + y * src->bytes_per_line; dp = s->pixels + y * s->pitch; #ifndef WORDS_BIGENDIAN dp += s->format->BytesPerPixel -1; #endif if (*opaque) op = (*opaque)->pixels + y * (*opaque)->pitch; for (x = 0; x < src->width; x++) { *dp = R_ALPHA(*sp); if (op) *op++ = (*dp >= (256-64)) ? cl : 0; sp++; dp += s->format->BytesPerPixel; } } if (*opaque) SDL_UnlockSurface(*opaque); SDL_UnlockSurface(s); return s; }
void SdlDisplay::sdlInit(bool multi) { snakeInit(); if (multi) p2snakeInit(); if (SDL_Init(SDL_INIT_VIDEO || SDL_INIT_TIMER) == -1) std::cerr << "SDL video init failure" << std::endl; if (TTF_Init() == -1) std::cerr << "SDL font init failure" << std::endl; if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, MIX_DEFAULT_CHANNELS, 1024) == -1) std::cerr << "SDL audio init failure, error : " << Mix_GetError() << std::endl; font = TTF_OpenFont(FONT, 20); SDL_WM_SetCaption("---Nibbler---", NULL); screen = SDL_SetVideoMode(WIDTH, HEIGHT, BPP, SDL_DOUBLEBUF | SDL_HWSURFACE); sprite1 = IMG_Load("images/body1.png"); sprite2 = IMG_Load("images/body2.png"); mushroom = IMG_Load("images/mushroom.png"); apple = IMG_Load("images/apple.png"); grass = SDL_LoadBMP("images/grass.bmp"); menu = IMG_Load("images/menu/menu1.png"); head1 = IMG_Load("images/head1r.png"); head2 = IMG_Load("images/head2r.png"); blacktexture = SDL_LoadBMP("images/black.bmp"); queue1 = IMG_Load("images/qr.png"); queue2 = IMG_Load("images/qr.png"); back = SDL_AllocSurface(SDL_HWSURFACE, WIDTH, HEIGHT, BPP, 0, 0, 0, 0); sdlFillBackground(); sdlSetRect(&rtmp, i * 20, j * 20, 0, 0); SDL_FillRect(back, &rtmp, SDL_MapRGB(screen->format, 100, 100, 255)); if (screen == NULL) start = false; }
/** * Saves a screenshot of the screen's contents. * @param filename Filename of the PNG file. */ void Screen::screenshot(const std::string &filename) const { SDL_Surface *screenshot = SDL_AllocSurface(0, getWidth() - getWidth()%4, getHeight(), 24, 0xff, 0xff00, 0xff0000, 0); if (isOpenGLEnabled()) { #ifndef __NO_OPENGL GLenum format = GL_RGB; for (int y = 0; y < getHeight(); ++y) { glReadPixels(0, getHeight()-(y+1), getWidth() - getWidth()%4, 1, format, GL_UNSIGNED_BYTE, ((Uint8*)screenshot->pixels) + y*screenshot->pitch); } glErrorCheck(); #endif } else { SDL_BlitSurface(_screen, 0, screenshot, 0); } unsigned error = lodepng::encode(filename, (const unsigned char *)(screenshot->pixels), getWidth() - getWidth()%4, getHeight(), LCT_RGB); if (error) { Log(LOG_ERROR) << "Saving to PNG failed: " << lodepng_error_text(error); } SDL_FreeSurface(screenshot); }
void sdl_drawImage8_fromData(cgdata *cg, int dx, int dy, int w, int h) { SDL_Surface *s; SDL_Rect r_src, r_dst; s = SDL_AllocSurface(SDL_SWSURFACE, w, h, 8, 0, 0, 0, 0); SDL_LockSurface(s); #if 0 /* for broken cg */ if (s->pitch == s->w) { memcpy(s->pixels, cg->pic, w * h); } else #endif { int i = h; BYTE *p_src = (cg->pic + cg->data_offset), *p_dst = s->pixels; while (i--) { memcpy(p_dst, p_src, w); p_dst += s->pitch; p_src += cg->width; } } SDL_UnlockSurface(s); sdl_pal_check(); if (sdl_dib->format->BitsPerPixel > 8 && cg->pal) { int i, i_st = 0, i_end = 256; SDL_Color *c = s->format->palette->colors; BYTE *r = cg->pal->red, *g = cg->pal->green, *b = cg->pal->blue; if (cg->type == ALCG_VSP) { i_st = (cg->vsp_bank << 4); i_end = i_st + 16; c += i_st; } for (i = i_st; i < i_end; i++) { c->r = *(r++); c->g = *(g++); c->b = *(b++); c++; } } else { memcpy(s->format->palette->colors, sdl_col, sizeof(SDL_Color) * 256); } if (cg->spritecolor != -1) { SDL_SetColorKey(s, SDL_SRCCOLORKEY, cg->spritecolor); } setRect(r_src, 0, 0, w, h); setRect(r_dst, dx, dy, w, h); SDL_BlitSurface(s, &r_src, sdl_dib, &r_dst); SDL_FreeSurface(s); }
SDL_Surface* IMG_LoadTIF_RW(SDL_RWops* src) { TIFF* tiff; SDL_Surface* surface = NULL; Uint32 img_width, img_height; Uint32 Rmask, Gmask, Bmask, Amask, mask; Uint32 x, y; Uint32 half; if ( !src ) { /* The error message has been set in SDL_RWFromFile */ return NULL; } /* turn off memory mapped access with the m flag */ tiff = TIFFClientOpen("SDL_image", "rm", (thandle_t)src, tiff_read, tiff_write, tiff_seek, tiff_close, tiff_size, NULL, NULL); if(!tiff) return NULL; /* Retrieve the dimensions of the image from the TIFF tags */ TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &img_width); TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &img_height); Rmask = 0x000000FF; Gmask = 0x0000FF00; Bmask = 0x00FF0000; Amask = 0xFF000000; surface = SDL_AllocSurface(SDL_SWSURFACE, img_width, img_height, 32, Rmask, Gmask, Bmask, Amask); if(!surface) return NULL; if(!TIFFReadRGBAImage(tiff, img_width, img_height, surface->pixels, 0)) return NULL; /* libtiff loads the image upside-down, flip it back */ half = img_height / 2; for(y = 0; y < half; y++) { Uint32 *top = (Uint32 *)surface->pixels + y * surface->pitch/4; Uint32 *bot = (Uint32 *)surface->pixels + (img_height - y - 1) * surface->pitch/4; for(x = 0; x < img_width; x++) { Uint32 tmp = top[x]; top[x] = bot[x]; bot[x] = tmp; } } TIFFClose(tiff); return surface; }
/* Load a JPEG type image from an SDL datasource */ SDL_Surface *IMG_LoadJPG_RW(SDL_RWops *src) { int start; struct jpeg_decompress_struct cinfo; JSAMPROW rowptr[1]; SDL_Surface *volatile surface = NULL; struct my_error_mgr jerr; if ( !src ) { /* The error message has been set in SDL_RWFromFile */ return NULL; } start = SDL_RWtell(src); if ( IMG_InitJPG() < 0 ) { return NULL; } /* Create a decompression structure and load the JPEG header */ cinfo.err = lib.jpeg_std_error(&jerr.errmgr); jerr.errmgr.error_exit = my_error_exit; jerr.errmgr.output_message = output_no_message; if(setjmp(jerr.escape)) { /* If we get here, libjpeg found an error */ lib.jpeg_destroy_decompress(&cinfo); if ( surface != NULL ) { SDL_FreeSurface(surface); } SDL_RWseek(src, start, SEEK_SET); IMG_QuitJPG(); IMG_SetError("JPEG loading error"); return NULL; } lib.jpeg_create_decompress(&cinfo); jpeg_SDL_RW_src(&cinfo, src); lib.jpeg_read_header(&cinfo, TRUE); if(cinfo.num_components == 4) { /* Set 32-bit Raw output */ cinfo.out_color_space = JCS_CMYK; cinfo.quantize_colors = FALSE; lib.jpeg_calc_output_dimensions(&cinfo); /* Allocate an output surface to hold the image */ surface = SDL_AllocSurface(SDL_SWSURFACE, cinfo.output_width, cinfo.output_height, 32, #if SDL_BYTEORDER == SDL_LIL_ENDIAN 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); #else 0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF); #endif } else {
void Graphics_Init(int fullscreen) { switch (OPERATINGSYSTEM) { case 1: LoadSurface(ARCODATADIR "boss_linux.png",&GfxData[BOSS]);break; default: LoadSurface(ARCODATADIR "boss_windows.png",&GfxData[BOSS]);break; } LoadSurface(ARCODATADIR "menu.png",&GfxData[MENU]); LoadSurface(ARCODATADIR "menuitems.png",&GfxData[MENUITEMS]); LoadSurface(ARCODATADIR "credits.png",&GfxData[CREDITS]); LoadSurface(ARCODATADIR "deck.png",&GfxData[DECK]); SDL_SetColorKey(GfxData[DECK],SDL_SRCCOLORKEY,SDL_MapRGB(GfxData[DECK]->format,255,0,255)); LoadSurface(ARCODATADIR "nums_big.png",&GfxData[NUMSBIG]); SDL_SetColorKey(GfxData[NUMSBIG],SDL_SRCCOLORKEY,SDL_MapRGB(GfxData[NUMSBIG]->format,255,0,255)); LoadSurface(ARCODATADIR "gamebg.png",&GfxData[GAMEBG]); LoadSurface(ARCODATADIR "castle.png",&GfxData[CASTLE]); LoadSurface(ARCODATADIR "dlgmsg.png",&GfxData[DLGMSG]); LoadSurface(ARCODATADIR "dlgerror.png",&GfxData[DLGERROR]); LoadSurface(ARCODATADIR "dlgnetwork.png",&GfxData[DLGNETWORK]); LoadSurface(ARCODATADIR "dlgwinner.png",&GfxData[DLGWINNER]); LoadSurface(ARCODATADIR "dlglooser.png",&GfxData[DLGLOOSER]); SDL_SetColorKey(GfxData[CASTLE],SDL_SRCCOLORKEY,SDL_MapRGB(GfxData[CASTLE]->format,255,0,255)); numssmall=BFont_LoadFont(ARCODATADIR "nums_small.png"); if (!numssmall) FatalError("Data file 'nums_small.png' is missing or corrupt."); bigfont=BFont_LoadFont(ARCODATADIR "bigfont.png"); if (!bigfont) FatalError("Data file 'bigfont.png' is missing or corrupt."); font=BFont_LoadFont(ARCODATADIR "font.png"); if (!font) FatalError("Data file 'font.png' is missing or corrupt."); BFont_SetCurrentFont(font); if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE)<0) FatalError("Couldn't initialize SDL"); SDL_WM_SetCaption("Arcomage v" ARCOVER,NULL); GfxData[SCREEN]=SDL_SetVideoMode(resX,resY,0,SDL_SWSURFACE|(fullscreen*SDL_FULLSCREEN)); if (!GfxData[SCREEN]) FatalError("Couldn't set 640x480 video mode"); GfxData[BUFFER]=SDL_AllocSurface(GfxData[SCREEN]->flags,GfxData[SCREEN]->w,GfxData[SCREEN]->h,GfxData[SCREEN]->format->BitsPerPixel,GfxData[SCREEN]->format->Rmask,GfxData[SCREEN]->format->Gmask,GfxData[SCREEN]->format->Bmask,0); if (!GfxData[BUFFER]) FatalError("Unable to create double buffer!"); }
PUBLIC SDL_Surface * surface_from_dib (void *lp) { SDL_Surface *retval; retval = SDL_LoadCF_DIB (lp); if (retval) { int first_bpp; first_bpp = SDL_bpp (retval); if (first_bpp < 8) { /* TODO: convert < 8bpp to 8bpp */ } else if (first_bpp > 8) { /* convert > 8bpp to our particular 32bpp */ SDL_Surface *new_surface; int pixels_per_line; int n_lines; enum { A = 0x00000000, R = 0x0000FF00, G = 0x00FF0000, B = 0xFF000000 }; pixels_per_line = SDL_pixels_per_line (retval); n_lines = SDL_n_lines (retval); new_surface = SDL_AllocSurface (SDL_SWSURFACE, pixels_per_line, n_lines, 32, R, G, B, A); if (!new_surface || #if SDL_MAJOR_VERSION == 0 && SDL_MINOR_VERSION < 9 SDL_MapSurface (retval, new_surface->format) != 0 || #endif SDL_BlitSurface (retval, NULL, new_surface, NULL) != 0) { if (new_surface) { SDL_FreeSurface (new_surface); new_surface = NULL; } } SDL_FreeSurface (retval); retval = new_surface; } } return retval; }
int FlcInit(const char *filename) { flc.pMembuf=NULL; flc.membufSize=0; if(FlcCheckHeader(filename)) { Log(LOG_ERROR) << "Flx file failed header check."; //exit(1); return -1; } if (flc.realscreen->getSurface()->getSurface()->format->BitsPerPixel == 8) { flc.mainscreen = flc.realscreen->getSurface()->getSurface(); } else { flc.mainscreen = SDL_AllocSurface(SDL_SWSURFACE, flc.screen_w, flc.screen_h, 8, 0, 0, 0, 0); } return 0; //SDLInit(filename); } /* FlcInit */
PRIVATE SDL_Surface * surface_from_gworld (GWorldPtr gp) { SDL_Surface *retval; if (!gp) retval = NULL; else { int pixels_per_line; int n_lines; PixMapHandle pm; enum { A = 0x00000000, R = 0x0000FF00, G = 0x00FF0000, B = 0xFF000000 }; mac_pixel32 *ip; sdl_pixel24 *op; Rect r; pm = GetGWorldPixMap (gp); LockPixels (pm); r = PIXMAP_BOUNDS (pm); n_lines = RECT_HEIGHT (&r); pixels_per_line = RECT_WIDTH (&r); retval = SDL_AllocSurface (SDL_SWSURFACE, pixels_per_line, n_lines, 32, R, G, B, A); SDL_LockSurface (retval); op = SDL_Surface_pixels (retval); ip = (typeof (ip)) GetPixBaseAddr (pm); memcpy (op, ip, n_lines * pixels_per_line * sizeof *ip); #if 0 #warning THIS IS BROKEN memset (op, 0x00, 4 * n_lines * pixels_per_line); memset (op, 0xFF, 4 * n_lines * pixels_per_line / 2); #endif SDL_UnlockSurface (retval); UnlockPixels (pm); } return retval; }
static SDL_Surface *com2surface(agsurface_t *src) { SDL_Surface *s; int y; BYTE *sp, *dp; s = SDL_AllocSurface(SDL_SWSURFACE, src->width, src->height, src->depth, 0, 0, 0, 0); SDL_LockSurface(s); sp = s->pixels; dp = src->pixel; for (y = 0; y < src->height; y++) { memcpy(sp, dp, src->width); sp += s->pitch; dp += src->bytes_per_line; } SDL_UnlockSurface(s); return s; }
/* * 指定範囲にパレット col を rate の割合で重ねる CK1 */ void sdl_wrapColor(int sx, int sy, int w, int h, int cl, int rate) { SDL_Surface *s; SDL_Rect r_src,r_dst; s = SDL_AllocSurface(SDL_SWSURFACE, w, h, sdl_dib->format->BitsPerPixel, 0, 0, 0, 0); if (s->format->BitsPerPixel == 8) { memcpy(s->format->palette->colors, sdl_dib->format->palette->colors, sizeof(SDL_Color)*256); } else { cl = (cl < 256) ? SDL_MapRGB(sdl_dib->format, sdl_col[cl].r, sdl_col[cl].g, sdl_col[cl].b) : cl; } setRect(r_src, 0, 0, w, h); SDL_FillRect(s, &r_src, cl); SDL_SetAlpha(s, RLEFLAG(SDL_SRCALPHA), R_ALPHA(rate)); setRect(r_dst, sx, sy, w, h); SDL_BlitSurface(s, &r_src, sdl_dib, &r_dst); SDL_FreeSurface(s); }
static void fader_in(int n) { static agsurface_t *work, *disp; if (n == 0) { SDL_Rect r_src, r_dst; s_fader = SDL_AllocSurface(sdl_dib->flags, sdl_display->w, sdl_display->h, sdl_display->format->BitsPerPixel, 0, 0, 0, 0); if (sdl_display->format->BitsPerPixel == 8) { memcpy(s_fader->format->palette->colors, sdl_display->format->palette->colors, sizeof(SDL_Color) * 256); } setRect(r_src, view_x, view_y, view_w, view_h); setRect(r_dst, winoffset_x, winoffset_y, view_w, view_h); SDL_BlitSurface(sdl_dib, &r_src, s_fader, &r_dst); work = surface2com(s_fader); disp = surface2com(sdl_display); } if (n == 255) { SDL_FreeSurface(s_fader); sdl_updateAll(false); g_free(work); g_free(disp); return; } SDL_LockSurface(s_fader); SDL_LockSurface(sdl_display); image_fadeIn(work, disp, n / 16); SDL_UnlockSurface(sdl_display); SDL_UnlockSurface(s_fader); SDL_UpdateRect(sdl_display,0,0,0,0); }
void *TCOD_sys_get_surface(int width, int height, bool alpha) { Uint32 rmask,gmask,bmask,amask; SDL_Surface *bitmap; int flags=SDL_SWSURFACE; if ( alpha ) { if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) { rmask=0x000000FF; gmask=0x0000FF00; bmask=0x00FF0000; amask=0xFF000000; } else { rmask=0xFF000000; gmask=0x00FF0000; bmask=0x0000FF00; amask=0x000000FF; } flags|=SDL_SRCALPHA; } else { if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) { rmask=0x0000FF; gmask=0x00FF00; bmask=0xFF0000; } else { rmask=0xFF0000; gmask=0x00FF00; bmask=0x0000FF; } amask=0; } bitmap=SDL_AllocSurface(flags,width,height, alpha ? 32:24, rmask,gmask,bmask,amask); if ( alpha ) { SDL_SetAlpha(bitmap, SDL_SRCALPHA, 255); } return (void *)bitmap; }
/** * Initialize data structures needed buy the player and read the whole file into memory * @param filename Video file name * @param frameCallback Function to call each video frame * @param game Pointer to the Game instance * @param dx An offset on the x axis for the video to be rendered * @param dy An offset on the y axis for the video to be rendered */ bool FlcPlayer::init(const char *filename, void(*frameCallBack)(), Game *game, int dx, int dy) { if (_fileBuf != 0) { Log(LOG_ERROR) << "Trying to init a video player that is already initialized"; return false; } _frameCallBack = frameCallBack; _realScreen = game->getScreen(); _realScreen->clear(); _game = game; _dx = dx; _dy = dy; _fileSize = 0; _frameCount = 0; _audioFrameData = 0; _hasAudio = false; _audioData.loadingBuffer = 0; _audioData.playingBuffer = 0; std::ifstream file; file.open(filename, std::ifstream::in | std::ifstream::binary | std::ifstream::ate); if (!file.is_open()) { Log(LOG_ERROR) << "Could not open FLI/FLC file: " << filename; return false; } std::streamoff size = file.tellg(); file.seekg(0, std::ifstream::beg); // TODO: substitute with a cross-platform memory mapped file? _fileBuf = new Uint8[size]; _fileSize = size; file.read((char *)_fileBuf, size); file.close(); _audioFrameData = _fileBuf + 128; // Let's read the first 128 bytes readFileHeader(); // If it's a FLC or FLI file, it's ok if (_headerType == SDL_SwapLE16(FLI_TYPE) || (_headerType == SDL_SwapLE16(FLC_TYPE))) { _screenWidth = _headerWidth; _screenHeight = _headerHeight; _screenDepth = 8; Log(LOG_INFO) << "Playing flx, " << _screenWidth << "x" << _screenHeight << ", " << _headerFrames << " frames"; } else { Log(LOG_ERROR) << "Flx file failed header check."; return false; } // If the current surface used is at 8bpp use it if (_realScreen->getSurface()->getSurface()->format->BitsPerPixel == 8) { _mainScreen = _realScreen->getSurface()->getSurface(); } else // Otherwise create a new one { _mainScreen = SDL_AllocSurface(SDL_SWSURFACE, _screenWidth, _screenHeight, 8, 0, 0, 0, 0); } return true; }
SDL_Surface *TTF_RenderUNICODE_Solid(TTF_Font *font, const Uint16 *text, SDL_Color fg) { int xstart, width; int w, h; SDL_Surface *textbuf; SDL_Palette *palette; const Uint16 *ch; Uint8 *src, *dst; int row, col; TT_Error error; /* Get the dimensions of the text surface */ if ( (TTF_SizeUNICODE(font, text, &w, &h) < 0) || !w ) { TTF_SetError("Text has zero width"); return(NULL); } /* Create the target surface */ width = w; w = (w+7)&~7; textbuf = SDL_AllocSurface(SDL_SWSURFACE, w, h, 8, 0, 0, 0, 0); if ( textbuf == NULL ) { return(NULL); } /* Fill the palette with the foreground color */ palette = textbuf->format->palette; palette->colors[0].r = 255-fg.r; palette->colors[0].g = 255-fg.g; palette->colors[0].b = 255-fg.b; palette->colors[1].r = fg.r; palette->colors[1].g = fg.g; palette->colors[1].b = fg.b; SDL_SetColorKey(textbuf, SDL_SRCCOLORKEY, 0); /* Load and render each character */ xstart = 0; for ( ch=text; *ch; ++ch ) { error = Find_Glyph(font, *ch); if ( ! error ) { w = font->current->bitmap.width; src = (Uint8 *)font->current->bitmap.bitmap; for ( row = 0; row < h; ++row ) { dst = (Uint8 *)textbuf->pixels + row * textbuf->pitch + xstart + font->current->minx; for ( col = 0; col < w; col += 8 ) { Uint8 c = *src++; *dst++ |= (c&0x80)>>7; c <<= 1; *dst++ |= (c&0x80)>>7; c <<= 1; *dst++ |= (c&0x80)>>7; c <<= 1; *dst++ |= (c&0x80)>>7; c <<= 1; *dst++ |= (c&0x80)>>7; c <<= 1; *dst++ |= (c&0x80)>>7; c <<= 1; *dst++ |= (c&0x80)>>7; c <<= 1; *dst++ |= (c&0x80)>>7; } } xstart += font->current->advance; if ( font->style & TTF_STYLE_BOLD ) { xstart += font->glyph_overhang; } } }
/****************************************************************************** Description.: this is the main worker thread it loops forever, grabs a fresh frame, decompressed the JPEG and displays the decoded data using SDL Input Value.: Return Value: ******************************************************************************/ void *worker_thread(void *arg) { int frame_size = 0, firstrun = 1; SDL_Surface *screen = NULL, *image = NULL; decompressed_image rgbimage; /* initialze the buffer for the decompressed image */ rgbimage.buffersize = 0; rgbimage.buffer = NULL; /* initialze the SDL video subsystem */ if(SDL_Init(SDL_INIT_VIDEO) < 0) { fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); exit(EXIT_FAILURE); } /* just allocate a large buffer for the JPEGs */ if((frame = malloc(4096 * 1024)) == NULL) { OPRINT("not enough memory for worker thread\n"); exit(EXIT_FAILURE); } /* set cleanup handler to cleanup allocated ressources */ pthread_cleanup_push(worker_cleanup, NULL); while(!pglobal->stop) { DBG("waiting for fresh frame\n"); pthread_mutex_lock(&pglobal->in[input_number].db); pthread_cond_wait(&pglobal->in[plugin_number].db_update, &pglobal->in[plugin_number].db); /* read buffer */ frame_size = pglobal->in[plugin_number].size; memcpy(frame, pglobal->in[plugin_number].buf, frame_size); pthread_mutex_unlock(&pglobal->in[plugin_number].db); /* decompress the JPEG and store results in memory */ if(decompress_jpeg(frame, frame_size, &rgbimage)) { DBG("could not properly decompress JPEG data\n"); continue; } if(firstrun) { /* create the primary surface (the visible window) */ screen = SDL_SetVideoMode(rgbimage.width, rgbimage.height, 0, SDL_ANYFORMAT | SDL_HWSURFACE); SDL_WM_SetCaption("MJPG-Streamer Viewer", NULL); /* create a SDL surface to display the data */ image = SDL_AllocSurface(SDL_SWSURFACE, rgbimage.width, rgbimage.height, 24, #if SDL_BYTEORDER == SDL_LIL_ENDIAN 0x0000FF, 0x00FF00, 0xFF0000, #else 0xFF0000, 0x00FF00, 0x0000FF, #endif 0); /* copy the decoded data across */ memcpy(image->pixels, rgbimage.buffer, rgbimage.width * rgbimage.height * 3); free(rgbimage.buffer); /* now, that we know the dimensions, we can directly copy to the right surface */ rgbimage.buffer = image->pixels; rgbimage.buffersize = rgbimage.width * rgbimage.height * 3; firstrun = 0; } /* copy the image to the primary surface */ SDL_BlitSurface(image, NULL, screen, NULL); /* redraw the whole surface */ SDL_Flip(screen); } pthread_cleanup_pop(1); /* get rid of the image */ SDL_FreeSurface(image); return NULL; }
SDL_Surface *IMG_LoadPNG_RW(SDL_RWops *src) { int start; const char *error; SDL_Surface *volatile surface; png_structp png_ptr; png_infop info_ptr; png_uint_32 width, height; int bit_depth, color_type, interlace_type; Uint32 Rmask; Uint32 Gmask; Uint32 Bmask; Uint32 Amask; SDL_Palette *palette; png_bytep *volatile row_pointers; int row, i; volatile int ckey = -1; png_color_16 *transv; if ( !src ) { /* The error message has been set in SDL_RWFromFile */ return NULL; } start = SDL_RWtell(src); if ( IMG_InitPNG() < 0 ) { return NULL; } /* Initialize the data we will clean up when we're done */ error = NULL; png_ptr = NULL; info_ptr = NULL; row_pointers = NULL; surface = NULL; /* Create the PNG loading context structure */ png_ptr = lib.png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,NULL,NULL); if (png_ptr == NULL){ error = "Couldn't allocate memory for PNG file or incompatible PNG dll"; goto done; } /* Allocate/initialize the memory for image information. REQUIRED. */ info_ptr = lib.png_create_info_struct(png_ptr); if (info_ptr == NULL) { error = "Couldn't create image information for PNG file"; goto done; } /* Set error handling if you are using setjmp/longjmp method (this is * the normal method of doing things with libpng). REQUIRED unless you * set up your own error handlers in png_create_read_struct() earlier. */ if ( setjmp(png_ptr->jmpbuf) ) { error = "Error reading the PNG file."; goto done; } /* Set up the input control */ lib.png_set_read_fn(png_ptr, src, png_read_data); /* Read PNG header info */ lib.png_read_info(png_ptr, info_ptr); lib.png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); /* tell libpng to strip 16 bit/color files down to 8 bits/color */ lib.png_set_strip_16(png_ptr) ; /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single * byte into separate bytes (useful for paletted and grayscale images). */ lib.png_set_packing(png_ptr); /* scale greyscale values to the range 0..255 */ if(color_type == PNG_COLOR_TYPE_GRAY) lib.png_set_expand(png_ptr); /* For images with a single "transparent colour", set colour key; if more than one index has transparency, or if partially transparent entries exist, use full alpha channel */ if (lib.png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { int num_trans; Uint8 *trans; lib.png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, &transv); if(color_type == PNG_COLOR_TYPE_PALETTE) { /* Check if all tRNS entries are opaque except one */ int i, t = -1; for(i = 0; i < num_trans; i++) if(trans[i] == 0) { if(t >= 0) break; t = i; } else if(trans[i] != 255) break; if(i == num_trans) { /* exactly one transparent index */ ckey = t; } else { /* more than one transparent index, or translucency */ lib.png_set_expand(png_ptr); } } else ckey = 0; /* actual value will be set later */ } if ( color_type == PNG_COLOR_TYPE_GRAY_ALPHA ) lib.png_set_gray_to_rgb(png_ptr); lib.png_read_update_info(png_ptr, info_ptr); lib.png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); /* Allocate the SDL surface to hold the image */ Rmask = Gmask = Bmask = Amask = 0 ; if ( color_type != PNG_COLOR_TYPE_PALETTE ) { if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) { Rmask = 0x000000FF; Gmask = 0x0000FF00; Bmask = 0x00FF0000; Amask = (info_ptr->channels == 4) ? 0xFF000000 : 0; } else { int s = (info_ptr->channels == 4) ? 0 : 8; Rmask = 0xFF000000 >> s; Gmask = 0x00FF0000 >> s; Bmask = 0x0000FF00 >> s; Amask = 0x000000FF >> s; } } surface = SDL_AllocSurface(SDL_SWSURFACE, width, height, bit_depth*info_ptr->channels, Rmask,Gmask,Bmask,Amask); if ( surface == NULL ) { error = "Out of memory"; goto done; } if(ckey != -1) { if(color_type != PNG_COLOR_TYPE_PALETTE) /* FIXME: Should these be truncated or shifted down? */ ckey = SDL_MapRGB(surface->format, (Uint8)transv->red, (Uint8)transv->green, (Uint8)transv->blue); SDL_SetColorKey(surface, SDL_SRCCOLORKEY, ckey); } /* Create the array of pointers to image data */ row_pointers = (png_bytep*) malloc(sizeof(png_bytep)*height); if ( (row_pointers == NULL) ) { error = "Out of memory"; goto done; } for (row = 0; row < (int)height; row++) { row_pointers[row] = (png_bytep) (Uint8 *)surface->pixels + row*surface->pitch; } /* Read the entire image in one go */ lib.png_read_image(png_ptr, row_pointers); /* and we're done! (png_read_end() can be omitted if no processing of * post-IDAT text/time/etc. is desired) * In some cases it can't read PNG's created by some popular programs (ACDSEE), * we do not want to process comments, so we omit png_read_end lib.png_read_end(png_ptr, info_ptr); */ /* Load the palette, if any */ palette = surface->format->palette; if ( palette ) { if(color_type == PNG_COLOR_TYPE_GRAY) { palette->ncolors = 256; for(i = 0; i < 256; i++) { palette->colors[i].r = i; palette->colors[i].g = i; palette->colors[i].b = i; } } else if (info_ptr->num_palette > 0 ) { palette->ncolors = info_ptr->num_palette; for( i=0; i<info_ptr->num_palette; ++i ) { palette->colors[i].b = info_ptr->palette[i].blue; palette->colors[i].g = info_ptr->palette[i].green; palette->colors[i].r = info_ptr->palette[i].red; } } } done: /* Clean up and return */ if ( png_ptr ) { lib.png_destroy_read_struct(&png_ptr, info_ptr ? &info_ptr : (png_infopp)0, (png_infopp)0); } if ( row_pointers ) { free(row_pointers); } if ( error ) { SDL_RWseek(src, start, SEEK_SET); if ( surface ) { SDL_FreeSurface(surface); surface = NULL; } IMG_QuitPNG(); IMG_SetError(error); } else { IMG_QuitPNG(); } return(surface); }
SDL_Surface *IMG_LoadPNM_RW(SDL_RWops *src) { SDL_Surface *surface = NULL; int width, height; int maxval, y, bpl; Uint8 *row; Uint8 *buf = NULL; char *error = NULL; Uint8 magic[2]; int ascii; enum { PBM, PGM, PPM } kind; #define ERROR(s) do { error = (s); goto done; } while(0) if(!src) return NULL; SDL_RWread(src, magic, 2, 1); kind = magic[1] - '1'; ascii = 1; if(kind >= 3) { ascii = 0; kind -= 3; } width = ReadNumber(src); height = ReadNumber(src); if(width <= 0 || height <= 0) ERROR("Unable to read image width and height"); if(kind != PBM) { maxval = ReadNumber(src); if(maxval <= 0 || maxval > 255) ERROR("unsupported PNM format"); } else maxval = 255; /* never scale PBMs */ /* binary PNM allows just a single character of whitespace after the last parameter, and we've already consumed it */ if(kind == PPM) { /* 24-bit surface in R,G,B byte order */ surface = SDL_AllocSurface(SDL_SWSURFACE, width, height, 24, #if SDL_BYTEORDER == SDL_LIL_ENDIAN 0x000000ff, 0x0000ff00, 0x00ff0000, #else 0x00ff0000, 0x0000ff00, 0x000000ff, #endif 0); } else { /* load PBM/PGM as 8-bit indexed images */ surface = SDL_AllocSurface(SDL_SWSURFACE, width, height, 8, 0, 0, 0, 0); } if ( surface == NULL ) ERROR("Out of memory"); bpl = width * surface->format->BytesPerPixel; if(kind == PGM) { SDL_Color *c = surface->format->palette->colors; int i; for(i = 0; i < 256; i++) c[i].r = c[i].g = c[i].b = i; surface->format->palette->ncolors = 256; } else if(kind == PBM) { /* for some reason PBM has 1=black, 0=white */ SDL_Color *c = surface->format->palette->colors; c[0].r = c[0].g = c[0].b = 255; c[1].r = c[1].g = c[1].b = 0; surface->format->palette->ncolors = 2; bpl = (width + 7) >> 3; buf = malloc(bpl); if(buf == NULL) ERROR("Out of memory"); }
/*-------------------------------------------------------------------------- truecolor png image loader (backend) takes a buffer containing raw image data and returns an SDL_Surface srcbuf : [in] buffer containing a complete image file buflen : [in] length of the input buffer --------------------------------------------------------------------------*/ SDL_Surface *vulture_load_surface(char *srcbuf, unsigned int buflen) { png_structp png_ptr; png_infop info_ptr; Uint32 Rmask, Gmask, Bmask, Amask; png_uint_32 width, height; int bit_depth, color_type, row; png_bytep * row_pointers = NULL; SDL_Surface *img, *convert; /* vulture_load_surface converts everything to screen format for faster blitting * so we can't continue if we don't have a screen yet */ if (!vulture_screen) return NULL; /* no NULL pointers, please */ if (!srcbuf) return NULL; img = NULL; /* memory region must contain a png file */ if (png_sig_cmp((unsigned char *)srcbuf, 0, PNG_BYTES_TO_CHECK)) return NULL; /* Create the PNG loading context structure */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) return NULL; /* Allocate/initialize the memory for image information. REQUIRED. */ info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) goto out; /* Set up error handling */ if (setjmp(png_ptr->jmpbuf)) goto out; png_set_read_fn(png_ptr, (char *)srcbuf, vulture_png_read_callback); /* Read PNG header info */ png_read_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL); /* reduce 16 bit per channel to 8 bit per channel */ png_set_strip_16(png_ptr); /* expand 1,2,4 bit grayscale to 8 bit grayscale; expand paletted images to rgb, * expand tRNS to true alpha channel */ png_set_expand(png_ptr); /* expand grayscale to full rgb */ png_set_gray_to_rgb(png_ptr); /* add an opaque alpha channel to anything that doesn't have one yet */ png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; /* get the component mask for the surface */ if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) { Rmask = 0x000000FF; Gmask = 0x0000FF00; Bmask = 0x00FF0000; Amask = 0xFF000000; } else { Rmask = 0xFF000000; Gmask = 0x00FF0000; Bmask = 0x0000FF00; Amask = 0x000000FF; } img = SDL_AllocSurface(SDL_SWSURFACE | SDL_SRCALPHA, width, height, 32, Rmask, Gmask, Bmask, Amask); if (!img) goto out; /* Create the array of pointers to image data */ row_pointers = new png_bytep[height]; if (!row_pointers) { SDL_FreeSurface(img); img = NULL; goto out; } for (row = 0; row < (int)height; row++) row_pointers[row] = (png_bytep)(Uint8 *)img->pixels + row * img->pitch; /* read the image */ png_read_image(png_ptr, row_pointers); out: png_destroy_read_struct(&png_ptr, info_ptr ? &info_ptr : NULL, NULL); if (row_pointers) delete row_pointers; if (!img) return NULL; convert = SDL_DisplayFormatAlpha(img); SDL_FreeSurface(img); img = convert; return img; }
/* Initialise SDL and create a window of the correct size. */ int BaseEngine::Initialise( char* strCaption, int iScreenWidth, int iScreenHeight, char* szFontName, int iFontSize ) { m_iScreenWidth = iScreenWidth; m_iScreenHeight = iScreenHeight; // Initialize SDL's subsystems if (SDL_Init(SDL_INIT_VIDEO) < 0) { fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError()); return 1; } // Register SDL_Quit to be called at exit; makes sure things are // cleaned up when we quit. atexit(SDL_Quit); // True type font stuff TTF_Init(); atexit(TTF_Quit); m_oFontManager.LoadFonts(); // Load the default font - used whenever NULL is passed if ( ( szFontName != NULL ) && ( strlen(szFontName) > 0 ) ) g_pMainFont = m_oFontManager.GetFont( szFontName, iFontSize ); // Attempt to create a m_iScreenWidth x m_iScreenHeight window with 32bit pixels. m_pActualScreen = SDL_SetVideoMode(m_iScreenWidth, m_iScreenHeight, 32, SDL_SWSURFACE); // m_pActualScreen = SDL_SetVideoMode(m_iScreenWidth, m_iScreenHeight, 32, SDL_HWSURFACE); // m_pActualScreen = SDL_SetVideoMode(m_iScreenWidth, m_iScreenHeight, 32, SDL_DOUBLEBUF); SDL_WM_SetCaption( strCaption, NULL ); #if defined(_MSC_VER) SDL_SysWMinfo i; SDL_VERSION( &i.version ); if ( SDL_GetWMInfo ( &i ) ) { HWND hwnd = i.window; SetWindowPos( hwnd, HWND_TOP, 0, 0, m_iScreenWidth, m_iScreenHeight, SWP_NOSIZE ); } #endif // WIN32 m_pBackgroundSurface = SDL_AllocSurface( SDL_SWSURFACE/*flags*/, m_iScreenWidth, m_iScreenHeight, 32, 0,0,0,0 ); // If we fail, return error. if (m_pActualScreen == NULL) { fprintf(stderr, "Unable to set up video: %s\n", SDL_GetError()); return 2; } // Retrieve the number of ints per row from the screen information m_iIntsPerScreenRow = m_pActualScreen->pitch/sizeof(unsigned int); //m_puiScreenBuffer = new unsigned int [ m_iIntsPerScreenRow * m_iScreenHeight ]; // Initialise key status m_pKeyStatus = new int[1 + SDLK_LAST - SDLK_FIRST]; memset( m_pKeyStatus, 0, sizeof(int)*(1 + SDLK_LAST - SDLK_FIRST) ); // Call method to allow custom sub-class initialiation. GameInit(); return 0; // success }
void playVideo(const string &file) { //myFillRect(screen, NULL, 0); //SDL_GL_SwapBuffers(); SMPEG *mpeg; SMPEG_Info info; mpeg = SMPEG_new(file.c_str(), &info, false); bool hasAudio = (info.has_audio > 0); if ( SMPEG_error(mpeg) ) { dout << "MPEG error: " << SMPEG_error(mpeg) << endl; exit(1); } int done = 0; SDL_Surface *videoSurface = SDL_AllocSurface( SDL_SWSURFACE, nearestPow2(info.width), nearestPow2(info.height), 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 ); if ( !videoSurface ) { dout << "Failed to allocate memory for video playback" << endl; exit(1); } SMPEG_enablevideo(mpeg, 1); SDL_mutex *mutex = SDL_CreateMutex(); SMPEG_setdisplay(mpeg, videoSurface, mutex, videoUpdate ); SMPEG_scaleXY(mpeg, info.width, info.height); //SMPEG_setdisplayregion(mpeg, 0, 0, info.width, info.height); //SMPEG_setdisplay(mpeg, screen, NULL, update); if(hasAudio) { SDL_AudioSpec audiofmt; Uint16 format; int freq, channels; /* Tell SMPEG what the audio format is */ Mix_QuerySpec(&freq, &format, &channels); audiofmt.format = format; audiofmt.freq = freq; audiofmt.channels = channels; SMPEG_actualSpec(mpeg, &audiofmt); /* Hook in the MPEG music mixer */ Mix_HookMusic(SMPEG_playAudioSDL, mpeg); SMPEG_enableaudio(mpeg, 1); SMPEG_setvolume(mpeg, 100); } else { Mix_PauseMusic(); SMPEG_enableaudio(mpeg, 0); } glBlendFunc(GL_ONE, GL_ZERO); glEnable(GL_TEXTURE_2D); SMPEG_play(mpeg); while( !done && SMPEG_status( mpeg ) == SMPEG_PLAYING ) { SDL_Event event; while ( SDL_PollEvent(&event) ) { switch (event.type) { case SDL_KEYDOWN: { if ( event.key.keysym.sym == SDLK_SPACE ) { done = 1; } break; } case SDL_QUIT: { exit(1); } default: break; } } if(drawVideoFrame) { SDL_mutexP(mutex); drawVideoFrame = false; drawVideo(videoSurface, info.width, info.height); //printf("draw in %i\n", time(NULL)); SDL_mutexV(mutex); SDL_GL_SwapBuffers(); } } SMPEG_stop(mpeg); if(hasAudio) { Mix_HookMusic(NULL, NULL); } else { Mix_ResumeMusic(); } SDL_FreeSurface(videoSurface); myFillRect(screen, NULL, 0); SDL_GL_SwapBuffers(); SMPEG_delete(mpeg); }
/* Load a JPEG type image from an SDL datasource */ SDL_Surface *IMG_LoadJPG_RW(SDL_RWops *src) { struct jpeg_decompress_struct cinfo; JSAMPROW rowptr[1]; SDL_Surface *volatile surface = NULL; struct my_error_mgr jerr; /* Create a decompression structure and load the JPEG header */ cinfo.err = jpeg_std_error(&jerr.errmgr); jerr.errmgr.error_exit = my_error_exit; jerr.errmgr.output_message = output_no_message; if(setjmp(jerr.escape)) { /* If we get here, libjpeg found an error */ jpeg_destroy_decompress(&cinfo); IMG_SetError("JPEG loading error"); SDL_FreeSurface(surface); return NULL; } jpeg_create_decompress(&cinfo); jpeg_SDL_RW_src(&cinfo, src); jpeg_read_header(&cinfo, TRUE); /* Set 24-bit RGB output */ cinfo.out_color_space = JCS_RGB; cinfo.quantize_colors = FALSE; #ifdef FAST_JPEG cinfo.scale_num = 1; cinfo.scale_denom = 1; cinfo.dct_method = JDCT_FASTEST; cinfo.do_fancy_upsampling = FALSE; #endif jpeg_calc_output_dimensions(&cinfo); /* Allocate an output surface to hold the image */ surface = SDL_AllocSurface(SDL_SWSURFACE, cinfo.output_width, cinfo.output_height, 24, #if SDL_BYTEORDER == SDL_LIL_ENDIAN 0x0000FF, 0x00FF00, 0xFF0000, #else 0xFF0000, 0x00FF00, 0x0000FF, #endif 0); if ( surface == NULL ) { IMG_SetError("Out of memory"); goto done; } /* Decompress the image */ jpeg_start_decompress(&cinfo); while ( cinfo.output_scanline < cinfo.output_height ) { rowptr[0] = (JSAMPROW)(Uint8 *)surface->pixels + cinfo.output_scanline * surface->pitch; jpeg_read_scanlines(&cinfo, rowptr, (JDIMENSION) 1); } jpeg_finish_decompress(&cinfo); /* Clean up and return */ done: jpeg_destroy_decompress(&cinfo); return(surface); }
PUBLIC SDL_Surface * surface_from_dib (void *lp) { BITMAPINFOHEADER *bp; SDL_Surface *retval; retval = NULL; bp = lp; switch (bp->biBitCount) { case 1: case 2: case 4: case 8: case 16: case 32: default: /* TODO */ break; case 24: { enum { A = 0xFF000000, R = 0x00FF0000, G = 0x0000FF00, B = 0x000000FF }; typedef struct { uint8 zero PACKED; uint8 red PACKED; uint8 green PACKED; uint8 blue PACKED; } sdl_pixel; typedef struct { uint8 blue PACKED; uint8 red PACKED; uint8 green PACKED; } dib_pixel; int pixels_per_line; boolean_t inverted_p; int n_lines; sdl_pixel *op, *eop; dib_pixel *ip, *eip; int in_pitch; int out_pitch; int ip_advance; int op_advance; pixels_per_line = bp->biWidth; inverted_p = (bp->biHeight > 0); n_lines = inverted_p ? bp->biHeight : -bp->biHeight; retval = SDL_AllocSurface (SDL_SWSURFACE, pixels_per_line, n_lines, 32, R, G, B, A); SDL_LockSurface (retval); op = SDL_Surface_pixels (retval); ip = (typeof (ip)) (bp + 1); out_pitch = SDL_Surface_pitch (retval); in_pitch = roundup (pixels_per_line * sizeof *ip, 4); ip_advance = in_pitch - sizeof *ip * pixels_per_line; op_advance = out_pitch - sizeof *op * pixels_per_line; if (inverted_p) { advance_n_bytes (&ip, in_pitch * (n_lines - 1)); ip_advance -= 2 * in_pitch; } eip = ip; advance_n_bytes (&eip, n_lines * (ip_advance + pixels_per_line * sizeof *ip)); for (; ip != eip; advance_n_bytes (&ip, ip_advance), advance_n_bytes (&op, op_advance)) for (eop = op + pixels_per_line; op != eop; ++ip, ++op) { op->zero = 0; op->red = ip->red; op->green = ip->green; op->blue = ip->blue; } SDL_UnlockSurface (retval); break; } } return retval; }
/* Load a PCX type image from an SDL datasource */ SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src) { struct PCXheader pcxh; Uint32 Rmask; Uint32 Gmask; Uint32 Bmask; Uint32 Amask; SDL_Surface *surface = NULL; int width, height; int y, bpl; Uint8 *row, *buf = NULL; char *error = NULL; int bits, src_bits; if ( ! src ) { goto done; } if ( ! SDL_RWread(src, &pcxh, sizeof(pcxh), 1) ) { error = "file truncated"; goto done; } pcxh.Xmin = SDL_SwapLE16(pcxh.Xmin); pcxh.Ymin = SDL_SwapLE16(pcxh.Ymin); pcxh.Xmax = SDL_SwapLE16(pcxh.Xmax); pcxh.Ymax = SDL_SwapLE16(pcxh.Ymax); pcxh.BytesPerLine = SDL_SwapLE16(pcxh.BytesPerLine); /* Create the surface of the appropriate type */ width = (pcxh.Xmax - pcxh.Xmin) + 1; height = (pcxh.Ymax - pcxh.Ymin) + 1; Rmask = Gmask = Bmask = Amask = 0; src_bits = pcxh.BitsPerPixel * pcxh.NPlanes; if((pcxh.BitsPerPixel == 1 && pcxh.NPlanes >= 1 && pcxh.NPlanes <= 4) || (pcxh.BitsPerPixel == 8 && pcxh.NPlanes == 1)) { bits = 8; } else if(pcxh.BitsPerPixel == 8 && pcxh.NPlanes == 3) { bits = 24; if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) { Rmask = 0x000000FF; Gmask = 0x0000FF00; Bmask = 0x00FF0000; } else { Rmask = 0xFF0000; Gmask = 0x00FF00; Bmask = 0x0000FF; } } else { error = "unsupported PCX format"; goto done; } surface = SDL_AllocSurface(SDL_SWSURFACE, width, height, bits, Rmask, Gmask, Bmask, Amask); if ( surface == NULL ) goto done; bpl = pcxh.NPlanes * pcxh.BytesPerLine; buf = malloc(bpl); row = surface->pixels; for ( y=0; y<surface->h; ++y ) { /* decode a scan line to a temporary buffer first */ int i, count = 0; Uint8 ch; Uint8 *dst = (src_bits == 8) ? row : buf; for(i = 0; i < bpl; i++) { if(!count) { if(!SDL_RWread(src, &ch, 1, 1)) { error = "file truncated"; goto done; } if( (ch & 0xc0) == 0xc0) { count = ch & 0x3f; if(!SDL_RWread(src, &ch, 1, 1)) { error = "file truncated"; goto done; } } else count = 1; } dst[i] = ch; count--; } if(src_bits <= 4) { /* expand planes to 1 byte/pixel */ Uint8 *src = buf; int plane; for(plane = 0; plane < pcxh.NPlanes; plane++) { int i, j, x = 0; for(i = 0; i < pcxh.BytesPerLine; i++) { Uint8 byte = *src++; for(j = 7; j >= 0; j--) { unsigned bit = (byte >> j) & 1; row[x++] |= bit << plane; } } } } else if(src_bits == 24) {
void SFont_InputInfo( SDL_Surface *Dest, SFont_FontInfo *Font, int x, int y, int PixelWidth, char *text) { SDL_Event event; int ch=-1,blink=0; unsigned long blinktimer=0; SDL_Surface *Back; SDL_Rect rect; int previous; // int ofs=(text[0]-33)*2+1; // int leftshift=(Font->CharPos[ofs]-Font->CharPos[ofs-1])/2; Back = SDL_AllocSurface(Dest->flags, Dest->w, Font->h, Dest->format->BitsPerPixel, Dest->format->Rmask, Dest->format->Gmask, Dest->format->Bmask, 0); rect.x=0; rect.y=y; rect.w=Dest->w; rect.h=Font->Surface->h; SDL_BlitSurface(Dest, &rect, Back, NULL); SFont_PutStringInfo(Dest,Font,x,y,text); SDL_UpdateRects(Dest, 1, &rect); // start input previous=SDL_EnableUNICODE(1); blinktimer=SDL_GetTicks(); while (ch!=SDLK_RETURN) { if (event.type==SDL_KEYDOWN) { ch=event.key.keysym.unicode; if (((ch>31)||(ch=='\b')) && (ch<128)) { if ((ch=='\b')&&(strlen(text)>0)) text[strlen(text)-1]='\0'; else if (ch!='\b') sprintf(text,"%s%c",text,ch); if (SFont_TextWidthInfo(Font,text)>PixelWidth) text[strlen(text)-1]='\0'; SDL_BlitSurface( Back, NULL, Dest, &rect); SFont_PutStringInfo(Dest, Font, x, y, text); SDL_UpdateRects(Dest, 1, &rect); // printf("%s ## %d\n",text,strlen(text)); SDL_WaitEvent(&event); } } if (SDL_GetTicks()>blinktimer) { blink=1-blink; blinktimer=SDL_GetTicks()+500; if (blink) { SFont_PutStringInfo(Dest, Font, x+SFont_TextWidthInfo(Font,text), y, "|"); SDL_UpdateRects(Dest, 1, &rect); // SDL_UpdateRect(Dest, x+SFont_TextWidthInfo(Font,text), y, SFont_TextWidthInfo(Font,"|"), Font->Surface->h); } else { SDL_BlitSurface( Back, NULL, Dest, &rect); SFont_PutStringInfo(Dest, Font, x, y, text); SDL_UpdateRects(Dest, 1, &rect); // SDL_UpdateRect(Dest, x-(Font->CharPos[ofs]-Font->CharPos[ofs-1])/2, y, PixelWidth, Font->Surface->h); } } SDL_Delay(1); SDL_PollEvent(&event); } text[strlen(text)]='\0'; SDL_FreeSurface(Back); SDL_EnableUNICODE(previous); //restore the previous state }
// ------------------------------------------------------ // Initialize a requester int Display_Requester(LPREQUESTER Requester, int Action) { int i; // Inhibit main actions In_Requester = TRUE; Current_Requester = Requester; // Minim mum size Size_X = 0; Size_Y = 0; // Register the extra action to perform Requester_Action = Action; // Parse the text int Max_Buttons_Size; int Biggest_Button; char *txt = Requester->Text; char *txt_beg; i = 0; Nbr_Lines = 0; Nbr_Buttons = 0; Max_Buttons_Size = 0; Req_Timer = 0; Req_TimeOut = Requester->TimeOut; Req_Picture = NULL; if(Requester->Picture) Req_Picture = *Requester->Picture; Req_Default_Button = -1; Cancel_Button = -1; Req_Pressed_Button = 0; memset(Req_Txt_Lines, 0, sizeof(Req_Txt_Lines)); txt_beg = txt; while(txt[0]) { if(txt[0] == '\n') { Req_Txt_Lines[Nbr_Lines] = (char *) malloc(i + 1); memset(Req_Txt_Lines[Nbr_Lines], 0, i + 1); strncpy(Req_Txt_Lines[Nbr_Lines], txt_beg, i); Req_Txt_Pos_X[Nbr_Lines] = Get_Size_Text(Req_Txt_Lines[Nbr_Lines]); if(Req_Txt_Pos_X[Nbr_Lines] > Size_X) { Size_X = Req_Txt_Pos_X[Nbr_Lines]; Get_Size_Text(Req_Txt_Lines[Nbr_Lines]); } Nbr_Lines++; i = 0; txt++; txt_beg = txt; } i++; txt++; } if(i > 0) { Req_Txt_Lines[Nbr_Lines] = (char *) malloc(i + 1); memset(Req_Txt_Lines[Nbr_Lines], 0, i + 1); strncpy(Req_Txt_Lines[Nbr_Lines], txt_beg, i); Req_Txt_Pos_X[Nbr_Lines] = Get_Size_Text(Req_Txt_Lines[Nbr_Lines]); if(Req_Txt_Pos_X[Nbr_Lines] > Size_X) { Size_X = Req_Txt_Pos_X[Nbr_Lines]; } Nbr_Lines++; } // Parse the buttons LPREQUESTER_BUTTON Button; Button = Requester->Buttons; Biggest_Button = 0; while(Button) { Buttons_Text[Nbr_Buttons] = Button->Text; Buttons_Keys[Nbr_Buttons] = Button->Key; if(Get_Size_Text(Button->Text) + 42 > Biggest_Button) { Biggest_Button = Get_Size_Text(Button->Text) + 30; } // Record the buttons type switch(Button->Type) { case BUTTON_DEFAULT: Req_Default_Button = Nbr_Buttons + 1; break; case BUTTON_CANCEL: Cancel_Button = Nbr_Buttons + 1; break; } Nbr_Buttons++; Button = (LPREQUESTER_BUTTON) Button->Next; } for(i = 0; i < Nbr_Buttons; i++) { Buttons_Size[i] = Biggest_Button; Max_Buttons_Size += Buttons_Size[i]; } if(Max_Buttons_Size > Size_X) Size_X = Max_Buttons_Size; if(!Size_X) { Size_X = Req_Picture->w + ((BEVEL_SIZE) * 2) + 1; } else { Size_X += 150; } float Si = (float) Size_X / (float) Nbr_Buttons; float Pos_Si = 0.0f; for(i = 0; i < Nbr_Buttons; i++) { Buttons_Pos[i] = (int) (((Si - (float) Buttons_Size[i]) / 2.0f) + Pos_Si); Pos_Si += Si; } for(i = 0; i < Nbr_Lines; i++) { Req_Txt_Pos_X[i] = (Size_X - Req_Txt_Pos_X[i]) / 2; } if(!Nbr_Lines) { Size_Y = Req_Picture->h + ((BEVEL_SIZE) * 2); } else { Size_Y = (((Nbr_Lines + 5) * Font_Height) + 18); } Pos_X = (CONSOLE_WIDTH - Size_X) / 2; Pos_Y = (CONSOLE_HEIGHT - Size_Y) / 2; Req_Back = SDL_AllocSurface(SDL_SWSURFACE, Size_X + 1, Size_Y + 1, 32, 0xff0000, 0xff00, 0xff, 0xff000000); if(Req_Back) { Copy_To_Surface(Main_Screen, Req_Back, 0, 0, Pos_X, Pos_Y, Pos_X + Size_X + 1, Pos_Y + Size_Y + 1); } return(0); }
/*--------------------------------------------------------------------------*/ static SDL_Surface* ReadImage( gifdata* gd, int len, int height, int cmapSize, unsigned char cmap[3][MAXCOLORMAPSIZE], int interlace, int ignore ) { SDL_Surface* image; unsigned char c; int i, v; int xpos = 0, ypos = 0, pass = 0; /* Initialize the compression routines */ if ( !SDL_RWread(gd->src,&c,1,1) ) { SDL_SetError( "EOF / read error on image data" ); return NULL; } if ( LWZReadByte(gd,TRUE,c) < 0 ) { SDL_SetError( "error reading image" ); return NULL; } /* If this is an "uninteresting picture" ignore it. */ if ( ignore ) { while ( LWZReadByte(gd,FALSE,c) >= 0 ) ; return NULL; } image = SDL_AllocSurface( SDL_SWSURFACE, len, height, 8, 0, 0, 0, 0 ); for ( i = 0; i < cmapSize; i++ ) { image->format->palette->colors[i].r = cmap[CM_RED][i]; image->format->palette->colors[i].g = cmap[CM_GREEN][i]; image->format->palette->colors[i].b = cmap[CM_BLUE][i]; } while ( (v = LWZReadByte(gd,FALSE,c)) >= 0 ) { ((Uint8*)image->pixels)[xpos + ypos*image->pitch] = (Uint8)v; ++xpos; if ( xpos == len ) { xpos = 0; if ( interlace ) { switch ( pass ) { case 0: case 1: ypos += 8; break; case 2: ypos += 4; break; case 3: ypos += 2; break; } if ( ypos >= height ) { ++pass; switch ( pass ) { case 1: ypos = 4; break; case 2: ypos = 2; break; case 3: ypos = 1; break; default: goto fini; } } } else { ++ypos; } } if ( ypos >= height ) break; } fini: return image; }