4 #include "../settings.h"
8 #include "nxsurface.fdh"
10 #ifdef CONFIG_MUTABLE_SCALE
15 NXSurface::NXSurface()
22 NXSurface::NXSurface(int wd
, int ht
, NXFormat
*format
)
25 AllocNew(wd
, ht
, format
);
30 NXSurface::NXSurface(SDL_Surface
*from_sfc
, bool free_surface
)
33 fFreeSurface
= free_surface
;
36 NXSurface::~NXSurface()
41 // static function, and requires a reload of all surfaces
42 void NXSurface::SetScale(int factor
)
44 #ifdef CONFIG_MUTABLE_SCALE
47 staterr("NXSurface::SetScale: CONFIG_MUTABLE_SCALE not set");
52 void c------------------------------() {}
55 // allocate for an empty surface of the given size
56 bool NXSurface::AllocNew(int wd
, int ht
, NXFormat
*format
)
60 fSurface
= SDL_CreateRGBSurface(SDL_SRCCOLORKEY
, wd
*SCALE
, ht
*SCALE
, \
61 format
->BitsPerPixel
, format
->Rmask
, format
->Gmask
, format
->Bmask
, format
->Amask
);
65 staterr("NXSurface::AllocNew: failed to allocate RGB surface");
73 // load the surface from a .pbm or bitmap file
74 bool NXSurface::LoadImage(const char *pbm_name
, bool use_colorkey
, int use_display_format
)
80 if (use_display_format
== -1)
81 { // use value specified in settings
82 use_display_format
= settings
->displayformat
;
85 image
= SDL_LoadBMP(pbm_name
);
88 staterr("NXSurface::LoadImage: load failed of '%s'!", pbm_name
);
92 fSurface
= Scale(image
, SCALE
, use_colorkey
, true, use_display_format
);
93 return (fSurface
== NULL
);
97 NXSurface
*NXSurface::FromFile(const char *pbm_name
, bool use_colorkey
, int use_display_format
)
99 NXSurface
*sfc
= new NXSurface
;
100 if (sfc
->LoadImage(pbm_name
, use_colorkey
, use_display_format
))
111 void c------------------------------() {}
114 // draw some or all of another surface onto this surface.
115 void NXSurface::DrawSurface(NXSurface
*src
, \
116 int dstx
, int dsty
, int srcx
, int srcy
, int wd
, int ht
)
118 SDL_Rect srcrect
, dstrect
;
120 srcrect
.x
= srcx
* SCALE
;
121 srcrect
.y
= srcy
* SCALE
;
122 srcrect
.w
= wd
* SCALE
;
123 srcrect
.h
= ht
* SCALE
;
125 dstrect
.x
= dstx
* SCALE
;
126 dstrect
.y
= dsty
* SCALE
;
128 SDL_BlitSurface(src
->fSurface
, &srcrect
, fSurface
, &dstrect
);
131 void NXSurface::DrawSurface(NXSurface
*src
, int dstx
, int dsty
)
133 DrawSurface(src
, dstx
, dsty
, 0, 0, src
->Width(), src
->Height());
136 // draw the given source surface in a repeating pattern across the entire width of the surface.
137 // x_dst: an starting X with which to offset the pattern horizontally (usually negative).
138 // y_dst: the Y coordinate to copy to on the destination.
139 // y_src: the Y coordinate to copy from.
140 // height: the number of pixels tall to copy.
141 void NXSurface::BlitPatternAcross(NXSurface
*src
,
142 int x_dst
, int y_dst
, int y_src
, int height
)
144 SDL_Rect srcrect
, dstrect
;
147 srcrect
.w
= src
->fSurface
->w
;
148 srcrect
.y
= (y_src
* SCALE
);
149 srcrect
.h
= (height
* SCALE
);
151 int x
= (x_dst
* SCALE
);
152 int y
= (y_dst
* SCALE
);
153 int destwd
= fSurface
->w
;
160 SDL_BlitSurface(src
->fSurface
, &srcrect
, fSurface
, &dstrect
);
161 x
+= src
->fSurface
->w
;
168 void c------------------------------() {}
172 void NXSurface::DrawRect(int x1
, int y1
, int x2
, int y2
, uint8_t r
, uint8_t g
, uint8_t b
)
175 uint32_t color
= MapColor(r
, g
, b
);
180 rect
.w
= ((x2
- x1
) + 1) * SCALE
;
182 SDL_FillRect(fSurface
, &rect
, color
);
185 SDL_FillRect(fSurface
, &rect
, color
);
190 rect
.h
= ((y2
- y1
) + 1) * SCALE
;
191 SDL_FillRect(fSurface
, &rect
, color
);
194 SDL_FillRect(fSurface
, &rect
, color
);
198 void NXSurface::FillRect(int x1
, int y1
, int x2
, int y2
, uint8_t r
, uint8_t g
, uint8_t b
)
204 rect
.w
= ((x2
- x1
) + 1) * SCALE
;
205 rect
.h
= ((y2
- y1
) + 1) * SCALE
;
207 SDL_FillRect(fSurface
, &rect
, MapColor(r
, g
, b
));
210 void NXSurface::Clear(uint8_t r
, uint8_t g
, uint8_t b
)
212 SDL_FillRect(fSurface
, NULL
, MapColor(r
, g
, b
));
216 void NXSurface::DrawPixel(int x
, int y
, uint8_t r
, uint8_t g
, uint8_t b
)
218 DrawRect(x
, y
, x
, y
, r
, g
, b
);
222 void c------------------------------() {}
225 int NXSurface::Width()
227 return fSurface
->w
/ SCALE
;
230 int NXSurface::Height()
232 return fSurface
->h
/ SCALE
;
235 NXFormat
*NXSurface::Format()
237 return fSurface
->format
;
240 void NXSurface::Flip()
246 void c------------------------------() {}
249 void NXSurface::set_clip_rect(int x
, int y
, int w
, int h
)
251 NXRect
rect(x
* SCALE
, y
* SCALE
, w
* SCALE
, h
* SCALE
);
252 SDL_SetClipRect(fSurface
, &rect
);
255 void NXSurface::set_clip_rect(NXRect
*rect
)
257 SDL_SetClipRect(fSurface
, rect
);
260 void NXSurface::clear_clip_rect()
262 SDL_SetClipRect(fSurface
, NULL
);
266 void c------------------------------() {}
269 // internal function which scales the given SDL surface by the given factor.
270 SDL_Surface
*NXSurface::Scale(SDL_Surface
*original
, int factor
, \
271 bool use_colorkey
, bool free_original
, bool use_display_format
)
275 if (factor
== 1 && free_original
)
281 scaled
= SDL_CreateRGBSurface(SDL_SRCCOLORKEY
, \
282 original
->w
* SCALE
, \
283 original
->h
* SCALE
, \
284 original
->format
->BitsPerPixel
, \
285 original
->format
->Rmask
, original
->format
->Gmask
,
286 original
->format
->Bmask
, original
->format
->Amask
);
288 if (original
->format
->BitsPerPixel
== 8)
289 { // copy the palette from the old surface to the new surface
290 SDL_Color palette
[256];
291 for(int i
=0;i
<256;i
++)
293 SDL_GetRGB(i
, original
->format
, &palette
[i
].r
, &palette
[i
].g
, &palette
[i
].b
);
296 SDL_SetColors(scaled
, palette
, 0, 256);
299 // all the .pbm files are 8bpp, so I haven't had a reason
300 // to write any other scalers.
301 switch(original
->format
->BitsPerPixel
)
304 Scale8(original
, scaled
, factor
);
308 staterr("NXSurface::Scale: unsupported bpp %d", original
->format
->BitsPerPixel
);
309 SDL_FreeSurface(scaled
);
313 // can get rid of original now if they wanted us to
315 SDL_FreeSurface(original
);
318 // set colorkey to black if requested
320 { // don't use SDL_RLEACCEL--it seems to actually make things a lot slower,
321 // especially on maps with motion tiles.
322 SDL_SetColorKey(scaled
, SDL_SRCCOLORKEY
, SDL_MapRGB(scaled
->format
, 0, 0, 0));
327 scaled
= palette_add(scaled
);
332 if (use_display_format
)
334 SDL_Surface
*ret_sfc
= SDL_DisplayFormat(scaled
);
335 SDL_FreeSurface(scaled
);
345 void NXSurface::Scale8(SDL_Surface
*src
, SDL_Surface
*dst
, int factor
)
349 for(y
=0;y
<src
->h
;y
++)
351 uint8_t *srcline
= (uint8_t *)src
->pixels
+ (y
* src
->pitch
);
352 uint8_t *dstline
= (uint8_t *)dst
->pixels
+ (y
* factor
* dst
->pitch
);
353 uint8_t *dstptr
= dstline
;
355 for(x
=0;x
<src
->w
;x
++)
357 for(i
=0;i
<factor
;i
++)
358 *(dstptr
++) = srcline
[x
];
362 for(i
=1;i
<factor
;i
++)
364 dstptr
+= dst
->pitch
;
365 memcpy(dstptr
, dstline
, dst
->pitch
);
371 void c------------------------------() {}
374 void NXSurface::EnableColorKey()
376 SDL_SetColorKey(fSurface
, SDL_SRCCOLORKEY
, SDL_MapRGB(fSurface
->format
, 0, 0, 0));
379 uint32_t NXSurface::MapColor(uint8_t r
, uint8_t g
, uint8_t b
)
381 return SDL_MapRGB(fSurface
->format
, r
, g
, b
);
385 void NXSurface::Free()
390 SDL_FreeSurface(fSurface
);