e14743d1 |
1 | |
2 | /* Simple program: Test bitmap blits */ |
3 | |
4 | #include <stdio.h> |
5 | #include <stdlib.h> |
6 | #include <string.h> |
7 | |
8 | #include "SDL.h" |
9 | #include "picture.xbm" |
10 | |
11 | /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ |
12 | static void quit(int rc) |
13 | { |
14 | SDL_Quit(); |
15 | exit(rc); |
16 | } |
17 | |
18 | SDL_Surface *LoadXBM(SDL_Surface *screen, int w, int h, Uint8 *bits) |
19 | { |
20 | SDL_Surface *bitmap; |
21 | Uint8 *line; |
22 | |
23 | /* Allocate the bitmap */ |
24 | bitmap = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 1, 0, 0, 0, 0); |
25 | if ( bitmap == NULL ) { |
26 | fprintf(stderr, "Couldn't allocate bitmap: %s\n", |
27 | SDL_GetError()); |
28 | return(NULL); |
29 | } |
30 | |
31 | /* Copy the pixels */ |
32 | line = (Uint8 *)bitmap->pixels; |
33 | w = (w+7)/8; |
34 | while ( h-- ) { |
35 | memcpy(line, bits, w); |
36 | /* X11 Bitmap images have the bits reversed */ |
37 | { int i, j; Uint8 *buf, byte; |
38 | for ( buf=line, i=0; i<w; ++i, ++buf ) { |
39 | byte = *buf; |
40 | *buf = 0; |
41 | for ( j=7; j>=0; --j ) { |
42 | *buf |= (byte&0x01)<<j; |
43 | byte >>= 1; |
44 | } |
45 | } |
46 | } |
47 | line += bitmap->pitch; |
48 | bits += w; |
49 | } |
50 | return(bitmap); |
51 | } |
52 | |
53 | int main(int argc, char *argv[]) |
54 | { |
55 | SDL_Surface *screen; |
56 | SDL_Surface *bitmap; |
57 | Uint8 video_bpp; |
58 | Uint32 videoflags; |
59 | Uint8 *buffer; |
60 | int i, k, done; |
61 | SDL_Event event; |
62 | Uint16 *buffer16; |
63 | Uint16 color; |
64 | Uint8 gradient; |
65 | SDL_Color palette[256]; |
66 | |
67 | |
68 | /* Initialize SDL */ |
69 | if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { |
70 | fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError()); |
71 | return(1); |
72 | } |
73 | |
74 | video_bpp = 0; |
75 | videoflags = SDL_SWSURFACE; |
76 | while ( argc > 1 ) { |
77 | --argc; |
78 | if ( strcmp(argv[argc-1], "-bpp") == 0 ) { |
79 | video_bpp = atoi(argv[argc]); |
80 | --argc; |
81 | } else |
82 | if ( strcmp(argv[argc], "-warp") == 0 ) { |
83 | videoflags |= SDL_HWPALETTE; |
84 | } else |
85 | if ( strcmp(argv[argc], "-hw") == 0 ) { |
86 | videoflags |= SDL_HWSURFACE; |
87 | } else |
88 | if ( strcmp(argv[argc], "-fullscreen") == 0 ) { |
89 | videoflags |= SDL_FULLSCREEN; |
90 | } else { |
91 | fprintf(stderr, |
92 | "Usage: %s [-bpp N] [-warp] [-hw] [-fullscreen]\n", |
93 | argv[0]); |
94 | quit(1); |
95 | } |
96 | } |
97 | |
98 | /* Set 640x480 video mode */ |
99 | if ( (screen=SDL_SetVideoMode(640,480,video_bpp,videoflags)) == NULL ) { |
100 | fprintf(stderr, "Couldn't set 640x480x%d video mode: %s\n", |
101 | video_bpp, SDL_GetError()); |
102 | quit(2); |
103 | } |
104 | |
105 | if (video_bpp==8) { |
106 | /* Set a gray colormap, reverse order from white to black */ |
107 | for ( i=0; i<256; ++i ) { |
108 | palette[i].r = 255-i; |
109 | palette[i].g = 255-i; |
110 | palette[i].b = 255-i; |
111 | } |
112 | SDL_SetColors(screen, palette, 0, 256); |
113 | } |
114 | |
115 | /* Set the surface pixels and refresh! */ |
116 | if ( SDL_LockSurface(screen) < 0 ) { |
117 | fprintf(stderr, "Couldn't lock the display surface: %s\n", |
118 | SDL_GetError()); |
119 | quit(2); |
120 | } |
121 | buffer=(Uint8 *)screen->pixels; |
122 | if (screen->format->BytesPerPixel!=2) { |
123 | for ( i=0; i<screen->h; ++i ) { |
124 | memset(buffer,(i*255)/screen->h, screen->pitch); |
125 | buffer += screen->pitch; |
126 | } |
127 | } |
128 | else |
129 | { |
130 | for ( i=0; i<screen->h; ++i ) { |
131 | gradient=((i*255)/screen->h); |
132 | color = SDL_MapRGB(screen->format, gradient, gradient, gradient); |
133 | buffer16=(Uint16*)buffer; |
134 | for (k=0; k<screen->w; k++) |
135 | { |
136 | *(buffer16+k)=color; |
137 | } |
138 | buffer += screen->pitch; |
139 | } |
140 | } |
141 | SDL_UnlockSurface(screen); |
142 | SDL_UpdateRect(screen, 0, 0, 0, 0); |
143 | |
144 | /* Load the bitmap */ |
145 | bitmap = LoadXBM(screen, picture_width, picture_height, |
146 | (Uint8 *)picture_bits); |
147 | if ( bitmap == NULL ) { |
148 | quit(1); |
149 | } |
150 | |
151 | /* Wait for a keystroke */ |
152 | done = 0; |
153 | while ( !done ) { |
154 | /* Check for events */ |
155 | while ( SDL_PollEvent(&event) ) { |
156 | switch (event.type) { |
157 | case SDL_MOUSEBUTTONDOWN: { |
158 | SDL_Rect dst; |
159 | |
160 | dst.x = event.button.x - bitmap->w/2; |
161 | dst.y = event.button.y - bitmap->h/2; |
162 | dst.w = bitmap->w; |
163 | dst.h = bitmap->h; |
164 | SDL_BlitSurface(bitmap, NULL, |
165 | screen, &dst); |
166 | SDL_UpdateRects(screen,1,&dst); |
167 | } |
168 | break; |
169 | case SDL_KEYDOWN: |
170 | /* Any key press quits the app... */ |
171 | done = 1; |
172 | break; |
173 | case SDL_QUIT: |
174 | done = 1; |
175 | break; |
176 | default: |
177 | break; |
178 | } |
179 | } |
180 | } |
181 | SDL_FreeSurface(bitmap); |
182 | SDL_Quit(); |
183 | return(0); |
184 | } |