19682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 29682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Simple program: Test bitmap blits */ 39682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 49682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <stdio.h> 59682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <stdlib.h> 69682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <string.h> 79682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 89682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SDL.h" 99682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "picture.xbm" 109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ 129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void quit(int rc) 139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Quit(); 159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall exit(rc); 169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallSDL_Surface *LoadXBM(SDL_Surface *screen, int w, int h, Uint8 *bits) 199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Surface *bitmap; 219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint8 *line; 229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Allocate the bitmap */ 249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bitmap = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 1, 0, 0, 0, 0); 259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( bitmap == NULL ) { 269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "Couldn't allocate bitmap: %s\n", 279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_GetError()); 289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(NULL); 299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Copy the pixels */ 329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall line = (Uint8 *)bitmap->pixels; 339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall w = (w+7)/8; 349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while ( h-- ) { 359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall memcpy(line, bits, w); 369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* X11 Bitmap images have the bits reversed */ 379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { int i, j; Uint8 *buf, byte; 389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for ( buf=line, i=0; i<w; ++i, ++buf ) { 399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall byte = *buf; 409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *buf = 0; 419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for ( j=7; j>=0; --j ) { 429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *buf |= (byte&0x01)<<j; 439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall byte >>= 1; 449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall line += bitmap->pitch; 489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bits += w; 499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(bitmap); 519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallint main(int argc, char *argv[]) 549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Surface *screen; 569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Surface *bitmap; 579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint8 video_bpp; 589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint32 videoflags; 599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint8 *buffer; 609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall int i, k, done; 619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Event event; 629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint16 *buffer16; 639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint16 color; 649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint8 gradient; 659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Color palette[256]; 669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Initialize SDL */ 699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { 709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError()); 719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(1); 729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall video_bpp = 0; 759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall videoflags = SDL_SWSURFACE; 769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while ( argc > 1 ) { 779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall --argc; 789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( strcmp(argv[argc-1], "-bpp") == 0 ) { 799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall video_bpp = atoi(argv[argc]); 809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall --argc; 819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else 829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( strcmp(argv[argc], "-warp") == 0 ) { 839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall videoflags |= SDL_HWPALETTE; 849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else 859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( strcmp(argv[argc], "-hw") == 0 ) { 869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall videoflags |= SDL_HWSURFACE; 879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else 889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( strcmp(argv[argc], "-fullscreen") == 0 ) { 899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall videoflags |= SDL_FULLSCREEN; 909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else { 919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, 929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall "Usage: %s [-bpp N] [-warp] [-hw] [-fullscreen]\n", 939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall argv[0]); 949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall quit(1); 959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Set 640x480 video mode */ 999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( (screen=SDL_SetVideoMode(640,480,video_bpp,videoflags)) == NULL ) { 1009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "Couldn't set 640x480x%d video mode: %s\n", 1019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall video_bpp, SDL_GetError()); 1029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall quit(2); 1039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (video_bpp==8) { 1069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Set a gray colormap, reverse order from white to black */ 1079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for ( i=0; i<256; ++i ) { 1089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall palette[i].r = 255-i; 1099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall palette[i].g = 255-i; 1109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall palette[i].b = 255-i; 1119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetColors(screen, palette, 0, 256); 1139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Set the surface pixels and refresh! */ 1169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( SDL_LockSurface(screen) < 0 ) { 1179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf(stderr, "Couldn't lock the display surface: %s\n", 1189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_GetError()); 1199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall quit(2); 1209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall buffer=(Uint8 *)screen->pixels; 1229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (screen->format->BytesPerPixel!=2) { 1239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for ( i=0; i<screen->h; ++i ) { 1249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall memset(buffer,(i*255)/screen->h, screen->pitch); 1259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall buffer += screen->pitch; 1269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall else 1299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 1309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for ( i=0; i<screen->h; ++i ) { 1319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall gradient=((i*255)/screen->h); 1329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall color = SDL_MapRGB(screen->format, gradient, gradient, gradient); 1339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall buffer16=(Uint16*)buffer; 1349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (k=0; k<screen->w; k++) 1359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 1369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *(buffer16+k)=color; 1379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall buffer += screen->pitch; 1399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_UnlockSurface(screen); 1429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_UpdateRect(screen, 0, 0, 0, 0); 1439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Load the bitmap */ 1459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bitmap = LoadXBM(screen, picture_width, picture_height, 1469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (Uint8 *)picture_bits); 1479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ( bitmap == NULL ) { 1489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall quit(1); 1499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Wait for a keystroke */ 1529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall done = 0; 1539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while ( !done ) { 1549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Check for events */ 1559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while ( SDL_PollEvent(&event) ) { 1569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall switch (event.type) { 1579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case SDL_MOUSEBUTTONDOWN: { 1589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Rect dst; 1599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall dst.x = event.button.x - bitmap->w/2; 1619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall dst.y = event.button.y - bitmap->h/2; 1629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall dst.w = bitmap->w; 1639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall dst.h = bitmap->h; 1649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_BlitSurface(bitmap, NULL, 1659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall screen, &dst); 1669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_UpdateRects(screen,1,&dst); 1679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 1699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case SDL_KEYDOWN: 1709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Any key press quits the app... */ 1719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall done = 1; 1729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 1739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case SDL_QUIT: 1749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall done = 1; 1759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 1769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall default: 1779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 1789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_FreeSurface(bitmap); 1829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Quit(); 1839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(0); 1849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 185