1 /* 2 * Copyright (C) 2004 Ivo Danihelka (ivo@danihelka.net) 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 */ 9 #include "View.h" 10 11 #include "PhaseLocker.h" 12 #include "ModelList.h" 13 #include "Decor.h" 14 15 #include "Cube.h" 16 #include "Anim.h" 17 #include "Dir.h" 18 #include "minmax.h" 19 20 //----------------------------------------------------------------- 21 /** 22 * Create new view. 23 * @param models wrapper arount models 24 */ View(const ModelList & models)25View::View(const ModelList &models) 26 : m_models(models), m_screenShift(0, 0) 27 { 28 m_animShift = 0; 29 m_shiftSize = SCALE; 30 m_screen = NULL; 31 } 32 //----------------------------------------------------------------- ~View()33View::~View() 34 { 35 removeDecors(); 36 } 37 //----------------------------------------------------------------- 38 void removeDecors()39View::removeDecors() 40 { 41 t_decors::iterator end = m_decors.end(); 42 for (t_decors::iterator i = m_decors.begin(); i != end; ++i) { 43 delete *i; 44 } 45 m_decors.clear(); 46 } 47 //----------------------------------------------------------------- 48 void drawDecors()49View::drawDecors() 50 { 51 t_decors::iterator end = m_decors.end(); 52 for (t_decors::iterator i = m_decors.begin(); i != end; ++i) { 53 (*i)->drawOnScreen(this, m_screen); 54 } 55 } 56 57 //----------------------------------------------------------------- 58 /** 59 * Prepare new anim. 60 */ 61 void noteNewRound(int phases)62View::noteNewRound(int phases) 63 { 64 m_animShift = 0; 65 computeShiftSize(phases); 66 } 67 //----------------------------------------------------------------- 68 void drawOn(SDL_Surface * screen)69View::drawOn(SDL_Surface *screen) 70 { 71 m_screen = screen; 72 m_animShift = min(SCALE, m_animShift + m_shiftSize); 73 m_models.drawOn(this); 74 drawDecors(); 75 } 76 //----------------------------------------------------------------- 77 /** 78 * Draw model. 79 * Care about model shift during move. 80 */ 81 void drawModel(Cube * model)82View::drawModel(Cube *model) 83 { 84 if (!model->isLost()) { 85 V2 screenPos = getScreenPos(model); 86 87 Anim::eSide side = Anim::SIDE_LEFT; 88 if (!model->isLeft()) { 89 side = Anim::SIDE_RIGHT; 90 } 91 model->anim()->drawAt(m_screen, 92 screenPos.getX(), screenPos.getY(), side); 93 } 94 } 95 //----------------------------------------------------------------- 96 /** 97 * Split move in a few phases. 98 */ 99 void computeShiftSize(int phases)100View::computeShiftSize(int phases) 101 { 102 if (phases > 0) { 103 m_shiftSize = SCALE / phases; 104 } 105 else { 106 m_shiftSize = SCALE; 107 } 108 } 109 //----------------------------------------------------------------- 110 /** 111 * Returns position on screen when model will be drawn. 112 */ 113 V2 getScreenPos(const Cube * model) const114View::getScreenPos(const Cube *model) const 115 { 116 V2 shift(0, 0); 117 Dir::eDir dir = model->getLastMoveDir(); 118 if (dir != Dir::DIR_NO) { 119 shift = Dir::dir2xy(dir); 120 shift = shift.scale(m_animShift); 121 } 122 shift = shift.plus(m_screenShift); 123 124 V2 anim_shift = model->const_anim()->getViewShift(); 125 return model->getLocation().plus(anim_shift).scale(SCALE).plus(shift); 126 } 127 //----------------------------------------------------------------- 128 /** 129 * Returns position of tile under cursor. 130 */ 131 V2 getFieldPos(const V2 & cursor) const132View::getFieldPos(const V2 &cursor) const 133 { 134 return cursor.minus(m_screenShift).shrink(SCALE); 135 } 136 137