271 lines
6.8 KiB
C
271 lines
6.8 KiB
C
|
#include "movie_effect.h"
|
||
|
|
||
|
#include "config.h"
|
||
|
#include "debug.h"
|
||
|
#include "memory.h"
|
||
|
#include "movie.h"
|
||
|
#include "palette.h"
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
// 0x5195F0
|
||
|
bool gMovieEffectsInitialized = false;
|
||
|
|
||
|
// 0x5195F4
|
||
|
MovieEffect* gMovieEffectHead = NULL;
|
||
|
|
||
|
// 0x638EC4
|
||
|
unsigned char _source_palette[768];
|
||
|
|
||
|
// 0x6391C4
|
||
|
bool _inside_fade;
|
||
|
|
||
|
// 0x487CC0
|
||
|
int movieEffectsInit()
|
||
|
{
|
||
|
if (gMovieEffectsInitialized) {
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
memset(_source_palette, 0, sizeof(_source_palette));
|
||
|
|
||
|
gMovieEffectsInitialized = true;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// 0x487CF4
|
||
|
void movieEffectsReset()
|
||
|
{
|
||
|
if (!gMovieEffectsInitialized) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
movieSetPaletteProc(NULL);
|
||
|
_movieSetPaletteFunc(NULL);
|
||
|
movieEffectsClear();
|
||
|
|
||
|
_inside_fade = false;
|
||
|
|
||
|
memset(_source_palette, 0, sizeof(_source_palette));
|
||
|
}
|
||
|
|
||
|
// 0x487D30
|
||
|
void movieEffectsExit()
|
||
|
{
|
||
|
if (!gMovieEffectsInitialized) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
movieSetPaletteProc(NULL);
|
||
|
_movieSetPaletteFunc(NULL);
|
||
|
movieEffectsClear();
|
||
|
|
||
|
_inside_fade = false;
|
||
|
|
||
|
memset(_source_palette, 0, sizeof(_source_palette));
|
||
|
}
|
||
|
|
||
|
// 0x487D7C
|
||
|
int movieEffectsLoad(const char* filePath)
|
||
|
{
|
||
|
if (!gMovieEffectsInitialized) {
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
movieSetPaletteProc(NULL);
|
||
|
_movieSetPaletteFunc(NULL);
|
||
|
movieEffectsClear();
|
||
|
_inside_fade = false;
|
||
|
memset(_source_palette, 0, sizeof(_source_palette));
|
||
|
|
||
|
if (filePath == NULL) {
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
Config config;
|
||
|
if (!configInit(&config)) {
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
int rc = -1;
|
||
|
|
||
|
char path[FILENAME_MAX];
|
||
|
strcpy(path, filePath);
|
||
|
|
||
|
char* pch = strrchr(path, '.');
|
||
|
if (pch != NULL) {
|
||
|
*pch = '\0';
|
||
|
}
|
||
|
|
||
|
strcpy(path + strlen(path), ".cfg");
|
||
|
|
||
|
if (!configRead(&config, path, true)) {
|
||
|
goto out;
|
||
|
}
|
||
|
|
||
|
int movieEffectsLength;
|
||
|
if (!configGetInt(&config, "info", "total_effects", &movieEffectsLength)) {
|
||
|
goto out;
|
||
|
}
|
||
|
|
||
|
int* movieEffectFrameList = internal_malloc(sizeof(*movieEffectFrameList) * movieEffectsLength);
|
||
|
if (movieEffectFrameList == NULL) {
|
||
|
goto out;
|
||
|
}
|
||
|
|
||
|
bool frameListRead;
|
||
|
if (movieEffectsLength >= 2) {
|
||
|
frameListRead = configGetIntList(&config, "info", "effect_frames", movieEffectFrameList, movieEffectsLength);
|
||
|
} else {
|
||
|
frameListRead = configGetInt(&config, "info", "effect_frames", &(movieEffectFrameList[0]));
|
||
|
}
|
||
|
|
||
|
if (frameListRead) {
|
||
|
int movieEffectsCreated = 0;
|
||
|
for (int index = 0; index < movieEffectsLength; index++) {
|
||
|
char section[20];
|
||
|
itoa(movieEffectFrameList[index], section, 10);
|
||
|
|
||
|
char* fadeTypeString;
|
||
|
if (!configGetString(&config, section, "fade_type", &fadeTypeString)) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
int fadeType = MOVIE_EFFECT_TYPE_NONE;
|
||
|
if (stricmp(fadeTypeString, "in") == 0) {
|
||
|
fadeType = MOVIE_EFFECT_TYPE_FADE_IN;
|
||
|
} else if (stricmp(fadeTypeString, "out") == 0) {
|
||
|
fadeType = MOVIE_EFFECT_TYPE_FADE_OUT;
|
||
|
}
|
||
|
|
||
|
if (fadeType == MOVIE_EFFECT_TYPE_NONE) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
int fadeColor[3];
|
||
|
if (!configGetIntList(&config, section, "fade_color", fadeColor, 3)) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
int steps;
|
||
|
if (!configGetInt(&config, section, "fade_steps", &steps)) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
MovieEffect* movieEffect = internal_malloc(sizeof(*movieEffect));
|
||
|
if (movieEffect == NULL) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
memset(movieEffect, 0, sizeof(*movieEffect));
|
||
|
movieEffect->startFrame = movieEffectFrameList[index];
|
||
|
movieEffect->endFrame = movieEffect->startFrame + steps - 1;
|
||
|
movieEffect->steps = steps;
|
||
|
movieEffect->fadeType = fadeType & 0xFF;
|
||
|
movieEffect->r = fadeColor[0] & 0xFF;
|
||
|
movieEffect->g = fadeColor[1] & 0xFF;
|
||
|
movieEffect->b = fadeColor[2] & 0xFF;
|
||
|
|
||
|
if (movieEffect->startFrame <= 1) {
|
||
|
_inside_fade = true;
|
||
|
}
|
||
|
|
||
|
movieEffect->next = gMovieEffectHead;
|
||
|
gMovieEffectHead = movieEffect;
|
||
|
|
||
|
movieEffectsCreated++;
|
||
|
}
|
||
|
|
||
|
if (movieEffectsCreated != 0) {
|
||
|
movieSetPaletteProc(_moviefx_callback_func);
|
||
|
_movieSetPaletteFunc(_moviefx_palette_func);
|
||
|
rc = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal_free(movieEffectFrameList);
|
||
|
|
||
|
out:
|
||
|
|
||
|
configFree(&config);
|
||
|
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
// 0x4880F0
|
||
|
void _moviefx_stop()
|
||
|
{
|
||
|
if (!gMovieEffectsInitialized) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
movieSetPaletteProc(NULL);
|
||
|
_movieSetPaletteFunc(NULL);
|
||
|
|
||
|
movieEffectsClear();
|
||
|
|
||
|
_inside_fade = false;
|
||
|
memset(_source_palette, 0, sizeof(_source_palette));
|
||
|
}
|
||
|
|
||
|
// 0x488144
|
||
|
void _moviefx_callback_func(int frame)
|
||
|
{
|
||
|
MovieEffect* movieEffect = gMovieEffectHead;
|
||
|
while (movieEffect != NULL) {
|
||
|
if (frame >= movieEffect->startFrame && frame <= movieEffect->endFrame) {
|
||
|
break;
|
||
|
}
|
||
|
movieEffect = movieEffect->next;
|
||
|
}
|
||
|
|
||
|
if (movieEffect != NULL) {
|
||
|
unsigned char palette[768];
|
||
|
int step = frame - movieEffect->startFrame + 1;
|
||
|
|
||
|
if (movieEffect->fadeType == MOVIE_EFFECT_TYPE_FADE_IN) {
|
||
|
for (int index = 0; index < 256; index++) {
|
||
|
palette[index * 3] = movieEffect->r - (step * (movieEffect->r - _source_palette[index * 3]) / movieEffect->steps);
|
||
|
palette[index * 3 + 1] = movieEffect->g - (step * (movieEffect->g - _source_palette[index * 3 + 1]) / movieEffect->steps);
|
||
|
palette[index * 3 + 2] = movieEffect->b - (step * (movieEffect->b - _source_palette[index * 3 + 2]) / movieEffect->steps);
|
||
|
}
|
||
|
} else {
|
||
|
for (int index = 0; index < 256; index++) {
|
||
|
palette[index * 3] = _source_palette[index * 3] - (step * (_source_palette[index * 3] - movieEffect->r) / movieEffect->steps);
|
||
|
palette[index * 3 + 1] = _source_palette[index * 3 + 1] - (step * (_source_palette[index * 3 + 1] - movieEffect->g) / movieEffect->steps);
|
||
|
palette[index * 3 + 2] = _source_palette[index * 3 + 2] - (step * (_source_palette[index * 3 + 2] - movieEffect->b) / movieEffect->steps);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
paletteSetEntries(palette);
|
||
|
}
|
||
|
|
||
|
_inside_fade = movieEffect != NULL;
|
||
|
}
|
||
|
|
||
|
// 0x4882AC
|
||
|
void _moviefx_palette_func(unsigned char* palette, int start, int end)
|
||
|
{
|
||
|
memcpy(_source_palette + 3 * start, palette, 3 * (end - start + 1));
|
||
|
|
||
|
if (!_inside_fade) {
|
||
|
paletteSetEntriesInRange(palette, start, end);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 0x488310
|
||
|
void movieEffectsClear()
|
||
|
{
|
||
|
MovieEffect* movieEffect = gMovieEffectHead;
|
||
|
while (movieEffect != NULL) {
|
||
|
MovieEffect* next = movieEffect->next;
|
||
|
internal_free(movieEffect);
|
||
|
movieEffect = next;
|
||
|
}
|
||
|
|
||
|
gMovieEffectHead = NULL;
|
||
|
}
|