core: Slight cleanup in GP_Context.
[gfxprim.git] / tests / SDL / blittest.c
blobc23776ca0c36916e22402e8517ecda2194a0ed8e
1 /*****************************************************************************
2 * This file is part of gfxprim library. *
3 * *
4 * Gfxprim is free software; you can redistribute it and/or *
5 * modify it under the terms of the GNU Lesser General Public *
6 * License as published by the Free Software Foundation; either *
7 * version 2.1 of the License, or (at your option) any later version. *
8 * *
9 * Gfxprim is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
12 * Lesser General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU Lesser General Public *
15 * License along with gfxprim; if not, write to the Free Software *
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
17 * Boston, MA 02110-1301 USA *
18 * *
19 * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
20 * <jiri.bluebear.dluhos@gmail.com> *
21 * *
22 * Copyright (C) 2009-2012 Cyril Hrubis <metan@ucw.cz> *
23 * *
24 *****************************************************************************/
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <errno.h>
29 #include <SDL/SDL.h>
31 #include "GP.h"
32 #include "GP_SDL.h"
34 static GP_Pixel black;
35 static GP_Pixel white;
37 SDL_Surface *display = NULL;
38 GP_Context context;
39 GP_Context *bitmap, *bitmap_raw, *bitmap_conv;
41 SDL_TimerID timer;
43 SDL_UserEvent timer_event;
45 static int pause_flag = 0;
47 static int bitmap_x, bitmap_y, bitmap_vx = -3, bitmap_vy = -3;
49 Uint32 timer_callback(__attribute__((unused)) Uint32 interval,
50 __attribute__((unused)) void *param)
52 timer_event.type = SDL_USEREVENT;
53 SDL_PushEvent((SDL_Event *) &timer_event);
54 return 10;
57 static char text_buf[255];
59 void redraw_screen(void)
61 if (pause_flag)
62 return;
64 bitmap_x += bitmap_vx;
65 bitmap_y += bitmap_vy;
67 if (bitmap_x + GP_ContextW(bitmap) > context.w) {
68 bitmap_vx = -bitmap_vx;
69 bitmap_x += bitmap_vx;
72 if (bitmap_x < 0) {
73 bitmap_vx = -bitmap_vx;
74 bitmap_x += bitmap_vx;
77 if (bitmap_y + GP_ContextH(bitmap) > context.h) {
78 bitmap_vy = -bitmap_vy;
79 bitmap_y += bitmap_vy;
82 if (bitmap_y < 0) {
83 bitmap_vy = -bitmap_vy;
84 bitmap_y += bitmap_vy;
87 SDL_LockSurface(display);
89 GP_FillRectXYWH(&context, 20, 20, 300, 50, black);
91 GP_Text(&context, NULL, 20, 20, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM,
92 white, black, text_buf);
94 GP_Print(&context, NULL, 250, 20, GP_ALIGN_RIGHT|GP_VALIGN_BOTTOM,
95 white, black, "%c|%c|%c", bitmap->x_swap ? 'x' : ' ',
96 bitmap->y_swap ? 'y' : ' ', bitmap->axes_swap ? 'a' : ' ');
98 GP_Blit(bitmap, 0, 0, GP_ContextW(bitmap), GP_ContextH(bitmap),
99 &context, bitmap_x, bitmap_y);
101 SDL_UpdateRect(display, bitmap_x, bitmap_y,
102 GP_ContextW(bitmap), GP_ContextH(bitmap));
103 SDL_UpdateRect(display, 20, 20, 400, 50);
105 SDL_UnlockSurface(display);
108 static void change_bitmap(void)
110 if (bitmap == bitmap_raw)
111 bitmap = bitmap_conv;
112 else
113 bitmap = bitmap_raw;
115 snprintf(text_buf, sizeof(text_buf), "'%s' -> '%s'",
116 GP_PixelTypes[bitmap->pixel_type].name,
117 GP_PixelTypes[context.pixel_type].name);
120 void event_loop(void)
122 SDL_Event event;
124 while (SDL_WaitEvent(&event) > 0) {
126 switch (event.type) {
128 case SDL_USEREVENT:
129 redraw_screen();
130 break;
131 case SDL_KEYDOWN:
132 switch (event.key.keysym.sym) {
133 case SDLK_p:
134 pause_flag = !pause_flag;
135 break;
136 case SDLK_x:
137 bitmap->x_swap = !bitmap->x_swap;
138 break;
139 case SDLK_y:
140 bitmap->y_swap = !bitmap->y_swap;
141 break;
142 case SDLK_a:
143 bitmap->axes_swap = !bitmap->axes_swap;
144 break;
145 case SDLK_SPACE:
146 change_bitmap();
147 break;
148 case SDLK_ESCAPE:
149 return;
150 default:
151 break;
153 break;
154 case SDL_QUIT:
155 return;
156 default:
157 break;
162 void print_instructions(void)
164 printf("Use the following keys to control the test:\n");
165 printf(" Esc ................. exit\n");
166 printf(" Space ............... converts bitmap to screen pixel format\n");
167 printf(" A ................... swap sprite axes\n");
168 printf(" X ................... mirror sprite X\n");
169 printf(" Y ................... mirror sprite Y\n");
170 printf(" P ................... pause\n");
173 int main(int argc, char *argv[])
175 int display_bpp = 0;
176 const char *sprite = "ball.ppm";
178 print_instructions();
180 int i;
181 for (i = 1; i < argc; i++) {
182 if (strcmp(argv[i], "-16") == 0) {
183 display_bpp = 16;
184 } else if (strcmp(argv[i], "-24") == 0) {
185 display_bpp = 24;
186 } else if (strcmp(argv[i], "-32") == 0) {
187 display_bpp = 32;
188 } else {
189 sprite = argv[i];
193 GP_SetDebugLevel(10);
195 if ((bitmap_raw = GP_LoadImage(sprite, NULL)) == NULL) {
196 fprintf(stderr, "Failed to load bitmap: %s\n", strerror(errno));
197 return 1;
200 /* Initialize SDL */
201 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0) {
202 fprintf(stderr, "Could not initialize SDL: %s\n", SDL_GetError());
203 return 1;
206 /* Create a window with a software back surface */
207 display = SDL_SetVideoMode(640, 480, display_bpp, SDL_SWSURFACE);
208 if (display == NULL) {
209 fprintf(stderr, "Could not open display: %s\n", SDL_GetError());
210 goto fail;
213 GP_SDL_ContextFromSurface(&context, display);
215 bitmap_conv = GP_ContextConvertAlloc(bitmap_raw, context.pixel_type);
216 change_bitmap();
218 black = GP_ColorToContextPixel(GP_COL_BLACK, &context);
219 white = GP_ColorToContextPixel(GP_COL_WHITE, &context);
221 /* Set up the refresh timer */
222 timer = SDL_AddTimer(60, timer_callback, NULL);
223 if (timer == 0) {
224 fprintf(stderr, "Could not set up timer: %s\n", SDL_GetError());
225 goto fail;
228 /* Enter the event loop */
229 event_loop();
231 /* We're done */
232 SDL_Quit();
233 return 0;
235 fail:
236 SDL_Quit();
237 return 1;