Files
Aerofoil/GpApp/RoomGraphics.cpp

445 lines
12 KiB
C++
Raw Normal View History

2019-11-11 00:11:59 -05:00
//============================================================================
//----------------------------------------------------------------------------
// RoomGraphics.c
//----------------------------------------------------------------------------
//============================================================================
#include "PLResources.h"
2019-12-30 20:53:11 -05:00
#include "PLStandardColors.h"
2019-11-11 00:11:59 -05:00
#include "Externs.h"
#include "Environ.h"
#include "MainWindow.h"
#include "RectUtils.h"
2020-05-21 03:30:11 -04:00
#include "ResolveCachingColor.h"
2019-11-11 00:11:59 -05:00
#include "Room.h"
2020-01-18 21:15:07 -05:00
#include "BitmapImage.h"
2019-11-11 00:11:59 -05:00
#define kManholeThruFloor 3957
2019-12-30 20:53:11 -05:00
void LoadGraphicSpecial (DrawSurface *surface, short);
2019-11-11 00:11:59 -05:00
void DrawRoomBackground (short, short, short);
void DrawFloorSupport (void);
void ReadyBackMap (void);
void RestoreWorkMap (void);
void DrawLighting (void);
Rect suppSrcRect;
2019-12-30 20:53:11 -05:00
DrawSurface *suppSrcMap;
2019-11-11 00:11:59 -05:00
Rect localRoomsDest[9];
Rect houseRect;
short numNeighbors, numLights, thisTiles[kNumTiles];
short localNumbers[9], thisBackground;
Boolean isStructure[9], wardBitSet;
extern Rect tempManholes[];
extern short numTempManholes, tvWithMovieNumber;
extern Boolean shadowVisible, takingTheStairs;
//============================================================== Functions
//-------------------------------------------------------------- DrawLocale
2020-04-01 14:53:44 -04:00
void ResetLocale (Boolean soft)
2019-11-11 00:11:59 -05:00
{
char wasState;
2020-04-01 14:53:44 -04:00
if (soft)
2019-11-11 00:11:59 -05:00
{
RemoveSavedMapsNotInRoom(localNumbers[kCentralRoom]);
ZeroDinahsNotInRoom(localNumbers[kCentralRoom]);
// Clear all dinah indexes, they'll be remapped
for (int i = 0; i < numMasterObjects; i++)
masterObjects[i].dynaNum = -1;
2019-11-11 00:11:59 -05:00
}
2020-04-01 14:53:44 -04:00
else
{
ZeroFlamesAndTheLike();
ZeroDinahs();
KillAllBands();
ZeroTriggers();
numTempManholes = 0;
FlushAnyTriggerPlaying();
DumpTriggerSound();
tvInRoom = false;
tvWithMovieNumber = -1;
for (int i = 0; i < 9; i++)
2020-04-01 14:53:44 -04:00
{
localNumbers[i] = GetNeighborRoomNumber(i);
isStructure[i] = IsRoomAStructure(localNumbers[i]);
}
ListAllLocalObjects();
}
2020-04-05 04:51:58 -04:00
ZeroMirrorRegion();
2020-04-01 14:53:44 -04:00
takingTheStairs = false;
const short roomV = (*thisHouse)->rooms[thisRoomNumber].floor;
2019-12-30 20:53:11 -05:00
2020-05-21 03:30:11 -04:00
PortabilityLayer::ResolveCachingColor blackColor = StdColors::Black();
backSrcMap->FillRect(backSrcRect, blackColor);
2019-11-11 00:11:59 -05:00
if (numNeighbors > 3)
{
numLights = GetNumberOfLights(localNumbers[kNorthWestRoom]);
DrawRoomBackground(localNumbers[kNorthWestRoom], kNorthWestRoom, roomV + 1);
DrawARoomsObjects(kNorthWestRoom, false);
2019-11-11 00:11:59 -05:00
numLights = GetNumberOfLights(localNumbers[kNorthEastRoom]);
DrawRoomBackground(localNumbers[kNorthEastRoom], kNorthEastRoom, roomV + 1);
DrawARoomsObjects(kNorthEastRoom, false);
2019-11-11 00:11:59 -05:00
numLights = GetNumberOfLights(localNumbers[kNorthRoom]);
DrawRoomBackground(localNumbers[kNorthRoom], kNorthRoom, roomV + 1);
DrawARoomsObjects(kNorthRoom, false);
2019-11-11 00:11:59 -05:00
numLights = GetNumberOfLights(localNumbers[kSouthWestRoom]);
DrawRoomBackground(localNumbers[kSouthWestRoom], kSouthWestRoom, roomV - 1);
DrawARoomsObjects(kSouthWestRoom, false);
2019-11-11 00:11:59 -05:00
numLights = GetNumberOfLights(localNumbers[kSouthEastRoom]);
DrawRoomBackground(localNumbers[kSouthEastRoom], kSouthEastRoom, roomV - 1);
DrawARoomsObjects(kSouthEastRoom, false);
2019-11-11 00:11:59 -05:00
numLights = GetNumberOfLights(localNumbers[kSouthRoom]);
DrawRoomBackground(localNumbers[kSouthRoom], kSouthRoom, roomV - 1);
DrawARoomsObjects(kSouthRoom, false);
2019-11-11 00:11:59 -05:00
}
if (numNeighbors > 1)
{
numLights = GetNumberOfLights(localNumbers[kWestRoom]);
DrawRoomBackground(localNumbers[kWestRoom], kWestRoom, roomV);
DrawARoomsObjects(kWestRoom, false);
2019-11-11 00:11:59 -05:00
DrawLighting();
numLights = GetNumberOfLights(localNumbers[kEastRoom]);
DrawRoomBackground(localNumbers[kEastRoom], kEastRoom, roomV);
DrawARoomsObjects(kEastRoom, false);
2019-11-11 00:11:59 -05:00
DrawLighting();
}
numLights = GetNumberOfLights(localNumbers[kCentralRoom]);
DrawRoomBackground(localNumbers[kCentralRoom], kCentralRoom, roomV);
2020-04-01 14:53:44 -04:00
DrawARoomsObjects(kCentralRoom, soft);
2019-11-11 00:11:59 -05:00
DrawLighting();
2019-12-27 18:05:32 -05:00
2019-11-11 00:11:59 -05:00
if (numNeighbors > 3)
DrawFloorSupport();
RestoreWorkMap();
shadowVisible = IsShadowVisible();
if (soft)
RedrawAllGrease();
2019-11-11 00:11:59 -05:00
}
//-------------------------------------------------------------- LoadGraphicSpecial
2019-12-30 20:53:11 -05:00
void LoadGraphicSpecial (DrawSurface *surface, short resID)
2019-11-11 00:11:59 -05:00
{
Rect bounds;
2020-01-18 21:15:07 -05:00
THandle<BitmapImage> thePicture;
2019-11-11 00:11:59 -05:00
thePicture = LoadHouseResource('PICT', resID).StaticCast<BitmapImage>();
2019-11-11 00:11:59 -05:00
if (thePicture == nil)
{
thePicture = LoadHouseResource('Date', resID).StaticCast<BitmapImage>();
2019-11-11 00:11:59 -05:00
if (thePicture == nil)
{
thePicture = LoadHouseResource('PICT', 2000).StaticCast<BitmapImage>();
2019-11-11 00:11:59 -05:00
if (thePicture == nil)
RedAlert(kErrFailedGraphicLoad);
}
}
2020-01-18 21:15:07 -05:00
bounds = (*thePicture)->GetRect();
2019-11-11 00:11:59 -05:00
OffsetRect(&bounds, -bounds.left, -bounds.top);
2019-12-30 20:53:11 -05:00
surface->DrawPicture(thePicture, bounds);
2019-12-29 23:14:37 -05:00
thePicture.Dispose();
2019-11-11 00:11:59 -05:00
}
//-------------------------------------------------------------- DrawRoomBackground
void DrawRoomBackground (short who, short where, short elevation)
{
Rect src, dest;
short i, pictID;
short tiles[kNumTiles];
char wasState;
if (where == kCentralRoom)
{
thisBackground = (*thisHouse)->rooms[who].background;
for (i = 0; i < kNumTiles; i++)
thisTiles[i] = (*thisHouse)->rooms[who].tiles[i];
}
if ((numLights == 0) && (who != kRoomIsEmpty))
{
2020-05-21 03:30:11 -04:00
PortabilityLayer::ResolveCachingColor blackColor = StdColors::Black();
backSrcMap->FillRect(localRoomsDest[where], blackColor);
2019-11-11 00:11:59 -05:00
return;
}
if (who == kRoomIsEmpty) // This call should be smarter than this
{
if (wardBitSet)
{
2020-05-21 03:30:11 -04:00
PortabilityLayer::ResolveCachingColor blackColor = StdColors::Black();
backSrcMap->FillRect(localRoomsDest[where], blackColor);
2019-11-11 00:11:59 -05:00
return;
}
if (elevation > 1)
{
pictID = kSky;
for (i = 0; i < kNumTiles; i++)
tiles[i] = 2;
}
else if (elevation == 1)
{
pictID = kMeadow;
for (i = 0; i < kNumTiles; i++)
tiles[i] = 0;
}
else
{
pictID = kDirt;
for (i = 0; i < kNumTiles; i++)
tiles[i] = 0;
}
}
else
{
pictID = (*thisHouse)->rooms[who].background;
for (i = 0; i < kNumTiles; i++)
tiles[i] = (*thisHouse)->rooms[who].tiles[i];
}
2019-12-30 20:53:11 -05:00
LoadGraphicSpecial(workSrcMap, pictID);
2019-11-11 00:11:59 -05:00
QSetRect(&src, 0, 0, kTileWide, kTileHigh);
QSetRect(&dest, 0, 0, kTileWide, kTileHigh);
QOffsetRect(&dest, localRoomsDest[where].left, localRoomsDest[where].top);
for (i = 0; i < kNumTiles; i++)
{
src.left = tiles[i] * kTileWide;
src.right = src.left + kTileWide;
CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap),
(BitMap *)*GetGWorldPixMap(backSrcMap),
&src, &dest, srcCopy);
2019-11-11 00:11:59 -05:00
QOffsetRect(&dest, kTileWide, 0);
}
}
//-------------------------------------------------------------- DrawFloorSupport
void DrawFloorSupport (void)
{
Rect src, dest, whoCares;
short i;
2019-12-27 18:05:32 -05:00
2019-12-30 20:53:11 -05:00
DrawSurface *surface = backSrcMap;
2019-11-11 00:11:59 -05:00
src = suppSrcRect;
if (isStructure[kNorthWestRoom])
{
dest = suppSrcRect; // left room's ceiling
QOffsetRect(&dest, localRoomsDest[kWestRoom].left,
localRoomsDest[kCentralRoom].top - suppSrcRect.bottom);
CopyBits((BitMap *)*GetGWorldPixMap(suppSrcMap),
(BitMap *)*GetGWorldPixMap(backSrcMap),
&src, &dest, srcCopy);
2019-11-11 00:11:59 -05:00
for (i = 0; i < numTempManholes; i++)
if (SectRect(&dest, &tempManholes[i], &whoCares))
{
tempManholes[i].top = dest.top;
tempManholes[i].bottom = dest.bottom;
2019-12-30 20:53:11 -05:00
LoadScaledGraphic(surface, kManholeThruFloor, &tempManholes[i]);
2019-11-11 00:11:59 -05:00
}
}
if (isStructure[kWestRoom])
{
dest = suppSrcRect; // left room's floor
QOffsetRect(&dest, localRoomsDest[kWestRoom].left,
localRoomsDest[kCentralRoom].bottom);
CopyBits((BitMap *)*GetGWorldPixMap(suppSrcMap),
(BitMap *)*GetGWorldPixMap(backSrcMap),
&src, &dest, srcCopy);
2019-11-11 00:11:59 -05:00
for (i = 0; i < numTempManholes; i++)
if (SectRect(&dest, &tempManholes[i], &whoCares))
{
tempManholes[i].top = dest.top;
tempManholes[i].bottom = dest.bottom;
2019-12-30 20:53:11 -05:00
LoadScaledGraphic(surface, kManholeThruFloor, &tempManholes[i]);
2019-11-11 00:11:59 -05:00
}
}
if (isStructure[kNorthRoom])
{
dest = suppSrcRect; // directly above main room
QOffsetRect(&dest, localRoomsDest[kCentralRoom].left,
localRoomsDest[kCentralRoom].top - suppSrcRect.bottom);
CopyBits((BitMap *)*GetGWorldPixMap(suppSrcMap),
(BitMap *)*GetGWorldPixMap(backSrcMap),
&src, &dest, srcCopy);
2019-11-11 00:11:59 -05:00
for (i = 0; i < numTempManholes; i++)
if (SectRect(&dest, &tempManholes[i], &whoCares))
{
tempManholes[i].top = dest.top;
tempManholes[i].bottom = dest.bottom;
2019-12-30 20:53:11 -05:00
LoadScaledGraphic(surface, kManholeThruFloor, &tempManholes[i]);
2019-11-11 00:11:59 -05:00
}
}
if (isStructure[kCentralRoom])
{
dest = suppSrcRect; // directly below main room
QOffsetRect(&dest, localRoomsDest[kCentralRoom].left,
localRoomsDest[kCentralRoom].bottom);
CopyBits((BitMap *)*GetGWorldPixMap(suppSrcMap),
(BitMap *)*GetGWorldPixMap(backSrcMap),
&src, &dest, srcCopy);
2019-11-11 00:11:59 -05:00
for (i = 0; i < numTempManholes; i++)
if (SectRect(&dest, &tempManholes[i], &whoCares))
{
tempManholes[i].top = dest.top;
tempManholes[i].bottom = dest.bottom;
2019-12-30 20:53:11 -05:00
LoadScaledGraphic(surface, kManholeThruFloor, &tempManholes[i]);
2019-11-11 00:11:59 -05:00
}
}
if (isStructure[kNorthEastRoom])
{
dest = suppSrcRect;
QOffsetRect(&dest, localRoomsDest[kEastRoom].left,
localRoomsDest[kCentralRoom].top - suppSrcRect.bottom);
CopyBits((BitMap *)*GetGWorldPixMap(suppSrcMap),
(BitMap *)*GetGWorldPixMap(backSrcMap),
&src, &dest, srcCopy);
2019-11-11 00:11:59 -05:00
for (i = 0; i < numTempManholes; i++)
if (SectRect(&dest, &tempManholes[i], &whoCares))
{
tempManholes[i].top = dest.top;
tempManholes[i].bottom = dest.bottom;
2019-12-30 20:53:11 -05:00
LoadScaledGraphic(surface, kManholeThruFloor, &tempManholes[i]);
2019-11-11 00:11:59 -05:00
}
}
if (isStructure[kEastRoom])
{
dest = suppSrcRect;
QOffsetRect(&dest, localRoomsDest[kEastRoom].left,
localRoomsDest[kCentralRoom].bottom);
CopyBits((BitMap *)*GetGWorldPixMap(suppSrcMap),
(BitMap *)*GetGWorldPixMap(backSrcMap),
&src, &dest, srcCopy);
2019-11-11 00:11:59 -05:00
for (i = 0; i < numTempManholes; i++)
if (SectRect(&dest, &tempManholes[i], &whoCares))
{
tempManholes[i].top = dest.top;
tempManholes[i].bottom = dest.bottom;
2019-12-30 20:53:11 -05:00
LoadScaledGraphic(surface, kManholeThruFloor, &tempManholes[i]);
2019-11-11 00:11:59 -05:00
}
}
}
//-------------------------------------------------------------- ReadyBackMap
void ReadyBackMap (void)
{
CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap),
(BitMap *)*GetGWorldPixMap(backSrcMap),
&workSrcRect, &workSrcRect, srcCopy);
2019-11-11 00:11:59 -05:00
}
//-------------------------------------------------------------- RestoreWorkMap
void RestoreWorkMap (void)
{
Rect dest;
dest = backSrcRect;
CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap),
(BitMap *)*GetGWorldPixMap(workSrcMap),
&backSrcRect, &backSrcRect, srcCopy);
2019-11-11 00:11:59 -05:00
}
//-------------------------------------------------------------- ReadyLevel
void ReadyLevel (void)
{
NilSavedMaps();
#ifdef COMPILEQT
if ((thisMac.hasQT) && (hasMovie) && (tvInRoom))
{
tvInRoom = false;
tvWithMovieNumber = -1;
2020-02-20 03:13:15 -05:00
theMovie.m_playing = false;
2019-11-11 00:11:59 -05:00
}
#endif
DetermineRoomOpenings();
2020-04-01 14:53:44 -04:00
ResetLocale(false);
2019-11-11 00:11:59 -05:00
InitGarbageRects();
}
//-------------------------------------------------------------- DrawLighting
void DrawLighting (void)
{
if (numLights == 0)
return;
else
{
// for future construction
}
}
//-------------------------------------------------------------- RedrawRoomLighting
void RedrawRoomLighting (void)
{
short roomV;
char wasState;
Boolean wasLit, isLit;
roomV = (*thisHouse)->rooms[thisRoomNumber].floor;
wasLit = numLights > 0;
numLights = GetNumberOfLights(localNumbers[kCentralRoom]);
isLit = numLights > 0;
if (wasLit != isLit)
{
DrawRoomBackground(localNumbers[kCentralRoom], kCentralRoom, roomV);
DrawARoomsObjects(kCentralRoom, true);
RedrawAllGrease();
2019-11-11 00:11:59 -05:00
DrawLighting();
UpdateOutletsLighting(localNumbers[kCentralRoom], numLights);
2019-11-11 00:11:59 -05:00
if (numNeighbors > 3)
DrawFloorSupport();
RestoreWorkMap();
AddRectToWorkRects(&localRoomsDest[kCentralRoom]);
shadowVisible = IsShadowVisible();
}
}