123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339 |
- /* GCSx
- ** SPAWNEDIT.CPP
- **
- ** Spawn-point editor-only functionality
- */
- /*****************************************************************************
- ** Copyright (C) 2003-2006 Janson
- **
- ** 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
- *****************************************************************************/
- #include "all.h"
- SpawnEdit::SpawnEdit(WorldEdit* myWorld, LayerEdit* myLayer, int newId) : Spawn(newId) { start_func
- assert(myWorld);
- world = myWorld;
- layer = myLayer;
- lockCount = 0;
- undoReady = 0;
- }
- SpawnEdit::~SpawnEdit() { start_func
- if (lockCount) {
- if (animgroup) animgroup->markUnlock();
- if (tileset) tileset->markUnlock();
- }
- }
- SpawnEdit::SpawnEdit(const SpawnEdit* copy, LayerEdit* myLayer, int newId) : Spawn(newId) { start_func
- world = copy->world;
- layer = myLayer;
- lockCount = 0;
- undoReady = 0;
-
- name = copy->name;
- script = copy->script;
- animgroup = copy->animgroup;
- tileset = copy->tileset;
- subid = copy->subid;
- x = copy->x;
- y = copy->y;
- }
- void SpawnEdit::setLayer(LayerEdit* newLayer) { start_func
- layer = newLayer;
- }
- void SpawnEdit::setUndoReady() { start_func
- undoReady = 1;
- }
-
- void SpawnEdit::setModified() { start_func
- // @TODO: if no layer..?
- if (layer) layer->setContentModified();
- }
- void SpawnEdit::calculateDisplayCoords() { start_func
- displayX = x;
- displayY = y;
- if (tileset) {
- displayW = tileset->getWidth();
- displayH = tileset->getHeight();
- }
- else if ((animgroup) && (lockCount)) {
- // (if not locked, animgroup isn't locked and we can't get info)
- // @TODO: anim group sizing
- displayW = 40;
- displayH = 40;
- }
- else {
- displayW = 40;
- displayH = 40;
- }
- }
- void SpawnEdit::setName(const std::string& newName, Window* srcWin, Window* exWin) throw_Undo { start_func
- if (name != newName) {
- setModified();
- if ((world) && (undoReady)) world->undo.storeUndoName(UndoBuffer::UNDO_SPAWNNAME, id, name, newName, srcWin);
- name = newName;
-
- desktop->broadcastObjChange(OBJ_SPAWN | OBJMOD_NAME, this, 0, 0, exWin);
- }
- }
- void SpawnEdit::setPos(int nX, int nY, int skipUndo, Window* srcWin, Window* exWin) throw_Undo { start_func
- if ((x != nX) || (y != nY)) {
- setModified();
- if ((world) && (undoReady) && (!skipUndo)) world->undo.storeUndoSpawnMove(id, layer->getId(), x, y, srcWin);
- x = nX;
- y = nY;
- calculateDisplayCoords();
-
- desktop->broadcastObjChange(OBJ_SPAWN | OBJMOD_POS, this, 0, 0, exWin);
- }
- }
- void SpawnEdit::setSprite(AnimGroup* newAnimgroup, TileSet* newTileset, int newId, Window* srcWin, Window* exWin) throw_File throw_Undo { start_func
- if ((newAnimgroup != animgroup) || (newTileset != tileset) || (newId != subid)) {
- assert(newId >= 0);
- if ((newAnimgroup) || (newTileset)) {
- assert(newId);
- if (newAnimgroup) assert(!newTileset);
- else assert(!newAnimgroup);
- }
- else assert(!newId);
- // Lock first (file exception point)
- if (lockCount) {
- if (newAnimgroup) newAnimgroup->markLock();
- if (newTileset) {
- try {
- newTileset->markLock();
- }
- catch (...) {
- if (newAnimgroup) newAnimgroup->markUnlock();
- throw;
- }
- }
- }
-
- setModified();
- int aId = 0;
- int tId = 0;
- if (animgroup) aId = animgroup->getId();
- if (tileset) tId = tileset->getId();
-
- // Undo (if fail, undo locking from earlier)
- try {
- if ((world) && (undoReady)) world->undo.storeUndoSpawnSprite(id, layer->getId(), aId, tId, subid, srcWin);
- }
- catch (...) {
- if (lockCount) {
- if (newTileset) newTileset->markUnlock();
- if (newAnimgroup) newAnimgroup->markUnlock();
- }
- throw;
- }
- // Now that all exceptions are passed, unlock prior
- if (lockCount) {
- if (animgroup) animgroup->markUnlock();
- if (tileset) tileset->markUnlock();
- }
-
- animgroup = newAnimgroup;
- tileset = newTileset;
- subid = newId;
- calculateDisplayCoords();
-
- desktop->broadcastObjChange(OBJ_SPAWN | OBJMOD_IMAGE, this, 0, 0, exWin);
- }
- }
- void SpawnEdit::setScript(Script* newScript, Window* srcWin, Window* exWin) throw_Undo { start_func
- if (script != newScript) {
- setModified();
- int sId = 0;
- if (script) sId = script->getId();
- if ((world) && (undoReady)) world->undo.storeUndoSpawnScript(id, layer->getId(), sId, srcWin);
- script = newScript;
-
- desktop->broadcastObjChange(OBJ_SPAWN | OBJMOD_SCRIPT, this, 0, 0, exWin);
- }
- }
- int SpawnEdit::propertiesDialog(Window* srcWin, Window* exWin) { start_func
- string newName = name;
- AnimGroup* newAnimgroup = animgroup;
- TileSet* newTileset = tileset;
- Script* newScript = script;
- int newId = subid;
-
- int result;
- if (layer) {
- result = SpawnPropertiesDialog::createWithSprite()->run(&newName, &newScript, &newAnimgroup, &newTileset, &newId, world);
- }
- else {
- result = SpawnPropertiesDialog::createNoSprite()->run(&newName, &newScript, NULL, NULL, NULL, world);
- }
- if (result) {
- // (no locking of layer needed- if we're here, our owner is obviously in memory)
- try {
- if ((world) && (undoReady)) world->undo.preUndoBlock();
- setName(newName, srcWin, exWin);
- setScript(newScript, srcWin, exWin);
- if (layer) {
- // @TODO: throw_File
- setSprite(newAnimgroup, newTileset, newId, srcWin, exWin);
- }
- if ((world) && (undoReady)) world->undo.postUndoBlock();
- // (at least one of script or sprite must still be present now)
- assert((script) || (newTileset) || (newAnimgroup));
- }
- catch (UndoException& e) {
- return 0;
- }
- return 1;
- }
-
- return 0;
- }
- void SpawnEdit::save(class FileWrite* file) throw_File { start_func
- file->writeInt(id);
- file->writeStr(name);
- if (script) file->writeInt(script->getId());
- else file->writeInt(0);
- if (animgroup) file->writeInt(animgroup->getId());
- else file->writeInt(0);
- if (tileset) file->writeInt(tileset->getId());
- else file->writeInt(0);
- file->writeInt(subid);
- file->writeInt(x);
- file->writeInt(y);
- }
- void SpawnEdit::blit(int offsetX, int offsetY, SDL_Surface* dest, int clipX, int clipY, int clipW, int clipH, int dim, int selection) { start_func
- assert(lockCount);
-
- // Outside of range?
- if ((displayX >= clipX + clipW) ||
- (displayY >= clipY + clipH) ||
- (clipX >= displayX + displayW) ||
- (clipY >= displayY + displayH)) return;
- if (dim == 1) dim = 0x80;
- else if (dim) dim = 0xC0;
- else dim = 0xFF;
-
- // Display
- if (tileset) {
- dynamic_cast<TileSetEdit*>(tileset)->blitTileFx(subid, dest, offsetX + displayX,
- offsetY + displayY,
- dim * Image::ALPHA_DEFAULT / 0xFF,
- 0, 0, 0, Image::COLOR_DEFAULT);
- }
- //else if (animgroup) {
- // @TODO: animgroup display (base on x/y, as displayx/y would be offset already)
- //}
- else {
- SDL_Surface* src = getIconSurface();
- alphaBlitFx(60, 160, src, offsetX + displayX, offsetY + displayY, dest, displayW,
- displayH, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, dim, 0xFF);
- }
-
- if (selection) {
- drawSelectRect(offsetX + displayX, offsetY + displayY, displayW, displayH,
- guiPacked[COLOR_SELECTION1], dest);
- drawAntsBox(offsetX + displayX, offsetY + displayY, displayW, displayH,
- desktop->currentSelectionPhase(), dest);
- }
- }
- int SpawnEdit::markLock() throw_File { start_func
- if (animgroup) animgroup->markLock();
- if (tileset) {
- try {
- tileset->markLock();
- }
- catch (...) {
- animgroup->markUnlock();
- throw;
- }
- }
- // (animgroup might not have been locked before)
- calculateDisplayCoords();
- return ++lockCount;
- }
- int SpawnEdit::markUnlock() { start_func
- --lockCount;
- assert(lockCount >= 0);
- if (lockCount == 0) {
- if (animgroup) animgroup->markUnlock();
- if (tileset) tileset->markUnlock();
- }
- return lockCount;
- }
- int SpawnEdit::isLocked() const { start_func
- return lockCount;
- }
- void SpawnEdit::load(FileRead* file, const World* world) throw_File { start_func
- AnimGroup* prevA = NULL;
- TileSet* prevT = NULL;
- if (lockCount) {
- // Unlock later, after all exception points
- prevA = animgroup;
- prevT = tileset;
- animgroup = NULL;
- tileset = NULL;
- }
- Spawn::load(file, world);
- if (lockCount) {
- try {
- if (animgroup) animgroup->markLock();
- try {
- if (tileset) tileset->markLock();
- }
- catch (...) {
- tileset->markUnlock();
- throw;
- }
- }
- catch (...) {
- // Revert to previous, still-locked items
- animgroup = prevA;
- tileset = prevT;
- throw;
- }
- }
-
- if (prevA) prevA->markUnlock();
- if (prevT) prevT->markUnlock();
-
- calculateDisplayCoords();
- undoReady = 1;
- }
|