2022-05-19 01:51:26 -07:00
|
|
|
#include "movie.h"
|
|
|
|
|
|
|
|
#include "color.h"
|
|
|
|
#include "core.h"
|
2022-06-18 22:48:30 -07:00
|
|
|
#include "db.h"
|
2022-05-19 01:51:26 -07:00
|
|
|
#include "debug.h"
|
|
|
|
#include "draw.h"
|
|
|
|
#include "game_config.h"
|
2022-06-18 22:48:30 -07:00
|
|
|
#include "geometry.h"
|
2022-05-19 01:51:26 -07:00
|
|
|
#include "memory_manager.h"
|
|
|
|
#include "movie_effect.h"
|
|
|
|
#include "movie_lib.h"
|
2022-05-28 02:34:49 -07:00
|
|
|
#include "platform_compat.h"
|
2022-07-05 01:00:55 -07:00
|
|
|
#include "pointer_registry.h"
|
2022-05-19 01:51:26 -07:00
|
|
|
#include "sound.h"
|
|
|
|
#include "text_font.h"
|
2022-07-29 06:04:05 -07:00
|
|
|
#include "window.h"
|
2022-05-19 01:51:26 -07:00
|
|
|
#include "window_manager.h"
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
2022-06-18 22:48:30 -07:00
|
|
|
#include <SDL.h>
|
|
|
|
|
|
|
|
typedef struct MovieSubtitleListNode {
|
|
|
|
int num;
|
|
|
|
char* text;
|
|
|
|
struct MovieSubtitleListNode* next;
|
|
|
|
} MovieSubtitleListNode;
|
|
|
|
|
|
|
|
static void* movieMallocImpl(size_t size);
|
|
|
|
static void movieFreeImpl(void* ptr);
|
|
|
|
static bool movieReadImpl(int fileHandle, void* buf, int count);
|
2022-07-29 06:04:05 -07:00
|
|
|
static void movieDirectImpl(SDL_Surface* surface, int srcWidth, int srcHeight, int srcX, int srcY, int destWidth, int destHeight, int a8, int a9);
|
|
|
|
static void movieBufferedImpl(SDL_Surface* surface, int srcWidth, int srcHeight, int srcX, int srcY, int destWidth, int destHeight, int a8, int a9);
|
|
|
|
static int _movieScaleSubRect(int win, unsigned char* data, int width, int height, int pitch);
|
|
|
|
static int _movieScaleSubRectAlpha(int win, unsigned char* data, int width, int height, int pitch);
|
|
|
|
static int _movieScaleWindowAlpha(int win, unsigned char* data, int width, int height, int pitch);
|
|
|
|
static int _blitAlpha(int win, unsigned char* data, int width, int height, int pitch);
|
|
|
|
static int _movieScaleWindow(int win, unsigned char* data, int width, int height, int pitch);
|
|
|
|
static int _blitNormal(int win, unsigned char* data, int width, int height, int pitch);
|
2022-06-18 22:48:30 -07:00
|
|
|
static void movieSetPaletteEntriesImpl(unsigned char* palette, int start, int end);
|
|
|
|
static int _noop();
|
|
|
|
static void _cleanupMovie(int a1);
|
|
|
|
static void _cleanupLast();
|
|
|
|
static File* movieOpen(char* filePath);
|
|
|
|
static void movieLoadSubtitles(char* filePath);
|
|
|
|
static void movieRenderSubtitles();
|
|
|
|
static int _movieStart(int win, char* filePath, int (*a3)());
|
|
|
|
static bool _localMovieCallback();
|
|
|
|
static int _stepMovie();
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
// 0x5195B8
|
2022-06-18 22:48:30 -07:00
|
|
|
static int gMovieWindow = -1;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x5195BC
|
2022-06-18 22:48:30 -07:00
|
|
|
static int gMovieSubtitlesFont = -1;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
// 0x5195C0
|
|
|
|
static MovieBlitFunc* gMovieBlitFuncs[2][2][2] = {
|
|
|
|
{
|
|
|
|
{
|
|
|
|
_blitNormal,
|
|
|
|
_blitNormal,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
_movieScaleWindow,
|
|
|
|
_movieScaleSubRect,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{
|
|
|
|
_blitAlpha,
|
|
|
|
_blitAlpha,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
_movieScaleWindowAlpha,
|
|
|
|
_movieScaleSubRectAlpha,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
// 0x5195E0
|
2022-06-18 22:48:30 -07:00
|
|
|
static MovieSetPaletteEntriesProc* gMovieSetPaletteEntriesProc = _setSystemPaletteEntries;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x5195E4
|
2022-06-18 22:48:30 -07:00
|
|
|
static int gMovieSubtitlesColorR = 31;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x5195E8
|
2022-06-18 22:48:30 -07:00
|
|
|
static int gMovieSubtitlesColorG = 31;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x5195EC
|
2022-06-18 22:48:30 -07:00
|
|
|
static int gMovieSubtitlesColorB = 31;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638E10
|
2022-06-18 22:48:30 -07:00
|
|
|
static Rect gMovieWindowRect;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638E20
|
2022-06-18 22:48:30 -07:00
|
|
|
static Rect _movieRect;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638E30
|
2022-06-18 22:48:30 -07:00
|
|
|
static void (*_movieCallback)();
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
// 0x638E34
|
|
|
|
MovieEndFunc* _endMovieFunc;
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
// 0x638E38
|
2022-06-18 22:48:30 -07:00
|
|
|
static MovieSetPaletteProc* gMoviePaletteProc;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638E3C
|
2022-07-29 06:04:05 -07:00
|
|
|
static MovieFailedOpenFunc* _failedOpenFunc;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638E40
|
2022-06-18 22:48:30 -07:00
|
|
|
static MovieBuildSubtitleFilePathProc* gMovieBuildSubtitleFilePathProc;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
// 0x638E44
|
|
|
|
static MovieStartFunc* _startMovieFunc;
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
// 0x638E48
|
2022-06-18 22:48:30 -07:00
|
|
|
static int _subtitleW;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638E4C
|
2022-06-18 22:48:30 -07:00
|
|
|
static int _lastMovieBH;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638E50
|
2022-06-18 22:48:30 -07:00
|
|
|
static int _lastMovieBW;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638E54
|
2022-06-18 22:48:30 -07:00
|
|
|
static int _lastMovieSX;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638E58
|
2022-06-18 22:48:30 -07:00
|
|
|
static int _lastMovieSY;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638E5C
|
2022-06-18 22:48:30 -07:00
|
|
|
static int _movieScaleFlag;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
// 0x638E60
|
|
|
|
static MoviePreDrawFunc* _moviePreDrawFunc;
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
// 0x638E64
|
2022-06-18 22:48:30 -07:00
|
|
|
static int _lastMovieH;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638E68
|
2022-06-18 22:48:30 -07:00
|
|
|
static int _lastMovieW;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638E6C
|
2022-06-18 22:48:30 -07:00
|
|
|
static int _lastMovieX;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638E70
|
2022-06-18 22:48:30 -07:00
|
|
|
static int _lastMovieY;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638E74
|
2022-06-18 22:48:30 -07:00
|
|
|
static MovieSubtitleListNode* gMovieSubtitleHead;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638E78
|
2022-06-18 22:48:30 -07:00
|
|
|
static unsigned int gMovieFlags;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638E7C
|
2022-06-18 22:48:30 -07:00
|
|
|
static int _movieAlphaFlag;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638E80
|
2022-06-18 22:48:30 -07:00
|
|
|
static bool _movieSubRectFlag;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638E84
|
2022-06-18 22:48:30 -07:00
|
|
|
static int _movieH;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638E88
|
2022-06-18 22:48:30 -07:00
|
|
|
static int _movieOffset;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638E8C
|
2022-07-29 06:04:05 -07:00
|
|
|
static MovieCaptureFrameProc* _movieCaptureFrameFunc;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638E90
|
2022-06-18 22:48:30 -07:00
|
|
|
static unsigned char* _lastMovieBuffer;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638E94
|
2022-06-18 22:48:30 -07:00
|
|
|
static int _movieW;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638E98
|
2022-07-29 06:04:05 -07:00
|
|
|
static MovieFrameGrabProc* _movieFrameGrabFunc;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638EA0
|
2022-06-18 22:48:30 -07:00
|
|
|
static int _subtitleH;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638EA4
|
2022-06-18 22:48:30 -07:00
|
|
|
static int _running;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638EA8
|
2022-06-18 22:48:30 -07:00
|
|
|
static File* gMovieFileStream;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638EAC
|
2022-06-18 22:48:30 -07:00
|
|
|
static unsigned char* _alphaWindowBuf;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638EB0
|
2022-06-18 22:48:30 -07:00
|
|
|
static int _movieX;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638EB4
|
2022-06-18 22:48:30 -07:00
|
|
|
static int _movieY;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638EBC
|
2022-06-18 22:48:30 -07:00
|
|
|
static File* _alphaHandle;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x638EC0
|
2022-06-18 22:48:30 -07:00
|
|
|
static unsigned char* _alphaBuf;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-06-18 22:48:30 -07:00
|
|
|
static SDL_Surface* gMovieSdlSurface = NULL;
|
2022-07-05 01:00:55 -07:00
|
|
|
static int gMovieFileStreamPointerKey = 0;
|
2022-05-24 13:19:36 -07:00
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
// NOTE: Unused.
|
|
|
|
//
|
|
|
|
// 0x4865E0
|
|
|
|
void _movieSetPreDrawFunc(MoviePreDrawFunc* preDrawFunc)
|
|
|
|
{
|
|
|
|
_moviePreDrawFunc = preDrawFunc;
|
|
|
|
}
|
|
|
|
|
|
|
|
// NOTE: Unused.
|
|
|
|
//
|
|
|
|
// 0x4865E8
|
|
|
|
void _movieSetFailedOpenFunc(MovieFailedOpenFunc* failedOpenFunc)
|
|
|
|
{
|
|
|
|
_failedOpenFunc = failedOpenFunc;
|
|
|
|
}
|
|
|
|
|
|
|
|
// NOTE: Unused.
|
|
|
|
//
|
|
|
|
// 0x4865F0
|
|
|
|
void _movieSetFunc(MovieStartFunc* startFunc, MovieEndFunc* endFunc)
|
|
|
|
{
|
|
|
|
_startMovieFunc = startFunc;
|
|
|
|
_endMovieFunc = endFunc;
|
|
|
|
}
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
// 0x4865FC
|
2022-06-18 22:48:30 -07:00
|
|
|
static void* movieMallocImpl(size_t size)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
return internal_malloc_safe(size, __FILE__, __LINE__); // "..\\int\\MOVIE.C", 209
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x486614
|
2022-06-18 22:48:30 -07:00
|
|
|
static void movieFreeImpl(void* ptr)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
internal_free_safe(ptr, __FILE__, __LINE__); // "..\\int\\MOVIE.C", 213
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x48662C
|
2022-06-18 22:48:30 -07:00
|
|
|
static bool movieReadImpl(int fileHandle, void* buf, int count)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
return fileRead(buf, 1, count, (File*)intToPtr(fileHandle)) == count;
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// 0x486654
|
2022-06-18 22:48:30 -07:00
|
|
|
static void movieDirectImpl(SDL_Surface* surface, int srcWidth, int srcHeight, int srcX, int srcY, int destWidth, int destHeight, int a8, int a9)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
int v14;
|
|
|
|
int v15;
|
|
|
|
|
2022-05-24 13:19:36 -07:00
|
|
|
SDL_Rect srcRect;
|
|
|
|
srcRect.x = srcX;
|
|
|
|
srcRect.y = srcY;
|
|
|
|
srcRect.w = srcWidth;
|
|
|
|
srcRect.h = srcHeight;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
v14 = gMovieWindowRect.right - gMovieWindowRect.left;
|
|
|
|
v15 = gMovieWindowRect.right - gMovieWindowRect.left + 1;
|
|
|
|
|
2022-05-24 13:19:36 -07:00
|
|
|
SDL_Rect destRect;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
if (_movieScaleFlag) {
|
|
|
|
if ((gMovieFlags & MOVIE_EXTENDED_FLAG_0x08) != 0) {
|
2022-05-24 13:19:36 -07:00
|
|
|
destRect.y = (gMovieWindowRect.bottom - gMovieWindowRect.top + 1 - destHeight) / 2;
|
|
|
|
destRect.x = (v15 - 4 * srcWidth / 3) / 2;
|
2022-05-19 01:51:26 -07:00
|
|
|
} else {
|
2022-05-24 13:19:36 -07:00
|
|
|
destRect.y = _movieY + gMovieWindowRect.top;
|
|
|
|
destRect.x = gMovieWindowRect.left + _movieX;
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
2022-05-24 13:19:36 -07:00
|
|
|
destRect.w = 4 * srcWidth / 3;
|
|
|
|
destRect.h = destHeight;
|
2022-05-19 01:51:26 -07:00
|
|
|
} else {
|
|
|
|
if ((gMovieFlags & MOVIE_EXTENDED_FLAG_0x08) != 0) {
|
2022-05-24 13:19:36 -07:00
|
|
|
destRect.y = (gMovieWindowRect.bottom - gMovieWindowRect.top + 1 - destHeight) / 2;
|
|
|
|
destRect.x = (v15 - destWidth) / 2;
|
2022-05-19 01:51:26 -07:00
|
|
|
} else {
|
2022-05-24 13:19:36 -07:00
|
|
|
destRect.y = _movieY + gMovieWindowRect.top;
|
|
|
|
destRect.x = gMovieWindowRect.left + _movieX;
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
2022-05-24 13:19:36 -07:00
|
|
|
destRect.w = destWidth;
|
|
|
|
destRect.h = destHeight;
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
2022-05-24 13:19:36 -07:00
|
|
|
_lastMovieSX = srcX;
|
|
|
|
_lastMovieSY = srcY;
|
|
|
|
_lastMovieX = destRect.x;
|
|
|
|
_lastMovieY = destRect.y;
|
|
|
|
_lastMovieBH = srcHeight;
|
|
|
|
_lastMovieW = destRect.w;
|
|
|
|
gMovieSdlSurface = surface;
|
|
|
|
_lastMovieBW = srcWidth;
|
|
|
|
_lastMovieH = destRect.h;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-05-21 13:04:08 -07:00
|
|
|
// The code above assumes `gMovieWindowRect` is always at (0,0) which is not
|
|
|
|
// the case in HRP. For blitting purposes we have to adjust it relative to
|
|
|
|
// the actual origin. We do it here because the variables above need to stay
|
|
|
|
// in movie window coordinate space (for proper subtitles positioning).
|
2022-05-24 13:19:36 -07:00
|
|
|
destRect.x += gMovieWindowRect.left;
|
|
|
|
destRect.y += gMovieWindowRect.top;
|
|
|
|
|
|
|
|
if (_movieCaptureFrameFunc != NULL) {
|
|
|
|
if (SDL_LockSurface(surface) == 0) {
|
2022-07-29 06:04:05 -07:00
|
|
|
_movieCaptureFrameFunc(static_cast<unsigned char*>(surface->pixels),
|
|
|
|
srcWidth,
|
|
|
|
srcHeight,
|
|
|
|
surface->pitch,
|
|
|
|
destRect.x,
|
|
|
|
destRect.y,
|
|
|
|
destRect.w,
|
|
|
|
destRect.h);
|
2022-05-24 13:19:36 -07:00
|
|
|
SDL_UnlockSurface(surface);
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
2022-05-24 13:19:36 -07:00
|
|
|
}
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-05-24 13:19:36 -07:00
|
|
|
// TODO: This is a super-ugly hack. The reason is that surfaces managed by
|
|
|
|
// MVE does not have palette. If we blit from these internal surfaces into
|
|
|
|
// backbuffer surface (with palette set), all we get is shiny white box.
|
|
|
|
SDL_SetSurfacePalette(surface, gSdlSurface->format->palette);
|
|
|
|
SDL_BlitSurface(surface, &srcRect, gSdlSurface, &destRect);
|
2022-07-12 00:10:23 -07:00
|
|
|
SDL_BlitSurface(gSdlSurface, NULL, gSdlTextureSurface, NULL);
|
|
|
|
SDL_UpdateTexture(gSdlTexture, NULL, gSdlTextureSurface->pixels, gSdlTextureSurface->pitch);
|
|
|
|
SDL_RenderClear(gSdlRenderer);
|
|
|
|
SDL_RenderCopy(gSdlRenderer, gSdlTexture, NULL, NULL);
|
|
|
|
SDL_RenderPresent(gSdlRenderer);
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// 0x486900
|
2022-06-18 22:48:30 -07:00
|
|
|
static void movieBufferedImpl(SDL_Surface* a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
if (gMovieWindow == -1) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
_lastMovieBW = a2;
|
2022-05-24 13:19:36 -07:00
|
|
|
gMovieSdlSurface = a1;
|
2022-05-19 01:51:26 -07:00
|
|
|
_lastMovieBH = a2;
|
|
|
|
_lastMovieW = a6;
|
|
|
|
_lastMovieH = a7;
|
|
|
|
_lastMovieX = a4;
|
|
|
|
_lastMovieY = a5;
|
|
|
|
_lastMovieSX = a4;
|
|
|
|
_lastMovieSY = a5;
|
|
|
|
|
2022-05-24 13:19:36 -07:00
|
|
|
if (SDL_LockSurface(a1) != 0) {
|
2022-05-19 01:51:26 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_movieCaptureFrameFunc != NULL) {
|
2022-07-29 06:04:05 -07:00
|
|
|
_movieCaptureFrameFunc(static_cast<unsigned char*>(a1->pixels), a2, a3, a1->pitch, _movieRect.left, _movieRect.top, a6, a7);
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (_movieFrameGrabFunc != NULL) {
|
2022-07-29 06:04:05 -07:00
|
|
|
_movieFrameGrabFunc(static_cast<unsigned char*>(a1->pixels), a2, a3, a1->pitch);
|
2022-05-19 01:51:26 -07:00
|
|
|
} else {
|
2022-07-29 06:04:05 -07:00
|
|
|
MovieBlitFunc* func = gMovieBlitFuncs[_movieAlphaFlag][_movieScaleFlag][_movieSubRectFlag];
|
|
|
|
if (func(gMovieWindow, static_cast<unsigned char*>(a1->pixels), a2, a3, a1->pitch) != 0) {
|
|
|
|
if (_moviePreDrawFunc != NULL) {
|
|
|
|
_moviePreDrawFunc(gMovieWindow, &_movieRect);
|
|
|
|
}
|
|
|
|
|
|
|
|
windowRefreshRect(gMovieWindow, &_movieRect);
|
|
|
|
}
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
2022-05-24 13:19:36 -07:00
|
|
|
SDL_UnlockSurface(a1);
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
// NOTE: Unused.
|
|
|
|
//
|
|
|
|
// 0x486A98
|
|
|
|
void _movieSetFrameGrabFunc(MovieFrameGrabProc* proc)
|
|
|
|
{
|
|
|
|
_movieFrameGrabFunc = proc;
|
|
|
|
}
|
|
|
|
|
|
|
|
// NOTE: Unused.
|
|
|
|
//
|
|
|
|
// 0x486AA0
|
|
|
|
void _movieSetCaptureFrameFunc(MovieCaptureFrameProc* func)
|
|
|
|
{
|
|
|
|
_movieCaptureFrameFunc = func;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x486B68
|
|
|
|
int _movieScaleSubRect(int win, unsigned char* data, int width, int height, int pitch)
|
|
|
|
{
|
|
|
|
int windowWidth = windowGetWidth(win);
|
|
|
|
unsigned char* windowBuffer = windowGetBuffer(win) + windowWidth * _movieY + _movieX;
|
|
|
|
if (width * 4 / 3 > _movieW) {
|
|
|
|
gMovieFlags |= 0x01;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int v1 = width / 3;
|
|
|
|
for (int y = 0; y < height; y++) {
|
|
|
|
int x;
|
|
|
|
for (x = 0; x < v1; x++) {
|
|
|
|
unsigned int value = data[0];
|
|
|
|
value |= data[1] << 8;
|
|
|
|
value |= data[2] << 16;
|
|
|
|
value |= data[2] << 24;
|
|
|
|
|
|
|
|
*(unsigned int*)windowBuffer = value;
|
|
|
|
|
|
|
|
windowBuffer += 4;
|
|
|
|
data += 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (x = x * 3; x < width; x++) {
|
|
|
|
*windowBuffer++ = *data++;
|
|
|
|
}
|
|
|
|
|
|
|
|
data += pitch - width;
|
|
|
|
windowBuffer += windowWidth - _movieW;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
// 0x486C74
|
2022-07-29 06:04:05 -07:00
|
|
|
int _movieScaleSubRectAlpha(int win, unsigned char* data, int width, int height, int pitch)
|
|
|
|
{
|
|
|
|
gMovieFlags |= 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// NOTE: Uncollapsed 0x486C74.
|
|
|
|
int _movieScaleWindowAlpha(int win, unsigned char* data, int width, int height, int pitch)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
gMovieFlags |= 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x486C80
|
2022-07-29 06:04:05 -07:00
|
|
|
int _blitAlpha(int win, unsigned char* data, int width, int height, int pitch)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-29 06:04:05 -07:00
|
|
|
int windowWidth = windowGetWidth(win);
|
|
|
|
unsigned char* windowBuffer = windowGetBuffer(win);
|
|
|
|
_alphaBltBuf(data, width, height, pitch, _alphaWindowBuf, _alphaBuf, windowBuffer + windowWidth * _movieY + _movieX, windowWidth);
|
|
|
|
return 1;
|
|
|
|
}
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
// 0x486CD4
|
|
|
|
int _movieScaleWindow(int win, unsigned char* data, int width, int height, int pitch)
|
|
|
|
{
|
|
|
|
int windowWidth = windowGetWidth(win);
|
|
|
|
if (width != 3 * windowWidth / 4) {
|
|
|
|
gMovieFlags |= 1;
|
|
|
|
return 0;
|
|
|
|
}
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
unsigned char* windowBuffer = windowGetBuffer(win);
|
|
|
|
for (int y = 0; y < height; y++) {
|
|
|
|
int scaledWidth = width / 3;
|
|
|
|
for (int x = 0; x < scaledWidth; x++) {
|
|
|
|
unsigned int value = data[0];
|
|
|
|
value |= data[1] << 8;
|
|
|
|
value |= data[2] << 16;
|
|
|
|
value |= data[3] << 24;
|
|
|
|
|
|
|
|
*(unsigned int*)windowBuffer = value;
|
|
|
|
|
|
|
|
windowBuffer += 4;
|
|
|
|
data += 3;
|
|
|
|
}
|
|
|
|
data += pitch - width;
|
|
|
|
}
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x486D84
|
2022-07-29 06:04:05 -07:00
|
|
|
int _blitNormal(int win, unsigned char* data, int width, int height, int pitch)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-29 06:04:05 -07:00
|
|
|
int windowWidth = windowGetWidth(win);
|
|
|
|
unsigned char* windowBuffer = windowGetBuffer(win);
|
|
|
|
_drawScaled(windowBuffer + windowWidth * _movieY + _movieX, _movieW, _movieH, windowWidth, data, width, height, pitch);
|
2022-05-19 01:51:26 -07:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x486DDC
|
2022-06-18 22:48:30 -07:00
|
|
|
static void movieSetPaletteEntriesImpl(unsigned char* palette, int start, int end)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
if (end != 0) {
|
|
|
|
gMovieSetPaletteEntriesProc(palette + start * 3, start, end + start - 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x486E08
|
2022-06-18 22:48:30 -07:00
|
|
|
static int _noop()
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// initMovie
|
|
|
|
// 0x486E0C
|
|
|
|
void movieInit()
|
|
|
|
{
|
|
|
|
movieLibSetMemoryProcs(movieMallocImpl, movieFreeImpl);
|
|
|
|
movieLibSetPaletteEntriesProc(movieSetPaletteEntriesImpl);
|
|
|
|
_MVE_sfSVGA(640, 480, 480, 0, 0, 0, 0, 0, 0);
|
|
|
|
movieLibSetReadProc(movieReadImpl);
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x486E98
|
2022-06-18 22:48:30 -07:00
|
|
|
static void _cleanupMovie(int a1)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
if (!_running) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
if (_endMovieFunc != NULL) {
|
|
|
|
_endMovieFunc(gMovieWindow, _movieX, _movieY, _movieW, _movieH);
|
|
|
|
}
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
int frame;
|
|
|
|
int dropped;
|
|
|
|
_MVE_rmFrameCounts(&frame, &dropped);
|
|
|
|
debugPrint("Frames %d, dropped %d\n", frame, dropped);
|
|
|
|
|
|
|
|
if (_lastMovieBuffer != NULL) {
|
|
|
|
internal_free_safe(_lastMovieBuffer, __FILE__, __LINE__); // "..\\int\\MOVIE.C", 787
|
|
|
|
_lastMovieBuffer = NULL;
|
|
|
|
}
|
|
|
|
|
2022-05-24 13:19:36 -07:00
|
|
|
if (gMovieSdlSurface != NULL) {
|
|
|
|
if (SDL_LockSurface(gMovieSdlSurface) == 0) {
|
2022-05-21 08:22:03 -07:00
|
|
|
_lastMovieBuffer = (unsigned char*)internal_malloc_safe(_lastMovieBH * _lastMovieBW, __FILE__, __LINE__); // "..\\int\\MOVIE.C", 802
|
2022-05-24 13:19:36 -07:00
|
|
|
blitBufferToBuffer((unsigned char*)gMovieSdlSurface->pixels + gMovieSdlSurface->pitch * _lastMovieSX + _lastMovieSY, _lastMovieBW, _lastMovieBH, gMovieSdlSurface->pitch, _lastMovieBuffer, _lastMovieBW);
|
|
|
|
SDL_UnlockSurface(gMovieSdlSurface);
|
2022-05-19 01:51:26 -07:00
|
|
|
} else {
|
|
|
|
debugPrint("Couldn't lock movie surface\n");
|
|
|
|
}
|
|
|
|
|
2022-05-24 13:19:36 -07:00
|
|
|
gMovieSdlSurface = NULL;
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (a1) {
|
|
|
|
_MVE_rmEndMovie();
|
|
|
|
}
|
|
|
|
|
|
|
|
_MVE_ReleaseMem();
|
|
|
|
|
|
|
|
fileClose(gMovieFileStream);
|
|
|
|
|
|
|
|
if (_alphaWindowBuf != NULL) {
|
|
|
|
blitBufferToBuffer(_alphaWindowBuf, _movieW, _movieH, _movieW, windowGetBuffer(gMovieWindow) + _movieY * windowGetWidth(gMovieWindow) + _movieX, windowGetWidth(gMovieWindow));
|
|
|
|
windowRefreshRect(gMovieWindow, &_movieRect);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_alphaHandle != NULL) {
|
|
|
|
fileClose(_alphaHandle);
|
|
|
|
_alphaHandle = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_alphaBuf != NULL) {
|
|
|
|
internal_free_safe(_alphaBuf, __FILE__, __LINE__); // "..\\int\\MOVIE.C", 840
|
|
|
|
_alphaBuf = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_alphaWindowBuf != NULL) {
|
|
|
|
internal_free_safe(_alphaWindowBuf, __FILE__, __LINE__); // "..\\int\\MOVIE.C", 845
|
|
|
|
_alphaWindowBuf = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (gMovieSubtitleHead != NULL) {
|
|
|
|
MovieSubtitleListNode* next = gMovieSubtitleHead->next;
|
|
|
|
internal_free_safe(gMovieSubtitleHead->text, __FILE__, __LINE__); // "..\\int\\MOVIE.C", 851
|
|
|
|
internal_free_safe(gMovieSubtitleHead, __FILE__, __LINE__); // "..\\int\\MOVIE.C", 852
|
|
|
|
gMovieSubtitleHead = next;
|
|
|
|
}
|
|
|
|
|
|
|
|
_running = 0;
|
|
|
|
_movieSubRectFlag = 0;
|
|
|
|
_movieScaleFlag = 0;
|
|
|
|
_movieAlphaFlag = 0;
|
|
|
|
gMovieFlags = 0;
|
|
|
|
gMovieWindow = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x48711C
|
|
|
|
void movieExit()
|
|
|
|
{
|
|
|
|
_cleanupMovie(1);
|
|
|
|
|
|
|
|
if (_lastMovieBuffer) {
|
|
|
|
internal_free_safe(_lastMovieBuffer, __FILE__, __LINE__); // "..\\int\\MOVIE.C", 869
|
|
|
|
_lastMovieBuffer = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x487150
|
|
|
|
void _movieStop()
|
|
|
|
{
|
|
|
|
if (_running) {
|
|
|
|
gMovieFlags |= MOVIE_EXTENDED_FLAG_0x02;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x487164
|
|
|
|
int movieSetFlags(int flags)
|
|
|
|
{
|
|
|
|
if ((flags & MOVIE_FLAG_0x04) != 0) {
|
|
|
|
gMovieFlags |= MOVIE_EXTENDED_FLAG_0x04 | MOVIE_EXTENDED_FLAG_0x08;
|
|
|
|
} else {
|
|
|
|
gMovieFlags &= ~MOVIE_EXTENDED_FLAG_0x08;
|
|
|
|
if ((flags & MOVIE_FLAG_0x02) != 0) {
|
|
|
|
gMovieFlags |= MOVIE_EXTENDED_FLAG_0x04;
|
|
|
|
} else {
|
|
|
|
gMovieFlags &= ~MOVIE_EXTENDED_FLAG_0x04;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((flags & MOVIE_FLAG_0x01) != 0) {
|
|
|
|
_movieScaleFlag = 1;
|
|
|
|
|
|
|
|
if ((gMovieFlags & MOVIE_EXTENDED_FLAG_0x04) != 0) {
|
|
|
|
_sub_4F4BB(3);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
_movieScaleFlag = 0;
|
|
|
|
|
|
|
|
if ((gMovieFlags & MOVIE_EXTENDED_FLAG_0x04) != 0) {
|
|
|
|
_sub_4F4BB(4);
|
|
|
|
} else {
|
|
|
|
gMovieFlags &= ~MOVIE_EXTENDED_FLAG_0x08;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((flags & MOVIE_FLAG_0x08) != 0) {
|
|
|
|
gMovieFlags |= MOVIE_EXTENDED_FLAG_0x10;
|
|
|
|
} else {
|
|
|
|
gMovieFlags &= ~MOVIE_EXTENDED_FLAG_0x10;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x48725C
|
|
|
|
void _movieSetPaletteFunc(MovieSetPaletteEntriesProc* proc)
|
|
|
|
{
|
|
|
|
gMovieSetPaletteEntriesProc = proc != NULL ? proc : _setSystemPaletteEntries;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x487274
|
|
|
|
void movieSetPaletteProc(MovieSetPaletteProc* proc)
|
|
|
|
{
|
|
|
|
gMoviePaletteProc = proc;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x4872E8
|
2022-06-18 22:48:30 -07:00
|
|
|
static void _cleanupLast()
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
if (_lastMovieBuffer != NULL) {
|
|
|
|
internal_free_safe(_lastMovieBuffer, __FILE__, __LINE__); // "..\\int\\MOVIE.C", 981
|
|
|
|
_lastMovieBuffer = NULL;
|
|
|
|
}
|
|
|
|
|
2022-05-24 13:19:36 -07:00
|
|
|
gMovieSdlSurface = NULL;
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// 0x48731C
|
2022-06-18 22:48:30 -07:00
|
|
|
static File* movieOpen(char* filePath)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
gMovieFileStream = fileOpen(filePath, "rb");
|
|
|
|
if (gMovieFileStream == NULL) {
|
|
|
|
if (_failedOpenFunc == NULL) {
|
|
|
|
debugPrint("Couldn't find movie file %s\n", filePath);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (gMovieFileStream == NULL && _failedOpenFunc(filePath) != 0) {
|
|
|
|
gMovieFileStream = fileOpen(filePath, "rb");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return gMovieFileStream;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x487380
|
2022-06-18 22:48:30 -07:00
|
|
|
static void movieLoadSubtitles(char* filePath)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-05-21 13:04:08 -07:00
|
|
|
_subtitleW = windowGetWidth(gMovieWindow);
|
2022-05-19 01:51:26 -07:00
|
|
|
_subtitleH = fontGetLineHeight() + 4;
|
|
|
|
|
|
|
|
if (gMovieBuildSubtitleFilePathProc != NULL) {
|
|
|
|
filePath = gMovieBuildSubtitleFilePathProc(filePath);
|
|
|
|
}
|
|
|
|
|
2022-05-28 02:34:49 -07:00
|
|
|
char path[COMPAT_MAX_PATH];
|
2022-05-19 01:51:26 -07:00
|
|
|
strcpy(path, filePath);
|
|
|
|
|
|
|
|
debugPrint("Opening subtitle file %s\n", path);
|
|
|
|
File* stream = fileOpen(path, "r");
|
|
|
|
if (stream == NULL) {
|
|
|
|
debugPrint("Couldn't open subtitle file %s\n", path);
|
|
|
|
gMovieFlags &= ~MOVIE_EXTENDED_FLAG_0x10;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
MovieSubtitleListNode* prev = NULL;
|
|
|
|
int subtitleCount = 0;
|
|
|
|
while (!fileEof(stream)) {
|
|
|
|
char string[260];
|
|
|
|
string[0] = '\0';
|
|
|
|
fileReadString(string, 259, stream);
|
|
|
|
if (*string == '\0') {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2022-05-21 08:22:03 -07:00
|
|
|
MovieSubtitleListNode* subtitle = (MovieSubtitleListNode*)internal_malloc_safe(sizeof(*subtitle), __FILE__, __LINE__); // "..\\int\\MOVIE.C", 1050
|
2022-05-19 01:51:26 -07:00
|
|
|
subtitle->next = NULL;
|
|
|
|
|
|
|
|
subtitleCount++;
|
|
|
|
|
|
|
|
char* pch;
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
pch = strchr(string, '\n');
|
|
|
|
if (pch != NULL) {
|
2022-05-19 01:51:26 -07:00
|
|
|
*pch = '\0';
|
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
pch = strchr(string, '\r');
|
|
|
|
if (pch != NULL) {
|
2022-05-19 01:51:26 -07:00
|
|
|
*pch = '\0';
|
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
pch = strchr(string, ':');
|
|
|
|
if (pch != NULL) {
|
2022-05-19 01:51:26 -07:00
|
|
|
*pch = '\0';
|
|
|
|
subtitle->num = atoi(string);
|
|
|
|
subtitle->text = strdup_safe(pch + 1, __FILE__, __LINE__); // "..\\int\\MOVIE.C", 1058
|
|
|
|
|
|
|
|
if (prev != NULL) {
|
|
|
|
prev->next = subtitle;
|
|
|
|
} else {
|
|
|
|
gMovieSubtitleHead = subtitle;
|
|
|
|
}
|
|
|
|
|
|
|
|
prev = subtitle;
|
|
|
|
} else {
|
|
|
|
debugPrint("subtitle: couldn't parse %s\n", string);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fileClose(stream);
|
|
|
|
|
|
|
|
debugPrint("Read %d subtitles\n", subtitleCount);
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x48755C
|
2022-06-18 22:48:30 -07:00
|
|
|
static void movieRenderSubtitles()
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
if (gMovieSubtitleHead == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((gMovieFlags & MOVIE_EXTENDED_FLAG_0x10) == 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int v1 = fontGetLineHeight();
|
|
|
|
int v2 = (480 - _lastMovieH - _lastMovieY - v1) / 2 + _lastMovieH + _lastMovieY;
|
|
|
|
|
|
|
|
if (_subtitleH + v2 > _windowGetYres()) {
|
|
|
|
_subtitleH = _windowGetYres() - v2;
|
|
|
|
}
|
|
|
|
|
|
|
|
int frame;
|
|
|
|
int dropped;
|
|
|
|
_MVE_rmFrameCounts(&frame, &dropped);
|
|
|
|
|
|
|
|
while (gMovieSubtitleHead != NULL) {
|
|
|
|
if (frame < gMovieSubtitleHead->num) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
MovieSubtitleListNode* next = gMovieSubtitleHead->next;
|
|
|
|
|
|
|
|
windowFill(gMovieWindow, 0, v2, _subtitleW, _subtitleH, 0);
|
|
|
|
|
|
|
|
int oldFont;
|
|
|
|
if (gMovieSubtitlesFont != -1) {
|
|
|
|
oldFont = fontGetCurrent();
|
|
|
|
fontSetCurrent(gMovieSubtitlesFont);
|
|
|
|
}
|
|
|
|
|
|
|
|
int colorIndex = (gMovieSubtitlesColorR << 10) | (gMovieSubtitlesColorG << 5) | gMovieSubtitlesColorB;
|
|
|
|
_windowWrapLine(gMovieWindow, gMovieSubtitleHead->text, _subtitleW, _subtitleH, 0, v2, _colorTable[colorIndex] | 0x2000000, TEXT_ALIGNMENT_CENTER);
|
|
|
|
|
|
|
|
Rect rect;
|
|
|
|
rect.right = _subtitleW;
|
|
|
|
rect.top = v2;
|
|
|
|
rect.bottom = v2 + _subtitleH;
|
|
|
|
rect.left = 0;
|
|
|
|
windowRefreshRect(gMovieWindow, &rect);
|
|
|
|
|
|
|
|
internal_free_safe(gMovieSubtitleHead->text, __FILE__, __LINE__); // "..\\int\\MOVIE.C", 1108
|
|
|
|
internal_free_safe(gMovieSubtitleHead, __FILE__, __LINE__); // "..\\int\\MOVIE.C", 1109
|
|
|
|
|
|
|
|
gMovieSubtitleHead = next;
|
|
|
|
|
|
|
|
if (gMovieSubtitlesFont != -1) {
|
|
|
|
fontSetCurrent(oldFont);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x487710
|
2022-06-18 22:48:30 -07:00
|
|
|
static int _movieStart(int win, char* filePath, int (*a3)())
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
int v15;
|
|
|
|
int v16;
|
|
|
|
int v17;
|
|
|
|
|
|
|
|
if (_running) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
_cleanupLast();
|
|
|
|
|
|
|
|
gMovieFileStream = movieOpen(filePath);
|
|
|
|
if (gMovieFileStream == NULL) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2022-07-05 01:00:55 -07:00
|
|
|
gMovieFileStreamPointerKey = ptrToInt(gMovieFileStream);
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
gMovieWindow = win;
|
|
|
|
_running = 1;
|
|
|
|
gMovieFlags &= ~MOVIE_EXTENDED_FLAG_0x01;
|
|
|
|
|
|
|
|
if ((gMovieFlags & MOVIE_EXTENDED_FLAG_0x10) != 0) {
|
|
|
|
movieLoadSubtitles(filePath);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((gMovieFlags & MOVIE_EXTENDED_FLAG_0x04) != 0) {
|
|
|
|
debugPrint("Direct ");
|
|
|
|
windowGetRect(gMovieWindow, &gMovieWindowRect);
|
|
|
|
debugPrint("Playing at (%d, %d) ", _movieX + gMovieWindowRect.left, _movieY + gMovieWindowRect.top);
|
|
|
|
_MVE_rmCallbacks(a3);
|
|
|
|
_MVE_sfCallbacks(movieDirectImpl);
|
|
|
|
|
|
|
|
v17 = 0;
|
|
|
|
v16 = _movieY + gMovieWindowRect.top;
|
|
|
|
v15 = _movieX + gMovieWindowRect.left;
|
|
|
|
} else {
|
|
|
|
debugPrint("Buffered ");
|
|
|
|
_MVE_rmCallbacks(a3);
|
|
|
|
_MVE_sfCallbacks(movieBufferedImpl);
|
|
|
|
v17 = 0;
|
|
|
|
v16 = 0;
|
|
|
|
v15 = 0;
|
|
|
|
}
|
|
|
|
|
2022-07-05 01:00:55 -07:00
|
|
|
_MVE_rmPrepMovie(gMovieFileStreamPointerKey, v15, v16, v17);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
if (_movieScaleFlag) {
|
|
|
|
debugPrint("scaled\n");
|
|
|
|
} else {
|
|
|
|
debugPrint("not scaled\n");
|
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
if (_startMovieFunc != NULL) {
|
|
|
|
_startMovieFunc(gMovieWindow);
|
|
|
|
}
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
if (_alphaHandle != NULL) {
|
2022-07-29 06:04:05 -07:00
|
|
|
int size;
|
|
|
|
fileReadInt32(_alphaHandle, &size);
|
|
|
|
|
|
|
|
short tmp;
|
|
|
|
fileReadInt16(_alphaHandle, &tmp);
|
|
|
|
fileReadInt16(_alphaHandle, &tmp);
|
|
|
|
|
|
|
|
_alphaBuf = (unsigned char*)internal_malloc_safe(size, __FILE__, __LINE__); // "..\\int\\MOVIE.C", 1178
|
|
|
|
_alphaWindowBuf = (unsigned char*)internal_malloc_safe(_movieH * _movieW, __FILE__, __LINE__); // "..\\int\\MOVIE.C", 1179
|
|
|
|
|
|
|
|
unsigned char* windowBuffer = windowGetBuffer(gMovieWindow);
|
|
|
|
blitBufferToBuffer(windowBuffer + windowGetWidth(gMovieWindow) * _movieY + _movieX,
|
|
|
|
_movieW,
|
|
|
|
_movieH,
|
|
|
|
windowGetWidth(gMovieWindow),
|
|
|
|
_alphaWindowBuf,
|
|
|
|
_movieW);
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
_movieRect.left = _movieX;
|
|
|
|
_movieRect.top = _movieY;
|
|
|
|
_movieRect.right = _movieW + _movieX;
|
|
|
|
_movieRect.bottom = _movieH + _movieY;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x487964
|
2022-06-18 22:48:30 -07:00
|
|
|
static bool _localMovieCallback()
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
movieRenderSubtitles();
|
|
|
|
|
|
|
|
if (_movieCallback != NULL) {
|
|
|
|
_movieCallback();
|
|
|
|
}
|
|
|
|
|
|
|
|
return _get_input() != -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x487AC8
|
|
|
|
int _movieRun(int win, char* filePath)
|
|
|
|
{
|
|
|
|
if (_running) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
_movieX = 0;
|
|
|
|
_movieY = 0;
|
|
|
|
_movieOffset = 0;
|
|
|
|
_movieW = windowGetWidth(win);
|
|
|
|
_movieH = windowGetHeight(win);
|
|
|
|
_movieSubRectFlag = 0;
|
|
|
|
return _movieStart(win, filePath, _noop);
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x487B1C
|
|
|
|
int _movieRunRect(int win, char* filePath, int a3, int a4, int a5, int a6)
|
|
|
|
{
|
|
|
|
if (_running) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
_movieX = a3;
|
|
|
|
_movieY = a4;
|
|
|
|
_movieOffset = a3 + a4 * windowGetWidth(win);
|
|
|
|
_movieW = a5;
|
|
|
|
_movieH = a6;
|
|
|
|
_movieSubRectFlag = 1;
|
|
|
|
|
|
|
|
return _movieStart(win, filePath, _noop);
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x487B7C
|
2022-06-18 22:48:30 -07:00
|
|
|
static int _stepMovie()
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
if (_alphaHandle != NULL) {
|
|
|
|
int size;
|
|
|
|
fileReadInt32(_alphaHandle, &size);
|
|
|
|
fileRead(_alphaBuf, 1, size, _alphaHandle);
|
|
|
|
}
|
|
|
|
|
|
|
|
int v1 = _MVE_rmStepMovie();
|
|
|
|
if (v1 != -1) {
|
|
|
|
movieRenderSubtitles();
|
|
|
|
}
|
|
|
|
|
|
|
|
return v1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x487BC8
|
|
|
|
void movieSetBuildSubtitleFilePathProc(MovieBuildSubtitleFilePathProc* proc)
|
|
|
|
{
|
|
|
|
gMovieBuildSubtitleFilePathProc = proc;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x487BD0
|
|
|
|
void movieSetVolume(int volume)
|
|
|
|
{
|
2022-07-12 02:09:53 -07:00
|
|
|
int normalizedVolume = _soundVolumeHMItoDirectSound(volume);
|
|
|
|
movieLibSetVolume(normalizedVolume);
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// 0x487BEC
|
|
|
|
void _movieUpdate()
|
|
|
|
{
|
|
|
|
if (!_running) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((gMovieFlags & MOVIE_EXTENDED_FLAG_0x02) != 0) {
|
|
|
|
debugPrint("Movie aborted\n");
|
|
|
|
_cleanupMovie(1);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((gMovieFlags & MOVIE_EXTENDED_FLAG_0x01) != 0) {
|
|
|
|
debugPrint("Movie error\n");
|
|
|
|
_cleanupMovie(1);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_stepMovie() == -1) {
|
|
|
|
_cleanupMovie(1);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gMoviePaletteProc != NULL) {
|
|
|
|
int frame;
|
|
|
|
int dropped;
|
|
|
|
_MVE_rmFrameCounts(&frame, &dropped);
|
|
|
|
gMoviePaletteProc(frame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x487C88
|
|
|
|
int _moviePlaying()
|
|
|
|
{
|
|
|
|
return _running;
|
|
|
|
}
|