00001 /* 00002 * Copyright (C) 2003-2006 The Pentagram Team 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; either version 2 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software 00016 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 */ 00018 00019 #include "pent_include.h" 00020 00021 #include "AnimDat.h" 00022 00023 #include "IDataSource.h" 00024 #include "ActorAnim.h" 00025 #include "AnimAction.h" 00026 #include "CoreApp.h" 00027 #include "GameInfo.h" 00028 00029 AnimDat::AnimDat() 00030 { 00031 00032 } 00033 00034 00035 AnimDat::~AnimDat() 00036 { 00037 for (unsigned int i = 0; i < anims.size(); i++) 00038 delete anims[i]; 00039 anims.clear(); 00040 } 00041 00042 ActorAnim* AnimDat::getAnim(uint32 shape) const 00043 { 00044 if (shape >= anims.size()) return 0; 00045 00046 return anims[shape]; 00047 } 00048 00049 AnimAction* AnimDat::getAnim(uint32 shape, uint32 action) const 00050 { 00051 if (shape >= anims.size()) return 0; 00052 if (anims[shape] == 0) return 0; 00053 00054 return anims[shape]->getAction(action); 00055 } 00056 00057 00058 void AnimDat::load(IDataSource *ds) 00059 { 00060 AnimFrame f; 00061 00062 // CONSTANT ! 00063 anims.resize(2048); 00064 00065 unsigned int actioncount = 64; 00066 if (GAME_IS_CRUSADER) 00067 actioncount = 256; 00068 00069 for (unsigned int shape = 0; shape < anims.size(); shape++) 00070 { 00071 ds->seek(4*shape); 00072 uint32 offset = ds->read4(); 00073 00074 if (offset == 0) { 00075 anims[shape] = 0; 00076 continue; 00077 } 00078 00079 ActorAnim *a = new ActorAnim(); 00080 00081 // CONSTANT ! 00082 a->actions.resize(actioncount); 00083 00084 for (unsigned int action = 0; action < actioncount; action++) 00085 { 00086 ds->seek(offset + action*4); 00087 uint32 actionoffset = ds->read4(); 00088 00089 if (actionoffset == 0) { 00090 a->actions[action] = 0; 00091 continue; 00092 } 00093 00094 a->actions[action] = new AnimAction(); 00095 00096 a->actions[action]->shapenum = shape; 00097 a->actions[action]->action = action; 00098 00099 ds->seek(actionoffset); 00100 uint32 actionsize = ds->read1(); 00101 a->actions[action]->size = actionsize; 00102 a->actions[action]->flags = ds->read1(); 00103 a->actions[action]->framerepeat = ds->read1(); 00104 a->actions[action]->flags |= ds->read1() << 8; 00105 00106 unsigned int dircount = 8; 00107 if (GAME_IS_CRUSADER && 00108 (a->actions[action]->flags & AnimAction::AAF_CRUS_16DIRS)) 00109 { 00110 dircount = 16; 00111 } 00112 a->actions[action]->dircount = dircount; 00113 00114 for (unsigned int dir = 0; dir < dircount; dir++) 00115 { 00116 a->actions[action]->frames[dir].clear(); 00117 00118 for (unsigned int j = 0; j < actionsize; j++) 00119 { 00120 if (GAME_IS_U8) { 00121 f.frame = ds->read1(); // & 0x7FF; 00122 uint8 x = ds->read1(); 00123 f.frame += (x & 0x7) << 8; 00124 f.deltaz = ds->readXS(1); 00125 f.sfx = ds->read1(); 00126 f.deltadir = ds->readXS(1); 00127 f.flags = ds->read1(); 00128 f.flags += (x & 0xF8) << 8; 00129 } else if (GAME_IS_CRUSADER) { 00130 // byte 0: low byte of frame 00131 f.frame = ds->read1(); 00132 // byte 1: low nibble part of frame 00133 uint8 x = ds->read1(); 00134 f.frame += (x & 0xF) << 8; 00135 // byte 2, 3: unknown; byte 3 might contain flags 00136 ds->skip(2); 00137 // byte 4: deltadir (signed) 00138 f.deltadir = ds->readXS(1); 00139 // byte 5: flags? 00140 f.flags = ds->read1(); 00141 // byte 6, 7: unknown 00142 ds->skip(2); 00143 00144 f.deltaz = 0; 00145 f.sfx = 0; 00146 } 00147 a->actions[action]->frames[dir].push_back(f); 00148 } 00149 } 00150 } 00151 00152 anims[shape] = a; 00153 } 00154 }