1 /*
2   Block Rage - the arcade game
3   Copyright (C) 1999-2005 Jiri Svoboda
4 
5   This file is part of Block Rage.
6 
7   Block Rage is free software; you can redistribute it and/or
8   modify it under the terms of the GNU General Public License
9   as published by the Free Software Foundation; either version 2
10   of the License, or (at your option) any later version.
11 
12   Block Rage is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16 
17   You should have received a copy of the GNU General Public License
18   along with Block Rage; if not, write to the Free Software
19   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 
21   Jiri Svoboda
22   jirik.svoboda@seznam.cz
23 */
24 
25 /*
26   This module interfaces SDL video.
27 */
28 
29 
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <SDL.h>
33 #include <string.h>
34 
35 #include "global.h"
36 #include "gfxout.h"
37 
38 static const char *wnd_caption = "Block Rage";
39 
40 static SDL_Surface *screen = NULL;
41 static int full_screen = 0;
42 SDL_Color colors[256];
43 int scr_x_size, scr_y_size;
44 int scr_bytes_pp;
45 
46 static int double_size=1;
47 
screen_lock(void)48 void screen_lock(void) {
49   if( SDL_MUSTLOCK(screen) ) {
50     if( SDL_LockSurface(screen)<0) {
51       fprintf(stderr,"Can't lock screen: %s\n", SDL_GetError());
52     }
53   }
54 }
55 
screen_unlock(void)56 void screen_unlock(void) {
57   if( SDL_MUSTLOCK(screen) ) {
58     SDL_UnlockSurface(screen);
59   }
60 }
61 
gfx_virt_cpy(pix_t * scr)62 void gfx_virt_cpy(pix_t *scr) {
63   pix_t *dst,*src;
64   int x,y;
65 
66   screen_lock();
67   src = (pix_t *)scr;
68   dst = (pix_t *)(void *)screen->pixels;
69 
70   if(double_size) {
71     for(y=0;y<scr_y_size;y++) {
72       for(x=0;x<scr_x_size;x++)
73         dst[x*2]=dst[x*2+1]=src[x];
74 
75       dst+=screen->pitch/scr_bytes_pp;
76 
77       for(x=0;x<scr_x_size;x++)
78         dst[x*2]=dst[x*2+1]=src[x];
79       src+=scr_x_size;
80       dst+=screen->pitch/scr_bytes_pp;
81     }
82   } else {
83     for(y=0;y<scr_y_size;y++) {
84       memcpy(dst,src,scr_x_size*scr_bytes_pp);
85       src+=scr_x_size;
86       dst+=screen->pitch/scr_bytes_pp;
87     }
88   }
89   screen_unlock();
90   SDL_UpdateRect(screen,0,0,screen->w,screen->h);
91 }
92 
gfx_virt_cpyarea(pix_t * scr,int x0,int y0,int w,int h)93 void gfx_virt_cpyarea(pix_t *scr, int x0, int y0, int w, int h) {
94   pix_t *src;
95   int x,y;
96   pix_t *dst;
97 
98   screen_lock();
99 
100   src = (pix_t *)(void *)scr + y0*scr_x_size + x0;
101 
102   if(double_size) {
103     dst = (pix_t *)(void *)screen->pixels + 2*y0*(screen->pitch/scr_bytes_pp)+2*x0;
104     for(y=0;y<h;y++) {
105       for(x=0;x<w;x++) {
106         dst[x*2]=dst[x*2+1]=src[x];
107       }
108       dst+=screen->pitch/scr_bytes_pp;
109 
110       for(x=0;x<w;x++) {
111         dst[x*2]=dst[x*2+1]=src[x];
112       }
113       src+=scr_x_size;
114       dst+=screen->pitch/scr_bytes_pp;
115     }
116     SDL_UpdateRect(screen,2*x0,2*y0,2*w,2*h);
117   } else {
118     dst = (pix_t *)(void *)screen->pixels + y0*(screen->pitch/scr_bytes_pp)+x0;
119     for(y=0;y<h;y++) {
120       memcpy(dst,src,w*scr_bytes_pp);
121       src += scr_x_size;
122       dst += screen->pitch/scr_bytes_pp;
123     }
124     SDL_UpdateRect(screen,x0,y0,w,h);
125   }
126 }
127 
gfx_mode_init(void)128 static int gfx_mode_init(void) {
129   int f = double_size ? 2 : 1;
130   int bits;
131 
132 #ifdef DIRECT_COLOR
133   bits=16;
134   scr_bytes_pp=2;
135 #else
136   bits=8;
137   scr_bytes_pp=1;
138 #endif
139 
140   SDL_WM_SetCaption(wnd_caption,wnd_caption);
141 
142   screen = SDL_SetVideoMode(scr_x_size*f,scr_y_size*f,
143     bits,SDL_SWSURFACE | (full_screen ? SDL_FULLSCREEN : 0));
144 
145   if(screen == NULL) {
146     fprintf(stderr,"blockrage: could not setup mode %dx%dx%dbit: %s\n",
147       scr_x_size*f,scr_y_size*f,bits,SDL_GetError());
148     return 0;
149   }
150 
151   return 1;
152 }
153 
gfx_init(void)154 int gfx_init(void) {
155 
156   if(SDL_Init(SDL_INIT_VIDEO)<0) {
157     fprintf(stderr,"error initialising SDL: %s\n", SDL_GetError());
158     return 0;
159   }
160 
161   atexit(SDL_Quit);
162 
163   return gfx_mode_init();
164 }
165 
gfx_deinit(void)166 int gfx_deinit(void) {
167   SDL_FreeSurface(screen); screen=NULL;
168   return 1;
169 }
170 
gfx_get_fullscreen(void)171 int gfx_get_fullscreen(void) {
172   return full_screen;
173 }
174 
gfx_reinit(void)175 static int gfx_reinit(void) {
176   int r;
177 
178   SDL_FreeSurface(screen); screen = NULL;
179   SDL_QuitSubSystem(SDL_INIT_VIDEO);
180   SDL_InitSubSystem(SDL_INIT_VIDEO);
181   r = gfx_mode_init();
182   if(r) {
183     SDL_SetPalette(screen, SDL_PHYSPAL, colors, 0, 256);
184     return 1;
185   }
186   return 0;
187 }
188 
gfx_set_fullscreen(int value)189 int gfx_set_fullscreen(int value) {
190   full_screen = value;
191   if(screen) return gfx_reinit();
192   else return 1;
193 }
194 
gfx_get_doublesize(void)195 int gfx_get_doublesize(void) {
196   return double_size;
197 }
198 
gfx_set_doublesize(int value)199 int gfx_set_doublesize(int value) {
200   double_size = value;
201   if(screen) return gfx_reinit();
202   else return 1;
203 }
204 
205 
gfx_setpalette(unsigned char * pal,int c0,int n)206 void gfx_setpalette(unsigned char *pal, int c0, int n) {
207   int i;
208 
209   if(n>256) n=256;
210 
211   for(i=0;i<n;i++) {
212     colors[i].r=pal[3*i]<<2;
213     colors[i].g=pal[3*i+1]<<2;
214     colors[i].b=pal[3*i+2]<<2;
215   }
216 
217   SDL_SetPalette(screen, SDL_PHYSPAL, colors, c0, n);
218 }
219 
220