Logo Search packages:      
Sourcecode: scummvm version File versions  Download package

map_v1.cpp

/* ScummVM - Graphic Adventure Engine
 *
 * ScummVM is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.      See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/tags/release-0-11-1/engines/gob/map_v1.cpp $
 * $Id: map_v1.cpp 30944 2008-02-23 22:50:18Z sev $
 *
 */


#include "common/stream.h"

#include "gob/gob.h"
#include "gob/map.h"
#include "gob/dataio.h"
#include "gob/goblin.h"
#include "gob/sound.h"
#include "gob/mult.h"

namespace Gob {

Map_v1::Map_v1(GobEngine *vm) : Map(vm) {
}

Map_v1::~Map_v1() {
}

void Map_v1::init(void) {
      if (_passMap || _itemsMap)
            return;

      _mapWidth = 26;
      _mapHeight = 28;

      _passMap = new int8[_mapHeight * _mapWidth];
      memset(_passMap, 0, _mapHeight * _mapWidth * sizeof(int8));

      _itemsMap = new int16*[_mapHeight];
       for (int i = 0; i < _mapHeight; i++) {
            _itemsMap[i] = new int16[_mapWidth];
            memset(_itemsMap[i], 0, _mapWidth * sizeof(int16));
      }

      _wayPointsCount = 40;
      _wayPoints = new Point[40];
      memset(_wayPoints, 0, sizeof(Point));
}

void Map_v1::loadMapObjects(const char *avjFile) {
      char avoName[128];
      byte *dataBuf;
      int16 handle;
      int16 tmp;
      int32 flag;
      int16 gobDataCount;
      int16 objDataCount;
      uint32 gobsPos;
      uint32 objsPos;

      strcpy(avoName, _sourceFile);
      strcat(avoName, ".avo");

      handle = _vm->_dataIO->openData(avoName);
      if (handle >= 0) {
            _loadFromAvo = true;
            _vm->_dataIO->closeData(handle);
            dataBuf = _vm->_dataIO->getData(avoName);
      } else {
            _loadFromAvo = false;
            dataBuf = _vm->_dataIO->getData(avjFile);
      }
      Common::MemoryReadStream mapData(dataBuf, 4294967295U);

      init();

      if (_loadFromAvo) {
            mapData.read(_passMap, _mapHeight * _mapWidth);

            for (int y = 0; y < _mapHeight; y++)
                  for (int x = 0; x < _mapWidth; x++)
                        _itemsMap[y][x] = mapData.readSByte();

            for (int i = 0; i < 40; i++) {
                  _wayPoints[i].x = mapData.readUint16LE();
                  _wayPoints[i].y = mapData.readUint16LE();
            }
            mapData.read(_itemPoses, szMap_ItemPos * 20);
      }

      mapData.skip(32 + 76 + 4 + 20);

      for (int i = 0; i < 3; i++) {
            tmp = mapData.readUint16LE();
            mapData.skip(tmp * 14);
      }

      loadSounds(mapData);

      mapData.skip(4 + 24);

      gobDataCount = mapData.readUint16LE();
      objDataCount = mapData.readUint16LE();

      gobsPos = mapData.pos();
      Common::MemoryReadStream gobsData(dataBuf + gobsPos, 4294967295U);
      mapData.skip(gobDataCount * 8);

      objsPos = mapData.pos();
      Common::MemoryReadStream objsData(dataBuf + objsPos, 4294967295U);
      mapData.skip(objDataCount * 8);

      loadGoblins(mapData, gobsPos);
      loadObjects(mapData, objsPos);

      tmp = mapData.readUint16LE();
      for (int i = 0; i < tmp; i++) {
            mapData.skip(30);

            flag = mapData.readSint32LE();
            mapData.skip(56);

            if (flag != 0)
                  mapData.skip(30);
      }

      mapData.skip(50);
      loadItemToObject(mapData);

      delete[] dataBuf;
}

void Map_v1::loadSounds(Common::SeekableReadStream &data) {
      int16 count;
      int16 handle;
      char buf[19];
      char sndNames[20][14];

      count = data.readUint16LE();

      for (int i = 0; i < count; i++) {
            data.read(buf, 14);
            buf[14] = 0;
            strcat(buf, ".SND");
            strcpy(sndNames[i], buf);
      }

      _vm->_snd->loadSample(_vm->_goblin->_soundData[14], "diamant1.snd");

      for (int i = 0; i < count; i++) {
            handle = _vm->_dataIO->openData(sndNames[i]);
            if (handle < 0)
                  continue;

            _vm->_dataIO->closeData(handle);
            _vm->_snd->loadSample(_vm->_goblin->_soundData[i], sndNames[i]);
      }
}

void Map_v1::loadGoblins(Common::SeekableReadStream &data, uint32 gobsPos) {
      Goblin::Gob_State *pState;
      uint32 tmpStateData[40 * 6];
      uint32 tmpPos;

      _vm->_goblin->_gobsCount = data.readUint16LE();
      for (int i = 0; i < _vm->_goblin->_gobsCount; i++) {
            int linesCount = (i == 3) ? 70 : 40;

            _vm->_goblin->_goblins[i] = new Goblin::Gob_Object;
            memset(_vm->_goblin->_goblins[i], 0, sizeof(Goblin::Gob_Object));

            tmpPos = data.pos();
            data.seek(gobsPos);
            _vm->_goblin->_goblins[i]->xPos = data.readUint16LE();
            _vm->_goblin->_goblins[i]->yPos = data.readUint16LE();
            _vm->_goblin->_goblins[i]->order = data.readUint16LE();
            _vm->_goblin->_goblins[i]->state = data.readUint16LE();
            gobsPos = data.pos();
            data.seek(tmpPos);

            _vm->_goblin->_goblins[i]->stateMach =
                        new Goblin::Gob_StateLine[linesCount];
            for (int state = 0; state < linesCount; ++state)
                  for (int col = 0; col < 6; ++col)
                        _vm->_goblin->_goblins[i]->stateMach[state][col] = 0;

            for (int state = 0; state < 40; ++state)
                  for (int col = 0; col < 6; ++col)
                        tmpStateData[state * 6 + col] = data.readUint32LE();

            data.skip(160);
            _vm->_goblin->_goblins[i]->multObjIndex = data.readByte();
            data.skip(1);

            _vm->_goblin->_goblins[i]->realStateMach =
                  _vm->_goblin->_goblins[i]->stateMach;
            for (int state = 0; state < 40; state++) {
                  for (int col = 0; col < 6; col++) {
                        if (tmpStateData[state * 6 + col] == 0) {
                              _vm->_goblin->_goblins[i]->stateMach[state][col] = 0;
                              continue;
                        }

                        Goblin::Gob_State *tmpState = new Goblin::Gob_State;
                        memset(tmpState, 0, sizeof(Goblin::Gob_State));

                        _vm->_goblin->_goblins[i]->stateMach[state][col] = tmpState;

                        tmpState->animation = data.readUint16LE();
                        tmpState->layer = data.readUint16LE();
                        data.skip(8);
                        tmpState->unk0 = data.readUint16LE();
                        tmpState->unk1 = data.readUint16LE();

                        data.skip(2);
                        if (data.readUint32LE() == 0) {
                              data.skip(2);
                              tmpState->sndItem = -1;
                        } else
                              tmpState->sndItem = data.readUint16LE();

                        tmpState->freq = data.readUint16LE();
                        tmpState->repCount = data.readUint16LE();
                        tmpState->sndFrame = data.readUint16LE();
                  }
            }
      }

      pState = new Goblin::Gob_State;
      memset(pState, 0, sizeof(Goblin::Gob_State));
      _vm->_goblin->_goblins[0]->stateMach[39][0] = pState;
      pState->layer = 98;
      pState->sndItem = -1;

      pState = new Goblin::Gob_State;
      memset(pState, 0, sizeof(Goblin::Gob_State));
      _vm->_goblin->_goblins[1]->stateMach[39][0] = pState;
      pState->layer = 99;
      pState->sndItem = -1;

      pState = new Goblin::Gob_State;
      memset(pState, 0, sizeof(Goblin::Gob_State));
      _vm->_goblin->_goblins[2]->stateMach[39][0] = pState;
      pState->layer = 100;
      pState->sndItem = -1;

      _vm->_goblin->_goblins[2]->stateMach[10][0]->sndFrame = 13;
      _vm->_goblin->_goblins[2]->stateMach[11][0]->sndFrame = 13;
      _vm->_goblin->_goblins[2]->stateMach[28][0]->sndFrame = 13;
      _vm->_goblin->_goblins[2]->stateMach[29][0]->sndFrame = 13;

      _vm->_goblin->_goblins[1]->stateMach[10][0]->sndFrame = 13;
      _vm->_goblin->_goblins[1]->stateMach[11][0]->sndFrame = 13;

      for (int state = 40; state < 70; state++) {
            pState = new Goblin::Gob_State;
            memset(pState, 0, sizeof(Goblin::Gob_State));
            _vm->_goblin->_goblins[3]->stateMach[state][0] = pState;
            _vm->_goblin->_goblins[3]->stateMach[state][1] = 0;

            pState->animation = 9;
            pState->layer = state - 40;
            pState->sndItem = -1;
      }
}

void Map_v1::loadObjects(Common::SeekableReadStream &data, uint32 objsPos) {
      Goblin::Gob_State *pState;
      uint32 tmpStateData[40 * 6];
      uint32 tmpPos;

      _vm->_goblin->_objCount = data.readUint16LE();
      for (int i = 0; i < _vm->_goblin->_objCount; i++) {
            _vm->_goblin->_objects[i] = new Goblin::Gob_Object;
            memset(_vm->_goblin->_objects[i], 0, sizeof(Goblin::Gob_Object));

            tmpPos = data.pos();
            data.seek(objsPos);
            _vm->_goblin->_objects[i]->xPos = data.readUint16LE();
            _vm->_goblin->_objects[i]->yPos = data.readUint16LE();
            _vm->_goblin->_objects[i]->order = data.readUint16LE();
            _vm->_goblin->_objects[i]->state = data.readUint16LE();
            objsPos = data.pos();
            data.seek(tmpPos);

            _vm->_goblin->_objects[i]->stateMach = new Goblin::Gob_StateLine[40];
            for (int state = 0; state < 40; ++state) {
                  for (int col = 0; col < 6; ++col) {
                        _vm->_goblin->_objects[i]->stateMach[state][col] = 0;
                        tmpStateData[state * 6 + col] = data.readUint32LE();
                  }
            }

            data.skip(160);
            _vm->_goblin->_objects[i]->multObjIndex = data.readByte();
            data.skip(1);

            _vm->_goblin->_objects[i]->realStateMach =
                  _vm->_goblin->_objects[i]->stateMach;
            for (int state = 0; state < 40; state++) {
                  for (int col = 0; col < 6; col++) {
                        if (tmpStateData[state * 6 + col] == 0) {
                              _vm->_goblin->_objects[i]->stateMach[state][col] = 0;
                              continue;
                        }

                        Goblin::Gob_State *tmpState = new Goblin::Gob_State;
                        memset(tmpState, 0, sizeof(Goblin::Gob_State));
                        _vm->_goblin->_objects[i]->stateMach[state][col] = tmpState;

                        tmpState->animation = data.readUint16LE();
                        tmpState->layer = data.readUint16LE();
                        data.skip(8);
                        tmpState->unk0 = data.readUint16LE();
                        tmpState->unk1 = data.readUint16LE();

                        data.skip(2);
                        if (data.readUint32LE() == 0) {
                              data.skip(2);
                              tmpState->sndItem = -1;
                        } else
                              tmpState->sndItem = data.readUint16LE();

                        tmpState->freq = data.readUint16LE();
                        tmpState->repCount = data.readUint16LE();
                        tmpState->sndFrame = data.readUint16LE();
                  }
            }
      }

      _vm->_goblin->_objects[10] = new Goblin::Gob_Object;
      memset(_vm->_goblin->_objects[10], 0, sizeof(Goblin::Gob_Object));

      _vm->_goblin->_objects[10]->stateMach = new Goblin::Gob_StateLine[40];
      for (int state = 0; state < 40; ++state)
            for (int col = 0; col < 6; ++col)
                  _vm->_goblin->_objects[10]->stateMach[state][col] = 0;

      pState = new Goblin::Gob_State;
      memset(pState, 0, sizeof(Goblin::Gob_State));
      _vm->_goblin->_objects[10]->stateMach[0][0] = pState;

      pState->animation = 9;
      pState->layer = 27;
      pState->sndItem = -1;

      _vm->_goblin->placeObject(_vm->_goblin->_objects[10], 1, 0, 0, 0, 0);

      _vm->_goblin->_objects[10]->realStateMach =
            _vm->_goblin->_objects[10]->stateMach;
      _vm->_goblin->_objects[10]->type = 1;
      _vm->_goblin->_objects[10]->unk14 = 1;
}

void Map_v1::loadItemToObject(Common::SeekableReadStream &data) {
      int16 count;

      if (data.readUint16LE() == 0)
            return;

      data.skip(1456);
      count = data.readUint16LE();
      for (int i = 0; i < count; i++) {
            data.skip(20);
            _vm->_goblin->_itemToObject[i] = data.readUint16LE();
            data.skip(5);
      }
}

void Map_v1::optimizePoints(Mult::Mult_Object *obj, int16 x, int16 y) {
      if (_nearestWayPoint < _nearestDest) {
            for (int i = _nearestWayPoint; i <= _nearestDest; i++) {
                  if (checkDirectPath(0, _curGoblinX, _curGoblinY,
                        _wayPoints[i].x, _wayPoints[i].y) == 1)
                        _nearestWayPoint = i;
            }
      } else if (_nearestWayPoint > _nearestDest) {
            for (int i = _nearestWayPoint; i >= _nearestDest; i--) {
                  if (checkDirectPath(0, _curGoblinX, _curGoblinY,
                        _wayPoints[i].x, _wayPoints[i].y) == 1)
                        _nearestWayPoint = i;
            }
      }
}

void Map_v1::findNearestToGob(Mult::Mult_Object *obj) {
      int16 wayPoint = findNearestWayPoint(_curGoblinX, _curGoblinY);

      if (wayPoint != -1)
            _nearestWayPoint = wayPoint;
}

void Map_v1::findNearestToDest(Mult::Mult_Object *obj) {
      int16 wayPoint = findNearestWayPoint(_destX, _destY);

      if (wayPoint != -1)
            _nearestDest = wayPoint;
}

} // End of namespace Gob

Generated by  Doxygen 1.6.0   Back to index