| |
| /* Simple program: Test bitmap blits */ |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| |
| #include "SDL.h" |
| #include "picture.xbm" |
| |
| /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ |
| static void |
| quit(int rc) |
| { |
| SDL_Quit(); |
| exit(rc); |
| } |
| |
| SDL_Surface * |
| LoadXBM(SDL_Surface * screen, int w, int h, Uint8 * bits) |
| { |
| SDL_Surface *bitmap; |
| Uint8 *line; |
| |
| /* Allocate the bitmap */ |
| bitmap = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 1, 0, 0, 0, 0); |
| if (bitmap == NULL) { |
| fprintf(stderr, "Couldn't allocate bitmap: %s\n", SDL_GetError()); |
| return (NULL); |
| } |
| |
| /* Copy the pixels */ |
| line = (Uint8 *) bitmap->pixels; |
| w = (w + 7) / 8; |
| while (h--) { |
| memcpy(line, bits, w); |
| /* X11 Bitmap images have the bits reversed */ |
| { |
| int i, j; |
| Uint8 *buf, byte; |
| for (buf = line, i = 0; i < w; ++i, ++buf) { |
| byte = *buf; |
| *buf = 0; |
| for (j = 7; j >= 0; --j) { |
| *buf |= (byte & 0x01) << j; |
| byte >>= 1; |
| } |
| } |
| } |
| line += bitmap->pitch; |
| bits += w; |
| } |
| return (bitmap); |
| } |
| |
| int |
| main(int argc, char *argv[]) |
| { |
| SDL_Surface *screen; |
| SDL_Surface *bitmap; |
| Uint8 video_bpp; |
| Uint32 videoflags; |
| Uint8 *buffer; |
| int i, k, done; |
| SDL_Event event; |
| Uint16 *buffer16; |
| Uint16 color; |
| Uint8 gradient; |
| SDL_Color palette[256]; |
| |
| |
| /* Initialize SDL */ |
| if (SDL_Init(SDL_INIT_VIDEO) < 0) { |
| fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); |
| return (1); |
| } |
| |
| video_bpp = 0; |
| videoflags = SDL_SWSURFACE; |
| while (argc > 1) { |
| --argc; |
| if (strcmp(argv[argc - 1], "-bpp") == 0) { |
| video_bpp = atoi(argv[argc]); |
| --argc; |
| } else if (strcmp(argv[argc], "-warp") == 0) { |
| videoflags |= SDL_HWPALETTE; |
| } else if (strcmp(argv[argc], "-hw") == 0) { |
| videoflags |= SDL_HWSURFACE; |
| } else if (strcmp(argv[argc], "-fullscreen") == 0) { |
| videoflags |= SDL_FULLSCREEN; |
| } else { |
| fprintf(stderr, |
| "Usage: %s [-bpp N] [-warp] [-hw] [-fullscreen]\n", |
| argv[0]); |
| quit(1); |
| } |
| } |
| |
| /* Set 640x480 video mode */ |
| if ((screen = SDL_SetVideoMode(640, 480, video_bpp, videoflags)) == NULL) { |
| fprintf(stderr, "Couldn't set 640x480x%d video mode: %s\n", |
| video_bpp, SDL_GetError()); |
| quit(2); |
| } |
| |
| if (video_bpp == 8) { |
| /* Set a gray colormap, reverse order from white to black */ |
| for (i = 0; i < 256; ++i) { |
| palette[i].r = 255 - i; |
| palette[i].g = 255 - i; |
| palette[i].b = 255 - i; |
| } |
| SDL_SetColors(screen, palette, 0, 256); |
| } |
| |
| /* Set the surface pixels and refresh! */ |
| if (SDL_LockSurface(screen) < 0) { |
| fprintf(stderr, "Couldn't lock the display surface: %s\n", |
| SDL_GetError()); |
| quit(2); |
| } |
| buffer = (Uint8 *) screen->pixels; |
| if (screen->format->BytesPerPixel != 2) { |
| for (i = 0; i < screen->h; ++i) { |
| memset(buffer, (i * 255) / screen->h, screen->pitch); |
| buffer += screen->pitch; |
| } |
| } else { |
| for (i = 0; i < screen->h; ++i) { |
| gradient = ((i * 255) / screen->h); |
| color = SDL_MapRGB(screen->format, gradient, gradient, gradient); |
| buffer16 = (Uint16 *) buffer; |
| for (k = 0; k < screen->w; k++) { |
| *(buffer16 + k) = color; |
| } |
| buffer += screen->pitch; |
| } |
| } |
| SDL_UnlockSurface(screen); |
| SDL_UpdateRect(screen, 0, 0, 0, 0); |
| |
| /* Load the bitmap */ |
| bitmap = LoadXBM(screen, picture_width, picture_height, |
| (Uint8 *) picture_bits); |
| if (bitmap == NULL) { |
| quit(1); |
| } |
| |
| /* Wait for a keystroke */ |
| done = 0; |
| while (!done) { |
| /* Check for events */ |
| while (SDL_PollEvent(&event)) { |
| switch (event.type) { |
| case SDL_MOUSEBUTTONDOWN: |
| { |
| SDL_Rect dst; |
| |
| dst.x = event.button.x - bitmap->w / 2; |
| dst.y = event.button.y - bitmap->h / 2; |
| dst.w = bitmap->w; |
| dst.h = bitmap->h; |
| SDL_BlitSurface(bitmap, NULL, screen, &dst); |
| SDL_UpdateRects(screen, 1, &dst); |
| } |
| break; |
| case SDL_KEYDOWN: |
| /* Any key press quits the app... */ |
| done = 1; |
| break; |
| case SDL_QUIT: |
| done = 1; |
| break; |
| default: |
| break; |
| } |
| } |
| } |
| SDL_FreeSurface(bitmap); |
| SDL_Quit(); |
| return (0); |
| } |