diff options
-rw-r--r-- | saga/actor.cpp | 83 | ||||
-rw-r--r-- | saga/actor.h | 17 | ||||
-rw-r--r-- | saga/interface.cpp | 51 | ||||
-rw-r--r-- | saga/scene.cpp | 10 | ||||
-rw-r--r-- | saga/scene.h | 7 | ||||
-rw-r--r-- | saga/sprite.cpp | 58 | ||||
-rw-r--r-- | saga/sprite.h | 6 |
7 files changed, 115 insertions, 117 deletions
diff --git a/saga/actor.cpp b/saga/actor.cpp index 73df0cefd0..ebe812c52a 100644 --- a/saga/actor.cpp +++ b/saga/actor.cpp @@ -39,13 +39,14 @@ #include "saga/actor.h" #include "saga/actordata.h" #include "saga/stream.h" +#include "saga/interface.h" namespace Saga { static int actorCompare(const ActorDataPointer& actor1, const ActorDataPointer& actor2) { - if (actor1->a_pt.y == actor2->a_pt.y) { + if (actor1->actorY == actor2->actorY) { return 0; - } else if (actor1->a_pt.y < actor2->a_pt.y) { + } else if (actor1->actorY < actor2->actorY) { return -1; } else { return 1; @@ -279,15 +280,37 @@ int Actor::direct(int msec) { void Actor::createDrawOrderList() { int i; + int beginSlope, endSlope, middle; ActorData *actor; _drawOrderList.clear(); for (i = 0;i < ACTORCOUNT;i++) { actor = &_actors[i]; if (actor->disabled) continue; + if (actor->sceneNumber != _vm->_scene->currentSceneNumber()) continue; - if (actor->sceneNumber == _vm->_scene->currentSceneNumber()) - _drawOrderList.pushBack(actor, actorCompare); + _drawOrderList.pushBack(actor, actorCompare); + + middle = ITE_STATUS_Y - actor->actorY / ACTOR_LMULT, + + _vm->_scene->getSlopes(beginSlope, endSlope); + + actor->screenDepth = (14 * middle) / endSlope + 1; + + if (middle <= beginSlope) { + actor->screenScale = 256; + } else { + if (middle >= endSlope) { + actor->screenScale = 1; + } else { + middle -= beginSlope; + endSlope -= beginSlope; + actor->screenScale = 256 - (middle * 256) / endSlope; + } + } + + actor->screenPosition.x = (actor->actorX / ACTOR_LMULT); + actor->screenPosition.y = (actor->actorY / ACTOR_LMULT) - actor->actorZ; } } @@ -314,13 +337,19 @@ int Actor::drawActors() { for (actorDrawOrderIterator = _drawOrderList.begin(); actorDrawOrderIterator != _drawOrderList.end(); ++actorDrawOrderIterator) { actor = actorDrawOrderIterator.operator*(); - if (actor->framesCount == 0) continue; + if (actor->framesCount == 0) { + warning("actor->framesCount == 0 actorId 0x%X", actor->actorId); + continue; + } o_idx = ActorOrientationLUT[actor->orient]; sprite_num = actor->frames[actor->action].dir[o_idx].frameIndex; sprite_num += actor->action_frame; - if (actor->spriteList->sprite_count <= sprite_num) continue; - _vm->_sprite->drawOccluded(back_buf, actor->spriteList, sprite_num, actor->s_pt.x, actor->s_pt.y); + if (actor->spriteList->sprite_count <= sprite_num) { + warning("(actor->spriteList->sprite_count <= sprite_num) actorId 0x%X", actor->actorId); + continue; + } + _vm->_sprite->drawOccluded(back_buf, actor->spriteList, sprite_num, actor->screenPosition, actor->screenScale, actor->screenDepth); // If actor's current intent is to speak, oblige him by // displaying his dialogue @@ -331,8 +360,8 @@ int Actor::drawActors() { actorDialogIterator = a_intent->si_diaglist.begin(); if (actorDialogIterator != a_intent->si_diaglist.end()) { a_dialogue = actorDialogIterator.operator->(); - diag_x = actor->s_pt.x; - diag_y = actor->s_pt.y; + diag_x = actor->screenPosition.x; + diag_y = actor->screenPosition.y; diag_y -= ACTOR_DIALOGUE_HEIGHT; _vm->textDraw(MEDIUM_FONT_ID, back_buf, a_dialogue->d_string, diag_x, diag_y, actor->speechColor, 0, FONT_OUTLINE | FONT_CENTERED); @@ -583,13 +612,13 @@ void Actor::walkTo(uint16 actorId, const Point *walk_pt, uint16 flags, SEMAPHORE } } -int Actor::setPathNode(WALKINTENT *walk_int, Point *src_pt, Point *dst_pt, SEMAPHORE *sem) { +int Actor::setPathNode(WALKINTENT *walk_int, const Point &src_pt, Point *dst_pt, SEMAPHORE *sem) { WALKNODE new_node; walk_int->wi_active = 1; - walk_int->org = *src_pt; + walk_int->org = src_pt; - assert((walk_int != NULL) && (src_pt != NULL) && (dst_pt != NULL)); + assert((walk_int != NULL) && (dst_pt != NULL)); new_node.node_pt = *dst_pt; new_node.calc_flag = 0; @@ -625,7 +654,7 @@ int Actor::handleWalkIntent(ActorData *actor, WALKINTENT *a_walkint, int *comple // Initialize walk intent if (!a_walkint->wi_init) { - setPathNode(a_walkint, &actor->a_pt, &a_walkint->dst_pt, a_walkint->sem); + setPathNode(a_walkint, Point(actor->actorX,actor->actorY), &a_walkint->dst_pt, a_walkint->sem); setDefaultAction(actor->actorId, ACTION_IDLE, ACTION_NONE); a_walkint->wi_init = 1; } @@ -741,11 +770,8 @@ int Actor::handleWalkIntent(ActorData *actor, WALKINTENT *a_walkint, int *comple actor_x = (int)new_a_x; actor_y = (int)new_a_y; - actor->a_pt.x = (int)new_a_x; - actor->a_pt.y = (int)new_a_y; - - actor->s_pt.x = actor->a_pt.x >> 2; - actor->s_pt.y = actor->a_pt.y >> 2; + actor->actorX = (int)new_a_x; + actor->actorY = (int)new_a_y; return SUCCESS; } @@ -753,17 +779,10 @@ int Actor::handleWalkIntent(ActorData *actor, WALKINTENT *a_walkint, int *comple void Actor::move(uint16 actorId, const Point &movePoint) { ActorData *actor; - int moveUp = 0; - actor = getActor(actorId); - if (movePoint.y < actor->a_pt.y) { - moveUp = 1; - } - - actor->a_pt = movePoint; - - AtoS(actor->s_pt, actor->a_pt); + actor->actorX = movePoint.x; + actor->actorY = movePoint.y; } void Actor::moveRelative(uint16 actorId, const Point &movePoint) { @@ -771,16 +790,10 @@ void Actor::moveRelative(uint16 actorId, const Point &movePoint) { actor = getActor(actorId); - actor->a_pt.x += movePoint.x; //TODO user rect.h - actor->a_pt.y += movePoint.y; - - AtoS(actor->s_pt, actor->a_pt); + actor->actorX += movePoint.x; + actor->actorY += movePoint.y; } -void Actor::AtoS(Point &screenPoint, const Point &actorPoint) { - screenPoint.x = (actorPoint.x / ACTOR_LMULT); - screenPoint.y = (actorPoint.y / ACTOR_LMULT); -} void Actor::StoA(Point &actorPoint, const Point &screenPoint) { actorPoint.x = (screenPoint.x * ACTOR_LMULT); diff --git a/saga/actor.h b/saga/actor.h index 545a130a75..bb75e54f10 100644 --- a/saga/actor.h +++ b/saga/actor.h @@ -181,7 +181,15 @@ struct ActorData { int nameIndex; // Actor's index in actor name string list byte speechColor; // Actor dialogue color uint16 flags; // Actor flags + int sceneNumber; // scene of actor + int actorX; // Actor's logical coordinates + int actorY; // + int actorZ; // + + Point screenPosition; // Actor's screen coordinates + int screenDepth; // + int screenScale; // int currentAction; int facingDirection; @@ -195,8 +203,6 @@ struct ActorData { int frameListResourceId; // Actor's frame list resource id - Point a_pt; // Actor's logical coordinates - Point s_pt; // Actor's screen coordinates int idle_time; @@ -237,6 +243,11 @@ struct ActorData { spriteList = NULL; spriteListResourceId = 0; flags = 0; + sceneNumber = 0; + actorX = 0; + actorY = 0; + actorZ = 0; + screenDepth = 0; idle_time = 0; orient = 0; @@ -294,7 +305,7 @@ public: private: int handleWalkIntent(ActorData *actor, WALKINTENT *a_walk_int, int *complete_p, int msec); int handleSpeakIntent(ActorData *actor, ACTORINTENT *a_aintent, int *complete_p, int msec); - int setPathNode(WALKINTENT *walk_int, Point *src_pt, Point *dst_pt, SEMAPHORE *sem); + int setPathNode(WALKINTENT *walk_int, const Point &src_pt, Point *dst_pt, SEMAPHORE *sem); ActorData *getActor(uint16 actorId); diff --git a/saga/interface.cpp b/saga/interface.cpp index 8bcede1578..cfb71bc374 100644 --- a/saga/interface.cpp +++ b/saga/interface.cpp @@ -318,11 +318,9 @@ int Interface::draw() { int xbase; int ybase; - int lportrait_x; - int lportrait_y; - int rportrait_x; - int rportrait_y; - + Point lportrait; + Point rportrait; + Point origin; back_buf = _vm->_gfx->getBackBuffer(); @@ -358,16 +356,16 @@ int Interface::draw() { } // Draw character portrait - lportrait_x = xbase + _iDesc.lportrait_x; - lportrait_y = ybase + _iDesc.lportrait_y; + lportrait.x = xbase + _iDesc.lportrait_x; + lportrait.y = ybase + _iDesc.lportrait_y; - _vm->_sprite->draw(back_buf, _defPortraits, _leftPortrait, lportrait_x, lportrait_y); + _vm->_sprite->draw(back_buf, _defPortraits, _leftPortrait, lportrait, 1); if (_panelMode == kPanelDialogue && _iDesc.rportrait_x >= 0) { - rportrait_x = xbase + _iDesc.rportrait_x; - rportrait_y = ybase + _iDesc.rportrait_y; + rportrait.x = xbase + _iDesc.rportrait_x; + rportrait.y = ybase + _iDesc.rportrait_y; - _vm->_sprite->draw(back_buf, _scenePortraits, _rightPortrait, rportrait_x, rportrait_y); + _vm->_sprite->draw(back_buf, _scenePortraits, _rightPortrait, rportrait, 1); } drawInventory(); @@ -457,8 +455,7 @@ int Interface::handleCommandClick(SURFACE *ds, const Point& imousePt) { int x_base; int y_base; - int button_x = 0; - int button_y = 0; + Point button; int old_set_button; int set_button; @@ -482,19 +479,19 @@ int Interface::handleCommandClick(SURFACE *ds, const Point& imousePt) { } if (_cPanel.buttons[set_button].flags & BUTTON_BITMAP) { - button_x = x_base + _cPanel.buttons[set_button].x1; - button_y = y_base + _cPanel.buttons[set_button].y1; + button.x = x_base + _cPanel.buttons[set_button].x1; + button.y = y_base + _cPanel.buttons[set_button].y1; _vm->_sprite->draw(ds, _cPanel.sprites, _cPanel.buttons[set_button]. - active_sprite - 1, button_x, button_y); + active_sprite - 1, button, 1); } if (_cPanel.buttons[old_set_button].flags & BUTTON_BITMAP) { - button_x = x_base + _cPanel.buttons[old_set_button].x1; - button_y = y_base + _cPanel.buttons[old_set_button].y1; + button.x = x_base + _cPanel.buttons[old_set_button].x1; + button.y = y_base + _cPanel.buttons[old_set_button].y1; _vm->_sprite->draw(ds, _cPanel.sprites, _cPanel.buttons[old_set_button]. - inactive_sprite - 1, button_x, button_y); + inactive_sprite - 1, button, 1); } } @@ -505,8 +502,7 @@ int Interface::handleCommandUpdate(SURFACE *ds, const Point& imousePt) { int hit_button; int ibutton_num; - int button_x = 0; - int button_y = 0; + Point button; int button_w = 0; int verb_idx = 0; @@ -546,16 +542,16 @@ int Interface::handleCommandUpdate(SURFACE *ds, const Point& imousePt) { color = _iDesc.cmd_txt_col; } - button_x = _cPanel.x + _cPanel.buttons[i].x1; - button_y = _cPanel.y + _cPanel.buttons[i].y1; + button.x = _cPanel.x + _cPanel.buttons[i].x1; + button.y = _cPanel.y + _cPanel.buttons[i].y1; _vm->_font->draw(SMALL_FONT_ID, ds, I_VerbData[verb_idx].verb_str, 0, - button_x + ((button_w / 2) - (string_w / 2)), button_y + 1, + button.x + ((button_w / 2) - (string_w / 2)), button.y + 1, color, _iDesc.cmd_txt_shadowcol, FONT_SHADOW); if ((i == _cPanel.set_button) && (_cPanel.buttons[i].flags & BUTTON_BITMAP)) { _vm->_sprite->draw(ds, _cPanel.sprites, _cPanel.buttons[i].active_sprite - 1, - button_x, button_y); + button, 1); } } @@ -704,15 +700,18 @@ void Interface::drawInventory() { int y = _iDesc.inv_ystart + _iDesc.inv_icon_yoffset; int width = _iDesc.inv_icon_width + _iDesc.inv_xspacing; int height = _iDesc.inv_icon_height + _iDesc.inv_yspacing; + Point drawPoint; for (int i = 0; i < _inventoryCount; i++) { if (_inventory[i] >= ARRAYSIZE(ObjectTable)) { continue; } + drawPoint.x = x + col * width; + drawPoint.y = y + row * height; _vm->_sprite->draw(back_buf, _vm->_mainSprites, ObjectTable[_inventory[i]].spritelistRn, - x + col * width, y + row * height); + drawPoint, 1); if (++col >= _iDesc.inv_columns) { if (++row >= _iDesc.inv_rows) { diff --git a/saga/scene.cpp b/saga/scene.cpp index fd0c5c19c6..8d3b39edfc 100644 --- a/saga/scene.cpp +++ b/saga/scene.cpp @@ -317,13 +317,9 @@ int Scene::getMode() { return _sceneMode; } -int Scene::getZInfo(SCENE_ZINFO *zinfo) { - assert(_initialized); - - zinfo->beginSlope = _desc.beginSlope; - zinfo->endSlope = _desc.endSlope; - - return SUCCESS; +void Scene::getSlopes(int &beginSlope, int &endSlope) { + beginSlope = ITE_STATUS_Y - _desc.beginSlope; // fixme: implement also IHNM_STATUS_Y + endSlope = ITE_STATUS_Y - _desc.endSlope; } int Scene::getBGInfo(SCENE_BGINFO *bginfo) { diff --git a/saga/scene.h b/saga/scene.h index a7e4ac877e..5f2bf3678b 100644 --- a/saga/scene.h +++ b/saga/scene.h @@ -40,10 +40,6 @@ enum SCENE_MODES { SCENE_MODE_ISO }; -struct SCENE_ZINFO { - int beginSlope; - int endSlope; -}; struct SCENE_BGINFO { int bg_x; @@ -56,7 +52,6 @@ struct SCENE_BGINFO { }; struct SCENE_INFO { - SCENE_ZINFO z_info; SCENE_BGINFO bg_info; TEXTLIST *text_list; }; @@ -232,9 +227,9 @@ class Scene { int getBGMaskInfo(int *w, int *h, byte **buf, size_t *buf_len); int isBGMaskPresent(void); int getBGInfo(SCENE_BGINFO *bginfo); - int getZInfo(SCENE_ZINFO *zinfo); int getBGPal(PALENTRY **pal); int getInfo(SCENE_INFO *si); + void getSlopes(int &beginSlope, int &endSlope); int clearSceneQueue(void); int changeScene(int scene_num); diff --git a/saga/sprite.cpp b/saga/sprite.cpp index a95e61aaea..897a10f386 100644 --- a/saga/sprite.cpp +++ b/saga/sprite.cpp @@ -173,7 +173,7 @@ int Sprite::freeSprite(SPRITELIST *spritelist) { return SUCCESS; } -int Sprite::draw(SURFACE *ds, SPRITELIST *sprite_list, int sprite_num, int spr_x, int spr_y) { +int Sprite::draw(SURFACE *ds, SPRITELIST *sprite_list, int sprite_num, const Point &screenCoord, int scale) { int offset; int offset_idx; byte *sprite_p; @@ -187,6 +187,7 @@ int Sprite::draw(SURFACE *ds, SPRITELIST *sprite_list, int sprite_num, int spr_x int clip_height; int x_align; int y_align; + Point spr_pt; if (!_initialized) { return FAILURE; @@ -209,38 +210,38 @@ int Sprite::draw(SURFACE *ds, SPRITELIST *sprite_list, int sprite_num, int spr_x sprite_data_p = sprite_p + readS.pos(); - spr_x += x_align; - spr_y += y_align; + spr_pt.x = screenCoord.x + x_align; + spr_pt.y = screenCoord.y + y_align; - if (spr_x < 0) { + if (spr_pt.x < 0) { return 0; } - if (spr_y < 0) { + if (spr_pt.y < 0) { return 0; } - decodeRLESprite(sprite_data_p, 64000, _decodeBuf, s_width * s_height); + decodeRLESprite(sprite_data_p, 64000, _decodeBuf, s_width * s_height, scale); - buf_row_p = (byte *)ds->pixels + ds->pitch * spr_y; + buf_row_p = (byte *)ds->pixels + ds->pitch * spr_pt.y; src_row_p = _decodeBuf; // Clip to right side of surface clip_width = s_width; - if (s_width > (ds->w - spr_x)) { - clip_width = (ds->w - spr_x); + if (s_width > (ds->w - spr_pt.x)) { + clip_width = (ds->w - spr_pt.x); } // Clip to bottom side of surface clip_height = s_height; - if (s_height > (ds->h - spr_y)) { - clip_height = (ds->h - spr_y); + if (s_height > (ds->h - spr_pt.y)) { + clip_height = (ds->h - spr_pt.y); } for (i = 0; i < clip_height; i++) { for (j = 0; j < clip_width; j++) { if (*(src_row_p + j) != 0) { - *(buf_row_p + j + spr_x) = *(src_row_p + j); + *(buf_row_p + j + spr_pt.x) = *(src_row_p + j); } } buf_row_p += ds->pitch; @@ -250,12 +251,11 @@ int Sprite::draw(SURFACE *ds, SPRITELIST *sprite_list, int sprite_num, int spr_x return SUCCESS; } -int Sprite::drawOccluded(SURFACE *ds, SPRITELIST *sprite_list, int sprite_num, int spr_x, int spr_y) { +int Sprite::drawOccluded(SURFACE *ds, SPRITELIST *sprite_list, int sprite_num, const Point &screenCoord, int scale, int depth) { int offset; int offset_idx; byte *sprite_p; const byte *sprite_data_p; - int i; int x, y; byte *dst_row_p; byte *src_row_p; @@ -266,8 +266,6 @@ int Sprite::drawOccluded(SURFACE *ds, SPRITELIST *sprite_list, int sprite_num, i int s_height; int x_align; int y_align; - int z_lut[SPRITE_ZMAX]; - int e_slope; // Clipinfo variables Point spr_pt; @@ -283,16 +281,13 @@ int Sprite::drawOccluded(SURFACE *ds, SPRITELIST *sprite_list, int sprite_num, i byte *mask_row_p; int mask_z; - // Z info variables - SCENE_ZINFO zinfo; - int actor_z; if (!_initialized) { return FAILURE; } if (!_vm->_scene->isBGMaskPresent()) { - return draw(ds, sprite_list, sprite_num, spr_x, spr_y); + return draw(ds, sprite_list, sprite_num, screenCoord, scale); } if (sprite_num >= sprite_list->sprite_count) { @@ -319,16 +314,7 @@ int Sprite::drawOccluded(SURFACE *ds, SPRITELIST *sprite_list, int sprite_num, i sprite_data_p = sprite_p + readS.pos(); - // Create actor Z occlusion LUT - _vm->_scene->getZInfo(&zinfo); - - e_slope = zinfo.endSlope; - for (i = 0; i < SPRITE_ZMAX; i++) { - z_lut[i] = (int)(e_slope + ((137.0 - e_slope) / 14.0) * (15.0 - i)); - } - - actor_z = spr_y; _vm->_scene->getBGMaskInfo(&mask_w, &mask_h, &mask_buf, &mask_buf_len); @@ -342,11 +328,8 @@ int Sprite::drawOccluded(SURFACE *ds, SPRITELIST *sprite_list, int sprite_num, i spr_dst_rect.right = ds->clip_rect.right; spr_dst_rect.bottom = MIN(ds->clip_rect.bottom, (int16)mask_h); - spr_pt.x = spr_x + x_align; - spr_pt.y = spr_y + y_align; - - spr_x += x_align; - spr_y += y_align; + spr_pt.x = screenCoord.x + x_align; + spr_pt.y = screenCoord.y + y_align; ci.dst_rect = &spr_dst_rect; ci.src_rect = &spr_src_rect; @@ -358,7 +341,7 @@ int Sprite::drawOccluded(SURFACE *ds, SPRITELIST *sprite_list, int sprite_num, i return SUCCESS; } - decodeRLESprite(sprite_data_p, 64000, _decodeBuf, s_width * s_height); + decodeRLESprite(sprite_data_p, 64000, _decodeBuf, s_width * s_height, scale); // Finally, draw the occluded sprite src_row_p = _decodeBuf + ci.src_draw_x + (ci.src_draw_y * s_width); @@ -373,7 +356,7 @@ int Sprite::drawOccluded(SURFACE *ds, SPRITELIST *sprite_list, int sprite_num, i for (x = 0; x < ci.draw_w; x++) { if (*src_p != 0) { mask_z = *mask_p & SPRITE_ZMASK; - if (actor_z > z_lut[mask_z]) { + if (mask_z > depth) { *dst_p = *src_p; } } @@ -396,7 +379,8 @@ int Sprite::drawOccluded(SURFACE *ds, SPRITELIST *sprite_list, int sprite_num, i return SUCCESS; } -int Sprite::decodeRLESprite(const byte *inbuf, size_t inbuf_len, byte *outbuf, size_t outbuf_len) { +//TODO write scale support +int Sprite::decodeRLESprite(const byte *inbuf, size_t inbuf_len, byte *outbuf, size_t outbuf_len, int scale) { int bg_runcount; int fg_runcount; const byte *inbuf_ptr; diff --git a/saga/sprite.h b/saga/sprite.h index 5ec28a74c5..99623bc1d3 100644 --- a/saga/sprite.h +++ b/saga/sprite.h @@ -65,11 +65,11 @@ class Sprite { int appendList(int resource_num, SPRITELIST *spritelist); int getListLen(SPRITELIST *spritelist); int freeSprite(SPRITELIST *spritelist); - int draw(SURFACE *ds, SPRITELIST *sprite_list, int sprite_num, int spr_x, int spr_y); - int drawOccluded(SURFACE *ds, SPRITELIST *sprite_list, int sprite_num, int spr_x, int spr_y); + int draw(SURFACE *ds, SPRITELIST *sprite_list, int sprite_num, const Point &screenCoord, int scale); + int drawOccluded(SURFACE *ds, SPRITELIST *sprite_list, int sprite_num, const Point &screenCoord, int scale, int depth); private: - int decodeRLESprite(const byte *inbuf, size_t inbuf_len, byte *outbuf, size_t outbuf_len); + int decodeRLESprite(const byte *inbuf, size_t inbuf_len, byte *outbuf, size_t outbuf_len, int scale); SagaEngine *_vm; bool _initialized; |