00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "mapview.h"
00027 #include <set>
00028
00029 mapview::mapview () : da ()
00030 {
00031 drawable::set_length (0);
00032 drawable::set_height (0);
00033 d_length = d_height = currentsubmap_ = posx_ = posy_ = 0;
00034 m_map = NULL;
00035 offx_ = offy_ = 0;
00036
00037 schedule_args = NULL;
00038 }
00039
00040 mapview::~mapview ()
00041 {
00042 detach_map ();
00043 Py_XDECREF (schedule_args);
00044 }
00045
00046 void mapview::attach_map (landmap * m)
00047 {
00048 m_map = m;
00049
00050 set_pos (0, 0, 0);
00051 }
00052
00053 void mapview::detach_map ()
00054 {
00055 if (!m_map) return;
00056
00057 m_map = NULL;
00058 }
00059
00060 s_int8 mapview::set_pos (u_int16 sm, u_int16 px, u_int16 py, s_int16 ox, s_int16 oy)
00061 {
00062 currentsubmap_ = sm;
00063 mapsquare_area * ms = m_map->submap[sm];
00064
00065 s_int32 tpx = px * MAPSQUARE_SIZE + ox;
00066 s_int32 tpy = py * MAPSQUARE_SIZE + oy;
00067
00068 if (tpx + length () > ms->area_length () * MAPSQUARE_SIZE)
00069 tpx = ms->area_length () * MAPSQUARE_SIZE - length ();
00070 if (tpy + height () > ms->area_height () * MAPSQUARE_SIZE)
00071 tpy = ms->area_height () * MAPSQUARE_SIZE - height ();
00072
00073 if (tpx < 0) tpx = 0;
00074 if (tpy < 0) tpy = 0;
00075
00076 px = tpx / MAPSQUARE_SIZE;
00077 py = tpy / MAPSQUARE_SIZE;
00078
00079 ox = tpx % MAPSQUARE_SIZE;
00080 oy = tpy % MAPSQUARE_SIZE;
00081
00082 posx_ = px;
00083 posy_ = py;
00084 offx_ = ox;
00085 offy_ = oy;
00086
00087 return 0;
00088 }
00089
00090 s_int8 mapview::center_on (u_int16 sm, u_int16 px, u_int16 py, s_int16 ox, s_int16 oy)
00091 {
00092 s_int32 tpx = px * MAPSQUARE_SIZE + ox - ((length () - MAPSQUARE_SIZE) >> 1);
00093 s_int32 tpy = py * MAPSQUARE_SIZE + oy - ((height () - MAPSQUARE_SIZE) >> 1);
00094
00095 if (tpx < 0) tpx = 0;
00096 if (tpy < 0) tpy = 0;
00097
00098 s_int16 npx = tpx / MAPSQUARE_SIZE;
00099 s_int16 npy = tpy / MAPSQUARE_SIZE;
00100
00101 s_int16 nox = tpx % MAPSQUARE_SIZE;
00102 s_int16 noy = tpy % MAPSQUARE_SIZE;
00103
00104 return set_pos (sm, npx, npy, nox, noy);
00105 }
00106
00107 void mapview::scroll_right ()
00108 {
00109 if (!can_scroll_right ())
00110 return;
00111 if (offx_ == MAPSQUARE_SIZE - 1)
00112 {
00113 offx_ = 0;
00114 posx_++;
00115 }
00116 else
00117 offx_++;
00118 }
00119
00120 void mapview::scroll_left ()
00121 {
00122 if (!can_scroll_left ())
00123 return;
00124 if (offx_ == 0)
00125 {
00126 offx_ = MAPSQUARE_SIZE - 1;
00127 posx_--;
00128 }
00129 else
00130 offx_--;
00131 }
00132
00133 void mapview::scroll_down ()
00134 {
00135 if (!can_scroll_down ())
00136 return;
00137 if (offy_ == MAPSQUARE_SIZE - 1)
00138 {
00139 offy_ = 0;
00140 posy_++;
00141 }
00142 else
00143 offy_++;
00144 }
00145
00146 void mapview::scroll_up ()
00147 {
00148 if (!can_scroll_up ())
00149 return;
00150 if (offy_ == 0)
00151 {
00152 offy_ = MAPSQUARE_SIZE - 1;
00153 posy_--;
00154 }
00155 else
00156 offy_--;
00157 }
00158
00159 void mapview::resize (u_int16 l, u_int16 h)
00160 {
00161 drawable::set_length (l);
00162 drawable::set_height (h);
00163 d_length = (l / MAPSQUARE_SIZE) + (l % MAPSQUARE_SIZE != 0);
00164 d_height = (h / MAPSQUARE_SIZE) + (h % MAPSQUARE_SIZE != 0);
00165 da.resize (length (), height ());
00166 }
00167
00168 s_int8 mapview::get_state (igzstream& file)
00169 {
00170 u_int16 a, b, c, d, sm;
00171 string t;
00172 bool bo;
00173
00174
00175
00176 a << file;
00177 b << file;
00178 resize (a, b);
00179
00180
00181 sm << file;
00182
00183
00184 a << file;
00185 b << file;
00186 c << file;
00187 d << file;
00188 set_pos (sm, a, b, c, d);
00189
00190
00191 PyObject * args = NULL;
00192 t << file;
00193 bo << file;
00194 if (bo) args = python::get_tuple (file);
00195 set_schedule (t, args);
00196 Py_XDECREF (args);
00197
00198 return 0;
00199 }
00200
00201 s_int8 mapview::put_state (ogzstream& file)
00202 {
00203 u_int16 b;
00204
00205
00206 b = length ();
00207 b >> file;
00208 b = height ();
00209 b >> file;
00210 currentsubmap_ >> file;
00211
00212
00213 posx_ >> file;
00214 posy_ >> file;
00215 offx_ >> file;
00216 offy_ >> file;
00217
00218
00219 schedule_file () >> file;
00220 if (schedule_args)
00221 {
00222 true >> file;
00223 python::put_tuple (schedule_args, file);
00224 }
00225 else false >> file;
00226
00227 return 0;
00228 }
00229
00230 void mapview::set_schedule (string file, PyObject * args)
00231 {
00232 if (file == "")
00233 {
00234 schedule.clear ();
00235 Py_XDECREF (schedule_args);
00236 schedule_args = NULL;
00237 }
00238 else
00239 {
00240 Py_XINCREF (args);
00241 schedule_args = args;
00242
00243 u_int16 argssize = args == NULL ? 1 : PyTuple_Size (args) + 1;
00244 PyObject * theargs;
00245
00246 theargs = PyTuple_New (argssize);
00247
00248
00249
00250 PyTuple_SetItem (theargs, 0, python::pass_instance (this, "mapview"));
00251 for (u_int16 i = 1; i < argssize; i++)
00252 {
00253 PyObject * intref = PyTuple_GetItem (args, i - 1);
00254 Py_INCREF (intref);
00255 PyTuple_SetItem (theargs, i, intref);
00256 }
00257 schedule.create_instance ("schedules.mapviews." + file, file, theargs);
00258 Py_DECREF (theargs);
00259 }
00260 schedule_file_ = file;
00261 }
00262
00263 bool mapview::update ()
00264 {
00265 schedule.run ();
00266
00267 return true;
00268 }
00269
00270 void mapview::draw (s_int16 x, s_int16 y, const drawing_area * da_opt,
00271 surface *target) const
00272 {
00273 static u_int16 i, j;
00274 static u_int16 i0, j0, ie, je;
00275 static list <mapsquare_tile>::iterator it;
00276 static list <mapsquare_char>::iterator itc;
00277 static list <mapcharacter *>::iterator itb;
00278 static mapsquare_area *l;
00279 static u_int16 offx, offy;
00280
00281 static list <mapsquare_tile> critical_draw;
00282 static list <mapsquare_char> characters_draw;
00283 static list <mapcharacter *> bubbles_draw;
00284
00285 if (!m_map)
00286 return;
00287
00288 static SDL_Rect trect;
00289 static drawing_area tda;
00290
00291 da.move (x, y);
00292 if (da_opt) da.assign_drawing_area (da_opt);
00293
00294 trect = da.setup_rects ();
00295 tda = trect;
00296
00297 l = m_map->submap[currentsubmap_];
00298 if (!l->area_length () || !l->area_height ())
00299 return;
00300
00301 i0 = posx_;
00302 j0 = posy_;
00303 ie = i0 + d_length + (offx_ != 0) < l->area_length () ? i0 + d_length + (offx_ !=
00304 0) : l->area_length ();
00305 je = j0 + d_height + (offy_ != 0) < l->area_height () ? j0 + d_height + (offy_ !=
00306 0) : l->area_height ();
00307
00308 offx = l->area_length () * MAPSQUARE_SIZE < length () ?
00309 (length () - l->area_length () * MAPSQUARE_SIZE) >> 1 : 0;
00310
00311 offy = l->area_height () * MAPSQUARE_SIZE < height () ?
00312 (height () - l->area_height () * MAPSQUARE_SIZE) >> 1 : 0;
00313
00314 x += offx;
00315 y += offy;
00316
00317
00318
00319 for (it = l->area[i0][j0].tiles.begin ();
00320 it != l->area[i0][j0].tiles.end () && *(it->base_tile) < *it; it++)
00321 if (it->x > it->base_tile->x && it->y > it->base_tile->y)
00322 critical_draw.push_back (*(it->base_tile));
00323
00324 for (itc = l->area[i0][j0].mapchars.begin ();
00325 itc != l->area[i0][j0].mapchars.end (); itc++)
00326 if (itc->x > itc->base_tile->x && itc->y > itc->base_tile->y)
00327 characters_draw.push_back (*itc);
00328
00329
00330 for (i = i0; i < ie && i < l->area_length (); i++)
00331 {
00332 for (it = l->area[i][j0].tiles.begin ();
00333 it != l->area[i][j0].tiles.end (); it++)
00334 if (it->x == it->base_tile->x && it->y > it->base_tile->y)
00335 critical_draw.push_back (*(it->base_tile));
00336
00337 for (itc = l->area[i][j0].mapchars.begin ();
00338 itc != l->area[i][j0].mapchars.end (); itc++)
00339 if (itc->x == itc->base_tile->x && itc->y > itc->base_tile->y)
00340 characters_draw.push_back (*itc);
00341 }
00342
00343
00344 for (it = l->area[ie - 1][j0].tiles.begin ();
00345 it != l->area[ie - 1][j0].tiles.end (); it++)
00346 if (it->x < it->base_tile->x && it->y > it->base_tile->y)
00347 critical_draw.push_back (*(it->base_tile));
00348
00349 for (itc = l->area[ie - 1][j0].mapchars.begin ();
00350 itc != l->area[ie - 1][j0].mapchars.end (); itc++)
00351 if (itc->x < itc->base_tile->x && itc->y > itc->base_tile->y)
00352 characters_draw.push_back (*itc);
00353
00354
00355 critical_draw.sort ();
00356 characters_draw.sort ();
00357
00358 it = critical_draw.begin ();
00359 itc = characters_draw.begin ();
00360 while (itc != characters_draw.end () || it != critical_draw.end ())
00361 {
00362 if (itc != characters_draw.end ())
00363 {
00364 if (it != critical_draw.end ())
00365 {
00366 if (it->base_tile->y <= itc->base_tile->y)
00367 {
00368 draw_tile (x, y, &tda, target, it);
00369 it++;
00370 }
00371 else
00372 {
00373 draw_mapchar (x, y, &tda, target, itc);
00374 if (itc->mchar->is_speaking ())
00375 bubbles_draw.push_back (itc->mchar);
00376 itc++;
00377 }
00378 }
00379 else
00380 {
00381 draw_mapchar (x, y, &tda, target, itc);
00382 if (itc->mchar->is_speaking ())
00383 bubbles_draw.push_back (itc->mchar);
00384 itc++;
00385 }
00386 }
00387 else
00388 {
00389 draw_tile (x, y, &tda, target, it);
00390 it++;
00391 }
00392 }
00393 critical_draw.clear ();
00394 characters_draw.clear ();
00395
00396
00397 for (j = j0; j < je; j++)
00398 {
00399
00400 for (it = l->area[i0][j].tiles.begin ();
00401 it != l->area[i0][j].tiles.end () && *(it->base_tile) <= *it;
00402 it++)
00403 if (it->y == it->base_tile->y && it->x > it->base_tile->x)
00404 draw_tile (x, y, &tda, target, it);
00405
00406 for (itc = l->area[i0][j].mapchars.begin ();
00407 itc != l->area[i0][j].mapchars.end (); itc++)
00408 if (itc->y == itc->base_tile->y && itc->x > itc->base_tile->x)
00409 characters_draw.push_back (*itc);
00410
00411
00412 for (i = i0; i < ie; i++)
00413 {
00414 for (it = l->area[i][j].base_begin;
00415 it != l->area[i][j].tiles.end () && *(it->base_tile) < *it;
00416 it++);
00417 for (; it != l->area[i][j].tiles.end () && *(it->base_tile) == *it;
00418 it++)
00419 draw_tile (x, y, &tda, target, it);
00420
00421 for (itc = l->area[i][j].mapchars.begin ();
00422 itc != l->area[i][j].mapchars.end (); itc++)
00423 if (*itc == *(itc->base_tile) &&
00424 itc->x == itc->mchar->posx () &&
00425 itc->y == itc->mchar->posy ())
00426 characters_draw.push_back (*itc);
00427 }
00428
00429
00430 for (it = l->area[ie - 1][j].tiles.begin ();
00431 it != l->area[ie - 1][j].tiles.end (); it++)
00432 if (it->y == it->base_tile->y && it->x < it->base_tile->x)
00433 draw_tile (x, y, &tda, target, it);
00434
00435 for (itc = l->area[ie - 1][j].mapchars.begin ();
00436 itc != l->area[ie - 1][j].mapchars.end (); itc++)
00437 if (itc->y == itc->base_tile->y && itc->x < itc->base_tile->x)
00438 characters_draw.push_back (*itc);
00439
00440
00441 for (itc = characters_draw.begin (); itc != characters_draw.end ();
00442 itc++)
00443 {
00444 draw_mapchar (x, y, &tda, target, itc);
00445 if (itc->mchar->is_speaking ())
00446 bubbles_draw.push_back (itc->mchar);
00447 }
00448 characters_draw.clear ();
00449 }
00450
00451
00452
00453 if (!l->area[i0][je - 1].tiles.empty ())
00454 for (it = --l->area[i0][je - 1].tiles.end ();
00455 it->y < it->base_tile->y; it--)
00456 {
00457 if (it->x > it->base_tile->x && it->y < it->base_tile->y)
00458 critical_draw.push_front (*(it->base_tile));
00459 if (it == l->area[i0][je - 1].tiles.begin ())
00460 break;
00461 }
00462
00463 for (itc = l->area[i0][je - 1].mapchars.begin ();
00464 itc != l->area[i0][je - 1].mapchars.end (); itc++)
00465 if (itc->x > itc->base_tile->x && itc->y < itc->base_tile->y)
00466 characters_draw.push_back (*itc);
00467
00468
00469 for (i = i0; i < ie && i < l->area_length (); i++)
00470 {
00471 if (!l->area[i][je - 1].tiles.empty ())
00472 for (it = --l->area[i][je - 1].tiles.end ();
00473 it->y < it->base_tile->y; it--)
00474 {
00475 if (it->x == it->base_tile->x && it->y < it->base_tile->y)
00476 critical_draw.push_front (*(it->base_tile));
00477 if (it == l->area[i][je - 1].tiles.begin ())
00478 break;
00479 }
00480
00481 for (itc = l->area[i][je - 1].mapchars.begin ();
00482 itc != l->area[i][je - 1].mapchars.end (); itc++)
00483 {
00484 if (itc->x == itc->base_tile->x && itc->y < itc->base_tile->y)
00485 {
00486 characters_draw.push_back (*itc);
00487 }
00488 }
00489 }
00490
00491
00492 if (!l->area[ie - 1][je - 1].tiles.empty ())
00493 for (it = --l->area[ie - 1][je - 1].tiles.end ();
00494 it->y < it->base_tile->y; it--)
00495 {
00496 if (it->x < it->base_tile->x && it->y < it->base_tile->y)
00497 critical_draw.push_front (*(it->base_tile));
00498 if (it == l->area[ie - 1][je - 1].tiles.begin ())
00499 break;
00500 }
00501
00502 for (itc = l->area[ie - 1][je - 1].mapchars.begin ();
00503 itc != l->area[ie - 1][je - 1].mapchars.end (); itc++)
00504 if (itc->x < itc->base_tile->x && itc->y < itc->base_tile->y)
00505 characters_draw.push_back (*itc);
00506
00507
00508
00509 critical_draw.sort ();
00510 characters_draw.sort ();
00511
00512 it = critical_draw.begin ();
00513 itc = characters_draw.begin ();
00514 while (itc != characters_draw.end () || it != critical_draw.end ())
00515 {
00516 if (itc != characters_draw.end ())
00517 {
00518 if (it != critical_draw.end ())
00519 {
00520 if (it->base_tile->y <= itc->base_tile->y)
00521 {
00522 draw_tile (x, y, &tda, target, it);
00523 it++;
00524 }
00525 else
00526 {
00527 draw_mapchar (x, y, &tda, target, itc);
00528 if (itc->mchar->is_speaking ())
00529 bubbles_draw.push_back (itc->mchar);
00530 itc++;
00531 }
00532 }
00533 else
00534 {
00535 draw_mapchar (x, y, &tda, target, itc);
00536 if (itc->mchar->is_speaking ())
00537 bubbles_draw.push_back (itc->mchar);
00538 itc++;
00539 }
00540 }
00541 else
00542 {
00543 draw_tile (x, y, &tda, target, it);
00544 it++;
00545 }
00546 }
00547
00548 for (itb = bubbles_draw.begin (); itb != bubbles_draw.end (); itb++)
00549 draw_bubble (x, y, &tda, target, itb);
00550
00551 critical_draw.clear ();
00552 characters_draw.clear ();
00553 bubbles_draw.clear ();
00554
00555 if (da_opt) da.detach_drawing_area ();
00556 }
00557
00558
00559
00560
00561
00562
00563 void mapview::draw_tile (s_int16 x, s_int16 y, const drawing_area * da_opt,
00564 surface * target, list<mapsquare_tile>::iterator it) const
00565 {
00566 it->mapobj->draw_from_base
00567 ((it->base_tile->x - posx_) * MAPSQUARE_SIZE - offx_ + x,
00568 (it->base_tile->y - posy_) * MAPSQUARE_SIZE - offy_ + y,
00569 da_opt, target);
00570 }
00571
00572 void mapview::draw_mapchar (s_int16 x, s_int16 y, const drawing_area * da_opt,
00573 surface * target, list<mapsquare_char>::iterator itc) const
00574 {
00575 u_int16 xdraw =
00576 ((itc->mchar->posx () - posx_ - itc->mchar->base_x ()) * MAPSQUARE_SIZE)
00577 + itc->mchar->offx () - offx_ + x;
00578
00579 u_int16 ydraw =
00580 ((itc->mchar->posy () - posy_ - itc->mchar->base_y ()) * MAPSQUARE_SIZE)
00581 + itc->mchar->offy () - offy_ + y;
00582
00583 itc->mchar->draw (xdraw, ydraw, da_opt, target);
00584 }
00585
00586 void mapview::draw_bubble (s_int16 x, s_int16 y, const drawing_area * da_opt,
00587 surface * target, list<mapcharacter *>::iterator itc) const
00588 {
00589 u_int16 xdraw =
00590 (((*itc)->posx () - posx_ - (*itc)->base_x ()) * MAPSQUARE_SIZE)
00591 + (*itc)->offx () - offx_ + x;
00592
00593 u_int16 ydraw =
00594 (((*itc)->posy () - posy_ - (*itc)->base_y ()) * MAPSQUARE_SIZE)
00595 + (*itc)->offy () - offy_ + y;
00596
00597 (*itc)->draw_bubble (xdraw, ydraw, da_opt, target);
00598 }