55 |
|
|
56 |
static DisplayFlags display_flags = SHOW_ALL; |
static DisplayFlags display_flags = SHOW_ALL; |
57 |
|
|
|
/* The absolute offset of the visible area inside the world. Under normal |
|
|
circumstances, these variables contain integers, but when softscrolling is |
|
|
active, they can temporarily assume fractional values. */ |
|
|
static double ScrollX = 0; |
|
|
static double ScrollY = 0; |
|
|
|
|
|
|
|
|
/* The width and height of a tile in pixels. Together with ScrollX, ScrollY, |
|
|
these two variables are used to convert world coordinates to screen |
|
|
coordinates. */ |
|
|
static int TileWidth = 32; |
|
|
static int TileHeight = 32; |
|
|
|
|
58 |
static GameDisplay *gamedpy = 0; |
static GameDisplay *gamedpy = 0; |
59 |
|
|
60 |
|
|
115 |
blitrect.y = common.y-newy+m_area.y; |
blitrect.y = common.y-newy+m_area.y; |
116 |
m_screen->update_rect(blitrect); |
m_screen->update_rect(blitrect); |
117 |
|
|
118 |
ScrollX = newx/double(m_tilew); |
m_offset = V2(newx/double(m_tilew), newy/double(m_tileh)); |
|
ScrollY = newy/double(m_tileh); |
|
|
|
|
|
m_offset = V2(ScrollX, ScrollY); |
|
119 |
|
|
120 |
RectList rl; |
RectList rl; |
121 |
rl.push_back (m_area); |
rl.push_back (m_area); |
215 |
} |
} |
216 |
|
|
217 |
void |
void |
218 |
DisplayEngine::draw_field (GC &gc, int x, int y) |
DisplayEngine::draw_all (px::GC &gc) |
219 |
{ |
{ |
220 |
|
WorldArea wa = screen_to_world (get_area()); |
221 |
int xpos, ypos; |
int xpos, ypos; |
222 |
world_to_screen (V2(x, y), &xpos, &ypos); |
world_to_screen (V2(wa.x, wa.y), &xpos, &ypos); |
|
|
|
223 |
for (unsigned i=0; i<m_layers.size(); ++i) { |
for (unsigned i=0; i<m_layers.size(); ++i) { |
224 |
m_layers[i]->draw (gc, WorldArea(x,y,1,1), xpos, ypos); |
clip(gc, get_area()); |
225 |
|
m_layers[i]->draw (gc, wa, xpos, ypos); |
226 |
|
m_layers[i]->draw_onepass(gc); |
227 |
} |
} |
228 |
} |
} |
229 |
|
|
|
|
|
230 |
void |
void |
231 |
DisplayEngine::draw_all (px::GC &gc) |
DisplayEngine::update_layer (DisplayLayer *l, WorldArea wa) |
232 |
{ |
{ |
233 |
WorldArea wa = screen_to_world (m_area); |
GC gc(m_screen); |
234 |
|
|
235 |
int x2 = wa.x+wa.w; |
int x2 = wa.x+wa.w; |
236 |
int y2 = wa.y+wa.h; |
int y2 = wa.y+wa.h; |
237 |
for (int x=wa.x; x<x2; x++) { |
|
238 |
for (int y=wa.y; y<y2; y++) { |
// ScreenArea sa = world_to_screen (WorldArea (x, y, 1, 1)); |
239 |
ScreenArea sa = world_to_screen (WorldArea (x, y, 1, 1)); |
// sa.intersect(get_area()); |
240 |
sa.intersect (m_area); |
clip(gc, get_area()); //sa); |
241 |
clip(gc, sa); |
for (int x=wa.x; x<x2; x++) |
242 |
draw_field(gc, x,y); |
for (int y=wa.y; y<y2; y++) |
243 |
} |
if (m_redrawp(x,y)) { |
244 |
} |
int xpos, ypos; |
245 |
|
world_to_screen (V2(x, y), &xpos, &ypos); |
246 |
|
l->draw (gc, WorldArea(x,y,1,1), xpos, ypos); |
247 |
|
} |
248 |
|
|
249 |
|
l->draw_onepass (gc); |
250 |
|
|
251 |
} |
} |
252 |
|
|
253 |
void |
void |
272 |
} |
} |
273 |
} |
} |
274 |
|
|
275 |
|
for (unsigned i=0; i<m_layers.size(); ++i) { |
276 |
int x2 = Min(m_width, wa.x+wa.w); |
update_layer (m_layers[i], wa); |
|
int y2 = Min(m_height, wa.y+wa.h); |
|
|
for (int x=Max(0, wa.x); x<x2; x++) { |
|
|
for (int y=Max(0,wa.y); y<y2; y++) { |
|
|
bool &redrawp = m_redrawp(x,y); |
|
|
if (redrawp) { |
|
|
ScreenArea sa = world_to_screen (WorldArea (x, y, 1, 1)); |
|
|
sa.intersect(area); |
|
|
clip(gc, sa); |
|
|
|
|
|
draw_field(gc, x,y); |
|
|
|
|
|
|
|
|
redrawp = false; |
|
|
m_screen->update_rect(sa); |
|
|
} |
|
|
} |
|
277 |
} |
} |
278 |
|
int x2 = wa.x+wa.w; |
279 |
|
int y2 = wa.y+wa.h; |
280 |
|
for (int x=wa.x; x<x2; x++) |
281 |
|
for (int y=wa.y; y<y2; y++) |
282 |
|
if (m_redrawp(x,y)) { |
283 |
|
m_redrawp(x,y) = false; |
284 |
|
m_screen->update_rect (world_to_screen (WorldArea (x, y, 1, 1))); |
285 |
|
} |
286 |
} |
} |
287 |
|
|
288 |
|
|
412 |
{ |
{ |
413 |
int x2 = a.x+a.w; |
int x2 = a.x+a.w; |
414 |
int y2 = a.y+a.h; |
int y2 = a.y+a.h; |
415 |
for (int x=a.x; x<x2; ++x) |
int tilew = get_engine()->get_tilew(); |
416 |
for (int y=a.y; y<y2; ++y) |
int tileh = get_engine()->get_tileh(); |
417 |
|
int xpos = destx; |
418 |
|
for (int x=a.x; x<x2; ++x) { |
419 |
|
int ypos = desty; |
420 |
|
for (int y=a.y; y<y2; ++y) { |
421 |
if (Model *m = m_models(x,y)) |
if (Model *m = m_models(x,y)) |
422 |
m->draw(gc, destx, desty); |
m->draw(gc, xpos, ypos); |
423 |
|
ypos += tileh; |
424 |
|
} |
425 |
|
xpos += tilew; |
426 |
|
} |
427 |
} |
} |
428 |
|
|
429 |
|
|
561 |
} |
} |
562 |
} |
} |
563 |
|
|
564 |
|
void |
565 |
|
DL_Sprites::draw (px::GC &gc, const WorldArea &a, int x, int y) |
566 |
|
{} |
567 |
|
|
568 |
|
|
569 |
void |
void |
570 |
DL_Sprites::draw (px::GC &gc, const WorldArea &a, int /*x*/, int /*y*/) |
DL_Sprites::draw_onepass (px::GC &gc) //, const WorldArea &a, int /*x*/, int /*y*/) |
571 |
{ |
{ |
572 |
clip (gc, get_engine()->world_to_screen(a)); |
// clip (gc, get_engine()->world_to_screen(a)); |
573 |
draw_sprites (false, gc); |
draw_sprites (false, gc); |
574 |
} |
} |
575 |
|
|
617 |
#include "SDL_gfxPrimitives.h" |
#include "SDL_gfxPrimitives.h" |
618 |
|
|
619 |
void |
void |
620 |
DL_Lines::draw (px::GC &gc, const WorldArea &a, int x, int y) |
DL_Lines::draw_onepass (px::GC &gc)//, const WorldArea &a, int x, int y) |
621 |
{ |
{ |
622 |
clip (gc, get_engine()->world_to_screen(a)); |
DisplayEngine *engine = get_engine(); |
623 |
|
|
624 |
|
// clip (gc, engine->world_to_screen(a)); |
625 |
|
|
626 |
SDL_Surface *surf = video::GetScreen()->get_surface(); |
SDL_Surface *surf = video::GetScreen()->get_surface(); |
627 |
|
|
628 |
Rect r = get_engine()->world_to_screen (a); |
Rect r = engine->get_area(); //world_to_screen (a); |
629 |
SDL_Rect s; |
SDL_Rect s; |
630 |
sdl::copy_rect(s, r); |
sdl::copy_rect(s, r); |
631 |
SDL_SetClipRect (surf, &s); |
SDL_SetClipRect (surf, &s); |
633 |
for (LineMap::iterator i=m_rubbers.begin(); i!= m_rubbers.end(); ++i) |
for (LineMap::iterator i=m_rubbers.begin(); i!= m_rubbers.end(); ++i) |
634 |
{ |
{ |
635 |
int x1, y1, x2, y2; |
int x1, y1, x2, y2; |
636 |
get_engine()->world_to_screen (i->second.start, &x1, &y1); |
engine->world_to_screen (i->second.start, &x1, &y1); |
637 |
get_engine()->world_to_screen (i->second.end, &x2, &y2); |
engine->world_to_screen (i->second.end, &x2, &y2); |
638 |
//aalineRGBA(surf, x1, y1, x2, y2, 240,140,20,255); |
aalineRGBA(surf, x1, y1, x2, y2, 240,140,20,255); |
639 |
lineRGBA(surf, x1, y1, x2, y2, 240,140,20,255); |
//lineRGBA(surf, x1, y1, x2, y2, 240,140,20,255); |
640 |
} |
} |
641 |
SDL_SetClipRect (surf, NULL); |
SDL_SetClipRect (surf, NULL); |
642 |
} |
} |
1031 |
} |
} |
1032 |
|
|
1033 |
void |
void |
1034 |
DL_Shadows::draw (px::GC &gc, const WorldArea &a, int x, int y) |
DL_Shadows::draw (px::GC &gc, const WorldArea &a, int destx, int desty) |
1035 |
{ |
{ |
1036 |
draw (gc, x, y, a.x, a.y); |
int x2 = a.x+a.w; |
1037 |
|
int y2 = a.y+a.h; |
1038 |
|
int tilew = get_engine()->get_tilew(); |
1039 |
|
int tileh = get_engine()->get_tileh(); |
1040 |
|
int xpos = destx; |
1041 |
|
for (int x=a.x; x<x2; ++x) { |
1042 |
|
int ypos = desty; |
1043 |
|
for (int y=a.y; y<y2; ++y) { |
1044 |
|
draw (gc, xpos, ypos, x, y); |
1045 |
|
ypos += tileh; |
1046 |
|
} |
1047 |
|
xpos += tilew; |
1048 |
|
} |
1049 |
} |
} |
1050 |
|
|
1051 |
bool |
bool |
1176 |
// Sprite following code |
// Sprite following code |
1177 |
//---------------------------------------------------------------------- |
//---------------------------------------------------------------------- |
1178 |
|
|
1179 |
Follower_Screen::Follower_Screen(DisplayEngine *e) |
Follower::Follower (DisplayEngine *e) |
1180 |
: Follower(e) |
: m_engine(e) |
1181 |
{ |
{ |
1182 |
ScreenArea gamearea = e->get_area(); |
ScreenArea gamearea = e->get_area(); |
1183 |
m_hoff = gamearea.w / e->get_tilew() - 1; |
m_hoff = gamearea.w / e->get_tilew() - 1; |
1184 |
m_voff = gamearea.h / e->get_tileh() - 1; |
m_voff = gamearea.h / e->get_tileh() - 1; |
1185 |
} |
} |
1186 |
|
|
|
|
|
1187 |
void |
void |
1188 |
Follower_Screen::center(const px::V2 &point) |
Follower::center(const px::V2 &point) |
1189 |
{ |
{ |
1190 |
set_offset(V2 (int(point[0] / m_hoff) * m_hoff, |
set_offset(V2 (int(point[0] / m_hoff) * m_hoff, |
1191 |
int(point[1] / m_voff) * m_voff)); |
int(point[1] / m_voff) * m_voff)); |
1192 |
} |
} |
1193 |
|
|
1194 |
bool |
bool |
1195 |
Follower_Screen::set_offset (V2 offs) |
Follower::set_offset (V2 offs) |
1196 |
{ |
{ |
1197 |
DisplayEngine *engine = get_engine(); |
DisplayEngine *e = get_engine(); |
1198 |
if (offs != engine->get_offset()) { |
if (offs != e->get_offset()) { |
1199 |
offs[0] = max (offs[0], 0.0); |
offs[0] = max (offs[0], 0.0); |
1200 |
offs[1] = max (offs[1], 0.0); |
offs[1] = max (offs[1], 0.0); |
1201 |
offs[0] = min (double(engine->get_width()-m_hoff-1), offs[0]); |
offs[0] = min (double(e->get_width()-get_hoff()-1), offs[0]); |
1202 |
offs[1] = min (double(engine->get_height()-m_voff-1), offs[1]); |
offs[1] = min (double(e->get_height()-get_voff()-1), offs[1]); |
1203 |
engine->set_offset(offs); |
e->set_offset(offs); |
1204 |
return true; |
return true; |
1205 |
} |
} |
1206 |
return false; |
return false; |
1207 |
} |
} |
1208 |
|
|
1209 |
|
Follower_Screen::Follower_Screen(DisplayEngine *e) |
1210 |
|
: Follower(e) |
1211 |
|
{} |
1212 |
|
|
1213 |
|
|
1214 |
/* Determine whether the screen must be scrolled or not, and change |
/* Determine whether the screen must be scrolled or not, and change |
1215 |
the coordinate origin of the screen accordingly. */ |
the coordinate origin of the screen accordingly. */ |
1216 |
void |
void |
1218 |
{ |
{ |
1219 |
DisplayEngine *engine = get_engine(); |
DisplayEngine *engine = get_engine(); |
1220 |
ScreenArea gamearea = engine->get_area(); |
ScreenArea gamearea = engine->get_area(); |
1221 |
|
int borderh = engine->get_tilew()/2; |
1222 |
|
int borderv = engine->get_tileh()/2; |
1223 |
|
|
1224 |
while (true) { |
while (true) { |
1225 |
int sx, sy; |
int sx, sy; |
1227 |
|
|
1228 |
V2 screenoff = engine->get_offset(); |
V2 screenoff = engine->get_offset(); |
1229 |
|
|
1230 |
if (sx < gamearea.x + TileWidth/2) |
if (sx < gamearea.x + borderh) |
1231 |
screenoff[0] -= m_hoff; |
screenoff[0] -= get_hoff(); |
1232 |
if (sy < gamearea.y + TileHeight/2) |
if (sy < gamearea.y + borderv) |
1233 |
screenoff[1] -= m_voff; |
screenoff[1] -= get_voff(); |
1234 |
|
|
1235 |
if (sx >= gamearea.x + gamearea.w-TileWidth/2) |
if (sx >= gamearea.x + gamearea.w-borderh) |
1236 |
screenoff[0] += m_hoff; |
screenoff[0] += get_hoff(); |
1237 |
if (sy >= gamearea.y + gamearea.h-TileHeight/2) |
if (sy >= gamearea.y + gamearea.h-borderv) |
1238 |
screenoff[1] += m_voff; |
screenoff[1] += get_voff(); |
1239 |
|
|
1240 |
if (set_offset(screenoff)) |
if (set_offset(screenoff)) |
1241 |
engine->mark_redraw_screen(); |
engine->mark_redraw_screen(); |
1252 |
scrollspeed(0), resttime(0) |
scrollspeed(0), resttime(0) |
1253 |
{} |
{} |
1254 |
|
|
1255 |
void |
void |
1256 |
Follower_Scrolling::center(const px::V2 &point) |
Follower_Scrolling::center(const px::V2 &point) |
1257 |
{ |
{ |
1258 |
tick(1000, point); |
Follower::center(point); |
1259 |
tick(1000, point); |
curpos = destpos = get_engine()->get_offset(); |
1260 |
} |
} |
1261 |
|
|
1262 |
|
|
1263 |
void |
void |
1264 |
Follower_Scrolling::tick(double dtime, const px::V2 &point) |
Follower_Scrolling::tick(double dtime, const px::V2 &point) |
1265 |
{ |
{ |
1266 |
DisplayEngine *engine = get_engine(); |
DisplayEngine *engine = get_engine(); |
1267 |
ScreenArea gamearea = engine->get_area(); |
ScreenArea gamearea = engine->get_area(); |
1268 |
|
int tilew = engine->get_tilew(); |
1269 |
|
int tileh = engine->get_tileh(); |
1270 |
|
const int border = 1; |
1271 |
|
|
1272 |
int sx, sy; |
int sx, sy; |
1273 |
engine->world_to_screen(point, &sx, &sy); |
engine->world_to_screen(point, &sx, &sy); |
1274 |
|
|
1275 |
const int border = 1; |
bool scrollx_p = (sx < gamearea.x + tilew*border) |
1276 |
bool scrollx_p = (sx < gamearea.x + TileWidth*border) |
|| (sx >= gamearea.x + gamearea.w - tilew*border); |
|
|| (sx >= gamearea.x + gamearea.w - TileWidth*border); |
|
1277 |
|
|
1278 |
bool scrolly_p = (sy < gamearea.y + TileHeight*border) |
bool scrolly_p = (sy < gamearea.y + tileh*border) |
1279 |
|| (sy >= gamearea.y + gamearea.h - TileHeight*border); |
|| (sy >= gamearea.y + gamearea.h - tileh*border); |
1280 |
|
|
1281 |
if (scrollx_p || scrolly_p) |
if (scrollx_p || scrolly_p) |
1282 |
{ |
{ |
1283 |
V2 olddest = destpos; |
V2 olddest = destpos; |
1284 |
|
V2 scrollpos = engine->get_offset(); |
1285 |
|
|
1286 |
currently_scrolling = true; |
currently_scrolling = true; |
1287 |
curpos = V2(ScrollX, ScrollY); |
curpos = scrollpos; |
1288 |
destpos = curpos + point - V2(ScrollX+gamearea.w/TileWidth/2, |
destpos = curpos + point - V2(scrollpos[0] + gamearea.w/tilew/2, |
1289 |
ScrollY+gamearea.h/TileHeight/2); |
scrollpos[1] + gamearea.h/tileh/2); |
1290 |
destpos[0] = int(destpos[0]*TileWidth)/TileWidth; |
destpos[0] = int(destpos[0]*tilew)/tilew; |
1291 |
destpos[1] = int(destpos[1]*TileHeight)/TileHeight; |
destpos[1] = int(destpos[1]*tileh)/tileh; |
1292 |
destpos[0] = max(0, min((int) destpos[0], |
destpos[0] = max(0, min((int) destpos[0], |
1293 |
engine->get_width()-gamearea.w/TileWidth)); |
engine->get_width()-gamearea.w/tilew)); |
1294 |
destpos[1] = max(0, min((int) destpos[1], |
destpos[1] = max(0, min((int) destpos[1], |
1295 |
engine->get_height()-gamearea.h/TileHeight)); |
engine->get_height()-gamearea.h/tileh)); |
1296 |
if (!scrollx_p) |
if (!scrollx_p) |
1297 |
destpos[0] = olddest[0]; //ScrollX; |
destpos[0] = olddest[0]; //ScrollX; |
1298 |
if (!scrolly_p) |
if (!scrolly_p) |
1299 |
destpos[1] = olddest[1]; //ScrollY; |
destpos[1] = olddest[1]; //ScrollY; |
1300 |
|
|
1301 |
scrollspeed = Max(40.0, length(destpos-curpos)/TileWidth*5); |
scrollspeed = Max(40.0, length(destpos-curpos)/tilew*5); |
1302 |
resttime = length(destpos - curpos)/scrollspeed; |
resttime = length(destpos - curpos)/scrollspeed; |
1303 |
dir = normalize(destpos - curpos); |
dir = normalize(destpos - curpos); |
1304 |
} |
} |
1484 |
set_follow_mode (FOLLOW_SCREEN); |
set_follow_mode (FOLLOW_SCREEN); |
1485 |
|
|
1486 |
// shadow_layer->new_world(w,h); |
// shadow_layer->new_world(w,h); |
|
ScrollX = ScrollY = 0; |
|
1487 |
} |
} |
1488 |
|
|
1489 |
StatusBar * |
StatusBar * |