[Scummvm-cvs-logs] CVS: scummvm/kyra codecs.cpp,NONE,1.1 codecs.h,NONE,1.1 cpsimage.cpp,NONE,1.1 font.cpp,NONE,1.1 palette.cpp,NONE,1.1 resource.cpp,NONE,1.1 resource.h,NONE,1.1 script.cpp,NONE,1.1 script.h,NONE,1.1 script_v1.cpp,NONE,1.1 wsamovie.cpp,NONE,1.1 wsamovie.h,NONE,1.1 kyra.cpp,1.2,1.3 kyra.h,1.1,1.2 module.mk,1.1,1.2
James Brown
ender at users.sourceforge.net
Thu Oct 14 23:08:28 CEST 2004
Update of /cvsroot/scummvm/scummvm/kyra
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20976
Modified Files:
kyra.cpp kyra.h module.mk
Added Files:
codecs.cpp codecs.h cpsimage.cpp font.cpp palette.cpp
resource.cpp resource.h script.cpp script.h script_v1.cpp
wsamovie.cpp wsamovie.h
Log Message:
Merge in some of LordHotos kyra code, with some changes.
It's still non-functional, but once I merge in some more of my local changes things should actually be moving a long a bit.
--- NEW FILE: codecs.cpp ---
/* ScummVM - Kyrandia Interpreter
* Copyright (C) 2003-2004 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header: /cvsroot/scummvm/scummvm/kyra/codecs.cpp,v 1.1 2004/10/15 06:06:47 ender Exp $
*
*/
#include "stdafx.h"
#include "codecs.h"
/*****************************************************************************
* decode.c - Decoding routines for format80, format40, format20
* and format3 type graphics
* Author: Olaf van der spek
* Modified for FreeCNC by Kareem Dana
* Modified for Kyra by Jack Burton
* Format3 decoding added by Jack Burton
* Modified for ScummVM by Johannes Schickel
****************************************************************************/
/** decompress format 80 compressed data.
* @param compressed data.
* @param pointer to output uncompressed data.
* @returns size of uncompressed data.
*/
namespace Kyra {
int Compression::decode80(const uint8* image_in, uint8* image_out) {
/*
0 copy 0cccpppp p
1 copy 10cccccc
2 copy 11cccccc p p
3 fill 11111110 c c v
4 copy 11111111 c c p p
*/
const uint8* copyp;
const uint8* readp = image_in;
uint8* writep = image_out;
uint16 code;
uint16 count;
#ifdef SCUMM_BIG_ENDIAN
uint16 bigend; /* temporary big endian var */
#endif
while (1)
{
code = *readp++;
if (~code & 0x80)
{
//bit 7 = 0
//command 0 (0cccpppp p): copy
count = (code >> 4) + 3;
copyp = writep - (((code & 0xf) << 8) + *readp++);
while (count--)
*writep++ = *copyp++;
}
else
{
//bit 7 = 1
count = code & 0x3f;
if (~code & 0x40)
{
//bit 6 = 0
if (!count)
//end of image
break;
//command 1 (10cccccc): copy
while (count--)
*writep++ = *readp++;
}
else
{
//bit 6 = 1
if (count < 0x3e)
{
//command 2 (11cccccc p p): copy
count += 3;
#ifdef SCUMM_BIG_ENDIAN
memcpy(&bigend, readp, 2);
copyp = (const uint8*)&image_out[*(const_cast<uint16*>((const uint16*)SWAP_BYTES_16(bigend))];
#else
copyp = (const uint8*)&image_out[*(const_cast<uint16*>((const uint16*)readp))];
#endif
readp += 2;
while (count--)
*writep++ = *copyp++;
}
else if (count == 0x3e)
{
//command 3 (11111110 c c v): fill
#ifdef SCUMM_BIG_ENDIAN
memset(&count, 0, sizeof(uint32));
memcpy(&count, readp, 2);
count = const_cast<uint16*>((const uint16*)SWAP_BYTES_16(count));
#else
count = *(const_cast<uint16*>((const uint16*)readp));
#endif
readp += 2;
code = *readp++;
while (count--)
*writep++ = code;
}
else
{
//command 4 (copy 11111111 c c p p): copy
#ifdef SCUMM_BIG_ENDIAN
memset(&count, 0, sizeof(uint32));
memcpy(&count, readp, 2);
count = const_cast<uint16*>((const uint16*)SWAP_BYTES_16(count));
#else
count = *(const_cast<uint16*>((const uint16*)readp));
#endif
readp += 2;
#ifdef SCUMM_BIG_ENDIAN
memcpy(&bigend, readp, 2);
copyp = (const uint8*)&image_out[*(const_cast<uint16*>((const uint16*)SWAP_BYTES_16(bigend))];
#else
copyp = (const uint8*)&image_out[*(const_cast<uint16*>((const uint16*)readp))];
#endif
readp += 2;
while (count--)
*writep++ = *copyp++;
}
}
}
}
return (writep - image_out);
}
/** decompress format 40 compressed data.
* @param compressed data.
* @param pointer to put uncompressed data in.
* @returns size of uncompressed data.
*/
int Compression::decode40(const uint8* image_in, uint8* image_out) {
/*
0 fill 00000000 c v
1 copy 0ccccccc
2 skip 10000000 c 0ccccccc
3 copy 10000000 c 10cccccc
4 fill 10000000 c 11cccccc v
5 skip 1ccccccc
*/
const uint8* readp = image_in;
uint8* writep = image_out;
uint16 code;
uint16 count;
while (1) {
code = *readp++;
if (~code & 0x80)
{
//bit 7 = 0
if (!code)
{
//command 0 (00000000 c v): fill
count = *readp++;
code = *readp++;
while (count--)
*writep++ ^= code;
}
else
{
//command 1 (0ccccccc): copy
count = code;
while (count--)
*writep++ ^= *readp++;
}
}
else
{
//bit 7 = 1
if (!(count = code & 0x7f))
{
#ifdef SCUMM_BIG_ENDIAN
memset(&count, 0, sizeof(uint32));
memcpy(&count, readp, 2);
count = const_cast<uint16*>((const uint16*)SWAP_BYTES_16(count));
#else
count = *(const_cast<uint16*>((const uint16*)readp));
#endif
readp += 2;
code = count >> 8;
if (~code & 0x80)
{
//bit 7 = 0
//command 2 (10000000 c 0ccccccc): skip
if (!count)
// end of image
break;
writep += count;
}
else
{
//bit 7 = 1
count &= 0x3fff;
if (~code & 0x40)
{
//bit 6 = 0
//command 3 (10000000 c 10cccccc): copy
while (count--)
*writep++ ^= *readp++;
}
else
{
//bit 6 = 1
//command 4 (10000000 c 11cccccc v): fill
code = *readp++;
while (count--)
*writep++ ^= code;
}
}
}
else //command 5 (1ccccccc): skip
writep += count;
}
}
return (writep - image_out);
}
/** decompress format 3 compressed data.
* @param compressed data.
* @param pointer to put uncompressed data in.
* @param size of uncompressed image.
*/
int Compression::decode3(const uint8* image_in, uint8* image_out, int size)
{ /* Untested on BIG-Endian machines */
/*
0 copy
1 fill
2 fill
*/
const uint8* readp = image_in;
uint8* writep = image_out;
int16 code;
int16 count;
do {
code = *const_cast<int8*>((const int8*)readp++);
if (code > 0) // Copy
{
count = code ;
while (count--)
*writep++ = *readp++;
}
else if (code == 0) // Fill(1)
{
count = *(const_cast<uint16*>((const uint16*)readp));
#ifdef SCUMM_LITTLE_ENDIAN
count = SWAP_BYTES_16(count);
#endif
readp += 2;
code = *readp++;
while (count--)
*writep++ = (uint8)code;
}
else if (code < 0) // Fill (2)
{
count = -code;
code = *readp++;
while (count--)
*writep++ = (uint8)code;
}
} while ((writep - image_out) < size);
//and, to be uniform to other decomp. functions...
return (writep - image_out);
}
/** decompress format 20 compressed data.
* @param compressed data.
* @param pointer to pu uncompressed data in.
* @param size of compressed data?
* @returns size of uncompressed data?
*/
int Compression::decode2(const uint8* s, uint8* d, int cb_s) {
const uint8* r = s;
const uint8* r_end = s + cb_s;
uint8* w = d;
while (r < r_end) {
int v = *r++;
if (v)
*w++ = v;
else {
v = *r++;
memset(w, 0, v);
w += v;
}
}
return w - d;
}
} // end of namespace Kyra
--- NEW FILE: codecs.h ---
/* ScummVM - Kyrandia Interpreter
* Copyright (C) 2003-2004 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header: /cvsroot/scummvm/scummvm/kyra/codecs.h,v 1.1 2004/10/15 06:06:47 ender Exp $
*
*/
/** Various decompression routines */
#ifndef __COMPRESSION_H
#define __COMPRESSION_H
// THIS CODE WAS TAKEN FROM FreeKyra Tools Module
#include "common/stdafx.h"
#include "common/scummsys.h"
namespace Kyra {
class Compression
{
public:
static int decode80(const uint8* image_in, uint8* image_out);
static int decode40(const uint8* image_in, uint8* image_out);
static int decode3(const uint8* image_in, uint8* image_out, int s);
static int decode2(const uint8* s, uint8* d, int cb_s);
};
} // end of namespace Kyra
#endif
--- NEW FILE: cpsimage.cpp ---
/* ScummVM - Kyrandia Interpreter
* Copyright (C) 2003-2004 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header: /cvsroot/scummvm/scummvm/kyra/cpsimage.cpp,v 1.1 2004/10/15 06:06:47 ender Exp $
*
*/
#include "stdafx.h"
#include "resource.h"
#include "codecs.h"
#include "common/stream.h"
namespace Kyra {
struct CPSResource {
uint32 size;
uint16 width;
};
static const CPSResource CPSResourceTable[] = {
{ 64000, 320 }, { 7740, 180 }, { 46080, 320 }, { 0, 0 }
};
static int16 getWidthFromCPSRes(uint32 size) {
int16 c = 0;
for (; CPSResourceTable[c].size; ++c) {
if (CPSResourceTable[c].size == size)
return CPSResourceTable[c].width;
}
return -1;
}
CPSImage::CPSImage(uint8* buffer, uint32 size) {
if (!buffer) {
error("resource created without data");
}
Common::MemoryReadStream bufferstream(buffer, size);
// reads in the Header
_cpsHeader._filesize = bufferstream.readUint16LE() + 2;
_cpsHeader._format = bufferstream.readUint16LE();
_cpsHeader._imagesize = bufferstream.readUint16LE();
_cpsHeader._pal = bufferstream.readUint32LE();
// lets check a bit
if(_cpsHeader._pal == 0x3000000) {
warning("CPS images with a palette aren't supported");
// skip 768 bytes
// if this was a compressed palette you should have strange graphics
bufferstream.seek(bufferstream.pos() + 768);
}
_image = new uint8[_cpsHeader._imagesize];
assert(_image);
uint8* imagebuffer = &buffer[bufferstream.pos()];
assert(imagebuffer);
if(_cpsHeader._format == 4) {
Compression::decode80(imagebuffer, _image);
} else if(_cpsHeader._format == 3) {
Compression::decode3(imagebuffer, _image, _cpsHeader._imagesize);
} else {
error("unknown CPS format %d", _cpsHeader._format);
}
int16 width = getWidthFromCPSRes(_cpsHeader._imagesize);
if(width == -1) {
warning("unknown CPS width(imagesize: %d)", _cpsHeader._imagesize);
delete [] buffer;
return;
}
_width = (uint16)width;
_height = _cpsHeader._imagesize / _width;
_transparency = -1;
delete [] buffer;
}
CPSImage::~CPSImage() {
delete [] _image;
delete _ownPalette;
}
void CPSImage::drawToPlane(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 x, uint16 y) {
if (_transparency == -1) {
// 'fast' blitting
uint8* src = _image;
uint8* dst = &plane[y * planepitch + x];
uint32 copysize = planepitch - x;
if (copysize > _width)
copysize = _width;
for (uint16 y_ = 0; y_ < _height && y + y_ < planeheight; ++y_) {
memcpy(dst, src, copysize * sizeof(uint8));
dst += planepitch;
src += _width;
}
} else {
// oh no! we have transparency so we have a very slow copy :/
uint8* src = _image;
uint8* dst = &plane[y * planepitch + x];
for (uint16 yadd = 0; yadd < _height; ++yadd) {
for (uint16 xadd = 0; xadd < _width; ++xadd) {
if (*src == _transparency) {
++dst;
++src;
} else {
*dst++ = *src++;
}
}
dst += planepitch - _width;
}
}
}
void CPSImage::drawToPlane(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 x, uint16 y,
uint16 srcx, uint16 srcy, uint16 srcwidth, uint16 srcheight) {
if (_transparency == -1) {
// 'fast' blitting
uint8* src = &_image[srcy * _width + srcx];
uint8* dst = &plane[y * planepitch + x];
uint32 copysize = planepitch - x;
if (copysize > srcwidth)
copysize = srcwidth;
for (uint16 y_ = 0; y_ < srcheight && y + y_ < planeheight; ++y_) {
memcpy(dst, src, copysize * sizeof(uint8));
dst += planepitch;
src += _width;
}
} else {
// oh no! we have transparency so we have a very slow copy :/
// blit it without transparency
uint8* src = &_image[srcy * _width + srcx];
uint8* dst = &plane[y * planepitch + x];
for (uint16 yadd = 0; yadd < _height; ++yadd) {
for (uint16 xadd = 0; xadd < _width; ++xadd) {
if (*src == _transparency) {
++dst;
++src;
} else {
*dst++ = *src++;
}
}
dst += planepitch - _width;
src += _width - srcwidth;
}
}
}
} // end of namespace Kyra
--- NEW FILE: font.cpp ---
/* ScummVM - Kyrandia Interpreter
* Copyright (C) 2003-2004 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header: /cvsroot/scummvm/scummvm/kyra/font.cpp,v 1.1 2004/10/15 06:06:47 ender Exp $
*
*/
#include "stdafx.h"
#include "resource.h"
#include "common/stream.h"
#include "common/array.h"
#ifdef DUMP_FILES
#include <cstdio>
#endif
namespace Kyra {
const uint16 FontHeader_Magic1 = 0x0500;
const uint16 FontHeader_Magic2 = 0x000e;
const uint16 FontHeader_Magic3 = 0x0014;
Font::Font(uint8* buffer, uint32 size) {
if (!buffer) {
error("resource created without data");
}
_buffer = buffer;
Common::MemoryReadStream bufferstream(buffer, size);
bufferstream.read(&_fontHeader, sizeof(_fontHeader));
// tests for the magic values
if(_fontHeader._magic1 != FontHeader_Magic1 || _fontHeader._magic2 != FontHeader_Magic2 ||
_fontHeader._magic3 != FontHeader_Magic3) {
error("magic vars in the fontheader are corrupt\n"
"_magic1 = 0x%x, _magic2 = 0x%x, _magic3 = 0x%x",
_fontHeader._magic1, _fontHeader._magic2, _fontHeader._magic3);
}
// init all the pointers
_offsetTable = (uint16*)&buffer[bufferstream.pos()];
_charWidth = &buffer[_fontHeader._charWidthOffset];
_charHeight = (uint16*)&buffer[_fontHeader._charHeightOffset];
_charBits = &buffer[_fontHeader._charBitsOffset];
// now prerender =)
preRenderAllChars(bufferstream.pos());
// This value seems to be a version or language variable
// Known Values
// ------------
// Russian Floppy: 0x1010
// German Floppy and English CD: 0x1011
// Kyrandia 2 should be 0x1012
debug("_version = 0x%x", _fontHeader._version);
delete [] _buffer;
_buffer = 0;
_offsetTable = 0;
_charHeight = 0;
_charWidth = 0;
_charBits = 0;
}
Font::~Font() {
}
uint32 Font::getStringWidth(const char* string, char terminator) {
uint32 strsize;
for (strsize = 0; string[strsize] != terminator; ++strsize)
;
uint32 stringwidth = 0;
for (uint32 pos = 0; pos < strsize; ++pos) {
stringwidth += _preRenderedChars[string[pos]].width;
}
return stringwidth;
}
const uint8* Font::getChar(char c, uint8* width, uint8* height, uint8* heightadd) {
PreRenderedChar& c_ = _preRenderedChars[c];
*width = c_.width;
*height = c_.height;
*heightadd = c_.heightadd;
return c_.c;
}
// splits up the String in a word
const char* Font::getNextWord(const char* string, uint32* size) {
uint32 startpos = 0;
*size = 0;
// gets start of the word
for (; string[startpos] == ' '; ++startpos)
;
// not counting size
for (*size = 0; string[startpos + *size] != ' ' && string[startpos + *size] != '\0'; ++(*size))
;
++(*size);
return &string[startpos];
}
// Move this to Font declaration?
struct WordChunk {
const char* _string;
uint32 _size;
};
void Font::drawStringToPlane(const char* string,
uint8* plane, uint16 planewidth, uint16 planeheight,
uint16 x, uint16 y, uint8 color) {
// lets do it word after word
Common::Array<WordChunk> words;
uint32 lastPos = 0;
uint32 lastSize = 0;
uint32 strlgt = strlen(string);
while (true) {
WordChunk newchunk;
newchunk._string = getNextWord(&string[lastPos], &lastSize);
newchunk._size = lastSize;
lastPos += lastSize;
words.push_back(newchunk);
if (lastPos >= strlgt)
break;
}
uint16 current_x = x, current_y = y;
uint8 heighest = 0;
const uint8* src = 0;
uint8 width = 0, height = 0, heightadd = 0;
// now the have alle of these words
for (uint32 tmp = 0; tmp < words.size(); ++tmp) {
lastSize = getStringWidth(words[tmp]._string, ' ');
// adjust x position
if (current_x + lastSize >= planewidth) {
// hmm lets move it a bit to the left
if (current_x == x && (int16)planewidth - (int16)lastSize >= 0) {
current_x = planewidth - lastSize;
} else {
current_x = x;
if (heighest)
current_y += heighest + 2;
else // now we are using just the fist char :)
current_y += _preRenderedChars[words[tmp]._string[0]].height;
heighest = 0;
}
}
// TODO: maybe test if current_y >= planeheight ?
// output word :)
for (lastPos = 0; lastPos < words[tmp]._size; ++lastPos) {
if (words[tmp]._string[lastPos] == '\0')
break;
// gets our char :)
src = getChar(words[tmp]._string[lastPos], &width, &height, &heightadd);
// lets draw our char
drawCharToPlane(src, color, width, height, plane, planewidth, planeheight, current_x, current_y + heightadd);
current_x += width;
heighest = MAX(heighest, height);
}
}
}
void Font::drawCharToPlane(const uint8* c, uint8 color, uint8 width, uint8 height,
uint8* plane, uint16 planewidth, uint16 planeheight, uint16 x, uint16 y) {
const uint8* src = c;
// blit them to the screen
for (uint8 yadd = 0; yadd < height; ++yadd) {
for (uint8 xadd = 0; xadd < width; ++xadd) {
switch(*src) {
case 1:
plane[(y + yadd) * planewidth + x + xadd] = color;
break;
case 2:
plane[(y + yadd) * planewidth + x + xadd] = 14;
break;
case 3:
plane[(y + yadd) * planewidth + x + xadd] = 0;
break;
default:
// nothing to do now
break;
};
++src;
}
}
}
void Font::preRenderAllChars(uint16 offsetTableOffset) {
uint16 startOffset = _offsetTable[0];
uint16 currentOffset = offsetTableOffset;
uint8 currentChar = 0;
for (; currentOffset < startOffset; ++currentChar, currentOffset += sizeof(uint16)) {
// lets prerender the char :)
PreRenderedChar newChar;
newChar.c = new uint8[(_charHeight[currentChar] >> 8) * _charWidth[currentChar]];
assert(newChar.c);
memset(newChar.c, 0, sizeof(uint8) * (_charHeight[currentChar] >> 8) * _charWidth[currentChar]);
newChar.height = (_charHeight[currentChar] >> 8);
newChar.width = _charWidth[currentChar];
newChar.heightadd = _charHeight[currentChar] & 0xFF;
uint8* src = _buffer + _offsetTable[currentChar];
uint8* dst = &newChar.c[0];
uint8 index = 0;
#ifdef DUMP_FILES
static char filename[32] = { 0 };
sprintf(filename, "dumps/char%d.dmp", currentChar);
FILE* dump = fopen(filename, "w+");
assert(dump);
fprintf(dump, "This should be a '%c'\n", currentChar);
#endif
// prerender the char
for (uint8 yadd = 0; yadd < newChar.height; ++yadd) {
for (uint8 xadd = 0; xadd < newChar.width; ++xadd) {
if (xadd % 2) {
index = ((*src) & 0xF0) >> 4;
++src;
} else {
index = (*src) & 0x0F;
}
switch(index) {
case 1:
#ifdef DUMP_FILES
fprintf(dump, "#");
#endif
dst[yadd * newChar.width + xadd] = 1;
break;
case 2:
#ifdef DUMP_FILES
fprintf(dump, "$");
#endif
dst[yadd * newChar.width + xadd] = 2;
break;
case 3:
#ifdef DUMP_FILES
fprintf(dump, "§");
#endif
dst[yadd * newChar.width + xadd] = 3;
break;
default:
#ifdef DUMP_FILES
fprintf(dump, "%d", index);
#endif
break;
};
}
if (newChar.width % 2) {
++src;
}
#ifdef DUMP_FILES
fprintf(dump, "\n");
#endif
}
#ifdef DUMP_FILES
fprintf(dump, "\nThis is the created map:\n");
// now print the whole thing again
for (uint8 yadd = 0; yadd < newChar.height; ++yadd) {
for (uint8 xadd = 0; xadd < newChar.width; ++xadd) {
fprintf(dump, "%d", dst[yadd * newChar.width + xadd]);
}
fprintf(dump, "\n");
}
fclose(dump);
#endif
_preRenderedChars[currentChar] = newChar;
if (currentChar == 255) {
break;
}
}
}
} // end of namespace Kyra
--- NEW FILE: palette.cpp ---
/* ScummVM - Kyrandia Interpreter
* Copyright (C) 2003-2004 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header: /cvsroot/scummvm/scummvm/kyra/palette.cpp,v 1.1 2004/10/15 06:06:47 ender Exp $
*
*/
#include "stdafx.h"
#include "resource.h"
#include "common/stream.h"
#include "codecs.h"
namespace Kyra {
Palette::Palette(uint8* data, uint32 size) {
if (!data) {
error("resource created without data");
}
if (size != 768) {
Common::MemoryReadStream datastream(data, size);
datastream.readSint32LE();
int imageSize = datastream.readSint16LE();
if (imageSize != 768) {
error("decompresed palette is not 768 byte long!");
}
// lets uncompress this palette :)
_palette = new uint8[imageSize];
assert(_palette);
// made decompression
if (Compression::decode80(data + 10, _palette) != 768) {
error("decode80 decompressesize != 768 bytes");
}
delete [] data;
data = _palette;
}
// hmm.. common/system.h Docu is wrong or SDL Backend has a bug :)
// a palette should have this order:
// R1-G1-B1-A1-R2-G2-B2-A2-...
// so we need 4 bytes per color
_palette = new uint8[256 * 4];
uint8* currentpossrc = &data[0];
uint8* currentposdst = &_palette[0];
// creates the original pallette (only first 6 bits are used)
for (uint32 i = 0; i < 256; i++) {
currentposdst[0] = currentpossrc[0] << 2;
currentposdst[1] = currentpossrc[1] << 2;
currentposdst[2] = currentpossrc[2] << 2;
currentpossrc += 3;
currentposdst += 4;
}
delete [] data;
}
} // end of namespace Kyra
--- NEW FILE: resource.cpp ---
/* ScummVM - Kyrandia Interpreter
* Copyright (C) 2003-2004 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header: /cvsroot/scummvm/scummvm/kyra/resource.cpp,v 1.1 2004/10/15 06:06:47 ender Exp $
*
*/
#include "stdafx.h"
#include "resource.h"
#include "wsamovie.h"
#include "common/file.h"
#include "script.h"
namespace Kyra {
Resourcemanager::Resourcemanager(KyraEngine* engine, const char* gamedir) {
_gameDir = gamedir;
// prefetches all PAK Files
// ugly a hardcoded list
// TODO: use the FS Backend to get all .PAK Files and load them
static const char* kyraFilelist[] = {
"A_E.PAK", "DAT.PAK", "F_L.PAK", "MAP_5.PAK", "MSC.PAK", "M_S.PAK",
"S_Z.PAK", "WSA1.PAK", "WSA2.PAK", "WSA3.PAK", "WSA4.PAK", "WSA5.PAK",
"WSA6.PAK", "startup.pak", "intro1.pak", 0
};
for (uint32 tmp = 0; kyraFilelist[tmp]; ++tmp) {
// prefetch file
PAKFile* file = new PAKFile(getPath() + kyraFilelist[tmp]);
assert(file);
if (file->isValid())
_pakfiles.push_back(file);
else
warning("couldn't load file '%s' correctly", kyraFilelist[tmp]);
}
}
Resourcemanager::~Resourcemanager() {
Common::List<PAKFile*>::iterator start = _pakfiles.begin();
for (;start != _pakfiles.end(); ++start) {
delete *start;
*start = 0;
}
}
uint8* Resourcemanager::fileData(const char* file, uint32* size) {
uint8* buffer = 0;
debug("looking for file '%s'", file);
File file_;
// test to open it in the main dir
if (file_.open((getPath() + file).c_str())) {
*size = file_.size();
buffer = new uint8[*size];
assert(buffer);
file_.read(buffer, *size);
file_.close();
} else {
// opens the file in a PAK File
Common::List<PAKFile*>::iterator start = _pakfiles.begin();
for (;start != _pakfiles.end(); ++start) {
*size = (*start)->getFileSize(file);
if (!*size)
continue;
buffer = new uint8[*size];
assert(buffer);
// creates a copy of the file
memcpy(buffer, (*start)->getFile(file), *size);
break;
}
}
if (!buffer || !(*size)) {
warning("couldn't find file '%s'", file);
}
return buffer;
}
Palette* Resourcemanager::loadPalette(const char* file) {
uint32 size = 0;
uint8* buffer = 0;
buffer = fileData(file, &size);
if (!buffer)
return 0;
return new Palette(buffer, size);
}
CPSImage* Resourcemanager::loadImage(const char* file) {
uint32 size = 0;
uint8* buffer = 0;
buffer = fileData(file, &size);
if (!buffer)
return 0;
return new CPSImage(buffer, size);
}
Font* Resourcemanager::loadFont(const char* file) {
uint32 size = 0;
uint8* buffer = 0;
buffer = fileData(file, &size);
if (!buffer)
return 0;
return new Font(buffer, size);
}
Movie* Resourcemanager::loadMovie(const char* file) {
// TODO: we have to check the Extenion to create the right movie
uint32 size = 0;
uint8* buffer = 0;
buffer = fileData(file, &size);
if (!buffer)
return 0;
return new WSAMovieV1(buffer, size);
}
VMContext* Resourcemanager::loadScript(const char* file) {
VMContext* context = new VMContext(_engine);
context->loadScript(file);
return context;
}
Common::String Resourcemanager::getPath(void) {
assert(_gameDir);
int32 len = strlen(_gameDir);
if(len < 1)
error("no valid gamedir");
// tests for an path seperator at the end
if (_gameDir[len - 1] == '\\') {
return string(_gameDir);
} else if (_gameDir[len - 1 ] == '/') {
return string(_gameDir);
}
// creates a path seperator at the end
// we are always using the path seperator from the system
// even if Windows shoudl accept '/'
#ifdef WIN32
return string(_gameDir) + "\\";
#else
return string(_gameDir) + "/";
#endif
}
///////////////////////////////////////////
// Pak file manager
#define PAKFile_Iterate Common::List<PakChunk*>::iterator start=_files.begin();start != _files.end(); ++start
PAKFile::PAKFile(const Common::String& file) {
File pakfile;
if (!pakfile.open(file.c_str())) {
warning("PAKFile couldn't open: '%s'", file.c_str());
return;
}
uint32 filesize = pakfile.size();
_buffer = new uint8[filesize];
assert(_buffer);
pakfile.read(_buffer, filesize);
pakfile.close();
// works with the file
uint32 pos = 0, startoffset = 0, endoffset = 0;
startoffset = *(reinterpret_cast<uint32*>((_buffer + pos)));
pos += 4;
while (pos < filesize) {
PakChunk* chunk = new PakChunk;
assert(chunk);
// saves the name
chunk->_name = reinterpret_cast<const char*>(_buffer + pos);
pos += strlen(chunk->_name) + 1;
if(!chunk->_name)
break;
endoffset = *(reinterpret_cast<uint32*>((_buffer + pos)));
pos += 4;
chunk->_data = _buffer + startoffset;
chunk->_size = endoffset - startoffset;
startoffset = endoffset;
_files.push_back(chunk);
}
}
PAKFile::~PAKFile() {
delete [] _buffer;
_buffer = 0;
for (PAKFile_Iterate) {
delete *start;
*start = 0;
}
}
const uint8* PAKFile::getFile(const char* file) {
for (PAKFile_Iterate) {
if (!scumm_stricmp((*start)->_name, file))
return (*start)->_data;
}
return 0;
}
uint32 PAKFile::getFileSize(const char* file) {
for (PAKFile_Iterate) {
if (!scumm_stricmp((*start)->_name, file))
return (*start)->_size;
}
return 0;
}
} // end of namespace Kyra
--- NEW FILE: resource.h ---
/* ScummVM - Kyrandia Interpreter
* Copyright (C) 2003-2004 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header: /cvsroot/scummvm/scummvm/kyra/resource.h,v 1.1 2004/10/15 06:06:47 ender Exp $
*
*/
#ifndef RESOURCE_H
#define RESOURCE_H
#include "common/stdafx.h"
#include "common/scummsys.h"
#include "common/str.h"
#include "common/list.h"
#include "common/map.h"
#include "kyra.h"
namespace Kyra {
// standard Package format for Kyrandia games
class PAKFile {
struct PakChunk {
const char* _name;
const uint8* _data;
uint32 _size;
};
public:
PAKFile(const Common::String& file);
~PAKFile();
const uint8* getFile(const char* file);
uint32 getFileSize(const char* file);
bool isValid(void) { return (_buffer != 0); }
private:
uint8* _buffer; // the whole file
Common::List<PakChunk*> _files; // the entries
};
// some resource types
class Palette;
class CPSImage;
class Font;
class Movie;
class VMContext;
// out resource manager
class Resourcemanager {
typedef Common::String string;
public:
Resourcemanager(KyraEngine* engine, const char* gamedir);
virtual ~Resourcemanager();
uint8* fileData(const char* file, uint32* size);
Palette* loadPalette(const char* file);
CPSImage* loadImage(const char* file);
Font* loadFont(const char* file);
Movie* loadMovie(const char* file);
VMContext* loadScript(const char* file);
protected:
KyraEngine* _engine;
string getPath(void);
const char* _gameDir;
Common::List<PAKFile*> _pakfiles;
};
class Palette {
public:
Palette(uint8* data, uint32 size);
~Palette() { delete [] _palette; }
uint8* getData(void) { return _palette; }
protected:
uint8* _palette;
};
class CPSImage {
public:
CPSImage(uint8* buffer, uint32 size);
~CPSImage();
Palette* palette(void) { return _ownPalette; }
bool hasPalette(void) { return (_ownPalette != 0); }
// if col == -1 then no transparany
void setTransparencyColor(int16 col) { _transparency = col; }
void drawToPlane(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 x, uint16 y);
void drawToPlane(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 x, uint16 y,
uint16 srcx, uint16 srcy, uint16 srcwidth, uint16 srcheight);
// only for testing :)
uint8 getColor(uint16 x, uint16 y) { return _image[y * _width + x]; }
uint8& operator[](uint16 index) { if(index > _width * _height) return _image[0]; return _image[index]; }
protected:
struct CPSHeader {
uint16 _filesize;
uint16 _format;
uint16 _imagesize;
uint32 _pal;
} _cpsHeader;
Palette* _ownPalette;
uint8* _image;
uint16 _width, _height;
int16 _transparency;
};
class Font {
public:
Font(uint8* buffer, uint32 size);
~Font();
uint32 getStringWidth(const char* string, char terminator = '\0');
void drawStringToPlane(const char* string,
uint8* plane, uint16 planewidth, uint16 planeheight,
uint16 x, uint16 y, uint8 color);
protected:
void drawCharToPlane(const uint8* c, uint8 color, uint8 width, uint8 height,
uint8* plane, uint16 planewidth, uint16 planeheight, uint16 x, uint16 y);
const uint8* getChar(char c, uint8* width, uint8* height, uint8* heightadd);
const char* getNextWord(const char* string, uint32* size);
void preRenderAllChars(uint16 offsetTableOffset);
uint8* _buffer;
uint16* _offsetTable;
uint8* _charWidth;
uint16* _charHeight;
uint8* _charBits;
// the chars I call 'prerendered' aren't really prerendered
// they are only 'decoded'
struct PreRenderedChar {
uint8* c;
uint8 width, height, heightadd;
};
Common::Map<uint8, PreRenderedChar> _preRenderedChars; // our prerendered chars :)
// INFO:
// _magic1 = 0x0500
// _magic2 = 0x000e
// _magic3 = 0x0014
#pragma START_PACK_STRUCTS
struct FontHeader {
uint16 _size;
uint16 _magic1, _magic2, _magic3;
uint16 _charWidthOffset, _charBitsOffset, _charHeightOffset;
uint16 _version;
uint16 _countChars;
uint8 _width, _height;
} GCC_PACK _fontHeader;
#pragma END_PACK_STRUCTS
};
} // end of namespace Kyra
#endif
--- NEW FILE: script.cpp ---
/* ScummVM - Kyrandia Interpreter
* Copyright (C) 2003-2004 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header: /cvsroot/scummvm/scummvm/kyra/script.cpp,v 1.1 2004/10/15 06:06:47 ender Exp $
*
*/
#include "stdafx.h"
#include "kyra.h"
#include "script.h"
#include "resource.h"
#include "common/stream.h"
#define COMMAND(x) { &VMContext::x, #x }
#define OPCODE(x) { &VMContext::x, #x }
namespace Kyra {
VMContext::VMContext(KyraEngine* engine) {
_engine = engine;
// now we create a list of all Command/Opcode procs and so
static CommandEntry commandProcs[] = {
// 0
COMMAND(c1_goToLine),
COMMAND(c1_setReturn),
COMMAND(c1_pushRetRec),
COMMAND(c1_push),
COMMAND(c1_push),
COMMAND(c1_pushVar),
COMMAND(c1_pushFrameNeg),
COMMAND(c1_pushFramePos),
COMMAND(c1_popRetRec),
COMMAND(c1_popVar),
// 10
COMMAND(c1_popFrameNeg),
COMMAND(c1_popFramePos),
COMMAND(c1_addToSP),
COMMAND(c1_subFromSP),
COMMAND(c1_execOpcode),
COMMAND(c1_ifNotGoTo),
COMMAND(c1_negate),
COMMAND(c1_evaluate),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
// 20
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
// 30
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
// 40
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
// 50
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
// 60
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
// 70
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
// 80
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
// 90
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
// 100
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
// 110
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
// 120
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
// 130
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
// 140
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
// 150
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
// 160
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
// 170
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
// 180
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
// 190
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
// 200
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
// 210
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
// 220
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
// 230
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
// 240
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
// 250
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
COMMAND(c1_unknownCommand),
{ 0, 0 }
};
_scriptFile = NULL;
_scriptFileSize = 0;
}
void VMContext::loadScript(const char* file) {
printf("a\n");
if (_scriptFile) {
delete [] _scriptFile;
_scriptFileSize = 0;
}
debug("--------------");
// loads the new file
_scriptFile = _engine->resManager()->fileData(file, &_scriptFileSize);
printf("c\n");
if (!_scriptFileSize || !_scriptFile) {
error("couldn't load script file '%s'", file);
}
Common::MemoryReadStream script(_scriptFile, _scriptFileSize);
memset(_chunks, 0, sizeof(ScriptChunk) * kCountChunkTypes);
uint8 chunkName[sizeof("EMC2ORDR") + 1];
// so lets look for our chunks :)
while(true) {
if (script.eof()) {
break;
}
// lets read only the first 4 chars
script.read(chunkName, sizeof(uint8) * 4);
chunkName[4] = '\0';
debug("chunk name(4 chars): '%s'", chunkName);
// check name of chunk
if (!scumm_stricmp((char*)chunkName, "FORM")) {
// FreeKyra swaps the size I only read it in BigEndian :)
_chunks[kForm]._size = script.readUint32BE();
debug("_chunks[kForm]._size = %d", _chunks[kForm]._size);
} else if (!scumm_stricmp((char*)chunkName, "TEXT")) {
uint32 text_size = script.readUint32BE();
text_size += text_size % 2 != 0 ? 1 : 0;
_chunks[kText]._data = _scriptFile + script.pos();
_chunks[kText]._size = READ_BE_UINT16(_chunks[kText]._data) >> 1;
_chunks[kText]._additional = _chunks[kText]._data + (_chunks[kText]._size << 1);
debug("_chunks[kText]._size = %d, real chunk size = %d", _chunks[kText]._size, text_size);
script.seek(script.pos() + text_size);
} else if (!scumm_stricmp((char*)chunkName, "DATA")) {
_chunks[kData]._size = script.readUint32BE();
_chunks[kData]._data = _scriptFile + script.pos();
debug("_chunks[kData]._size = %d", _chunks[kData]._size);
// mostly it will be the end of the file because all files should end with a 'DATA' chunk
script.seek(script.pos() + _chunks[kData]._size);
} else {
// read next 4 chars
script.read(&chunkName[4], sizeof(uint8) * 4);
chunkName[8] = '\0';
debug("chunk name(8 chars): '%s'", chunkName);
if (!scumm_stricmp((char*)chunkName, "EMC2ORDR")) {
_chunks[kEmc2Ordr]._size = script.readUint32BE() >> 1;
_chunks[kEmc2Ordr]._data = _scriptFile + script.pos();
debug("_chunks[kEmc2Ordr]._size = %d, real chunk size = %d", _chunks[kEmc2Ordr]._size, _chunks[kEmc2Ordr]._size * 2);
script.seek(script.pos() + _chunks[kEmc2Ordr]._size * 2);
} else {
// any unkown chunk or problems with seeking through the file
error("unknown chunk");
}
}
}
// so file loaded
debug("--------------");
}
int32 VMContext::param(int32 index) {
if (_stackPos - index + 1 >= 16 || _stackPos - index + 1 < 0)
return -0xFFFF;
return _stack[_stackPos - index + 1];
}
const char* VMContext::stringAtIndex(int32 index) {
if (index < 0 || (uint32)index >= _chunks[kText]._size)
return 0;
return (char*)(_chunks[kText]._additional + _chunks[kText]._data[index]);
}
bool VMContext::startScript(int32 func) {
if ((uint32)func >= _chunks[kEmc2Ordr]._size || func < 0) {
debug("script doesn't support function %d", func);
return false;
}
_instructionPos = (READ_BE_UINT16(&_chunks[kEmc2Ordr]._data[func]) << 1) + 2;
_stackPos = 0;
_tempPos = 0;
_delay = 0;
_scriptState = kScriptRunning;
return true;
}
uint32 VMContext::contScript(void) {
uint8* script_start = _chunks[kData]._data;
assert(script_start);
uint32 scriptStateAtStart = _scriptState;
// runs the script
while(true) {
if ((uint32)_instructionPos > _chunks[kData]._size) {
debug("_instructionPos( = %d) > _chunks[kData]._size( = %d)", _instructionPos, _chunks[kData]._size);
_error = true;
break;
}
_currentCommand = *(script_start + _instructionPos++);
// gets out
if (_currentCommand & 0x80) {
_argument = ((_currentCommand & 0x0F) << 8) | *(script_start + _instructionPos++);
_currentCommand &= 0xF0;
} else if (_currentCommand & 0x40) {
_argument = *(script_start + _instructionPos++);
} else if (_currentCommand & 0x20) {
_instructionPos++;
uint16 tmp = *(uint16*)(script_start + _instructionPos);
tmp &= 0xFF7F;
_argument = READ_BE_UINT16(&tmp);
_instructionPos += 2;
} else {
debug("unknown way of getting the command");
}
_currentCommand &= 0x1f;
CommandProc currentProc = _commands[_currentCommand].proc;
(this->*currentProc)();
if (_error) {
_scriptState = kScriptError;
break;
}
if (scriptStateAtStart != _scriptState) {
break;
}
}
return _scriptState;
}
} // end of namespace Kyra
--- NEW FILE: script.h ---
/* ScummVM - Kyrandia Interpreter
* Copyright (C) 2003-2004 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header: /cvsroot/scummvm/scummvm/kyra/script.h,v 1.1 2004/10/15 06:06:47 ender Exp $
*
*/
#ifndef VM_H
#define VM_H
namespace Kyra {
// TODO:
// find out more script functions
enum ScriptFunc {
kSetupScene = 0,
kClickEvent = 1, // _registers[1] and _registers[2] are mouse x, y _registers[4] is action
kActorEvent = 2,
kEnterEvent = 4,
kExitEvent = 5,
kLoadResources = 7
};
enum ScriptState {
kScriptStopped = 0,
kScriptRunning = 1,
kScriptWaiting = 2,
kScriptError = 3
};
class VMContext {
public:
VMContext(KyraEngine* engine);
~VMContext() { delete [] _scriptFile; }
void loadScript(const char* file);
const char* stringAtIndex(int32 index);
// TODO: check for 'over'flow
void pushStack(int32 value) { _stack[_stackPos++] = value; }
void registerValue(int32 reg, int32 value) { _registers[reg] = value; }
int32 checkReg(int32 reg) { return _registers[reg]; }
uint32 state(void) { return _scriptState; }
bool startScript(int32 func);
uint32 contScript(void);
protected:
KyraEngine* _engine;
uint8* _scriptFile;
uint32 _scriptFileSize;
uint32 _scriptState;
uint32 _delay;
int32 _registers[32]; // registers of the interpreter
int32 _stack[32]; // our stack
// TODO: check for 'under'flow
int32 popStack(void) { return _stack[_stackPos--]; }
int32& topStack(void) { return _stack[_stackPos]; }
uint32 _returnValue;
int32 _instructionPos;
int32 _stackPos;
int32 _tempPos;
// used by command & opcode procs
uint16 _argument;
uint8 _currentCommand;
uint32 _currentOpcode;
int32 param(int32 index);
const char* paramString(int32 index) { return stringAtIndex(param(index)); }
bool _error; // used by all command- and opcodefuncs
enum ScriptChunkTypes {
kForm = 0,
kEmc2Ordr = 1,
kText = 2,
kData = 3,
kCountChunkTypes
};
struct ScriptChunk {
uint32 _size;
uint8* _data; // by TEXT used for count of texts, by EMC2ODRD it is used for a count of somewhat
uint8* _additional; // currently only used for TEXT
};
ScriptChunk _chunks[kCountChunkTypes];
typedef void (VMContext::*CommandProc)();
struct CommandEntry {
CommandProc proc;
const char* desc;
};
typedef void (VMContext::*OpcodeProc)();
struct OpcodeEntry {
OpcodeProc proc;
const char* desc;
};
const CommandEntry* _commands;
const OpcodeEntry* _opcodes;
protected:
// the command procs
void c1_goToLine(void); // 0x00
void c1_setReturn(void); // 0x01
void c1_pushRetRec(void); // 0x02
void c1_push(void); // 0x03 & 0x04
void c1_pushVar(void); // 0x05
void c1_pushFrameNeg(void); // 0x06
void c1_pushFramePos(void); // 0x07
void c1_popRetRec(void); // 0x08
void c1_popVar(void); // 0x09
void c1_popFrameNeg(void); // 0x0A
void c1_popFramePos(void); // 0x0B
void c1_addToSP(void); // 0x0C
void c1_subFromSP(void); // 0x0D
void c1_execOpcode(void); // 0x0E
void c1_ifNotGoTo(void); // 0x0F
void c1_negate(void); // 0x10
void c1_evaluate(void); // 0x11
void c1_unknownCommand(void);
// the opcode procs
void o1_0x68(void); // 0x68
void o1_unknownOpcode(void);
};
} // end of namespace Kyra
#endif
--- NEW FILE: script_v1.cpp ---
/* ScummVM - Kyrandia Interpreter
* Copyright (C) 2003-2004 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header: /cvsroot/scummvm/scummvm/kyra/script_v1.cpp,v 1.1 2004/10/15 06:06:47 ender Exp $
*
*/
#include "stdafx.h"
#include "kyra.h"
#include "script.h"
namespace Kyra {
// Command procs
void VMContext::c1_unknownCommand(void) {
debug("unknown command '0x%x'.", _currentCommand);
debug("\targument: '0x%x'", _argument);
_error = true;
}
void VMContext::c1_goToLine(void) {
_instructionPos = _argument << 1;
}
void VMContext::c1_setReturn(void) {
_returnValue = _argument;
}
void VMContext::c1_pushRetRec(void) {
if (!_argument) {
pushStack(_returnValue);
} else {
int32 rec = ((int16)_tempPos << 16) | ((_instructionPos >> 1) + 1);
pushStack(rec);
_tempPos = _instructionPos;
}
}
void VMContext::c1_push(void) {
pushStack(_argument);
}
void VMContext::c1_pushVar(void) {
pushStack(_registers[_argument]);
}
void VMContext::c1_pushFrameNeg(void) {
pushStack(_stack[_tempPos + _argument]);
}
void VMContext::c1_pushFramePos(void) {
pushStack(_stack[_tempPos - _argument]);
}
void VMContext::c1_popRetRec(void) {
if (!_argument) {
_returnValue = popStack();
} else {
if (_stackPos <= 0) {
_scriptState = kScriptStopped;
}
int32 rec = popStack();
_tempPos = (int16)((rec & 0xFFFF0000) >> 16);
_instructionPos = (rec & 0x0000FFFF) * 2;
}
}
void VMContext::c1_popVar(void) {
_registers[_argument] = popStack();
}
void VMContext::c1_popFrameNeg(void) {
_stack[_tempPos + _argument] = popStack();
}
void VMContext::c1_popFramePos(void) {
_stack[_tempPos - _argument] = popStack();
}
void VMContext::c1_addToSP(void) {
_stackPos -= _argument;
}
void VMContext::c1_subFromSP(void) {
_stackPos += _argument;
}
void VMContext::c1_execOpcode(void) {
OpcodeProc proc = _opcodes[_argument].proc;
(this->*proc)();
}
void VMContext::c1_ifNotGoTo(void) {
if (!popStack()) {
_instructionPos = _argument << 1;
}
}
void VMContext::c1_negate(void) {
switch(_argument) {
case 0:
topStack() = !topStack();
break;
case 1:
topStack() = -topStack();
break;
case 2:
topStack() = ~topStack();
break;
default:
debug("unkown negate instruction %d", _argument);
_error = true;
break;
};
}
void VMContext::c1_evaluate(void) {
int32 x, y;
int32 res = false;
x = popStack();
y = popStack();
switch(_argument) {
case 0:
res = x && y;
break;
case 1:
res = x || y;
break;
case 3:
res = x != y;
break;
case 4:
res = x < y;
break;
case 5:
res = x <= y;
break;
case 6:
res = x > y;
break;
case 7:
res = x >= y;
break;
case 8:
res = x + y;
break;
case 9:
res = x - y;
break;
case 10:
res = x * y;
break;
case 11:
res = x / y;
break;
case 12:
res = x >> y;
break;
case 13:
res = x << y;
break;
case 14:
res = x & y;
break;
case 15:
res = x | y;
break;
case 16:
res = x % y;
break;
case 17:
res = x ^ y;
break;
default:
debug("unknown evaluate command");
break;
};
pushStack(res);
}
} // end of namespace Kyra
--- NEW FILE: wsamovie.cpp ---
/* ScummVM - Kyrandia Interpreter
* Copyright (C) 2003-2004 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header: /cvsroot/scummvm/scummvm/kyra/wsamovie.cpp,v 1.1 2004/10/15 06:06:47 ender Exp $
*
*/
#include "stdafx.h"
#include "wsamovie.h"
#include "codecs.h"
#include "common/stream.h"
namespace Kyra {
WSAMovieV1::WSAMovieV1(uint8* data, uint32 size) {
if (!data) {
error("resource created without data");
}
_buffer = data;
// I like these Streams .... =)
Common::MemoryReadStream datastream(data, size);
datastream.read(&_wsaHeader, sizeof(_wsaHeader));
// check for version
if (_wsaHeader._type) {
error("loading a WSA version 2 with the WSA version 1 loader");
}
uint16 offsetAdd = 0;
// checks now for own palette
if (_wsaHeader._type % 2) {
// don't now if this will work right, because a few lines before we use
// _wsaHeader._type for detect the version of the WSA movie,
// but this code was from FreeKyra Tools so I think it will work
// if this is a packed palette we have a problem :)
offsetAdd = 768 /* 0x300 */;
}
_frameCount = _wsaHeader._numFrames;
_offsetTable = new uint32[_wsaHeader._numFrames + 2];
assert(!_offsetTable);
// loads the offset table
for (uint32 tmp = 0; tmp < _wsaHeader._numFrames; ++tmp) {
_offsetTable[tmp] = datastream.readUint32LE() + offsetAdd;
}
if (offsetAdd) {
uint8* palbuffer = new uint8[offsetAdd];
assert(!palbuffer);
_ownPalette = new Palette(palbuffer, offsetAdd);
assert(!_ownPalette);
}
}
WSAMovieV1::~WSAMovieV1() {
delete [] _buffer;
delete [] _offsetTable;
delete _ownPalette;
}
const uint8* WSAMovieV1::loadFrame(uint16 frame, uint16* width, uint16* height) {
if (width) *width = _wsaHeader._width;
if (height) *height = _wsaHeader._height;
if (frame == _prefetchedFrame) {
return _currentFrame;
} else {
if (!_currentFrame) {
_currentFrame = new uint8[_wsaHeader._width * _wsaHeader._height];
assert(_currentFrame);
}
uint8* frameData = 0;
uint8 image40[64000]; // I think this crash on Plam OS :)
if (frame = _prefetchedFrame + 1) {
frameData = _buffer + _offsetTable[frame] + (hasPalette() ? 768 : 0);
Compression::decode80(frameData, image40);
Compression::decode40(image40, _currentFrame);
} else {
memset(_currentFrame, 0, _wsaHeader._width * _wsaHeader._height);
for (uint32 i = 0; i <= frame; i++)
{
frameData = _buffer + _offsetTable[i] + (hasPalette() ? 768 : 0);
Compression::decode80(frameData, image40);
Compression::decode40(image40, _currentFrame);
}
}
_prefetchedFrame = frame;
return _currentFrame;
}
return 0;
}
} // end of namespace Kyra
--- NEW FILE: wsamovie.h ---
/* ScummVM - Kyrandia Interpreter
* Copyright (C) 2003-2004 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header: /cvsroot/scummvm/scummvm/kyra/wsamovie.h,v 1.1 2004/10/15 06:06:47 ender Exp $
*
*/
#ifndef MOVIES_H
#define MOVIES_H
#include "resource.h"
namespace Kyra {
// a generic movie
class Movie {
public:
virtual ~Movie() {}
virtual const uint8* loadFrame(uint16 frame, uint16* width = 0, uint16* height = 0) = 0;
virtual uint16 countFrames(void) { return _frameCount; }
virtual bool hasPalette(void) { return (_ownPalette != 0); }
virtual Palette* palette(void) { return _ownPalette; }
protected:
uint16 _frameCount;
Palette* _ownPalette;
};
// movie format for Kyrandia 1
// there is also a new WSA Format for Kyrandia 2
// which i will implement in future
class WSAMovieV1 : public Movie {
public:
WSAMovieV1(uint8* data, uint32 size);
~WSAMovieV1();
const uint8* loadFrame(uint16 frame, uint16* width, uint16* height);
protected:
uint8* _buffer;
#pragma START_PACK_STRUCTS
struct WSAHeader {
uint16 _numFrames; // All right
uint16 _width; // should be right
uint16 _height; // should be right
uint8 _xPos; // could be wrong
uint8 _yPos; // could be wrong
uint16 _delta; // could be wrong
uint16 _type; // should be right
} GCC_PACK _wsaHeader;
#pragma END_PACK_STRUCTS
uint32* _offsetTable;
uint8* _currentFrame;
uint16 _prefetchedFrame;
};
} // end of namespace Kyra
#endif
Index: kyra.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/kyra.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- kyra.cpp 31 Jul 2004 09:31:15 -0000 1.2
+++ kyra.cpp 15 Oct 2004 06:06:47 -0000 1.3
@@ -1,5 +1,5 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2003 The ScummVM project
+/* ScummVM - Kyrandia Interpreter
+ * Copyright (C) 2003-2004 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -8,7 +8,7 @@
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
@@ -28,35 +28,58 @@
#include "sound/mixer.h"
#include "common/file.h"
#include "common/config-manager.h"
+
#include "kyra.h"
+#include "resource.h"
+#include "script.h"
-static const GameSettings kyra_setting =
- { "kyra", "Legend of Kyrandia", 0 };
+struct KyraGameSettings {
+ const char *name;
+ const char *description;
+ uint32 features;
+ const char *detectName;
+ GameSettings toGameSettings() const {
+ GameSettings dummy = { name, description, features };
+ return dummy;
+ }
+};
+
+static const KyraGameSettings kyra_settings[] = {
+ {"kyra1cd", "Legend of Kyrandia (CD)", GF_TALKIE & GF_KYRA1, "CHAPTER1.VRM"},
+ {"kyra1", "Legend of Kyrandia (Floppy)", GF_FLOPPY & GF_KYRA1, "INTRO.SND"},
+ { 0, 0, 0, 0}
+};
GameList Engine_KYRA_gameList() {
GameList games;
+ const KyraGameSettings *g = kyra_settings;
+
+ while (g->name) {
+ games.push_back(g->toGameSettings());
+ g++;
+ }
- games.push_back(kyra_setting);
return games;
}
-// TODO: Improve this :)
DetectedGameList Engine_KYRA_detectGames(const FSList &fslist) {
+ const KyraGameSettings *game;
DetectedGameList detectedGames;
- File test_file;
- // Iterate over all files in the given directory
- for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
- const char *name = file->displayName().c_str();
- if ((0 == scumm_stricmp("chapter1.vrm", name)) ||
- (0 == scumm_stricmp("chapter5.vrm", name))) {
- detectedGames.push_back(kyra_setting);
- printf("Detecting Kyra...\n");
- break;
+ for (game = kyra_settings; game->name; ++game) {
+ if (game->detectName == NULL)
+ continue;
+
+ for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
+ const char *name = file->displayName().c_str();
+ if ((!scumm_stricmp(game->detectName, name))) {
+ detectedGames.push_back(game->toGameSettings());
+ break;
+ }
}
}
- return detectedGames;
+ return detectedGames;
}
Engine *Engine_KYRA_create(GameDetector *detector, OSystem *syst) {
@@ -78,11 +101,37 @@
//getGameDataPath();
- // Initialize backend
- syst->initSize(320, 240);
+ // Initialize backen
+ syst->initSize(320, 200);
+ _screen = new uint8[320*200];
+ memset((void*)_screen, 0, sizeof(_screen));
+
+ _resMgr = new Resourcemanager(this, getGameDataPath());
+ assert(_resMgr);
+
+ setCurrentPalette(_resMgr->loadPalette("PALETTE.COL"));
+
+ // loads the 2 cursors
+ _mouse = _resMgr->loadImage("MOUSE.CPS"); //startup.pak
+ _items = _resMgr->loadImage("ITEMS.CPS");
+
+ // loads the Font
+ _font = _resMgr->loadFont("8FAT.FNT");
+ printf("loading scripts\n");
+ // loads out scripts
+ _npcScript = _resMgr->loadScript("_NPC.EMC");
+ _currentScript = _resMgr->loadScript("_STARTUP.EMC");
+ printf("done\n");
+
}
KyraEngine::~KyraEngine() {
+ delete _resMgr;
+ delete _mouse;
+ delete _items;
+ delete _npcScript;
+ delete _currentScript;
+ delete _font;
}
void KyraEngine::errorString(const char *buf1, char *buf2) {
@@ -91,10 +140,61 @@
void KyraEngine::go() {
warning("Kyrandia Engine ::go()");
+ // starts the init script
+ if (!_currentScript->startScript(kSetupScene)) {
+ error("couldn't init '_STARTUP.EMC' script");
+ }
+
+ if (_currentScript->contScript() != kScriptStopped) {
+ if (_currentScript->state() == kScriptError) {
+ error("couldn't run script");
+ } else {
+ warning("init script returned: %d", _currentScript->state());
+ }
+ }
+
+ while(true) {
+ OSystem::Event event;
+ //if (_debugger->isAttached())
+ // _debugger->onFrame();
+
+ updateScreen();
+ while (g_system->pollEvent(event)) {
+ switch (event.event_code) {
+ case OSystem::EVENT_QUIT:
+ g_system->quit();
+ break;
+ default:
+ break;
+ }
+ }
+ _system->delayMillis(10);
+ }
}
void KyraEngine::shutdown() {
_system->quit();
}
+
+void KyraEngine::updateScreen(void) {
+ _system->copyRectToScreen(_screen, 320, 0, 0, 320, 240);
+ _system->updateScreen();
+}
+
+void KyraEngine::setCurrentPalette(Palette* pal, bool delNextTime) {
+// if (_delPalNextTime)
+// delete _currentPal;
+
+// _delPalNextTime = delNextTime;
+
+// _currentPal = pal;
+
+ if (pal->getData()) {
+ _system->setPalette(pal->getData(), 0, 256);
+ } else {
+ warning("palette contains no data");
+ }
+}
+
} // End of namespace KYRA
Index: kyra.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/kyra.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- kyra.h 9 Apr 2004 12:36:06 -0000 1.1
+++ kyra.h 15 Oct 2004 06:06:47 -0000 1.2
@@ -22,26 +22,49 @@
#ifndef KYRA_H
#define KYRA_H
-#include "common/scummsys.h"
+//#include "common/scummsys.h"
#include "base/engine.h"
#include "base/gameDetector.h"
#include "common/util.h"
+enum {
+ GF_FLOPPY = 1 << 0,
+ GF_TALKIE = 1 << 1,
+ GF_KYRA1 = 1 << 2,
+ GF_KYRA2 = 1 << 3
+};
+
namespace Kyra {
+ class Resourcemanager;
+ class CPSImage;
+ class Font;
+ class Palette;
+ class VMContext;
class KyraEngine : public Engine {
-
+public:
+ KyraEngine(GameDetector *detector, OSystem *syst);
+ ~KyraEngine();
void errorString( const char *buf_input, char *buf_output);
+ void updateScreen(void);
+ void setCurrentPalette(Palette* pal, bool delNextTime = true);
+
+ Resourcemanager* resManager(void) { return _resMgr; }
+// MidiDriver* midiDriver(void) { return _midiDriver; }
+
protected:
void go();
void shutdown();
+ Resourcemanager* _resMgr;
+ uint8 *_screen;
-public:
-
- KyraEngine(GameDetector *detector, OSystem *syst);
- virtual ~KyraEngine();
+ Font* _font;
+ CPSImage* _mouse;
+ CPSImage* _items;
+ VMContext* _currentScript; // our current script
+ VMContext* _npcScript; // script from NPCs
};
} // End of namespace Kyra
Index: module.mk
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/module.mk,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- module.mk 9 Apr 2004 12:36:06 -0000 1.1
+++ module.mk 15 Oct 2004 06:06:47 -0000 1.2
@@ -1,7 +1,8 @@
MODULE := kyra
MODULE_OBJS = \
- kyra/kyra.o
+ kyra/kyra.o kyra/codecs.o kyra/script.o kyra/script_v1.o kyra/resource.o \
+ kyra/wsamovie.o kyra/palette.o kyra/cpsimage.o kyra/font.o
MODULE_DIRS += \
kyra
More information about the Scummvm-git-logs
mailing list