Commit 86cc9263 authored by anotherguest's avatar anotherguest

Updated scene playback with more animation attributes and types. Now playback...

Updated scene playback with more animation attributes and types. Now playback ][ frames which is full screen frames. Two types of frames missing FF and RC frames. These are the only frame left that are used.
parent 850a0675
......@@ -688,7 +688,7 @@ int main(int argc, char *argv[]) {
// Show the startup cutscene
/* try {
try {
scene = new Scene(F_STARTUP_0SC);
......@@ -709,7 +709,7 @@ int main(int argc, char *argv[]) {
}
delete scene;*/
delete scene;
// Load the menu
......
......@@ -36,6 +36,34 @@
#include "io/gfx/video.h"
#include "io/sound.h"
SceneFrame::SceneFrame(int frameType, unsigned char* frameData, int frameSize) {
soundId = -1;
this->frameData = frameData;
this->frameType = frameType;
this->frameSize = frameSize;
prev = NULL;
next = NULL;
}
SceneFrame::~SceneFrame() {
delete [] frameData;
if (next) delete next;
}
void SceneAnimation::addFrame(int frameType, unsigned char* frameData, int frameSize) {
SceneFrame* frame = new SceneFrame(frameType, frameData, frameSize);
if(sceneFrames == NULL) {
sceneFrames = frame;
}
else {
frame->prev = lastFrame;
lastFrame->next = frame;
}
lastFrame = frame;
frames++;
}
/**
* This is the 0sc format
* Offset, Size (hex), type
......@@ -53,12 +81,18 @@ SceneAnimation::SceneAnimation (SceneAnimation* newNext)
{
next = newNext;
background = NULL;
lastFrame = NULL;
sceneFrames = NULL;
frames = 0;
reverseAnimation = 0;
}
SceneAnimation::~SceneAnimation ()
{
if (next) delete next;
if(sceneFrames) delete sceneFrames;
if (background) SDL_FreeSurface(background);
}
......@@ -201,13 +235,18 @@ Scene::~Scene () {
}
int Scene::play () {
SDL_Rect dst;
unsigned int sceneIndex = 0;
SceneImage *image;
SceneAnimation* animation;
SceneFrame* currentFrame = NULL;
SceneFrame* lastFrame = NULL;
int frameDelay = 0;
int prevFrame = 0;
int continueToNextPage = 0;
unsigned int pageTime = pages[sceneIndex].pageTime;
unsigned int lastTicks = globalTicks;
int newpage = true;
......@@ -226,6 +265,7 @@ int Scene::play () {
int upOrLeft = 0;
int downOrRight = 0;
if(pages[sceneIndex].askForYesNo) {
// Should check for Y also
downOrRight = controls.release(C_ENTER) || controls.release(C_YES);;
......@@ -235,7 +275,7 @@ int Scene::play () {
}
if ((sceneIndex > 0 && upOrLeft) ||
downOrRight ||
downOrRight || continueToNextPage ||
((globalTicks-lastTicks) >= pageTime * 1000 && pageTime != 256 && pageTime != 0)) {
if(pages[sceneIndex].stopMusic) {
......@@ -252,7 +292,7 @@ int Scene::play () {
newpage = true;
pageTime = pages[sceneIndex].pageTime;
continueToNextPage = 0;
}
if (newpage) {
......@@ -306,17 +346,76 @@ int Scene::play () {
} else if (pages[sceneIndex].animIndex != -1) {
animation = animations;
while (animation && (animation->id != pages[sceneIndex].animIndex))
animation = animation->next;
if (animation && animation->background) {
dst.x = (canvasW - SW) >> 1;
dst.y = (canvasH - SH) >> 1;
SDL_BlitSurface(animation->background, NULL, canvas, &dst);
}
if(currentFrame == NULL) {
animation = animations;
while (animation && (animation->id != pages[sceneIndex].animIndex))
animation = animation->next;
if (animation && animation->background) {
dst.x = (canvasW - SW) >> 1;
dst.y = (canvasH - SH) >> 1;
frameDelay = 1000/(pages[sceneIndex].animSpeed>>8);
SDL_BlitSurface(animation->background, NULL, canvas, &dst);
currentFrame = animation->sceneFrames;
SDL_Delay(frameDelay);
}
}
else {
// Upload pixel data to the surface
if (SDL_MUSTLOCK(animation->background)) SDL_LockSurface(animation->background);
switch(currentFrame->frameType)
{
case ESquareAniHeader:
{
loadCompactedMem(currentFrame->frameSize, currentFrame->frameData,(unsigned char*) animation->background->pixels, SW, SH);
}
break;
default:
LOG("Scene::Play unknown type", currentFrame->frameType);
break;
}
if (SDL_MUSTLOCK(animation->background)) SDL_UnlockSurface(animation->background);
dst.x = (canvasW - SW) >> 1;
dst.y = (canvasH - SH) >> 1;
SDL_BlitSurface(animation->background, NULL, canvas, &dst);
if(currentFrame->soundId != -1 && animation->noSounds > 0) {
LOG("PLAY SOUND NAME",animation->soundNames[currentFrame->soundId-1]);
// Search for matching sound
for (int y = 0; y < nSounds ; y++) {
if (!strcmp(animation->soundNames[currentFrame->soundId-1], sounds[y].name)) {
playSound(y);
break;
}
}
}
lastFrame = currentFrame;
if(prevFrame) {
currentFrame = currentFrame->prev;
}
else {
currentFrame = currentFrame->next;
}
SDL_Delay(frameDelay);
if(currentFrame == NULL && animation->reverseAnimation) {
prevFrame = 1-prevFrame;
if(prevFrame) {
currentFrame = lastFrame->prev;
}
else {
currentFrame = lastFrame->next;
}
}
else if(currentFrame == NULL && !pageTime && !pages[sceneIndex].askForYesNo && pages[sceneIndex].nextPageAfterAnim) {
continueToNextPage = 1;
}
}
} else clearScreen(0);
......
......@@ -30,6 +30,46 @@
// Enums
/**
11
1L
/0/0
PB
FF
RN
RB
RC
RL
RR
][
PL
AN
_E
MX
ST
SL
*/
enum ANIHeaders
{
E11AniHeader = 0x3131, // Background/start image
E1LAniHeader = 0x4c31,
EPBAniHeader = 0x4250,
EFFAniHeader = 0x4646, // Floodfill? or full frame?
ERNAniHeader = 0x4e52,
ERBAniHeader = 0x4252,
ERCAniHeader = 0x4352,
ERLAniHeader = 0x4c52,
ERRAniHeader = 0x5252,
E_EHeader = 0x455F, // ANI End
ESquareAniHeader = 0x5b5d,
EMXAniHeader = 0x584d,
ESTAniHeader = 0x5453, // Sound tag
ESoundListAniHeader = 0x4C53,
EPlayListAniHeader = 0x4C50
};
enum
{
ESignatureLength = 0x13,
......@@ -97,7 +137,8 @@ class ScenePage {
int animLoops;
int animSpeed;
int animIndex;
int animIndex;
int nextPageAfterAnim;
// Length of the scene in seconds, or if zero = anim complete, or 256 = user interaction
int pageTime;
......@@ -144,16 +185,34 @@ class SceneFont {
};
class SceneFrame
{
public:
SceneFrame(int frameType, unsigned char* frameData, int frameSize);
~SceneFrame();
int soundId;
unsigned int frameType;
unsigned char* frameData;
int frameSize;
SceneFrame* next;
SceneFrame* prev;
};
class SceneAnimation
{
public:
SceneAnimation (SceneAnimation* newNext);
~SceneAnimation ();
void addFrame(int frameType, unsigned char* frameData, int frameSize);
SDL_Surface* background;
SceneAnimation* next;
int id;
int noSounds;
char soundNames[16][10];
SceneAnimation (SceneAnimation* newNext);
~SceneAnimation ();
SceneFrame* sceneFrames;
SceneFrame* lastFrame;
int frames;
int reverseAnimation;
};
class Scene {
......@@ -175,7 +234,8 @@ class Scene {
void loadScripts (File* f);
void loadData (File* f);
void loadAni (File* f, int dataIndex);
void LoadCompacted(int& size, File* f, unsigned char* pixdata, int width, int height);
void loadCompacted(int& size, File* f, unsigned char* pixdata, int width, int height);
void loadCompactedMem(int& size, unsigned char* frameData, unsigned char* pixdata, int width, int height);
public:
Scene (const char* fileName);
~Scene ();
......
......@@ -33,45 +33,6 @@
#include <string.h>
/**
11
1L
/0/0
PB
FF
RN
RB
RC
RL
RR
][
PL
AN
_E
MX
ST
SL
*/
enum ANIHeaders
{
E11AniHeader = 0x3131, // Background/start image
E1LAniHeader = 0x4c31,
EPBAniHeader = 0x4250,
EFFAniHeader = 0x4646, // Floodfill? or full frame?
ERNAniHeader = 0x4e52,
ERBAniHeader = 0x4252,
ERCAniHeader = 0x4352,
ERLAniHeader = 0x4c52,
ERRAniHeader = 0x5252,
E_EHeader = 0x455F, // ANI End
ESquareAniHeader = 0x5b5d,
EMXAniHeader = 0x584d,
ESTAniHeader = 0x5453, // Sound tag
ESoundListAniHeader = 0x4C53,
EPlayListAniHeader = 0x4C50
};
/*
* $0x $... Next x + 1 bytes are 'literals'; each byte colors 1 column (Max val $3F)
* $4x $yy Next x + 1 columns drawn in color yy (Max value $7E)
......@@ -79,7 +40,7 @@ enum ANIHeaders
* $8x Next x + 1 pixels are skipped, they're already the right color (Max val $FE)
* $FF $xxxx Skip next xxxx pixels of picture, they're already the right color
*/
void Scene::LoadCompacted(int& size, File* f, unsigned char* pixdata, int width, int height) {
void Scene::loadCompacted(int& size, File* f, unsigned char* pixdata, int width, int height) {
int pixels = 0;
unsigned char* endpixdata = pixdata + (width*height);
unsigned char* fillstart = NULL;
......@@ -161,6 +122,91 @@ void Scene::LoadCompacted(int& size, File* f, unsigned char* pixdata, int width,
LOG("PL Compacts pixels", pixels);
}
void Scene::loadCompactedMem(int& size, unsigned char* frameData, unsigned char* pixdata, int width, int height) {
int pixels = 0;
unsigned char* endpixdata = pixdata + (width*height);
unsigned char* fillstart = NULL;
while (size > 0) {
unsigned char header = *frameData;frameData++;
switch (header) {
case 0x7F: {
unsigned short fillWidth = *frameData;frameData++;
fillWidth+=((unsigned short)(*frameData))<<8;frameData++;
unsigned char fillColor = *frameData;frameData++;
fillstart = pixdata;
while(fillstart+fillWidth < endpixdata) {
memset(fillstart, fillColor, fillWidth);
fillstart+=width;
}
pixdata+=fillWidth;
pixels+=fillWidth;
size -= 3;
}
break;
case 0xff: {
unsigned short skip = *frameData;frameData++;
skip+=((unsigned short)(*frameData))<<8;frameData++;
pixels+=skip;
pixdata+=skip;
size -= 2;
}
break;
default:
if(header&0x80) {
unsigned short skip =(header-0x80)+1;
pixels+=skip;
pixdata+=skip;
}
else if(header&0x40) {
unsigned char fillColor = *frameData;frameData++;
unsigned char fillWidth = ((header-0x40)+1);
fillstart = pixdata;
while(fillstart+fillWidth < endpixdata) {
memset(fillstart, fillColor, fillWidth);
fillstart+=width;
}
pixdata+=fillWidth;
pixels+=fillWidth;
size--;
}
else {
int copyWidth = (header & 0x3f)+1;
unsigned char color;
for(int col = 0;col < copyWidth;col++) {
color= *frameData;frameData++;
if(color != 0xff){
fillstart = pixdata;
while(fillstart < endpixdata) {
*fillstart = color;
fillstart+=width;
}
}
pixdata++;
pixels++;
size--;
}
}
break;
}
size--;
}
LOG("PL Compacts pixels", pixels);
}
void Scene::loadAni (File *f, int dataIndex) {
unsigned short int aniType = f->loadShort();// should be 0x02
......@@ -188,8 +234,7 @@ void Scene::loadAni (File *f, int dataIndex) {
}
} else if (type == EPlayListAniHeader) {// PL
} else if (type == EPlayListAniHeader) {// PL
int pos = f->tell();
int nextPos = f->tell();
LOG("PL Read position", pos);
......@@ -253,7 +298,7 @@ void Scene::loadAni (File *f, int dataIndex) {
unsigned char* pixels;
pixels = new unsigned char[SW* SH];
memset(pixels, 0, SW*SH);
LoadCompacted(size, f, pixels, SW, SH);
loadCompacted(size, f, pixels, SW, SH);
animations->background = createSurface(pixels, SW, SH);
delete[] pixels;
// Use the most recently loaded palette
......@@ -263,29 +308,30 @@ void Scene::loadAni (File *f, int dataIndex) {
case EFFAniHeader:
{
//LoadCompacted(size, f, (unsigned char*) animations->background->pixels, SW, SH);
unsigned char* blockData = f->loadBlock(size);
animations->addFrame(EFFAniHeader, blockData, size);
}
break;
case ERNAniHeader:
case ERBAniHeader:
case ERCAniHeader:
case ERBAniHeader:
case ERLAniHeader:
case EMXAniHeader:
break;
case ERRAniHeader: // Rotate.. has zero length info
case ERRAniHeader: // Reverse animation when end found
animations->reverseAnimation = 1;
break;
case ESquareAniHeader: // ][ Flip??
case ERCAniHeader:
{
unsigned char header = f->loadChar();
LOG("PL 5b5d block header", header);
unsigned short int value = f->loadShort();
LOG("PL 5b5d block value", value);
unsigned char* blockData = f->loadBlock(size);
animations->addFrame(ERCAniHeader, blockData, size);
}break;
case ESquareAniHeader: // Full screen animation frame, that does n't clear the screen first.
{
unsigned char* blockData = f->loadBlock(size);
animations->addFrame(ESquareAniHeader, blockData, size);
}
break;
......@@ -296,6 +342,7 @@ void Scene::loadAni (File *f, int dataIndex) {
unsigned char soundIndex = f->loadChar();
unsigned char soundNote = f->loadChar();
unsigned char soundOffset = f->loadChar();
animations->lastFrame->soundId = soundIndex;
LOG("PL Audio tag with index", soundIndex);
LOG("PL Audio tag play at ", soundNote);
LOG("PL Audio tag play offset ", soundOffset);
......@@ -474,16 +521,16 @@ void Scene::loadScripts (File *f) {
pages[loop].animSpeed = f->loadShort();
pages[loop].animIndex = f->loadShort();
LOG("ESceneAnimationSetting loops", pages[loop].animLoops);
LOG("ESceneAnimationSetting speed", pages[loop].animSpeed);
LOG("ESceneAnimationSetting anim num", pages[loop].animIndex);
LOG("ESceneAnimation loops", pages[loop].animLoops);
LOG("ESceneAnimation speed", pages[loop].animSpeed);
LOG("ESceneAnimation anim num", pages[loop].animIndex);
}
break;
case ESceneAnimationPlayAndContinue:
{
unsigned char playAndContinue = f->loadChar();
LOG("ESceneAnimationPlayAndContinue", playAndContinue);
pages[loop].nextPageAfterAnim = f->loadChar();
LOG("ESceneAnimationPlayAndContinue", pages[loop].nextPageAfterAnim);
}
break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment