NXEngine v1.0.0.2
[NXEngine.git] / graphics / safemode.cpp
blob615ee563a69911b48aa2b7b29a3c44bc694b2795
2 // a limited and redundant graphics system which allows placing text on the screen
3 // in the case of startup errors or before the real data files are extracted.
4 #include <SDL/SDL.h>
5 #include <SDL/SDL_ttf.h>
6 #include <stdarg.h>
7 #include "../common/basics.h"
8 #include "../common/BList.h"
9 #include "../input.h"
10 #include "nxsurface.h"
11 #include "graphics.h"
12 #include "safemode.h"
13 #include "safemode.fdh"
15 using namespace safemode;
16 using namespace Graphics;
18 static BList textlist;
19 struct TextRecord
21 TextRecord();
22 ~TextRecord();
24 int x, y;
25 SDL_Surface *sfc;
28 static SDL_Surface *sdl_screen = NULL;
29 static TTF_Font *font;
31 extern const char *fontfile; // from font.cpp
32 extern int pointsize[]; // from font.cpp
34 static int nexty = 0;
35 static int fontheight = 0;
36 static SDL_Color textcolor;
37 static bool initilized = false;
38 static bool have_status = false;
40 bool safemode::init()
42 try
44 sdl_screen = NULL;
45 if (screen) sdl_screen = screen->GetSDLSurface();
46 if (!sdl_screen) throw "graphics not initilized";
48 if (TTF_Init() < 0)
50 throw stprintf("couldn't initialize SDL_ttf: %s", TTF_GetError());
53 font = TTF_OpenFont(fontfile, pointsize[SCALE]);
54 if (!font)
56 throw stprintf("couldn't open font: '%s': %s", fontfile, TTF_GetError());
59 static SDL_Color black;
60 SDL_Surface *temp = TTF_RenderText_Solid(font, "M", black);
61 if (temp)
63 fontheight = temp->h;
64 SDL_FreeSurface(temp);
66 else
68 throw "initial render failed";
71 textcolor.r = 0x00;
72 textcolor.g = 0xff;
73 textcolor.b = 0x80;
74 textlist.MakeEmpty();
76 moveto(SM_UPPER_THIRD);
77 initilized = true;
79 return 0;
81 catch(const char *error)
83 staterr("safemode::init: failed startup: %s", error);
84 sdl_screen = NULL;
85 return 1;
89 void safemode::close()
91 if (initilized)
93 FillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 0);
94 screen->Flip();
96 clear();
98 if (font) TTF_CloseFont(font);
99 sdl_screen = NULL;
104 void c------------------------------() {}
107 void safemode::moveto(int y)
109 switch(y)
111 case SM_CENTER:
112 nexty = ((SCREEN_HEIGHT * SCALE) / 2) - (fontheight / 2);
113 break;
115 case SM_UPPER_THIRD:
116 nexty = ((SCREEN_HEIGHT * SCALE) / 4) - (fontheight / 2);
117 break;
119 case SM_LOWER_THIRD:
120 nexty = ((SCREEN_HEIGHT * SCALE) / 4) - (fontheight / 2);
121 nexty = (SCREEN_HEIGHT * SCALE) - nexty;
122 break;
124 case SM_MIDUPPER_Y:
125 nexty = ((SCREEN_HEIGHT * SCALE) / 2) - (fontheight / 2);
126 nexty -= (32 * SCALE);
127 break;
129 default:
130 nexty = y;
131 break;
135 bool safemode::print(const char *fmt, ...)
137 va_list ar;
138 char buffer[128];
139 SDL_Surface *sfc;
141 va_start(ar, fmt);
142 vsnprintf(buffer, sizeof(buffer), fmt, ar);
143 va_end(ar);
145 stat("safemode print: '%s'", buffer);
147 if (buffer[0])
149 sfc = TTF_RenderText_Solid(font, buffer, textcolor);
150 if (!sfc)
152 staterr("safemode::print: failed to render string: '%s'", fmt);
153 return 1;
156 TextRecord *tr = new TextRecord;
157 tr->x = (((SCREEN_WIDTH * SCALE) / 2) - (sfc->w / 2));
158 tr->y = nexty;
159 tr->sfc = sfc;
160 textlist.AddItem(tr);
161 run();
164 nexty += (fontheight + (1 * SCALE));
165 return 0;
168 void safemode::clear()
170 while(textlist.CountItems())
171 delete (TextRecord *)textlist.RemoveItem(textlist.CountItems() - 1);
173 moveto(SM_UPPER_THIRD);
177 void safemode::run()
179 FillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0x20, 0x20, 0x20);
181 for(int i=0;;i++)
183 TextRecord *tr = (TextRecord *)textlist.ItemAt(i);
184 if (!tr) break;
186 SDL_Rect dstrect;
187 dstrect.x = tr->x;
188 dstrect.y = tr->y;
190 SDL_BlitSurface(tr->sfc, NULL, sdl_screen, &dstrect);
193 SDL_Flip(sdl_screen);
197 int safemode::run_until_key(bool delay)
199 stat("run_until_key()");
200 uint32_t start = SDL_GetTicks();
202 last_sdl_key = -1;
205 run();
206 input_poll();
207 SDL_Delay(50);
209 if (delay && (SDL_GetTicks() - start) < 500)
210 last_sdl_key = -1;
212 while(last_sdl_key == -1);
214 return last_sdl_key;
218 void safemode::status(const char *fmt, ...)
220 va_list ar;
221 char buffer[128];
223 va_start(ar, fmt);
224 vsnprintf(buffer, sizeof(buffer), fmt, ar);
225 va_end(ar);
227 clearstatus();
228 moveto(SM_CENTER);
229 print("%s", buffer);
231 have_status = true;
234 void safemode::clearstatus()
236 if (have_status)
238 // remove all except the header
239 while(textlist.CountItems() > 1)
240 delete (TextRecord *)textlist.RemoveItem(textlist.CountItems() - 1);
242 moveto(SM_CENTER);
243 have_status = false;
248 void c------------------------------() {}
251 TextRecord::TextRecord()
253 sfc = NULL;
256 TextRecord::~TextRecord()
258 if (sfc)
260 SDL_FreeSurface(sfc);
261 sfc = NULL;