4 #include <SDL/SDL_getenv.h>
9 #include "../dirnames.h"
10 #include "graphics.fdh"
12 NXSurface
*screen
= NULL
; // created from SDL's screen
13 static NXSurface
*drawtarget
= NULL
; // target of DrawRect etc; almost always screen
14 int screen_bpp
= 16; // the default if we can't get video info
16 const NXColor
DK_BLUE(0, 0, 0x21); // the popular dk blue backdrop color
17 const NXColor
BLACK(0, 0, 0); // pure black, only works if no colorkey
18 const NXColor
CLEAR(0, 0, 0); // the transparent/colorkey color
20 static bool is_fullscreen
= false;
21 static int current_res
= -1;
23 bool Graphics::init(int resolution
)
25 const SDL_VideoInfo
*info
;
27 // it's faster if we create the SDL screen at the bpp of the real screen.
28 // max fps went from 120 to 160 on my X11 system this way.
29 if ((info
= SDL_GetVideoInfo()))
31 stat("videoinfo: desktop bpp %d", info
->vfmt
->BitsPerPixel
);
32 if (info
->vfmt
->BitsPerPixel
> 8)
33 screen_bpp
= info
->vfmt
->BitsPerPixel
;
36 if (SetResolution(resolution
, false))
48 void Graphics::close()
50 stat("Graphics::Close()");
55 void c------------------------------() {}
58 bool Graphics::InitVideo()
60 SDL_Surface
*sdl_screen
;
62 stat("Graphics::InitVideo");
63 if (drawtarget
== screen
) drawtarget
= NULL
;
64 if (screen
) delete screen
;
66 uint32_t flags
= SDL_SWSURFACE
;
67 if (is_fullscreen
) flags
|= SDL_FULLSCREEN
;
69 putenv((char *)"SDL_VIDEO_CENTERED=1");
71 sdl_screen
= SDL_SetVideoMode(SCREEN_WIDTH
*SCALE
, SCREEN_HEIGHT
*SCALE
, screen_bpp
, flags
);
74 staterr("Graphics::InitVideo: error setting video mode");
78 SDL_WM_SetCaption("NXEngine", NULL
);
79 SDL_ShowCursor(is_fullscreen
== false);
81 screen
= new NXSurface(sdl_screen
, false);
82 if (!drawtarget
) drawtarget
= screen
;
86 bool Graphics::FlushAll()
88 stat("Graphics::FlushAll()");
89 Sprites::FlushSheets();
95 void Graphics::SetFullscreen(bool enable
)
97 if (is_fullscreen
!= enable
)
99 is_fullscreen
= enable
;
101 Graphics::FlushAll();
105 // change the video mode to one of the available resolution codes, currently:
106 // 0 - 640x480, Fullscreen
107 // 1 - Windowed scale x1 (320x240)
108 // 2 - Windowed scale x2 (640x480)
109 // 3 - Windowed scale x3 (960x720)
110 bool Graphics::SetResolution(int r
, bool restoreOnFailure
)
112 stat("Graphics::SetResolution(%d)", r
);
113 if (r
== current_res
)
116 int old_res
= current_res
;
121 is_fullscreen
= true;
126 is_fullscreen
= false;
130 stat("Setting scaling %d and fullscreen=%s", factor
, is_fullscreen
? "yes":"no");
131 NXSurface::SetScale(factor
);
133 if (Graphics::InitVideo())
135 staterr("Switch to resolution %d failed!", r
);
137 if (restoreOnFailure
)
139 staterr("Trying to recover old mode %d.", r
, old_res
);
140 if (Graphics::SetResolution(old_res
, false))
142 staterr("Fatal error: vidmode recovery failed!!!");
149 if (Graphics::FlushAll()) return 1;
153 // return a pointer to a null-terminated list of available resolutions.
154 const char **Graphics::GetResolutions()
156 static const char *res_str
[] =
159 "320x240", "640x480", "960x720",
167 void c------------------------------() {}
170 // copy a sprite into the current tileset.
171 // used to obtain the images for the star tiles (breakable blocks),
172 // and for animated motion tiles in Waterway.
173 void Graphics::CopySpriteToTile(int spr
, int tileno
, int offset_x
, int offset_y
)
175 NXRect srcrect
, dstrect
;
177 srcrect
.x
= (sprites
[spr
].frame
[0].dir
[0].sheet_offset
.x
+ offset_x
);
178 srcrect
.y
= (sprites
[spr
].frame
[0].dir
[0].sheet_offset
.y
+ offset_y
);
182 dstrect
.x
= (tileno
% 16) * TILE_W
;
183 dstrect
.y
= (tileno
/ 16) * TILE_H
;
187 NXSurface
*tileset
= Tileset::GetSurface();
188 NXSurface
*spritesheet
= Sprites::get_spritesheet(sprites
[spr
].spritesheet
);
190 if (tileset
&& spritesheet
)
192 // blank out the old tile data with clear
193 tileset
->FillRect(&dstrect
, CLEAR
);
195 // copy the sprite over
196 BlitSurface(spritesheet
, &srcrect
, tileset
, &dstrect
);
201 void Graphics::ShowLoadingScreen()
204 char fname
[MAXPATHLEN
];
206 sprintf(fname
, "%s/Loading.pbm", data_dir
);
207 if (loading
.LoadImage(fname
))
210 int x
= (SCREEN_WIDTH
/ 2) - (loading
.Width() / 2);
211 int y
= (SCREEN_HEIGHT
/ 2) - loading
.Height();
213 FillRect(0, 0, SCREEN_WIDTH
, SCREEN_HEIGHT
, 0, 0, 0);
214 DrawSurface(&loading
, x
, y
);
219 void c------------------------------() {}
222 // blit from one surface to another, just like SDL_BlitSurface.
223 void Graphics::BlitSurface(NXSurface
*src
, NXRect
*srcrect
, NXSurface
*dst
, NXRect
*dstrect
)
225 dst
->DrawSurface(src
, dstrect
->x
, dstrect
->y
, \
226 srcrect
->x
, srcrect
->y
, srcrect
->w
, srcrect
->h
);
230 void c------------------------------() {}
233 // draw the entire surface to the screen at the given coordinates.
234 void Graphics::DrawSurface(NXSurface
*src
, int x
, int y
)
236 drawtarget
->DrawSurface(src
, x
, y
);
240 // blit the specified portion of the surface to the screen
241 void Graphics::DrawSurface(NXSurface
*src
, \
242 int dstx
, int dsty
, int srcx
, int srcy
, int wd
, int ht
)
244 drawtarget
->DrawSurface(src
, dstx
, dsty
, srcx
, srcy
, wd
, ht
);
248 // blit the specified surface across the screen in a repeating pattern
249 void Graphics::BlitPatternAcross(NXSurface
*sfc
, int x_dst
, int y_dst
, int y_src
, int height
)
251 drawtarget
->BlitPatternAcross(sfc
, x_dst
, y_dst
, y_src
, height
);
255 void c------------------------------() {}
258 void Graphics::DrawRect(int x1
, int y1
, int x2
, int y2
, NXColor color
)
260 drawtarget
->DrawRect(x1
, y1
, x2
, y2
, color
);
263 void Graphics::FillRect(int x1
, int y1
, int x2
, int y2
, NXColor color
)
265 drawtarget
->FillRect(x1
, y1
, x2
, y2
, color
);
268 void Graphics::DrawPixel(int x
, int y
, NXColor color
)
270 drawtarget
->DrawPixel(x
, y
, color
);
274 void c------------------------------() {}
277 void Graphics::DrawRect(int x1
, int y1
, int x2
, int y2
, uint8_t r
, uint8_t g
, uint8_t b
)
279 drawtarget
->DrawRect(x1
, y1
, x2
, y2
, r
, g
, b
);
282 void Graphics::FillRect(int x1
, int y1
, int x2
, int y2
, uint8_t r
, uint8_t g
, uint8_t b
)
284 drawtarget
->FillRect(x1
, y1
, x2
, y2
, r
, g
, b
);
287 void Graphics::DrawPixel(int x
, int y
, uint8_t r
, uint8_t g
, uint8_t b
)
289 drawtarget
->DrawPixel(x
, y
, r
, g
, b
);
293 void c------------------------------() {}
296 void Graphics::set_clip_rect(int x
, int y
, int w
, int h
)
298 drawtarget
->set_clip_rect(x
, y
, w
, h
);
301 void Graphics::set_clip_rect(NXRect
*rect
)
303 drawtarget
->set_clip_rect(rect
);
306 void Graphics::clear_clip_rect()
308 drawtarget
->clear_clip_rect();
312 void c------------------------------() {}
315 // change the target surface of operation like DrawRect to something
316 // other than the screen.
317 void Graphics::SetDrawTarget(NXSurface
*surface
)
319 drawtarget
= surface
;