1 /* Copyright (C) 1995-2002  FSGames. Ported by Sean Ford and Yan Shosh
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16  */
17 //pixie.cpp
18 
19 /* ChangeLog
20 	buffers: 7/31/02:
21 		*include cleanup
22 	buffers: 8/8/02:
23 		*changed the SDL surfaces to 24bit
24 */
25 #include "graph.h"
26 
27 // ************************************************************
28 //  Pixie -- Base graphic object. It holds pixel by pixel data
29 //  of what should appear on screen. When told to, it handles
30 //  its own placing and movement on the background screen
31 //  buffer, though it requires info from the screen object.
32 // ************************************************************
33 /*
34   pixie()                                                       - Does nothing (DON'T USE)
35   pixie(char,short,short,screen)    - initializes the pixie data (pix = char)
36   short setxy(short, short)                   - set x,y coords (without drawing)
37   short move(short,short)                             - move pixie x,y
38   short draw(short,short)                             - put pixie x,y
39   short draw()
40   short on_screen()
41 */
42 
43 
44 // Pixie -- this initializes the graphics data for the pixie,
45 // as well as its graphics x and y size.  In addition, it informs
46 // the pixie of the screen object it is linked to.
pixie(unsigned char * data,short x,short y,screen * myscreen)47 pixie::pixie(unsigned char *data, short x, short y, screen  *myscreen)
48 {
49 	screenp = myscreen;
50 	bmp = data;
51 	sizex = x;
52 	sizey = y;
53 	size = (unsigned short) (sizex*sizey);
54 	//  oldbmp = (unsigned char *)new char[size];
55 	accel = 0;
56 }
57 
58 //buffers: new constructor that automatically calls init_sdl_surface
pixie(unsigned char * data,short x,short y,screen * myscreen,int doaccel)59 pixie::pixie(unsigned char *data, short x, short y, screen *myscreen, int doaccel)
60 {
61 	pixie(data,x,y,myscreen);
62 
63 	if(doaccel)
64 		init_sdl_surface();
65 }
66 
67 // Destruct the pixie and its variables
~pixie()68 pixie::~pixie()
69 {
70 	if(accel)
71 		SDL_FreeSurface(bmp_surface);
72 	//  delete oldbmp;
73 }
74 
75 // Set the pixie's x and y positon without drawing.
setxy(short x,short y)76 short pixie::setxy(short x, short y)
77 {
78 	xpos = x;
79 	ypos = y;
80 	return 1;
81 }
82 
83 // Allows the pixie to be moved using pixel coord data
move(short x,short y)84 short pixie::move(short x, short y)
85 {
86 	return setxy((short)(xpos+x),(short)(ypos+y));
87 }
88 
89 // Allows the pixie to be placed using pixel coord data
draw(short x,short y,viewscreen * view_buf)90 short pixie::draw(short x, short y, viewscreen  * view_buf)
91 {
92 	setxy(x, y);
93 	return draw(view_buf);
94 }
95 
draw(viewscreen * view_buf)96 short pixie::draw(viewscreen * view_buf)
97 {
98 	long xscreen, yscreen;
99 
100 	//  if (!on_screen(view_buf))
101 	//         return 0;
102 	//we actually don't need to waste time on the above since the clipper
103 	//will handle it
104 
105 	xscreen = (long) (xpos - view_buf->topx + view_buf->xloc);
106 	yscreen = (long) (ypos - view_buf->topy + view_buf->yloc);
107 
108 	if(accel)
109 	{
110 		view_buf->screenp->putbuffer(xscreen, yscreen, sizex, sizey,
111 		                             view_buf->xloc, view_buf->yloc,
112 		                             view_buf->endx, view_buf->endy,
113 		                             bmp_surface);
114 	}
115 	else
116 	{
117 		view_buf->screenp->putbuffer(xscreen, yscreen, sizex, sizey,
118 		                             view_buf->xloc, view_buf->yloc,
119 		                             view_buf->endx, view_buf->endy,
120 		                             bmp);
121 	}
122 
123 	return 1;
124 }
125 
126 // Allows the pixie to be placed using pixel coord data
drawMix(short x,short y,viewscreen * view_buf)127 short pixie::drawMix(short x, short y, viewscreen  * view_buf)
128 {
129 	setxy(x, y);
130 	return drawMix(view_buf);
131 }
132 
drawMix(viewscreen * view_buf)133 short pixie::drawMix(viewscreen * view_buf)
134 {
135 	long xscreen, yscreen;
136 
137 	//  if (!on_screen(view_buf))
138 	//         return 0;
139 	//we actually don't need to waste time on the above since the clipper
140 	//will handle it
141 
142 	xscreen = (long) (xpos - view_buf->topx + view_buf->xloc);
143 	yscreen = (long) (ypos - view_buf->topy + view_buf->yloc);
144 
145 	view_buf->screenp->walkputbuffer(xscreen, yscreen, sizex, sizey,
146 	                                 view_buf->xloc, view_buf->yloc,
147 	                                 view_buf->endx, view_buf->endy,
148 	                                 bmp, RED);
149 
150 	return 1;
151 }
152 
153 
put_screen(short x,short y)154 short pixie::put_screen(short x, short y)
155 {
156 	screenp->putdata(x, y, sizex, sizey, bmp);
157 	return 1;
158 }
159 
on_screen()160 short pixie::on_screen()
161 {
162 	short i;
163 	for (i=0; i < screenp->numviews; i++)
164 	{
165 		if (on_screen(screenp->viewob[i]))
166 			return 1;
167 	}
168 	return 0;
169 }
170 
on_screen(viewscreen * viewp)171 short pixie::on_screen(viewscreen  *viewp)
172 {
173 	short topx = viewp->topx;
174 	short topy = viewp->topy;
175 	short xview = viewp->xview;
176 	short yview = viewp->yview;
177 
178 	// Return 0 if off viewscreen.
179 	// These measurements are grid coords, not pixels.
180 	if ( (xpos+sizex) < topx)
181 		return 0;     // we are to the left of the view
182 	else if ( xpos > (topx + xview) )
183 		return 0;  // we are to the right of the view
184 	else if ( (ypos+sizey) < topy)
185 		return 0;  // we are above the view
186 	else if ( ypos > (topy + yview) )
187 		return 0; //we are below the view
188 	else
189 		return 1;
190 }
191 
192 //buffers: this func initializes the bmp_surface
init_sdl_surface(void)193 void pixie::init_sdl_surface(void)
194 {
195 	int r,g,b,c,i,j,num;
196 	SDL_Rect rect;
197 
198 	bmp_surface = SDL_CreateRGBSurface(SDL_SWSURFACE,sizex*screenp->mult,sizey*screenp->mult,24,
199 	                                   0,0,0,0);
200 	if(!bmp_surface)
201 	{
202 		printf("ERROR: pixie::init_sdl_surface(): could not create bmp_surface\n");
203 	}
204 
205 	num=0;
206 	for(i=0;i<sizey;i++)
207 		for(j=0;j<sizex;j++)
208 		{
209 			query_palette_reg(bmp[num],&r,&g,&b);
210 			c = SDL_MapRGB(bmp_surface->format,r*4,g*4,b*4);
211 			rect.x = j*screenp->mult;
212 			rect.y = i*screenp->mult;
213 			rect.w = rect.h = screenp->mult;
214 			SDL_FillRect(bmp_surface,&rect,c);
215 			num++;
216 		}
217 
218 	accel = 1;
219 }
220 
221 //buffers: turn SDL_Surface accel on and off
set_accel(int a)222 void pixie::set_accel(int a)
223 {
224 	if(a)
225 	{
226 		init_sdl_surface();
227 	}
228 	else
229 	{
230 		if(accel)
231 		{
232 			SDL_FreeSurface(bmp_surface);
233 			accel = 0;
234 		}
235 	}
236 }
237