1 /*------------------------------------------------------------------.
2 | Copyright 1997, 1998, 2000, 2001, 2002 Alexandre Duret-Lutz |
3 | <duret_g@epita.fr> |
4 | |
5 | This file is part of Heroes. |
6 | |
7 | Heroes is free software; you can redistribute it and/or modify it |
8 | under the terms of the GNU General Public License version 2 as |
9 | published by the Free Software Foundation. |
10 | |
11 | Heroes is distributed in the hope that it will be useful, but |
12 | WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | 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, write to the Free Software |
18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
19 | 02111-1307 USA |
20 `------------------------------------------------------------------*/
21
22 #include "system.h"
23 #include <SDL.h>
24 #include "video_low.h"
25 #include "debugmsg.h"
26 #include "errors.h"
27 #include "misc.h"
28 #include "argv.h"
29 #include "cast.h"
30
31 static a_pixel *screen_rv = 0; /* A pointer to the screen buffer associated
32 to the render visual. */
33 static int scr_w, scr_h; /* rendering buffer width and height */
34 static int scr_stretch;
35
36 /* screen_rv may be a direct pointer to the hardware video buffer, or
37 it may be a pointer to system (mallocated) memory, this depends on
38 the display driver (if the videomode were available or needed to be
39 emulated etc.). If screen_rv points directly to hardware video
40 it might requires locking. */
41
42 static SDL_Surface *visu = 0;
43 static int visu_options = SDL_HWPALETTE | SDL_DOUBLEBUF;
44 static bool SDL_initialized = false;
45 #define SDL_VIDEODRIVER "SDL_VIDEODRIVER"
46 static char *sdl_videodriver = 0;
47
48 void
set_display_params(const char * str)49 set_display_params (const char *str)
50 {
51 sdl_videodriver = strcat_alloc (SDL_VIDEODRIVER "=", str);
52 dmsg (D_SYSTEM | D_VIDEO, "put `%s' in environment", sdl_videodriver);
53 putenv (sdl_videodriver);
54 }
55
56 void
set_full_screen_mode(void)57 set_full_screen_mode (void)
58 {
59 visu_options |= SDL_FULLSCREEN;
60 }
61
62 /* Fullscreen mode is toggeled by pressing Alt+Enter.
63 Thanks to Sam Lantinga */
64 static int
Handle_AltEnter(const SDL_Event * event)65 Handle_AltEnter (const SDL_Event *event)
66 {
67 if (event->type == SDL_KEYDOWN
68 && event->key.keysym.sym == SDLK_RETURN
69 && event->key.keysym.mod & KMOD_ALT) {
70 SDL_WM_ToggleFullScreen (SDL_GetVideoSurface ());
71 return 0;
72 }
73 return 1;
74 }
75
76 /* init the SDL library, this can be called from joystick.c
77 or from init_video() */
78 void init_SDL (void);
79 void
init_SDL(void)80 init_SDL (void)
81 {
82 if (SDL_initialized)
83 return;
84 dmsg (D_SYSTEM | D_VIDEO | D_JOYSTICK | D_SOUND_TRACK | D_SOUND_EFFECT,
85 "initialize SDL");
86 SDL_Init (SDL_INIT_VIDEO
87 #ifdef HAVE_LIBSDL_MIXER
88 | ((nosfx && nosound) ? 0 : SDL_INIT_AUDIO)
89 #endif
90 #ifdef HAVE_SDL_JOYSTICKOPEN
91 | (joyoff ? 0 : SDL_INIT_JOYSTICK)
92 #endif
93 #ifdef DEBUG
94 | SDL_INIT_NOPARACHUTE
95 #endif
96 );
97
98 SDL_SetEventFilter(Handle_AltEnter);
99 SDL_initialized = true;
100 }
101
102 void
init_video_low(int stretch_,int * pitch)103 init_video_low (int stretch_, int *pitch)
104 {
105 scr_stretch = stretch_;
106 scr_w = 320 * scr_stretch;
107 scr_h = 200 * scr_stretch;
108
109 init_SDL ();
110 dmsg (D_VIDEO, "set video mode");
111 visu = SDL_SetVideoMode (scr_w, scr_h, 8, visu_options);
112 /* FIXME: the Linux/m68k binary is crashing in the vicinity */
113 if (!visu)
114 emsg (_("Failed to open visual: %s"), SDL_GetError());
115
116 if (SDL_MUSTLOCK (visu))
117 dmsg (D_VIDEO, "visual require locking");
118 else
119 screen_rv = visu->pixels;
120
121 *pitch = visu->pitch;
122
123 dmsg (D_VIDEO, "set misc. video parameters");
124
125 SDL_ShowCursor (0);
126 SDL_WM_SetCaption ("Heroes " VERSION,"Heroes");
127
128 /* setup event processing rules.
129 FIXME: this does not really belong to display.c
130 it should rather go to keyb.c */
131 SDL_EventState ((Uint8) SDL_ALLEVENTS, SDL_IGNORE);
132 SDL_EventState (SDL_KEYDOWN, SDL_ENABLE);
133 SDL_EventState (SDL_KEYUP, SDL_ENABLE);
134 SDL_EventState (SDL_QUIT, SDL_ENABLE);
135 #ifdef HAVE_SDL_ENABLEKEYREPEAT
136 SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
137 #endif
138 }
139
140 void
uninit_video_low(void)141 uninit_video_low (void)
142 {
143 dmsg (D_MISC, "free screen buffer");
144
145 if (SDL_initialized) {
146 SDL_Quit ();
147 SDL_initialized = false;
148 }
149 if (sdl_videodriver) {
150 putenv (const_cast_string (SDL_VIDEODRIVER));
151 XFREE0 (sdl_videodriver);
152 }
153 }
154
155 void
set_pal_entry(unsigned char c,unsigned char r,unsigned char g,unsigned char b)156 set_pal_entry (unsigned char c,
157 unsigned char r, unsigned char g, unsigned char b)
158 {
159 SDL_Color col;
160 col.r = r * 4;
161 col.g = g * 4;
162 col.b = b * 4;
163 dmsg (D_VIDEO, "set color %d=(%d,%d,%d)", c, r, g, b);
164 SDL_SetColors (visu, &col, c, 1);
165 }
166
167 void
set_pal(const unsigned char * ptr,int p,int n)168 set_pal (const unsigned char *ptr, int p, int n)
169 {
170 signed i;
171
172 SDL_Color cmap[256];
173 for (i = 0; i < 256; ++i) {
174 cmap[i].r = *ptr++ * 4;
175 cmap[i].g = *ptr++ * 4;
176 cmap[i].b = *ptr++ * 4;
177 }
178 dmsg (D_VIDEO, "set %d colors", n/3);
179 SDL_SetColors (visu, cmap, p/3, n/3);
180 }
181
182 void
vsynchro_low(const a_pixel * s,a_copy_function f)183 vsynchro_low (const a_pixel *s, a_copy_function f)
184 {
185 if (SDL_MUSTLOCK (visu))
186 SDL_LockSurface (visu);
187
188 screen_rv = visu->pixels;
189 f (s, screen_rv, 320);
190
191 if (SDL_MUSTLOCK (visu))
192 SDL_UnlockSurface (visu);
193
194 SDL_Flip (visu); /* can change visu->pixels */
195 }
196
197 void
vsynchro2_low(const a_pixel * s1,const a_pixel * s2,a_copy_function f)198 vsynchro2_low (const a_pixel *s1, const a_pixel *s2, a_copy_function f)
199 {
200 if (SDL_MUSTLOCK (visu))
201 SDL_LockSurface (visu);
202
203 screen_rv = visu->pixels;
204 f (s1, screen_rv, 160);
205 f (s2, screen_rv + 160 * scr_stretch, 160);
206
207 if (SDL_MUSTLOCK (visu))
208 SDL_UnlockSurface (visu);
209
210 SDL_Flip (visu); /* can change visu->pixels */
211 }
212