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[]) { ...@@ -688,7 +688,7 @@ int main(int argc, char *argv[]) {
// Show the startup cutscene // Show the startup cutscene
/* try { try {
scene = new Scene(F_STARTUP_0SC); scene = new Scene(F_STARTUP_0SC);
...@@ -709,7 +709,7 @@ int main(int argc, char *argv[]) { ...@@ -709,7 +709,7 @@ int main(int argc, char *argv[]) {
} }
delete scene;*/ delete scene;
// Load the menu // Load the menu
......
...@@ -36,6 +36,34 @@ ...@@ -36,6 +36,34 @@
#include "io/gfx/video.h" #include "io/gfx/video.h"
#include "io/sound.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 * This is the 0sc format
* Offset, Size (hex), type * Offset, Size (hex), type
...@@ -53,12 +81,18 @@ SceneAnimation::SceneAnimation (SceneAnimation* newNext) ...@@ -53,12 +81,18 @@ SceneAnimation::SceneAnimation (SceneAnimation* newNext)
{ {
next = newNext; next = newNext;
background = NULL; background = NULL;
lastFrame = NULL;
sceneFrames = NULL;
frames = 0;
reverseAnimation = 0;
} }
SceneAnimation::~SceneAnimation () SceneAnimation::~SceneAnimation ()
{ {
if (next) delete next; if (next) delete next;
if(sceneFrames) delete sceneFrames;
if (background) SDL_FreeSurface(background); if (background) SDL_FreeSurface(background);
} }
...@@ -201,13 +235,18 @@ Scene::~Scene () { ...@@ -201,13 +235,18 @@ Scene::~Scene () {
} }
int Scene::play () { int Scene::play () {
SDL_Rect dst; SDL_Rect dst;
unsigned int sceneIndex = 0; unsigned int sceneIndex = 0;
SceneImage *image; SceneImage *image;
SceneAnimation* animation; 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 pageTime = pages[sceneIndex].pageTime;
unsigned int lastTicks = globalTicks; unsigned int lastTicks = globalTicks;
int newpage = true; int newpage = true;
...@@ -226,6 +265,7 @@ int Scene::play () { ...@@ -226,6 +265,7 @@ int Scene::play () {
int upOrLeft = 0; int upOrLeft = 0;
int downOrRight = 0; int downOrRight = 0;
if(pages[sceneIndex].askForYesNo) { if(pages[sceneIndex].askForYesNo) {
// Should check for Y also // Should check for Y also
downOrRight = controls.release(C_ENTER) || controls.release(C_YES);; downOrRight = controls.release(C_ENTER) || controls.release(C_YES);;
...@@ -235,7 +275,7 @@ int Scene::play () { ...@@ -235,7 +275,7 @@ int Scene::play () {
} }
if ((sceneIndex > 0 && upOrLeft) || if ((sceneIndex > 0 && upOrLeft) ||
downOrRight || downOrRight || continueToNextPage ||
((globalTicks-lastTicks) >= pageTime * 1000 && pageTime != 256 && pageTime != 0)) { ((globalTicks-lastTicks) >= pageTime * 1000 && pageTime != 256 && pageTime != 0)) {
if(pages[sceneIndex].stopMusic) { if(pages[sceneIndex].stopMusic) {
...@@ -252,7 +292,7 @@ int Scene::play () { ...@@ -252,7 +292,7 @@ int Scene::play () {
newpage = true; newpage = true;
pageTime = pages[sceneIndex].pageTime; pageTime = pages[sceneIndex].pageTime;
continueToNextPage = 0;
} }
if (newpage) { if (newpage) {
...@@ -306,17 +346,76 @@ int Scene::play () { ...@@ -306,17 +346,76 @@ int Scene::play () {
} else if (pages[sceneIndex].animIndex != -1) { } else if (pages[sceneIndex].animIndex != -1) {
animation = animations; if(currentFrame == NULL) {
animation = animations;
while (animation && (animation->id != pages[sceneIndex].animIndex))
animation = animation->next; while (animation && (animation->id != pages[sceneIndex].animIndex))
animation = animation->next;
if (animation && animation->background) {
if (animation && animation->background) {
dst.x = (canvasW - SW) >> 1;
dst.y = (canvasH - SH) >> 1; dst.x = (canvasW - SW) >> 1;
SDL_BlitSurface(animation->background, NULL, canvas, &dst); 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); } else clearScreen(0);
......
...@@ -30,6 +30,46 @@ ...@@ -30,6 +30,46 @@
// Enums // 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 enum
{ {
ESignatureLength = 0x13, ESignatureLength = 0x13,
...@@ -97,7 +137,8 @@ class ScenePage { ...@@ -97,7 +137,8 @@ class ScenePage {
int animLoops; int animLoops;
int animSpeed; int animSpeed;
int animIndex; int animIndex;
int nextPageAfterAnim;
// Length of the scene in seconds, or if zero = anim complete, or 256 = user interaction // Length of the scene in seconds, or if zero = anim complete, or 256 = user interaction
int pageTime; int pageTime;
...@@ -144,16 +185,34 @@ class SceneFont { ...@@ -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 class SceneAnimation
{ {
public: public:
SceneAnimation (SceneAnimation* newNext);
~SceneAnimation ();
void addFrame(int frameType, unsigned char* frameData, int frameSize);
SDL_Surface* background; SDL_Surface* background;
SceneAnimation* next; SceneAnimation* next;
int id; int id;
int noSounds; int noSounds;
char soundNames[16][10]; char soundNames[16][10];
SceneAnimation (SceneAnimation* newNext); SceneFrame* sceneFrames;
~SceneAnimation (); SceneFrame* lastFrame;
int frames;
int reverseAnimation;
}; };
class Scene { class Scene {
...@@ -175,7 +234,8 @@ class Scene { ...@@ -175,7 +234,8 @@ class Scene {
void loadScripts (File* f); void loadScripts (File* f);
void loadData (File* f); void loadData (File* f);
void loadAni (File* f, int dataIndex); 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: public:
Scene (const char* fileName); Scene (const char* fileName);
~Scene (); ~Scene ();
......
...@@ -33,45 +33,6 @@ ...@@ -33,45 +33,6 @@
#include <string.h> #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) * $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) * $4x $yy Next x + 1 columns drawn in color yy (Max value $7E)
...@@ -79,7 +40,7 @@ enum ANIHeaders ...@@ -79,7 +40,7 @@ enum ANIHeaders
* $8x Next x + 1 pixels are skipped, they're already the right color (Max val $FE) * $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 * $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; int pixels = 0;
unsigned char* endpixdata = pixdata + (width*height); unsigned char* endpixdata = pixdata + (width*height);
unsigned char* fillstart = NULL; unsigned char* fillstart = NULL;
...@@ -161,6 +122,91 @@ void Scene::LoadCompacted(int& size, File* f, unsigned char* pixdata, int width, ...@@ -161,6 +122,91 @@ void Scene::LoadCompacted(int& size, File* f, unsigned char* pixdata, int width,
LOG("PL Compacts pixels", pixels); 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) { void Scene::loadAni (File *f, int dataIndex) {
unsigned short int aniType = f->loadShort();// should be 0x02 unsigned short int aniType = f->loadShort();// should be 0x02
...@@ -188,8 +234,7 @@ void Scene::loadAni (File *f, int dataIndex) { ...@@ -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 pos = f->tell();
int nextPos = f->tell(); int nextPos = f->tell();
LOG("PL Read position", pos); LOG("PL Read position", pos);
...@@ -253,7 +298,7 @@ void Scene::loadAni (File *f, int dataIndex) { ...@@ -253,7 +298,7 @@ void Scene::loadAni (File *f, int dataIndex) {
unsigned char* pixels; unsigned char* pixels;
pixels = new unsigned char[SW* SH]; pixels = new unsigned char[SW* SH];
memset(pixels, 0, 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); animations->background = createSurface(pixels, SW, SH);
delete[] pixels; delete[] pixels;
// Use the most recently loaded palette // Use the most recently loaded palette
...@@ -263,29 +308,30 @@ void Scene::loadAni (File *f, int dataIndex) { ...@@ -263,29 +308,30 @@ void Scene::loadAni (File *f, int dataIndex) {
case EFFAniHeader: case EFFAniHeader:
{ {
unsigned char* blockData = f->loadBlock(size);
//LoadCompacted(size, f, (unsigned char*) animations->background->pixels, SW, SH); animations->addFrame(EFFAniHeader, blockData, size);
} }
break; break;
case ERNAniHeader: case ERNAniHeader:
case ERBAniHeader: case ERBAniHeader:
case ERCAniHeader:
case ERLAniHeader: case ERLAniHeader:
case EMXAniHeader: case EMXAniHeader:
break; break;
case ERRAniHeader: // Rotate.. has zero length info case ERRAniHeader: // Reverse animation when end found
animations->reverseAnimation = 1;
break; break;
case ESquareAniHeader: // ][ Flip?? case ERCAniHeader:
{ {
unsigned char header = f->loadChar(); unsigned char* blockData = f->loadBlock(size);
LOG("PL 5b5d block header", header); animations->addFrame(ERCAniHeader, blockData, size);
unsigned short int value = f->loadShort(); }break;
LOG("PL 5b5d block value", value); 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; break;
...@@ -296,6 +342,7 @@ void Scene::loadAni (File *f, int dataIndex) { ...@@ -296,6 +342,7 @@ void Scene::loadAni (File *f, int dataIndex) {
unsigned char soundIndex = f->loadChar(); unsigned char soundIndex = f->loadChar();
unsigned char soundNote = f->loadChar(); unsigned char soundNote = f->loadChar();
unsigned char soundOffset = f->loadChar(); unsigned char soundOffset = f->loadChar();
animations->lastFrame->soundId = soundIndex;
LOG("PL Audio tag with index", soundIndex); LOG("PL Audio tag with index", soundIndex);
LOG("PL Audio tag play at ", soundNote); LOG("PL Audio tag play at ", soundNote);
LOG("PL Audio tag play offset ", soundOffset); LOG("PL Audio tag play offset ", soundOffset);
...@@ -474,16 +521,16 @@ void Scene::loadScripts (File *f) { ...@@ -474,16 +521,16 @@ void Scene::loadScripts (File *f) {
pages[loop].animSpeed = f->loadShort(); pages[loop].animSpeed = f->loadShort();
pages[loop].animIndex = f->loadShort(); pages[loop].animIndex = f->loadShort();
LOG("ESceneAnimationSetting loops", pages[loop].animLoops); LOG("ESceneAnimation loops", pages[loop].animLoops);
LOG("ESceneAnimationSetting speed", pages[loop].animSpeed); LOG("ESceneAnimation speed", pages[loop].animSpeed);
LOG("ESceneAnimationSetting anim num", pages[loop].animIndex); LOG("ESceneAnimation anim num", pages[loop].animIndex);
} }
break; break;
case ESceneAnimationPlayAndContinue: case ESceneAnimationPlayAndContinue:
{ {
unsigned char playAndContinue = f->loadChar(); pages[loop].nextPageAfterAnim = f->loadChar();
LOG("ESceneAnimationPlayAndContinue", playAndContinue); LOG("ESceneAnimationPlayAndContinue", pages[loop].nextPageAfterAnim);
} }
break; 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