mirror of
https://github.com/elasota/Aerofoil.git
synced 2025-09-24 07:06:36 +00:00
Get TVs working
This commit is contained in:
@@ -193,8 +193,7 @@ Boolean DoWeHaveSoundManager3 (void)
|
|||||||
|
|
||||||
Boolean DoWeHaveQuickTime (void)
|
Boolean DoWeHaveQuickTime (void)
|
||||||
{
|
{
|
||||||
PL_NotYetImplemented_TODO("Movies");
|
return true;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------- DoWeHaveDragManager
|
//-------------------------------------------------------------- DoWeHaveDragManager
|
||||||
|
@@ -39,7 +39,7 @@ extern Rect clutterSrcRect;
|
|||||||
extern Rect flowerSrc[];
|
extern Rect flowerSrc[];
|
||||||
extern Rect *srcRects;
|
extern Rect *srcRects;
|
||||||
|
|
||||||
extern Movie theMovie;
|
extern AnimationPlayer theMovie;
|
||||||
extern Rect movieRect;
|
extern Rect movieRect;
|
||||||
extern Boolean hasMovie, tvInRoom;
|
extern Boolean hasMovie, tvInRoom;
|
||||||
|
|
||||||
|
@@ -11,6 +11,7 @@
|
|||||||
#include "PLStringCompare.h"
|
#include "PLStringCompare.h"
|
||||||
#include "PLTextUtils.h"
|
#include "PLTextUtils.h"
|
||||||
#include "PLPasStr.h"
|
#include "PLPasStr.h"
|
||||||
|
#include "BitmapImage.h"
|
||||||
#include "DialogManager.h"
|
#include "DialogManager.h"
|
||||||
#include "Externs.h"
|
#include "Externs.h"
|
||||||
#include "Environ.h"
|
#include "Environ.h"
|
||||||
@@ -34,7 +35,7 @@ void CloseHouseMovie (void);
|
|||||||
Boolean IsFileReadOnly (const VFileSpec &);
|
Boolean IsFileReadOnly (const VFileSpec &);
|
||||||
|
|
||||||
|
|
||||||
Movie theMovie;
|
AnimationPlayer theMovie;
|
||||||
Rect movieRect;
|
Rect movieRect;
|
||||||
PortabilityLayer::ResourceArchive *houseResFork;
|
PortabilityLayer::ResourceArchive *houseResFork;
|
||||||
short wasHouseVersion;
|
short wasHouseVersion;
|
||||||
@@ -52,31 +53,12 @@ extern Boolean phoneBitSet, bannerStarCountOn;
|
|||||||
|
|
||||||
|
|
||||||
//============================================================== Functions
|
//============================================================== Functions
|
||||||
//-------------------------------------------------------------- LoopMovie
|
|
||||||
|
|
||||||
void LoopMovie (void)
|
|
||||||
{
|
|
||||||
THandle<long> theLoop;
|
|
||||||
UserData theUserData;
|
|
||||||
short theCount;
|
|
||||||
|
|
||||||
theLoop = NewHandle(sizeof(long)).StaticCast<long>();
|
|
||||||
(**theLoop) = 0;
|
|
||||||
theUserData = GetMovieUserData(theMovie);
|
|
||||||
theCount = CountUserDataType(theUserData, 'LOOP');
|
|
||||||
while (theCount--)
|
|
||||||
{
|
|
||||||
RemoveUserData(theUserData, 'LOOP', 1);
|
|
||||||
}
|
|
||||||
AddUserData(theUserData, theLoop.StaticCast<void>(), 'LOOP');
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------- OpenHouseMovie
|
//-------------------------------------------------------------- OpenHouseMovie
|
||||||
|
|
||||||
void OpenHouseMovie (void)
|
void OpenHouseMovie (void)
|
||||||
{
|
{
|
||||||
#ifdef COMPILEQT
|
#ifdef COMPILEQT
|
||||||
TimeBase theTime;
|
|
||||||
VFileSpec theSpec;
|
VFileSpec theSpec;
|
||||||
VFileInfo finderInfo;
|
VFileInfo finderInfo;
|
||||||
Handle spaceSaver;
|
Handle spaceSaver;
|
||||||
@@ -93,59 +75,23 @@ void OpenHouseMovie (void)
|
|||||||
if (theErr != PLErrors::kNone)
|
if (theErr != PLErrors::kNone)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
theErr = OpenMovieFile(theSpec, &movieRefNum, 0);
|
AnimationPackage *anim = AnimationPackage::Create();
|
||||||
if (theErr != PLErrors::kNone)
|
if (!anim)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!anim->Load(theSpec.m_dir, theSpec.m_name))
|
||||||
{
|
{
|
||||||
|
anim->Destroy();
|
||||||
YellowAlert(kYellowQTMovieNotLoaded, theErr);
|
YellowAlert(kYellowQTMovieNotLoaded, theErr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
theErr = NewMovieFromFile(&theMovie, movieRefNum, nil, theSpec.m_name,
|
movieRect = (*anim->GetFrame(0))->GetRect();
|
||||||
newMovieActive, &dataRefWasChanged);
|
|
||||||
if (theErr != PLErrors::kNone)
|
|
||||||
{
|
|
||||||
YellowAlert(kYellowQTMovieNotLoaded, theErr);
|
|
||||||
theErr = CloseMovieFile(movieRefNum);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
theErr = CloseMovieFile(movieRefNum);
|
|
||||||
|
|
||||||
spaceSaver = NewHandle(307200L);
|
|
||||||
if (spaceSaver == nil)
|
|
||||||
{
|
|
||||||
YellowAlert(kYellowQTMovieNotLoaded, 749);
|
|
||||||
CloseHouseMovie();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
GoToBeginningOfMovie(theMovie);
|
|
||||||
theErr = LoadMovieIntoRam(theMovie,
|
|
||||||
GetMovieTime(theMovie, 0L), GetMovieDuration(theMovie), 0);
|
|
||||||
if (theErr != PLErrors::kNone)
|
|
||||||
{
|
|
||||||
YellowAlert(kYellowQTMovieNotLoaded, theErr);
|
|
||||||
spaceSaver.Dispose();
|
|
||||||
CloseHouseMovie();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
spaceSaver.Dispose();
|
|
||||||
|
|
||||||
theErr = PrerollMovie(theMovie, 0, 0x000F0000);
|
|
||||||
if (theErr != PLErrors::kNone)
|
|
||||||
{
|
|
||||||
YellowAlert(kYellowQTMovieNotLoaded, theErr);
|
|
||||||
CloseHouseMovie();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
theTime = GetMovieTimeBase(theMovie);
|
|
||||||
SetTimeBaseFlags(theTime, loopTimeBase);
|
|
||||||
SetMovieMasterTimeBase(theMovie, theTime, nil);
|
|
||||||
LoopMovie();
|
|
||||||
|
|
||||||
GetMovieBox(theMovie, &movieRect);
|
|
||||||
|
|
||||||
hasMovie = true;
|
hasMovie = true;
|
||||||
|
theMovie.SetPackage(anim);
|
||||||
|
|
||||||
|
AnimationManager::GetInstance()->RegisterPlayer(&theMovie);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -159,9 +105,10 @@ void CloseHouseMovie (void)
|
|||||||
|
|
||||||
if ((thisMac.hasQT) && (hasMovie))
|
if ((thisMac.hasQT) && (hasMovie))
|
||||||
{
|
{
|
||||||
theErr = LoadMovieIntoRam(theMovie,
|
AnimationManager::GetInstance()->RemovePlayer(&theMovie);
|
||||||
GetMovieTime(theMovie, 0L), GetMovieDuration(theMovie), flushFromRam);
|
|
||||||
DisposeMovie(theMovie);
|
theMovie.m_animPackage->Destroy();
|
||||||
|
theMovie.m_animPackage = nullptr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
hasMovie = false;
|
hasMovie = false;
|
||||||
@@ -196,7 +143,9 @@ Boolean OpenHouse (void)
|
|||||||
houseOpen = true;
|
houseOpen = true;
|
||||||
OpenHouseResFork();
|
OpenHouseResFork();
|
||||||
|
|
||||||
hasMovie = false;
|
if (hasMovie)
|
||||||
|
CloseHouseMovie();
|
||||||
|
|
||||||
tvInRoom = false;
|
tvInRoom = false;
|
||||||
tvWithMovieNumber = -1;
|
tvWithMovieNumber = -1;
|
||||||
OpenHouseMovie();
|
OpenHouseMovie();
|
||||||
|
@@ -351,14 +351,6 @@ int gpAppMain()
|
|||||||
InitSrcRects();
|
InitSrcRects();
|
||||||
CreateOffscreens(); SpinCursor(2);
|
CreateOffscreens(); SpinCursor(2);
|
||||||
OpenMainWindow();
|
OpenMainWindow();
|
||||||
|
|
||||||
if (thisMac.hasQT)
|
|
||||||
{
|
|
||||||
theErr = EnterMovies();
|
|
||||||
if (theErr != PLErrors::kNone)
|
|
||||||
thisMac.hasQT = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
InitSound(); SpinCursor(2);
|
InitSound(); SpinCursor(2);
|
||||||
InitMusic(); SpinCursor(2);
|
InitMusic(); SpinCursor(2);
|
||||||
BuildHouseList();
|
BuildHouseList();
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
|
#include "BitmapImage.h"
|
||||||
#include "Externs.h"
|
#include "Externs.h"
|
||||||
#include "Environ.h"
|
#include "Environ.h"
|
||||||
#include "RectUtils.h"
|
#include "RectUtils.h"
|
||||||
@@ -679,10 +679,10 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
|||||||
whoCares = tvScreen1;
|
whoCares = tvScreen1;
|
||||||
ZeroRectCorner(&whoCares);
|
ZeroRectCorner(&whoCares);
|
||||||
OffsetRect(&whoCares, itsRect.left + 17, itsRect.top + 10);
|
OffsetRect(&whoCares, itsRect.left + 17, itsRect.top + 10);
|
||||||
GetMovieBox(theMovie, &movieRect);
|
movieRect = (*theMovie.m_animPackage->GetFrame(0))->GetRect();
|
||||||
CenterRectInRect(&movieRect, &whoCares);
|
CenterRectInRect(&movieRect, &whoCares);
|
||||||
SetMovieBox(theMovie, &movieRect);
|
theMovie.m_renderRect = movieRect;
|
||||||
SetMovieDisplayClipRgn(theMovie, &whoCares);
|
theMovie.m_constrainRect = whoCares;
|
||||||
tvOn = thisObject.data.g.state;
|
tvOn = thisObject.data.g.state;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -143,7 +143,7 @@ void NewGame (short mode)
|
|||||||
#ifdef COMPILEQT
|
#ifdef COMPILEQT
|
||||||
if ((thisMac.hasQT) && (hasMovie))
|
if ((thisMac.hasQT) && (hasMovie))
|
||||||
{
|
{
|
||||||
SetMovieGWorld(theMovie, &mainWindow->m_surface, nil);
|
theMovie.m_surface = &mainWindow->m_surface;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -195,11 +195,11 @@ void NewGame (short mode)
|
|||||||
#ifdef COMPILEQT
|
#ifdef COMPILEQT
|
||||||
if ((thisMac.hasQT) && (hasMovie) && (tvInRoom))
|
if ((thisMac.hasQT) && (hasMovie) && (tvInRoom))
|
||||||
{
|
{
|
||||||
SetMovieActive(theMovie, true);
|
theMovie.m_playing = true;
|
||||||
if (tvOn)
|
if (tvOn)
|
||||||
{
|
{
|
||||||
StartMovie(theMovie);
|
AnimationManager::GetInstance()->RegisterPlayer(&theMovie);
|
||||||
MoviesTask(theMovie, 0);
|
AnimationManager::GetInstance()->RefreshPlayer(&theMovie);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -218,8 +218,7 @@ void NewGame (short mode)
|
|||||||
if ((thisMac.hasQT) && (hasMovie) && (tvInRoom))
|
if ((thisMac.hasQT) && (hasMovie) && (tvInRoom))
|
||||||
{
|
{
|
||||||
tvInRoom = false;
|
tvInRoom = false;
|
||||||
StopMovie(theMovie);
|
theMovie.m_playing = false;
|
||||||
SetMovieActive(theMovie, false);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -399,7 +398,7 @@ void PlayGame (void)
|
|||||||
{
|
{
|
||||||
#ifdef COMPILEQT
|
#ifdef COMPILEQT
|
||||||
if ((thisMac.hasQT) && (hasMovie) && (tvInRoom) && (tvOn))
|
if ((thisMac.hasQT) && (hasMovie) && (tvInRoom) && (tvOn))
|
||||||
MoviesTask(theMovie, 0);
|
AnimationManager::GetInstance()->RefreshPlayer(&theMovie);
|
||||||
#endif
|
#endif
|
||||||
RenderFrame();
|
RenderFrame();
|
||||||
HandleDynamicScoreboard();
|
HandleDynamicScoreboard();
|
||||||
@@ -424,7 +423,7 @@ void PlayGame (void)
|
|||||||
{
|
{
|
||||||
#ifdef COMPILEQT
|
#ifdef COMPILEQT
|
||||||
if ((thisMac.hasQT) && (hasMovie) && (tvInRoom) && (tvOn))
|
if ((thisMac.hasQT) && (hasMovie) && (tvInRoom) && (tvOn))
|
||||||
MoviesTask(theMovie, 0);
|
AnimationManager::GetInstance()->RefreshPlayer(&theMovie);
|
||||||
#endif
|
#endif
|
||||||
RenderFrame();
|
RenderFrame();
|
||||||
HandleDynamicScoreboard();
|
HandleDynamicScoreboard();
|
||||||
|
@@ -380,7 +380,7 @@ void ReadyLevel (void)
|
|||||||
{
|
{
|
||||||
tvInRoom = false;
|
tvInRoom = false;
|
||||||
tvWithMovieNumber = -1;
|
tvWithMovieNumber = -1;
|
||||||
StopMovie(theMovie);
|
theMovie.m_playing = false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -308,8 +308,8 @@ void MoveRoomToRoom (gliderPtr thisGlider, short where)
|
|||||||
RenderFrame();
|
RenderFrame();
|
||||||
if ((thisMac.hasQT) && (hasMovie) && (tvInRoom) && (tvOn))
|
if ((thisMac.hasQT) && (hasMovie) && (tvInRoom) && (tvOn))
|
||||||
{
|
{
|
||||||
GoToBeginningOfMovie(theMovie);
|
theMovie.Restart();
|
||||||
StartMovie(theMovie);
|
theMovie.m_playing = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -346,8 +346,8 @@ void TransportRoomToRoom (gliderPtr thisGlider)
|
|||||||
RenderFrame();
|
RenderFrame();
|
||||||
if ((thisMac.hasQT) && (hasMovie) && (tvInRoom) && (tvOn))
|
if ((thisMac.hasQT) && (hasMovie) && (tvInRoom) && (tvOn))
|
||||||
{
|
{
|
||||||
GoToBeginningOfMovie(theMovie);
|
theMovie.Restart();
|
||||||
StartMovie(theMovie);
|
theMovie.m_playing = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -385,8 +385,8 @@ void MoveDuctToDuct (gliderPtr thisGlider)
|
|||||||
RenderFrame();
|
RenderFrame();
|
||||||
if ((thisMac.hasQT) && (hasMovie) && (tvInRoom) && (tvOn))
|
if ((thisMac.hasQT) && (hasMovie) && (tvInRoom) && (tvOn))
|
||||||
{
|
{
|
||||||
GoToBeginningOfMovie(theMovie);
|
theMovie.Restart();
|
||||||
StartMovie(theMovie);
|
theMovie.m_playing = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -424,8 +424,8 @@ void MoveMailToMail (gliderPtr thisGlider)
|
|||||||
RenderFrame();
|
RenderFrame();
|
||||||
if ((thisMac.hasQT) && (hasMovie) && (tvInRoom) && (tvOn))
|
if ((thisMac.hasQT) && (hasMovie) && (tvInRoom) && (tvOn))
|
||||||
{
|
{
|
||||||
GoToBeginningOfMovie(theMovie);
|
theMovie.Restart();
|
||||||
StartMovie(theMovie);
|
theMovie.m_playing = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@@ -44,13 +44,13 @@ void ToggleTV (short index)
|
|||||||
{
|
{
|
||||||
if (dinahs[index].active)
|
if (dinahs[index].active)
|
||||||
{
|
{
|
||||||
GoToBeginningOfMovie(theMovie);
|
theMovie.Restart();
|
||||||
StartMovie(theMovie);
|
theMovie.m_playing = true;
|
||||||
tvOn = true;
|
tvOn = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
StopMovie(theMovie);
|
theMovie.m_playing = false;
|
||||||
tvOn = false;
|
tvOn = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,140 +1,273 @@
|
|||||||
#include "PLMovies.h"
|
#include "PLMovies.h"
|
||||||
|
|
||||||
PLError_t EnterMovies()
|
#include "BitmapImage.h"
|
||||||
|
#include "MemoryManager.h"
|
||||||
|
#include "PLQDraw.h"
|
||||||
|
#include "PLResources.h"
|
||||||
|
#include "QDManager.h"
|
||||||
|
#include "QDPixMap.h"
|
||||||
|
#include "ResourceManager.h"
|
||||||
|
|
||||||
|
#include "rapidjson/rapidjson.h"
|
||||||
|
#include "rapidjson/document.h"
|
||||||
|
|
||||||
|
|
||||||
|
AnimationPlayer::AnimationPlayer()
|
||||||
|
: m_animPackage(nullptr)
|
||||||
|
, m_renderRect(Rect::Create(0, 0, 0, 0))
|
||||||
|
, m_constrainRect(Rect::Create(0, 0, 0, 0))
|
||||||
|
, m_surface(nullptr)
|
||||||
|
, m_playing(false)
|
||||||
|
, m_timer(0)
|
||||||
|
, m_frameIndex(0)
|
||||||
|
, m_isFrameCurrent(false)
|
||||||
|
, m_next(nullptr)
|
||||||
|
, m_prev(nullptr)
|
||||||
{
|
{
|
||||||
return PLErrors::kNone;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UserData GetMovieUserData(Movie movie)
|
void AnimationPlayer::SetPackage(AnimationPackage *animPackage)
|
||||||
{
|
{
|
||||||
PL_NotYetImplemented();
|
m_animPackage = animPackage;
|
||||||
return nullptr;
|
Restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
int CountUserDataType(UserData userData, UInt32 type)
|
void AnimationPlayer::Restart()
|
||||||
{
|
{
|
||||||
PL_NotYetImplemented();
|
m_isFrameCurrent = (m_frameIndex == 0);
|
||||||
return 0;
|
|
||||||
|
m_playing = false;
|
||||||
|
m_timer = 0;
|
||||||
|
m_frameIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PLError_t RemoveUserData(UserData userData, UInt32 type, int index)
|
AnimationPackage *AnimationPackage::Create()
|
||||||
{
|
{
|
||||||
PL_NotYetImplemented();
|
void *storage = PortabilityLayer::MemoryManager::GetInstance()->Alloc(sizeof(AnimationPackage));
|
||||||
return PLErrors::kNone;
|
if (!storage)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return new (storage) AnimationPackage();
|
||||||
}
|
}
|
||||||
|
|
||||||
PLError_t AddUserData(UserData userData, Handle data, UInt32 type)
|
void AnimationPackage::Destroy()
|
||||||
{
|
{
|
||||||
PL_NotYetImplemented();
|
this->~AnimationPackage();
|
||||||
return PLErrors::kNone;
|
PortabilityLayer::MemoryManager::GetInstance()->Release(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
PLError_t OpenMovieFile(const VFileSpec &fsSpec, short *outRefNum, int permissions)
|
bool AnimationPackage::Load(PortabilityLayer::VirtualDirectory_t virtualDir, const PLPasStr &path)
|
||||||
{
|
{
|
||||||
PL_NotYetImplemented_TODO("Movies");
|
m_resArchive = PortabilityLayer::ResourceManager::GetInstance()->LoadResFile(virtualDir, path);
|
||||||
return PLErrors::kNone;
|
if (!m_resArchive)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
THandle<void> movieMetadataRes = m_resArchive->LoadResource('muvi', 0);
|
||||||
|
if (!movieMetadataRes)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const void *movieMetadata = *movieMetadataRes;
|
||||||
|
|
||||||
|
rapidjson::Document document;
|
||||||
|
document.Parse(static_cast<const char*>(movieMetadata), movieMetadataRes.MMBlock()->m_size);
|
||||||
|
|
||||||
|
movieMetadataRes.Dispose();
|
||||||
|
|
||||||
|
if (document.HasParseError() || !document.IsObject())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!document.HasMember("frameRateNumerator") || !document.HasMember("frameRateDenominator"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const rapidjson::Value &frameRateNumeratorJSON = document["frameRateNumerator"];
|
||||||
|
const rapidjson::Value &frameRateDenominatorJSON = document["frameRateDenominator"];
|
||||||
|
|
||||||
|
if (!frameRateNumeratorJSON.IsInt() && !frameRateDenominatorJSON.IsInt())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const int frameRateNumerator = frameRateNumeratorJSON.GetInt();
|
||||||
|
const int frameRateDenominator = frameRateDenominatorJSON.GetInt();
|
||||||
|
|
||||||
|
if (frameRateNumerator < 1 || frameRateDenominator < 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (frameRateDenominator > INT_MAX / 60 || frameRateDenominator * 60 < frameRateNumerator)
|
||||||
|
return false; // We only support up to 60fps
|
||||||
|
|
||||||
|
m_frameRateNumerator = frameRateNumerator;
|
||||||
|
m_frameRateDenominator = frameRateDenominator;
|
||||||
|
|
||||||
|
uint32_t numFrames = 0;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (numFrames + 1 > 0x7fff)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
THandle<void> frameRes = m_resArchive->LoadResource('PICT', numFrames + 1);
|
||||||
|
if (!frameRes)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (frameRes.MMBlock()->m_size < sizeof(BitmapImage))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
numFrames++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numFrames == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
void *imageListStorage = PortabilityLayer::MemoryManager::GetInstance()->Alloc(sizeof(THandle<BitmapImage>) * numFrames);
|
||||||
|
if (!imageListStorage)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_images = static_cast<THandle<BitmapImage>*>(imageListStorage);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < numFrames; i++)
|
||||||
|
new (m_images + i) THandle<BitmapImage>();
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < numFrames; i++)
|
||||||
|
m_images[i] = m_resArchive->LoadResource('PICT', i + 1).StaticCast<BitmapImage>();
|
||||||
|
|
||||||
|
m_numImages = numFrames;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
PLError_t NewMovieFromFile(Movie *movie, short refNum, const short *optResId, StringPtr resName, int flags, Boolean *unused)
|
const THandle<BitmapImage> &AnimationPackage::GetFrame(size_t index) const
|
||||||
{
|
{
|
||||||
PL_NotYetImplemented_TODO("Movies");
|
return m_images[index];
|
||||||
return PLErrors::kNone;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PLError_t CloseMovieFile(short refNum)
|
size_t AnimationPackage::NumFrames() const
|
||||||
{
|
{
|
||||||
PL_NotYetImplemented();
|
return m_numImages;
|
||||||
return PLErrors::kNone;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PLError_t GoToBeginningOfMovie(Movie movie)
|
uint32_t AnimationPackage::GetFrameRateNumerator() const
|
||||||
{
|
{
|
||||||
PL_NotYetImplemented();
|
return m_frameRateNumerator;
|
||||||
return PLErrors::kNone;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PLError_t LoadMovieIntoRam(Movie movie, TimeValue time, TimeValue duration, int flags)
|
uint32_t AnimationPackage::GetFrameRateDenominator() const
|
||||||
{
|
{
|
||||||
PL_NotYetImplemented();
|
return m_frameRateDenominator;
|
||||||
return PLErrors::kNone;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TimeValue GetMovieTime(Movie movie, TimeRecord *outCurrentTime)
|
|
||||||
|
AnimationPackage::AnimationPackage()
|
||||||
|
: m_images(nullptr)
|
||||||
|
, m_resArchive(nullptr)
|
||||||
|
, m_numImages(0)
|
||||||
{
|
{
|
||||||
PL_NotYetImplemented();
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TimeValue GetMovieDuration(Movie movie)
|
AnimationPackage::~AnimationPackage()
|
||||||
{
|
{
|
||||||
PL_NotYetImplemented();
|
m_resArchive->Destroy();
|
||||||
return 0;
|
PortabilityLayer::MemoryManager::GetInstance()->Release(m_images);
|
||||||
}
|
}
|
||||||
|
|
||||||
PLError_t PrerollMovie(Movie movie, TimeValue time, UInt32 rate)
|
|
||||||
|
void AnimationManager::RegisterPlayer(AnimationPlayer *player)
|
||||||
{
|
{
|
||||||
PL_NotYetImplemented();
|
assert(player->m_prev == nullptr || player->m_next == nullptr);
|
||||||
return PLErrors::kNone;
|
|
||||||
|
if (!m_firstPlayer)
|
||||||
|
m_firstPlayer = player;
|
||||||
|
|
||||||
|
if (m_lastPlayer)
|
||||||
|
m_lastPlayer->m_next = player;
|
||||||
|
|
||||||
|
player->m_prev = m_lastPlayer;
|
||||||
|
player->m_next = nullptr;
|
||||||
|
|
||||||
|
m_lastPlayer = player;
|
||||||
}
|
}
|
||||||
|
|
||||||
TimeBase GetMovieTimeBase(Movie movie)
|
void AnimationManager::RemovePlayer(AnimationPlayer *player)
|
||||||
{
|
{
|
||||||
PL_NotYetImplemented();
|
if (m_firstPlayer == player)
|
||||||
return nullptr;
|
m_firstPlayer = m_firstPlayer->m_next;
|
||||||
|
|
||||||
|
if (m_lastPlayer == player)
|
||||||
|
m_lastPlayer = m_lastPlayer->m_prev;
|
||||||
|
|
||||||
|
if (player->m_prev)
|
||||||
|
player->m_prev->m_next = player->m_next;
|
||||||
|
if (player->m_next)
|
||||||
|
player->m_next->m_prev = player->m_prev;
|
||||||
|
|
||||||
|
player->m_prev = player->m_next = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
PLError_t SetTimeBaseFlags(TimeBase timeBase, int flags)
|
void AnimationManager::RefreshPlayer(AnimationPlayer *player)
|
||||||
{
|
{
|
||||||
PL_NotYetImplemented();
|
if (!player->m_playing || !player->m_animPackage || !player->m_surface)
|
||||||
return PLErrors::kNone;
|
return;
|
||||||
|
|
||||||
|
AnimationPackage *anim = player->m_animPackage;
|
||||||
|
|
||||||
|
if (!player->m_isFrameCurrent)
|
||||||
|
{
|
||||||
|
player->m_isFrameCurrent = true;
|
||||||
|
|
||||||
|
THandle<BitmapImage> img = anim->GetFrame(player->m_frameIndex);
|
||||||
|
|
||||||
|
DrawSurface *surface = player->m_surface;
|
||||||
|
|
||||||
|
if (player->m_renderRect == player->m_constrainRect)
|
||||||
|
surface->DrawPicture(img, player->m_renderRect);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DrawSurface *renderSurface = nullptr;
|
||||||
|
if (PortabilityLayer::QDManager::GetInstance()->NewGWorld(&renderSurface, surface->m_port.GetPixelFormat(), player->m_renderRect, nullptr) != PLErrors::kNone)
|
||||||
|
return;
|
||||||
|
|
||||||
|
renderSurface->DrawPicture(img, player->m_renderRect);
|
||||||
|
|
||||||
|
CopyBits(*renderSurface->m_port.GetPixMap(), *surface->m_port.GetPixMap(), &player->m_constrainRect, &player->m_constrainRect, srcCopy);
|
||||||
|
|
||||||
|
PortabilityLayer::QDManager::GetInstance()->DisposeGWorld(renderSurface);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetMovieMasterTimeBase(Movie movie, TimeBase timeBase, void *unused)
|
void AnimationManager::TickPlayers(uint32_t numTicks)
|
||||||
{
|
{
|
||||||
PL_NotYetImplemented();
|
for (AnimationPlayer *player = m_firstPlayer; player; player = player->m_next)
|
||||||
|
{
|
||||||
|
AnimationPackage *anim = player->m_animPackage;
|
||||||
|
|
||||||
|
uint32_t fptNumerator = anim->GetFrameRateNumerator();
|
||||||
|
uint32_t fptDenominator = anim->GetFrameRateDenominator() * 60;
|
||||||
|
|
||||||
|
for (uint32_t t = 0; t < numTicks; t++)
|
||||||
|
{
|
||||||
|
player->m_timer += fptNumerator;
|
||||||
|
if (player->m_timer >= fptDenominator)
|
||||||
|
{
|
||||||
|
player->m_timer -= fptDenominator;
|
||||||
|
player->m_frameIndex++;
|
||||||
|
if (player->m_frameIndex == anim->NumFrames())
|
||||||
|
player->m_frameIndex = 0;
|
||||||
|
|
||||||
|
player->m_isFrameCurrent = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetMovieBox(Movie movie, Rect *rect)
|
AnimationManager *AnimationManager::GetInstance()
|
||||||
{
|
{
|
||||||
PL_NotYetImplemented();
|
return &ms_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StopMovie(Movie movie)
|
AnimationManager::AnimationManager()
|
||||||
|
: m_firstPlayer(nullptr)
|
||||||
|
, m_lastPlayer(nullptr)
|
||||||
{
|
{
|
||||||
PL_NotYetImplemented();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisposeMovie(Movie movie)
|
AnimationManager AnimationManager::ms_instance;
|
||||||
{
|
|
||||||
PL_NotYetImplemented();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetMovieGWorld(Movie movie, DrawSurface *graf, void *unknown)
|
|
||||||
{
|
|
||||||
PL_NotYetImplemented();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetMovieActive(Movie movie, Boolean active)
|
|
||||||
{
|
|
||||||
PL_NotYetImplemented();
|
|
||||||
}
|
|
||||||
|
|
||||||
void StartMovie(Movie movie)
|
|
||||||
{
|
|
||||||
PL_NotYetImplemented();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MoviesTask(Movie movie, int unknown)
|
|
||||||
{
|
|
||||||
PL_NotYetImplemented();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetMovieBox(Movie movie, const Rect *rect)
|
|
||||||
{
|
|
||||||
PL_NotYetImplemented();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetMovieDisplayClipRgn(Movie movie, const Rect *rect)
|
|
||||||
{
|
|
||||||
PL_NotYetImplemented();
|
|
||||||
}
|
|
||||||
|
@@ -3,62 +3,85 @@
|
|||||||
#define __PL_MOVIES_H__
|
#define __PL_MOVIES_H__
|
||||||
|
|
||||||
#include "PLApplication.h"
|
#include "PLApplication.h"
|
||||||
|
#include "VirtualDirectory.h"
|
||||||
|
|
||||||
struct UserDataObject;
|
namespace PortabilityLayer
|
||||||
struct TimeBaseObject;
|
|
||||||
struct MovieObject;
|
|
||||||
|
|
||||||
struct UserDataBackingStorage
|
|
||||||
{
|
{
|
||||||
|
class ResourceArchive;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DrawSurface;
|
||||||
|
class AnimationPackage;
|
||||||
|
|
||||||
|
struct AnimationPlayer
|
||||||
|
{
|
||||||
|
AnimationPackage *m_animPackage;
|
||||||
|
Rect m_renderRect;
|
||||||
|
Rect m_constrainRect;
|
||||||
|
DrawSurface *m_surface;
|
||||||
|
bool m_playing;
|
||||||
|
|
||||||
|
uint32_t m_timer;
|
||||||
|
uint16_t m_frameIndex;
|
||||||
|
bool m_isFrameCurrent;
|
||||||
|
|
||||||
|
AnimationPlayer *m_next;
|
||||||
|
AnimationPlayer *m_prev;
|
||||||
|
|
||||||
|
AnimationPlayer();
|
||||||
|
|
||||||
|
void SetPackage(AnimationPackage *animPackage);
|
||||||
|
void Restart();
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef int64_t TimeValue;
|
class AnimationPackage final
|
||||||
|
|
||||||
struct TimeRecord
|
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
static AnimationPackage *Create();
|
||||||
|
void Destroy();
|
||||||
|
|
||||||
|
bool Load(PortabilityLayer::VirtualDirectory_t virtualDir, const PLPasStr &path);
|
||||||
|
|
||||||
|
const THandle<BitmapImage> &GetFrame(size_t index) const;
|
||||||
|
size_t NumFrames() const;
|
||||||
|
uint32_t GetFrameRateNumerator() const;
|
||||||
|
uint32_t GetFrameRateDenominator() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit AnimationPackage();
|
||||||
|
~AnimationPackage();
|
||||||
|
|
||||||
|
THandle<BitmapImage> *m_images;
|
||||||
|
PortabilityLayer::ResourceArchive *m_resArchive;
|
||||||
|
size_t m_numImages;
|
||||||
|
|
||||||
|
uint32_t m_frameRateNumerator;
|
||||||
|
uint32_t m_frameRateDenominator;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum MovieFlags
|
struct AnimationPlayerRef
|
||||||
{
|
{
|
||||||
newMovieActive = 1,
|
AnimationPlayer *m_player;
|
||||||
flushFromRam = 2,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum TimeBaseFlags
|
class AnimationManager final
|
||||||
{
|
{
|
||||||
loopTimeBase = 1,
|
public:
|
||||||
|
void RegisterPlayer(AnimationPlayer *player);
|
||||||
|
void RemovePlayer(AnimationPlayer *player);
|
||||||
|
|
||||||
|
void RefreshPlayer(AnimationPlayer *player);
|
||||||
|
void TickPlayers(uint32_t numTicks);
|
||||||
|
|
||||||
|
static AnimationManager *GetInstance();
|
||||||
|
|
||||||
|
private:
|
||||||
|
AnimationManager();
|
||||||
|
|
||||||
|
AnimationPlayer *m_firstPlayer;
|
||||||
|
AnimationPlayer *m_lastPlayer;
|
||||||
|
|
||||||
|
static AnimationManager ms_instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef UserDataObject *UserData;
|
|
||||||
typedef TimeBaseObject *TimeBase;
|
|
||||||
typedef MovieObject *Movie;
|
|
||||||
|
|
||||||
|
|
||||||
PLError_t EnterMovies();
|
|
||||||
|
|
||||||
UserData GetMovieUserData(Movie movie);
|
|
||||||
int CountUserDataType(UserData userData, UInt32 type);
|
|
||||||
PLError_t RemoveUserData(UserData userData, UInt32 type, int index); // Index is 1-based
|
|
||||||
PLError_t AddUserData(UserData userData, Handle data, UInt32 type);
|
|
||||||
PLError_t OpenMovieFile(const VFileSpec &fsSpec, short *outRefNum, int permissions);
|
|
||||||
PLError_t NewMovieFromFile(Movie *movie, short refNum, const short *optResId, StringPtr resName, int flags, Boolean *unused);
|
|
||||||
PLError_t CloseMovieFile(short refNum);
|
|
||||||
PLError_t GoToBeginningOfMovie(Movie movie);
|
|
||||||
PLError_t LoadMovieIntoRam(Movie movie, TimeValue time, TimeValue duration, int flags);
|
|
||||||
TimeValue GetMovieTime(Movie movie, TimeRecord *outCurrentTime);
|
|
||||||
TimeValue GetMovieDuration(Movie movie);
|
|
||||||
PLError_t PrerollMovie(Movie movie, TimeValue time, UInt32 rate);
|
|
||||||
TimeBase GetMovieTimeBase(Movie movie);
|
|
||||||
PLError_t SetTimeBaseFlags(TimeBase timeBase, int flags);
|
|
||||||
void SetMovieMasterTimeBase(Movie movie, TimeBase timeBase, void *unused);
|
|
||||||
void GetMovieBox(Movie movie, Rect *rect);
|
|
||||||
void StopMovie(Movie movie);
|
|
||||||
void DisposeMovie(Movie movie);
|
|
||||||
void SetMovieGWorld(Movie movie, DrawSurface *graf, void *unknown);
|
|
||||||
void SetMovieActive(Movie movie, Boolean active);
|
|
||||||
void StartMovie(Movie movie);
|
|
||||||
void MoviesTask(Movie movie, int unknown);
|
|
||||||
void SetMovieBox(Movie movie, const Rect *rect);
|
|
||||||
void SetMovieDisplayClipRgn(Movie movie, const Rect *rect);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -698,13 +698,16 @@ void DrawSurface::DrawPicture(THandle<BitmapImage> pictHdl, const Rect &bounds)
|
|||||||
if (bpp != 1 && bpp != 4 && bpp != 8 && bpp != 16 && bpp != 24)
|
if (bpp != 1 && bpp != 4 && bpp != 8 && bpp != 16 && bpp != 24)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const uint32_t numColors = infoHeader.m_numColors;
|
uint32_t numColors = infoHeader.m_numColors;
|
||||||
if (numColors > 256)
|
if (numColors > 256)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (numColors == 0 && bpp <= 8)
|
||||||
|
numColors = (1 << bpp);
|
||||||
|
|
||||||
const uint8_t *ctabLoc = bmpBytes + sizeof(fileHeader) + infoHeader.m_thisStructureSize;
|
const uint8_t *ctabLoc = bmpBytes + sizeof(fileHeader) + infoHeader.m_thisStructureSize;
|
||||||
|
|
||||||
const size_t ctabSize = infoHeader.m_numColors * sizeof(PortabilityLayer::BitmapColorTableEntry);
|
const size_t ctabSize = numColors * sizeof(PortabilityLayer::BitmapColorTableEntry);
|
||||||
const size_t availCTabBytes = bmpSize - sizeof(fileHeader) - infoHeader.m_thisStructureSize;
|
const size_t availCTabBytes = bmpSize - sizeof(fileHeader) - infoHeader.m_thisStructureSize;
|
||||||
|
|
||||||
if (ctabSize > availCTabBytes)
|
if (ctabSize > availCTabBytes)
|
||||||
@@ -770,8 +773,8 @@ void DrawSurface::DrawPicture(THandle<BitmapImage> pictHdl, const Rect &bounds)
|
|||||||
int32_t firstSourceCol = sourceRect.m_topLeft.m_x;
|
int32_t firstSourceCol = sourceRect.m_topLeft.m_x;
|
||||||
|
|
||||||
const size_t destPitch = pixMap->GetPitch();
|
const size_t destPitch = pixMap->GetPitch();
|
||||||
uint8_t *firstDestRow = static_cast<uint8_t*>(pixMap->GetPixelData()) + destPitch * static_cast<uint32_t>(drawOrigin.m_y + truncatedTop);
|
uint8_t *firstDestRow = static_cast<uint8_t*>(pixMap->GetPixelData()) + destPitch * static_cast<uint32_t>(drawOrigin.m_y - targetPixMapRect.top + truncatedTop);
|
||||||
size_t firstDestCol = static_cast<uint32_t>(drawOrigin.m_x + truncatedLeft);
|
size_t firstDestCol = static_cast<uint32_t>(drawOrigin.m_x - targetPixMapRect.left + truncatedLeft);
|
||||||
|
|
||||||
const PortabilityLayer::StandardPalette *stdPalette = PortabilityLayer::StandardPalette::GetInstance();
|
const PortabilityLayer::StandardPalette *stdPalette = PortabilityLayer::StandardPalette::GetInstance();
|
||||||
|
|
||||||
|
@@ -310,7 +310,7 @@ namespace PortabilityLayer
|
|||||||
}
|
}
|
||||||
else if (resTypeID == ResTypeID('STR#'))
|
else if (resTypeID == ResTypeID('STR#'))
|
||||||
extension = ".txt";
|
extension = ".txt";
|
||||||
else if (resTypeID == ResTypeID('DITL'))
|
else if (resTypeID == ResTypeID('DITL') || resTypeID == ResTypeID('muvi'))
|
||||||
extension = ".json";
|
extension = ".json";
|
||||||
|
|
||||||
char resourceFile[64];
|
char resourceFile[64];
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
#include "PLCore.h"
|
#include "PLCore.h"
|
||||||
#include "PLEventQueue.h"
|
#include "PLEventQueue.h"
|
||||||
#include "PLKeyEncoding.h"
|
#include "PLKeyEncoding.h"
|
||||||
|
#include "PLMovies.h"
|
||||||
#include "PLSysCalls.h"
|
#include "PLSysCalls.h"
|
||||||
#include "PLTimeTaggedVOSEvent.h"
|
#include "PLTimeTaggedVOSEvent.h"
|
||||||
#include "DisplayDeviceManager.h"
|
#include "DisplayDeviceManager.h"
|
||||||
@@ -130,6 +131,8 @@ namespace PLSysCalls
|
|||||||
PortabilityLayer::SuspendApplication(PortabilityLayer::HostSuspendCallID_Delay, args, nullptr);
|
PortabilityLayer::SuspendApplication(PortabilityLayer::HostSuspendCallID_Delay, args, nullptr);
|
||||||
|
|
||||||
ImportVOSEvents(PortabilityLayer::DisplayDeviceManager::GetInstance()->GetTickCount());
|
ImportVOSEvents(PortabilityLayer::DisplayDeviceManager::GetInstance()->GetTickCount());
|
||||||
|
|
||||||
|
AnimationManager::GetInstance()->TickPlayers(ticks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -40,6 +40,9 @@ struct Rect
|
|||||||
Rect &operator-=(const Point &point);
|
Rect &operator-=(const Point &point);
|
||||||
Rect &operator+=(const Point &point);
|
Rect &operator+=(const Point &point);
|
||||||
|
|
||||||
|
bool operator!=(const Rect &other) const;
|
||||||
|
bool operator==(const Rect &other) const;
|
||||||
|
|
||||||
uint16_t Height() const;
|
uint16_t Height() const;
|
||||||
uint16_t Width() const;
|
uint16_t Width() const;
|
||||||
|
|
||||||
@@ -213,6 +216,18 @@ inline Rect &Rect::operator+=(const Point &point)
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool Rect::operator!=(const Rect &other) const
|
||||||
|
{
|
||||||
|
if (this->top != other.top || this->bottom != other.bottom || this->left != other.left || this->right != other.right)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Rect::operator==(const Rect &other) const
|
||||||
|
{
|
||||||
|
return !((*this) != other);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline uint16_t Rect::Height() const
|
inline uint16_t Rect::Height() const
|
||||||
|
Reference in New Issue
Block a user