1 /*
2     SCREENLIB:  A framebuffer library based on the SDL library
3     Copyright (C) 1997  Sam Lantinga
4 
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 
19     Sam Lantinga
20     5635-34 Springhouse Dr.
21     Pleasanton, CA 94588 (USA)
22     slouken@devolution.com
23 */
24 
25 #ifndef _SDL_FrameBuf_h
26 #define _SDL_FrameBuf_h
27 
28 /* A simple display management class based on SDL:
29 
30    It supports medium-slow line drawing, rectangle filling, and fading,
31    and it supports loading 8 bits-per-pixel masked images.
32 */
33 
34 #include <stdio.h>
35 #include <string.h>
36 #include <stdarg.h>
37 
38 #include "SDL.h"
39 
40 /* Macros to make sure we lock the screen if necessary (used internally!) */
41 #define LOCK_IF_NEEDED()	{ if ( ! locked )  Lock(); }
42 #define UNLOCK_IF_NEEDED()	{ if ( locked ) Unlock(); }
43 
44 typedef enum {
45 	DOCLIP,
46 	NOCLIP
47 } clipval;
48 
49 class FrameBuf {
50 
51 public:
52 	FrameBuf();
53 	int Init(int width, int height, Uint32 video_flags,
54 			SDL_Color *colors = NULL, SDL_Surface *icon = NULL);
55 	~FrameBuf();
56 
57 	/* Setup routines */
58 	/* Set the image palette -- 256 entries */
59 	void SetPalette(SDL_Color *colors);
60 	/* Set the background color -- used by Clear() */
61 	void   SetBackground(Uint8 r, Uint8 g, Uint8 b);
62 	/* Map an RGB value to a color pixel */
63 	Uint32 MapRGB(Uint8 R, Uint8 G, Uint8 B);
64 	/* Set the blit clipping rectangle */
65 	void   ClipBlit(SDL_Rect *cliprect);
66 
67 	/* Event Routines */
PollEvent(SDL_Event * event)68 	int PollEvent(SDL_Event *event) {
69 		return(SDL_PollEvent(event));
70 	}
WaitEvent(SDL_Event * event)71 	int WaitEvent(SDL_Event *event) {
72 		return(SDL_WaitEvent(event));
73 	}
ToggleFullScreen(void)74 	int ToggleFullScreen(void) {
75 		return(SDL_WM_ToggleFullScreen(SDL_GetVideoSurface()));
76 	}
77 
78 	/* Locking blitting and update routines */
79 	void Lock(void);
80 	void Unlock(void);
81 	void QueueBlit(int dstx, int dsty, SDL_Surface *src,
82 			int srcx, int srcy, int w, int h, clipval do_clip);
QueueBlit(int x,int y,SDL_Surface * src,clipval do_clip)83 	void QueueBlit(int x, int y, SDL_Surface *src, clipval do_clip) {
84 		QueueBlit(x, y, src, 0, 0, src->w, src->h, do_clip);
85 	}
QueueBlit(int x,int y,SDL_Surface * src)86 	void QueueBlit(int x, int y, SDL_Surface *src) {
87 		QueueBlit(x, y, src, DOCLIP);
88 	}
89 	void PerformBlits(void);
90 	void Update(int auto_update = 0);
91 	void Fade(void);		/* Fade screen out, then in */
92 
93 	/* Informational routines */
Width(void)94 	Uint16 Width(void) {
95 		return(screen->w);
96 	}
Height(void)97 	Uint16 Height(void) {
98 		return(screen->h);
99 	}
Format(void)100 	SDL_PixelFormat *Format(void) {
101 		return(screenfg->format);
102 	}
103 
104 	/* Set the drawing focus (foreground or background) */
FocusFG(void)105 	void FocusFG(void) {
106 		UNLOCK_IF_NEEDED();
107 		screen = screenfg;
108 	}
FocusBG(void)109 	void FocusBG(void) {
110 		UNLOCK_IF_NEEDED();
111 		screen = screenbg;
112 	}
113 
114 	/* Drawing routines */
115 	/* These drawing routines must be surrounded by Lock()/Unlock() calls */
116 	void Clear(Sint16 x, Sint16 y, Uint16 w, Uint16 h,
117 						clipval do_clip = NOCLIP);
Clear(void)118 	void Clear(void) {
119 		Clear(0, 0, screen->w, screen->h);
120 	}
121 	void DrawPoint(Sint16 x, Sint16 y, Uint32 color);
122 	void DrawLine(Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color);
123 	void DrawRect(Sint16 x1, Sint16 y1, Uint16 w, Uint16 h, Uint32 color);
124 	void FillRect(Sint16 x1, Sint16 y1, Uint16 w, Uint16 h, Uint32 color);
125 
126 	/* Load and convert an 8-bit image with the given mask */
127 	SDL_Surface *LoadImage(Uint16 w, Uint16 h, Uint8 *pixels,
128 							Uint8 *mask = NULL);
129 	void FreeImage(SDL_Surface *image);
130 
131 	/* Area copy/dump routines */
132 	SDL_Surface *GrabArea(Uint16 x, Uint16 y, Uint16 w, Uint16 h);
133 	int ScreenDump(char *prefix, Uint16 x, Uint16 y, Uint16 w, Uint16 h);
134 
135 	/* Cursor handling routines */
ShowCursor(void)136 	void ShowCursor(void) {
137 		SDL_ShowCursor(1);
138 	}
HideCursor(void)139 	void HideCursor(void) {
140 		SDL_ShowCursor(0);
141 	}
142 	void SetCaption(char *caption, char *icon = NULL) {
143 		if ( icon == NULL ) {
144 			icon = caption;
145 		}
146 		SDL_WM_SetCaption(caption, icon);
147 	}
148 
149 	/* Error message routine */
Error(void)150 	char *Error(void) {
151 		return(errstr);
152 	}
153 
154 private:
155 	/* The current display and background */
156 	SDL_Surface *screen;
157 	SDL_Surface *screenfg;
158 	SDL_Surface *screenbg;
159 	Uint8 *screen_mem;
160 	Uint32 image_map[256];
161 	int locked, faded;
162 
163 	/* Error message */
SetError(char * fmt,...)164 	void SetError(char *fmt, ...) {
165 		va_list ap;
166 
167 		va_start(ap, fmt);
168 		vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
169 		va_end(ap);
170 		errstr = errbuf;
171         }
172 	char *errstr;
173 	char  errbuf[1024];
174 
175 	/* Blit queue list */
176 #define QUEUE_CHUNK	16
177 	typedef struct {
178 		SDL_Surface *src;
179 		SDL_Rect srcrect;
180 		SDL_Rect dstrect;
181 	} BlitQ;
182 	BlitQ *blitQ;
183 	int blitQlen;
184 	int blitQmax;
185 
186 	/* Rectangle update list */
187 #define UPDATE_CHUNK	QUEUE_CHUNK*2
188 	void AddDirtyRect(SDL_Rect *rect);
189 	int updatelen;
190 	int updatemax;
191 	SDL_Rect *updatelist;
192 	Uint16 dirtypitch;
193 	SDL_Rect **dirtymap;
194 	Uint16 dirtymaplen;
ClearDirtyList(void)195 	void ClearDirtyList(void) {
196 		updatelen = 0;
197 		memset(dirtymap, 0, dirtymaplen*sizeof(SDL_Rect *));
198 	}
199 
200 	/* Background color */
201 	Uint8  BGrgb[3];
202 	Uint32 BGcolor;
203 
204 	/* Blit clipping rectangle */
205 	SDL_Rect clip;
206 
207 	/* List of loaded images */
208 	typedef struct image_list {
209 		SDL_Surface *image;
210 		struct image_list *next;
211 	} image_list;
212 	image_list images, *itail;
213 
214 	/* Function to write to the display surface */
215 	void (*PutPixel)(Uint8 *screen_loc, SDL_Surface *screen, Uint32 pixel);
216 };
217 
218 #endif /* _SDL_FrameBuf_h */
219