4f49e25362dd5d966ad884f6ad538f4490a07424
[experiments/SDL.git] / scrolling / sdl-scrolling.c
1 /* 
2  * sdl-scrolling - Example program for scrolling images in SDL
3  *
4  * Copyright (C) 2013  Antonio Ospite <ospite@studenti.unina.it>
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <errno.h>
21 #include <SDL.h>
22 #include <SDL_image.h>
23
24 #define WIDTH 800
25 #define HEIGHT 480
26
27 #define FPS 30
28
29 static int mod(int a, int b)
30 {
31         int c = a % b;
32         return (c < 0) ? c + b : c;
33 }
34
35 static SDL_Surface *load_image(const char *filename)
36 {
37         SDL_Surface *image = NULL;
38         SDL_Surface *optimized_image = NULL;
39
40         image = IMG_Load(filename);
41         if (!image) {
42                 fprintf(stderr, "IMG_Load: %s\n", IMG_GetError());
43                 return NULL;
44         }
45
46         optimized_image = SDL_DisplayFormat(image);
47         if (!optimized_image) {
48                 fprintf(stderr, "erro whan calling SDL_DisplayFormat().\n");
49                 return NULL;
50         }
51         SDL_FreeSurface(image);
52
53         return optimized_image;
54 }
55
56 int main(int argc, char *argv[])
57 {
58         int ret;
59         SDL_Surface* screen = NULL;
60         SDL_Surface* map = NULL;
61         SDL_Rect viewport = {0 , 0, WIDTH, HEIGHT};
62         SDL_Event event;
63         SDL_Joystick *joystick = NULL;
64
65         int running = 1;
66
67         Sint16 y_offset = 0;
68         Sint16 y = 0;
69         Sint16 lastframe_limit;
70         Uint32 time_start;
71         Uint32 time_end;
72
73         if (argc != 2) {
74                 fprintf(stderr, "usage: %s <image>\n", argv[0]);
75                 return -EINVAL;
76         }
77
78         SDL_Init(SDL_INIT_TIMER | SDL_INIT_JOYSTICK);
79
80         screen = SDL_SetVideoMode(WIDTH, HEIGHT, 32, SDL_HWSURFACE);
81         if (!screen) {
82                 fprintf(stderr, "Cannot set video mode\n");
83                 ret = -EINVAL;
84                 goto out;
85         }
86
87         map = load_image(argv[1]);
88         if (!map) {
89                 ret = -EINVAL;
90                 goto out;
91         }
92
93         lastframe_limit = (map->h - HEIGHT);
94
95         if (SDL_NumJoysticks() > 0)
96                 joystick = SDL_JoystickOpen(0);
97
98         SDL_JoystickEventState(SDL_ENABLE);
99         SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
100
101         while (running) {
102                 time_start = SDL_GetTicks();
103
104                 while(SDL_PollEvent(&event)) {
105                         switch(event.type) {
106                         case SDL_QUIT:
107                                 running = 0;
108                                 break;
109
110                         case SDL_KEYDOWN:
111                                 switch(event.key.keysym.sym) {
112                                 case SDLK_ESCAPE:
113                                 case SDLK_q:
114                                         running = 0;
115                                         break;
116
117                                 case SDLK_UP:
118                                         y_offset += 1;
119                                         break;
120
121                                 case SDLK_DOWN:
122                                         y_offset -= 1;
123                                         break;
124
125                                 default:
126                                         printf("key: '%s' keysym: %d\n",
127                                                SDL_GetKeyName(event.key.keysym.sym),
128                                                event.key.keysym.sym);
129                                         break;
130                                 }
131                                 break;
132
133                         case SDL_JOYAXISMOTION:
134                                 fprintf(stderr, "Joystick which: %d, axis: %d, value: %d\n",
135                                         event.jaxis.which, event.jaxis.axis, event.jaxis.value);
136                                 if (event.jaxis.which == 0) {
137                                         if (event.jaxis.axis == 0)
138                                                 /* TODO: improve scaling here */
139                                                 y_offset = event.jaxis.value;
140                                 }
141                         }
142                 }
143
144                 y += y_offset;
145                 y = mod(y, lastframe_limit);
146
147                 viewport.y = y;
148                 SDL_BlitSurface(map, &viewport, screen, NULL);
149                 SDL_Flip(screen);
150
151                 time_end = SDL_GetTicks();
152                 if (time_end - time_start < 1000 / FPS)
153                         SDL_Delay((1000 / FPS) - (time_end - time_start));
154         }
155
156         ret = 0;
157
158         if (SDL_JoystickOpened(0))
159                 SDL_JoystickClose(joystick);
160
161         SDL_FreeSurface(map);
162 out:
163         SDL_Quit();
164         return ret;
165 }